【问题标题】:Why does this FSM not reach 100% code coverage?为什么这个 FSM 没有达到 100% 的代码覆盖率?
【发布时间】:2017-02-06 23:34:43
【问题描述】:

我在 VHDL 中有以下简单的 FSM 描述:

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;

在 ModelSim/QuestaSim 中,FSM 没有达到 100% 的代码覆盖率。我发现了两个问题:

  1. 其他情况,由于枚举被所有选项完全覆盖,因此不需要覆盖。但是无法访问此分支... 为什么 QuestaSim 期望覆盖此分支?

  2. QuestaSim 显示了我的示例 FSM 的错误状态图。该图包含状态的自边:RUNNINGFINISH。这些边缘不存在,也无法被覆盖。
    如果我删除默认分配 fsm_ns &lt;= fsm_cs; 并在 IDLE 状态下添加一个 else 分支,我将获得完全覆盖。

    if req = '1' then
      fsm_ns <= RUNNING;
    else
      fsm_ns <= IDLE;
    end if;
    

    为什么状态图显示假边,为什么我不能使用默认分配?

我可以接受第 1 项,但第 2 项是个问题。如果我以这种风格编写我的 FSM,我会复制很多不需要的代码,并且大多数合成器将无法识别 FSM 模式!所以我将失去 FSM 优化和综合检查。

【问题讨论】:

  • 如果您删除others 案例会怎样?然后 QuestaSim 不能要求它被覆盖。或者你的意思是如果没有others它就会抱怨,即使所有情况都被显式处理?
  • 我可以删除其他情况,但是如果在这样一个简单的示例中任务失败,那么在更复杂的情况下会发生什么?
  • 10.9 案例陈述告诉我们其他选择在这里是合法的。根据类型 STATES 确定选择超出了代码执行分析工具的范围,而不超出了 case 语句的 VHDL 分析范围。 tmeissner 的 --coverage off/on 似乎是一个有效的解决方案。正如 Brian 所暗示的那样,您在测试台中缺少端口 rdy 的实际声明。

标签: vhdl code-coverage modelsim questasim


【解决方案1】:

一些观察,再次使用 ghdl。

注释掉rdy 端口后,ghdl 再次报告100% 的覆盖率。

具有讽刺意味的是,“others”子句中的null 获得了 20 次点击……这很可疑。由于它是流程中的最后一条活动线,我相信任何唤醒流程但不执行任何操作的事件都会记录在这里。

end case 之后添加的null; 收集了这 20 个命中,证实了这一点 - 但 others 案例仍未记录为覆盖漏洞(尽管没有命中)。我的假设是因为null 没有生成代码,所以它没有被跟踪。向when others 分支添加一个无害但可跟踪的操作fsm_ns &lt;= IDLE; 现在会产生一个覆盖漏洞(令人讨厌的是,当end case 之后的null 被删除时,它会收到虚假命中。

总结:

  • 值得在when othersnull 之后测试活动语句的效果作为跟踪覆盖率的钩子end case 以便“进程结束”代码不会错误地记录在最后一个案例臂上
  • ghdl 需要在这两个方面进行一些整理,也许将null 翻译为“nop”以将覆盖范围挂钩。

抱歉,我无法在此处阐明 Modelsim 的行为。

但是,存在但无法访问的代码 - “死代码” - 被视为代表高完整性实践中的设计错误,因此我认为 Modelsim 正确地突出显示它,而 ghdl 则在它没有的情况下不正确.

这与安全状态机设计问题有些相关,其中 SEU(可能来自宇宙射线)会破坏状态寄存器。请注意,如果STATES 的成员少于 2**n 个,则将出现“其他”状态,并且通过 null 操作,如果此 SM 达到该状态,它将锁定在那里。 (但是,删除“others”子句并不能纠正这一点,综合工具可能会断定“others”子句不可达并删除它。安全 SM 设计是另一个主题)

【讨论】:

    【解决方案2】:
    1. 当其他人按预期显示为未覆盖时。您可以使用以下命令排除它:

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

      我在其他情况不能出现的每个案例陈述中都这样做 命中。

    2. 即使没有 else 分支,我也能获得 100% 的状态覆盖率。 IDLE 状态下的 if 条件具有 100% 的分支覆盖率,即使没有 else 分支 (Active: 4, True Hits: 1, AllFalse: 3)。对于 100% FSM 覆盖,您应该排除复位信号的隐含变化,或者您必须在每个 FSM 状态下拉复位。您可以在编译时使用-nofsmresettrans swith 排除重置状态更改。

    我使用 Modelsim DE 10.5c 和 10.6 以及 Questa 10.6 得到了相同的行为。

    顺便说一句:如果 FSM 的某些部分位于依赖于泛型的生成块内,我将无法获得 FSM 覆盖,因此我不得不对生成的内容进行评论,并且只保留其中一个重置过程。我认为这是 Modelsim/Questa 的限制,它不能识别生成块内的 FSM,但我不是。该帮助还暗示使用泛型的 FSM 未得到认可。也许这里就是这种情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-17
      • 2015-06-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多