У меня есть следующий простой FSM описание в VHDL:Почему этот FSM не достигает покрытия 100% кода?
library ieee;
use ieee.std_logic_1164.all;
entity coverage1 is
port (
clk : in std_logic;
rst : in std_logic;
req : in std_logic;
ack : out std_logic
);
end entity coverage1;
architecture rtl of coverage1 is
type STATES is (IDLE, RUNNING, FINISH);
signal fsm_cs : STATES := IDLE;
signal fsm_ns : STATES;
begin
process (fsm_cs, req) is
begin
fsm_ns <= fsm_cs;
ack <= '0';
case fsm_cs is
when IDLE =>
if req = '1' then
fsm_ns <= RUNNING;
end if;
when RUNNING =>
fsm_ns <= FINISH;
when FINISH =>
ack <= '1';
fsm_ns <= IDLE;
when others =>
null;
end case;
end process;
process (clk) is
begin
if rising_edge(clk) then
if rst = '1' then
fsm_cs <= IDLE;
else
fsm_cs <= fsm_ns;
end if;
end if;
end process;
end architecture;
И этот испытательный стенд:
library ieee;
use ieee.std_logic_1164.all;
entity coverage1_tb is
end entity coverage1_tb;
architecture tb of coverage1_tb is
signal clk : std_logic := '1';
signal rst : std_logic;
signal req : std_logic;
signal ack : std_logic;
signal finished : boolean := false;
begin
coverage1_1: entity work.coverage1
port map (
clk => clk,
rst => rst,
req => req,
rdy => rdy,
ack => ack);
clk <= not clk after 5 ns when not finished else unaffected;
process
begin
rst <= '1';
wait until rising_edge(clk);
rst <= '0';
req <= '0';
wait until rising_edge(clk);
req <= '1';
wait until rising_edge(clk);
req <= '0';
wait until rising_edge(clk) and ack = '1';
wait until rising_edge(clk);
finished <= true;
wait;
end process;
end architecture tb;
ФШМ не достигает покрытия кода 100% в ModelSim/QuestaSim. Я нашел две проблемы:
остальные дела, в которых не требуется, поскольку перечисление полностью покрывается за счет всех вариантов, предлагается покрыть. Но эта ветка недоступна ... Почему QuestaSim ожидает покрытия для этой ветки?
QuestaSim показывает диаграмму ложного состояния для моего примера FSM. Диаграмма содержит собственные ребра для состояний:
RUNNING
иFINISH
. Эти края не существуют и не могут быть покрыты.
Если я удалю присвоение по умолчаниюfsm_ns <= fsm_cs;
и добавлю ветку else в состояние IDLE, я получу полное покрытие.if req = '1' then fsm_ns <= RUNNING; else fsm_ns <= IDLE; end if;
Почему диаграмма состояний показывают ложные ребра и почему я не могу использовать задания по умолчанию?
Я могу жить с номером 1, но пункт 2 является проблемой. Если я напишу свои FSM в этом стиле, я дублирую много ненужного кода, и большинство синтезаторов не узнают шаблон FSM! Поэтому я потеряю оптимизацию FSM и проведу синтез.
Что делать, если вы удалите корпус 'other'? Тогда QuestaSim не может потребовать, чтобы он был закрыт. Или вы имеете в виду, что он жалуется, что нет «других», хотя все дела обрабатываются в явном виде? – mkrieger1
Я могу удалить другой случай, но если квесты терпят неудачу на таком простом примере, что происходит в более сложных сценариях? – Paebbels