首页 > 解决方案 > 了解状态机中的干扰锁存器

问题描述

请看一下这个简单状态机的示例代码:

entity Top is
    Port ( Clock : in STD_LOGIC;
           Reset : in STD_LOGIC;
           TREADY : out STD_LOGIC
           );
end Top;

architecture Behavioral of Top is
    
    type STATE_t is (S0, S1, S2);
    signal CurrentState : STATE_t := S0;
    
    signal TREADY_Int   : STD_LOGIC := '0';
    
begin

    -- Transit network
    process(Clock, Reset, CurrentState)
        variable NextState : STATE_t;
    begin
        if(rising_edge(Clock)) then
            case CurrentState is
                when S0 =>
                    if(Reset = '1') then
                        NextState := S0;
                    else
                        NextState := S1;
                    end if;
                when S1 =>
                     NextState := S2;
                when S2 =>
                    NextState := S1;
            end case;
        end if;
        
        CurrentState <= NextState;
    end process;

    -- Output network
    process(CurrentState)
    begin
        if(CurrentState = S0) then
            TREADY_Int <= '0';
        elsif(CurrentState = S1) then
            TREADY_Int <= '1';
        elsif(CurrentState = S2) then
            TREADY_Int <= '0';
        end if;
    end process;
    
    TREADY <= TREADY_Int;

end Behavioral;

综合向我显示以下警告:

[Synth 8-327] inferring latch for variable 'TREADY_Int_reg'

带闩锁的示意图

当我将输出网络的最后一个条件更改为

    else
        TREADY_Int <= '0';
    end if;

闩锁也不见了

Schemativ 不带闩锁

那么为什么第一个版本中输出状态机的最后一个条件会导致锁存器呢?为什么else不是elsif()? 在我看来,这两个表达式是相等的,因为状态机只有三个状态,所以在处理所有其他状态elseelsif(<ThirdState>)应该是相同的。但似乎我的理解在这里是错误的。

标签: vhdlstate-machine

解决方案


通常最好不要假设合成器和你一样聪明。else正如您所发现的,使用更安全。

这是另一个例子。这个更好:

process (A, B)
begin
  if (A < B)
    F <= ...
  else
    F <= ...
  end if;
end process;

比这个:

process (A, B)
begin
  if (A < B)
    F <= ...
  end if;
  if (A >= B)
    F <= ...
  end if;
end process;

推荐阅读