Я работаю над проектом, использующим VHDL, и столкнулся с проблемой во время одного из моих тестовых стендов. Я тестирую все входные комбинации для комбинационного компонента, используя цикл for в моем стимулирующем процессе, но у меня есть оператор case внутри цикла foor, который ведет себя не так, как я этого хочу.
Это сегмент кода, который ведет себя не так, как я хочу:
for i in 0 to 20 loop
case opcode is
when "01001" | "01010" | "01100" | "01110" | "10000" =>
d <= '0';
wait for period;
d <= '1';
when "00010" | "00100" | "00101" | "00110" | "10001" | "10010" | "10011" =>
d <= '1';
when others =>
d <= '0';
end case;
wait for period;
opcode <= opcode + 1;
end loop;
Например, я ожидаю, что d
станет 1
, когда opcode
станет 00010
. Однако в моделировании d
становится 1
, когда opcode
становится 00011
, а не 00010
(то же самое и для всех других случаев), как если бы значение, которое проверяет оператор case, уменьшается на 1. Я изменил opcode
внутри оператора case на opcode+1
, и это сработало. правильно. Я знаю, что VHDL — это язык описания оборудования и что его поведение отличается от языка программирования, но я до сих пор не могу понять, почему это происходит, и хотел бы получить объяснение.
Компонент, который я тестирую, комбинационный, у меня нет часов.
Я искал «дельта-гонку», и на самом деле это была дельта-гонка, но в моем коде моделирования! Значение opcode
обновляется, но все еще не воспринимается стимулирующим процессом, поэтому оператор case проверяет наличие устаревшего opcode
и обновляется только после того, как я нажму wait for period
. Я вставил wait for 0 ns;
в начале цикла for, чтобы запустить новый дельта-цикл вручную, и это сработало! Спасибо!
Симулятор не «обнаруживает» обновление сигнала opcode
до тех пор, пока не попадет в оператор ожидания. Добавление wait for 0 ns;
в начале цикла решает проблему.
Вместо
wait for period
попробуйтеwait until rising_edge(clk)
. Я подозреваю, что у вас дельта-гонка