这是编写 VHDL 异步复位代码的有效方法吗?

Is this a valid way to code a VHDL async reset?

我已经选择了一些 VHDL 代码来维护它有一个以我不熟悉的方式编写的重置。我不确定它是否有效,而且我的模拟器 (Modelsim) 发出了我不期望的警告。模式示例:

process(clk, reset_n)
begin
  if reset_n = '0' then
    counter <= (others=>'0');
  end if;
  if rising_edge(clk) then
    case state is
    when IDLE      =>
      if signal_a = signal_b then
        state <= DATA;
      end if;
    when DATA => 
      state <= IDLE;
    when others =>
    end case;
    if state = DATA then
      counter <= counter + 1;
    else
      counter <= (others => '0');
    end if;
  end if;
end process;

Modelsim 警告说 statesignal_asignal_b“在进程中读取但不在敏感列表中”。我不希望因为它们在时钟块中并且该过程对时钟敏感。

这是异步重置的有效编码风格吗?我希望看到的是 elsif rising_edge(clk),但我明白这会导致其他非重置信号 (state) 的混合出现问题。

此模式可能不会像您预期的那样运行,也可能不会合成(如果合成,则它不会与代码匹配)。

此代码使用时钟覆盖重置。如果复位被断言('0'),那么计数器将被复位,但是如果 clk 是 运行ning 它将 运行 就好像 reset_n'1'.这是因为进程仅由敏感列表中信号上的 'event' 触发,因此仅当 reset_n 更改为“0”时才会发生重置。这在 VHDL 中通常无关紧要,因为复位分支的优先级高于时钟。因此,如果它被计时,则采用复位分支。但是在这里,因为复位的优先级较低,所以就好像reset_n是一个负边沿时钟。

在实际硬件上,这是不同的。敏感列表通常会被忽略,硬件是根据流程中的代码构建的。我预计这将无法构建,因为它会抱怨没有与模板匹配的逻辑,或者双边缘触发器是不允许的。

要解决此问题,请按照您的建议将时钟分支设置为 elsif,并且您还需要将 state 添加到重置中以避免在 [=17= 上意外启用时钟],或将重置移动到进程的底部,它将正确覆盖时钟分配,并允许您在同一进程中混合使用重置和非重置寄存器。