5

让我们看下面的示例代码:

always @(posedge clock)
   begin
   if (reset == 1)
     begin
        something <= 0
     end
   end

现在假设重置从 0 变为 1,同时时钟有一个姿势。那时会有东西<= 0吗?或者下次有时钟摆位时会发生这种情况(假设重置保持在1)?

4

4 回答 4

3

如果reset是同步的并且基于clock,模拟器将在下一个时钟而不是当前时钟上看到重置。物理设计具有时钟到 Q,因此在导致它的同一时钟中不会观察到复位上升。您可能会在波形中看到与时钟同时复位。reset <= 1'b1;使分配发生在调度程序的末尾附近(在所有代码执行之后)。

为了在查看波形时不必担心这一点,一些逻辑设计人员喜欢在分配上设置延迟,从而创建人为的时钟到 Q 延迟(例如reset <= #1 1'b1;something <=#1 0;)。综合工具会忽略延迟,但有些会给出警告。使用宏可以避免该警告。

`ifdef SYNTHESIS
`define Q   /* blank */
`else
`define Q #1
`endif
...
reset <= `Q 1'b1;
...
something <=`Q 1'b1;
...

如果reset是异步的并且与同步复位一起使用,则需要遵守建立时间要求。在模拟中,如果时钟和复位同时上升,则由您的 Verilog 调度程序决定复位是新值还是旧值。通常它将采用左侧值(旧值),这意味着在当前时钟上将错过复位。物理设计的不确定性以及亚稳定性风险。

于 2013-07-08T20:18:13.453 回答
2

这取决于究竟是如何reset驱动的。

如果resetsomething都被同一个时钟触发,那么在复位为 1 后的一个时钟周期内,某些东西将变为 0。例如:

always @(posedge clock)
   begin
   if (somethingelse)
     begin
        reset <= 1;
     end
   end
于 2013-07-08T19:54:30.557 回答
1

您编写的代码推断出具有同步复位的触发器。这意味着假设“复位”信号在以这种方式使用之前与“时钟”域同步。如果“复位”信号不同步,那么您应该修改代码以推断具有异步复位的触发器,如下所示:

always@(posedge clock or posedge reset)
begin
  if (reset)
    something <= 0
  else 
    something <= something_else
end

回到您的问题并假设您编写的代码是您想要的,结果取决于重置的驱动方式。如果它是同步的,那么模拟器将在下一个时钟沿看到它。如果它是异步的,那么模拟器可以假设任何东西,它可能因模拟器而异。请注意,在模拟器中,一切都是一系列事件,没有同时发生的事情。

在物理世界中,您编写的代码将生成一个触发器,其复位信号是驱动该触发器输入的组合的输入之一。现在,如果复位是同步的,则可以保证在此 flop 不会发生建立或保持违规。触发器是否会在这个时钟或下一个时钟中“看到”复位取决于合成电路的各种延迟(通常这是复位始终保持几个时钟周期以确保设计中的所有触发器的主要原因看到重置)。如果复位是异步的,那么触发器将进入亚稳态。你永远不会在你的设计中想要这个。希望这可以澄清。

于 2013-07-12T09:32:30.173 回答
0

简短的回答是,您的两个结果中的任何一个(立即或下一个周期)都可能发生。这是一个标准的竞态条件,模拟器可以自由地以任何他们想要的方式处理它;有些人会给出一个答案,而另一些人会给出另一个答案。

对于长答案,请查看有关 VHDL delta 周期如何工作的任何介绍性文本。Verilog 没有指定“增量周期”,但任何 Verilog 模拟器都将以完全相同的方式工作,只是在整体调度算法中有一些(不相关的)变化。在这种情况下,调度程序发现它在特定增量的队列中有两个事件 - 复位上升和时钟上升。这就是“同时”的意思。它以未指定的方式选择一个(例如,它可能在文本源中较早或较晚),处理与该边缘相关的所有更改,然后返回并处理与另一边缘相关的所有更改。

于 2013-07-09T07:54:25.687 回答