2017-02-06 2 views
1

У меня есть следующий простой 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. Я нашел две проблемы:

  1. остальные дела, в которых не требуется, поскольку перечисление полностью покрывается за счет всех вариантов, предлагается покрыть. Но эта ветка недоступна ... Почему QuestaSim ожидает покрытия для этой ветки?

  2. 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 и проведу синтез.

+0

Что делать, если вы удалите корпус 'other'? Тогда QuestaSim не может потребовать, чтобы он был закрыт. Или вы имеете в виду, что он жалуется, что нет «других», хотя все дела обрабатываются в явном виде? – mkrieger1

+0

Я могу удалить другой случай, но если квесты терпят неудачу на таком простом примере, что происходит в более сложных сценариях? – Paebbels

ответ

2

Некоторые наблюдения, снова используя ghdl.

Комментируя порт rdy, ghdl снова сообщает о покрытии 100%.

По иронии судьбы null в статье «другие» получает 20 обращений ... что вызывает подозрение. Поскольку это последняя активная линия в этом процессе, я считаю, что здесь происходят события, которые пробуждают этот процесс, но ничего не делают.

null; добавил после end case собирает эти 20 хитов, подтверждающим это, - но others дела до сих пор не записываются как отверстие покрытия (несмотря на отсутствие хитов). Моя гипотеза заключается в том, что поскольку null не генерирует код, он не отслеживается. Добавление безвредных, но отслеживаются действиями fsm_ns <= IDLE; к when others ветви теперь дает отверстие покрытия (которое, раздражающе, получает ложные удары, когда null после end case удаляется

Резюме:.

  • это стоит испытывать эффект активное утверждение как крюк для покрытия отслеживания в when others и null после end case так, что «конца процесса» код не неправильно вошедшие в последнем случае руках
  • ghdl нуждается в некоторых уборках в этих двух областях, perha ps перевод null как 'nop' для захвата покрытия.

enter image description here

К сожалению, я не могу пролить свет на поведение ModelSim здесь.

Однако код, который присутствует, но не достижим - «мертвый код» - рассматривается как представляющий ошибку дизайна в практике с высокой степенью целостности, поэтому я считаю, что Modelsim правильно выделяет его, а ghdl является неправильным в тех случаях, когда он делает не.

Это связано с вопросом о создании безопасного государственного автомата, где SEU (возможно, из космического луча) разлагает государственный регистр. Обратите внимание, что с менее чем 2 ** n членами STATES, будет «другое» состояние, и с действием null этот SM закроется там, если он когда-либо достигнет этого состояния. (Тем не менее, удаление «другое» положение не исправить, что и инструмент синтеза может заключить «другие» пункт недостижим и удалить его в любом случае. Safe SM является еще одной темой)

1
  1. , когда другие отображается как не охваченный, как ожидалось. Вы можете исключить его с помощью:

    -- coverage off 
    when others => null; 
    -- coverage on 
    

    Я делаю это в любом случае заявление, где другие дело не может быть хитом.

  2. Я получаю 100% покрытие штата, даже без ветви else. Значение if условно в состоянии IDLE имеет 100% -ное покрытие ветви, даже без ветви else (Active: 4, True Hits: 1, AllFalse: 3). Для покрытия 100% FSM вы должны исключить неявные изменения по сигналу сброса, или вам нужно выполнить сброс в каждом состоянии FSM. При компиляции вы можете исключить изменения состояния сброса с помощью -nofsmresettrans swith.

Я получаю такое же поведение, используя Modelsim DE 10.5c и 10.6 и Questa 10.6.

BTW: Я не могу получить покрытие FSM, если части FSM находятся внутри генерирующего блока, который зависит от общего типа, поэтому мне пришлось вытеснить генерирующий материал и оставить его только в одном из процессов сброса. Я думаю, что это ограничение Modelsim/Questa, которое не распознает FSM внутри блоков генерации, но я не знаю. В помощи также намекает, что FSM, использующие дженерики, не распознаются. Может быть, здесь и здесь.

Смежные вопросы