Пожалуйста, взгляните на этот пример кода простого конечного автомата:
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;
а еще защелка пропала
Так почему же последнее условие конечного автомата вывода в первой версии приводит к защелке? Почему else
не elsif ()
? На мой взгляд, эти два выражения равны, потому что конечный автомат имеет только три состояния, поэтому else
и elsif (<ThirdState>)
должны быть одинаковыми при обработке всех остальных состояний. Но, похоже, мое понимание здесь неверно.
Нет, не думаю. В связанной теме обсуждается ошибка во время условия if с STD_LOGIC, когда пользователь не обрабатывает все случаи (STD_LOGIC имеет 9 состояний) и без часов, поэтому защелка вполне нормальна. В этом разделе обсуждается предстоящая защелка в автомате состояний с синхронизацией, где обрабатываются все состояния.
№ IEEE Std 1076-2008 16.8 Стандартные пакеты синтеза, 16.8.2 Интерпретация стандартных логических типов, 16.8.2.2 Значения STD_LOGIC_1164. Защелка TREADY_int для первого результата синтеза не имеет ничего общего с базовым типом std_ulogic, имеющим 9 значений перечисления.
Вы правы, извините.
Обычно лучше не думать, что синтезатор так же умен, как и вы. Использование 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;
Возможный дубликат Почему я получаю предполагаемые защелки?