【问题标题】:Design of "simple" VHDL module still drives me mad“简单”的 VHDL 模块的设计仍然让我抓狂
【发布时间】:2011-07-05 07:00:36
【问题描述】:

感谢您的所有意见,我实施了您的建议,但问题仍然存在。模拟结果工作正常,但硬件 输出不同的东西。简单回顾一下,我有两个确定实体行为的 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;

测试程序

   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 综合,会不会因为我的架构中没有复位信号而导致实例化了错误类型的锁存器?

非常感谢 cmets 进一步帮助解决此问题, 帕特里克

【问题讨论】:

    标签: hardware vhdl hdl


    【解决方案1】:

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

    【讨论】:

    • 我不得不承认我不确定如何检查。我刚刚检查了在合成过程中没有出现闩锁和其他警告。此外,该设计不违反关键路径。我可以重新设计我的模块以避免这种竞争条件吗?非常感谢
    • 我不是在谈论设计,而是在讨论输入信号/时钟在硬件上的实际应用方式,即输入信号不应在时钟上升沿附近变化。
    猜你喜欢
    • 1970-01-01
    • 2010-11-19
    • 1970-01-01
    • 1970-01-01
    • 2014-03-25
    • 2010-12-29
    • 1970-01-01
    • 1970-01-01
    • 2011-05-09
    相关资源
    最近更新 更多