Systemverilog规则4.7(非确定性)由vcs vs iverilog / modelsim

时间:2016-11-11 06:50:03

标签: version-control system-verilog iverilog

我仍然对SystemVerilog 2012规则4.7的实施方式感到困惑。 规则规定在这种情况下:

module test;
  logic a;
  integer cnt;

  initial begin
    cnt = 0;
    #100;
    a <= 0;
    a <= 1;
    a <= 0;
    a <= 1;
    a <= 0;
  end

  always @(posedge a)
    begin
      cnt <= cnt + 1;
    end
endmodule

所有分配都将在非阻塞分配队列上进行调度,然后必须按顺序执行。最后一个值获胜。 到目前为止,一切都很清楚。

接下来会发生什么,但对于所有模拟器来说都不一样。 iverilog和Modelsim(至少是Vivado 2016/3版)在&#39; a&#39;上创建一个事件,这会导致cnt递增。这似乎也符合Cummings先生在SNUG 2000上的行为

然而,

VCS过滤掉中间值并仅应用最后一个值,顺便说一下,这也是真正的触发器工作的方式。

在这种情况下,它不是一个纯粹的假设讨论,模拟结果是不同的,并且iverilog / modelsim行为可能导致很难捕获的错误,因为触发器切换但波形中没有看到值变化。

另一点是:如果iverilog / modelsim是正确的,为什么他们会创建一个事件而不是两个?

编辑: 补充说明。

上面的例子确实不是很有意义。 一个更现实的案例是

always @(posedge clk)
  begin
    clk2 <= 1'b1;
    if (somecondition)
      clk2 <= 1'b0;
  end

always @(posedge clk2, negedge rst_n)
  begin
    if (!rst_n)
      q <= 1'b0;
    else
      q <= ~q;
end

这是完全合法的,在真正的硬件中永远不会出现问题。 第一个总是在逻辑上与

完全相同
always @(posedge clk)
  begin
    if (somecondition)
      clk2 <= 1'b0;
    else
      clk2 <= 1'b1;
  end

但是,如果你使用ModelSim模拟第一个版本,你会看到你的q愉快地切换,clk2常数为0.这将是一个调试的噩梦。

1 个答案:

答案 0 :(得分:1)

您的上一个问题很容易解释。并非模拟器只创建一个事件,他们不会认为只有第一个事件安排@(posedge)恢复always进程而其他事件发生在NBA区域之前总是阻止在下一个活动区域恢复执行。

我不能证明其他模拟器的行为是正确的。你不允许在真实硬件中对同一个触发器进行多次分配,所以你不能这么简单地进行类比。可以有一个不定时的描述,并且可以在没有时间的情况下获得多个(@ posedge&#39; s)。因此过滤会阻止编码风格。