“简单”VHDL模块的设计仍然让我很生气

时间:2011-02-27 16:16:11

标签: hardware vhdl hdl

感谢您的所有意见,我实施了您的建议,但问题仍然存在。仿真结果很好,但硬件 输出不同的东西。简单地回顾一下,我有两个ctrl信号来确定实体的行为:

GET    (ctrl = "00000000") sets register tx to input of op1
SH1_L (ctrl = "00000001")  res := (op1 << 1) | tx;
                           tx  := tx >> 31;

这是VHDL代码:

    library ieee;
    use ieee.std_logic_1164.all;

     entity test is
     port
     (
       op1   : in  std_logic_vector(31 downto 0);      -- Input operand
       ctrl   : in std_logic_vector(7 downto 0);          -- Control signal
       clk   : in  std_logic;                                     -- clock
       res   : out std_logic_vector(31 downto 0)       -- Result
     );
     end;

     architecture rtl of test is

       type res_sel_type is (GET, SH1_L);

       constant Z : std_logic_vector(31 downto 0) := (others => '0');

       signal res_sel  : res_sel_type;
       signal load      : std_logic := '0';
       signal shl        : std_logic := '0';

       signal tx        : std_logic_vector(31 downto 0) := (others => '0');
       signal inp1    : std_logic_vector(31 downto 0) := (others => '0');

     begin

       dec_op: process (ctrl, op1)
       begin

         res_sel  <= GET;
         load      <= '0';
         shl        <= '0';
         inp1      <= ( others => '0');

         case ctrl is

            -- store operand
                when "00000000" =>
                   inp1      <= op1;
                   load      <= '1';
                   res_sel <= GET;

                -- 1-bit left-shift with carry
                when "00000001" =>
                 inp1      <= op1;
                 shl        <= '1';
                 res_sel <= SH1_L;

                when others =>
                   -- Leave default values

                end case;

       end process;

       sel_out: process (res_sel, inp1, tx)
       begin

         case res_sel is

          when SH1_L =>
           res  <= ( inp1(30 downto 0) & '0' ) or tx;

           when others =>
           res <= (others => '0');

         end case;

       end process;

       sync: process(clk)
       begin
        if clk'event and clk = '1' then
             if load = '1' then
                tx <= op1;
             elsif shl = '1' then
                tx <= Z(30 downto 0) & op1(31);
             end if;
       end if;
       end process;

     end rtl;

TESTPROGRAM

   GET  0               (this sets tx <= 0 )
   SH1_L 0xfedcba90     exp. output: 0xfdb97520  act. output = 0xfdb97521
   SH1_L 0x7654321f     exp. output: 0xeca8643f  act. output = 0xeca8643f
   SH1_L 0x71234567     exp. output: 0xe2468ace  act. output = 0xe2468ace

如您所见,第一个SH1_L操作的最后一位是错误的。第一个SH1_L操作产生NEXT SH1_L操作的进位 MSB被设置为输入之一,但是,似乎在当前SH1_L操作中已经考虑了这个进位,这是错误的(t​​x应该为零)。 我检查了综合报告并且没有锁存器,所以我有点无能为力,几乎绝望在这里出了什么问题。我使用Xilinx ISE 12.1 合成,可能会出现问题,因为我的架构中没有复位信号,错误的锁存器被实例化了吗?

非常感谢您提供进一步的有用评论来解决这个问题, 帕特里克

1 个答案:

答案 0 :(得分:0)

与RTL仿真不同,输入和时钟的实际时序并不理想。例如,时钟树可能具有比输入缓冲器更长的延迟,反之亦然。你考虑过这个吗?