对于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版本)在'a‘上创建one事件,这会导致cnt增加。这似乎也符合卡明斯先生在“舒适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愉快地切换开。这将是调试的噩梦。
发布于 2016-11-11 17:24:59
你的最后一个问题很容易解释。这并不是说模拟器只创建一个事件,而是没有--只有第一个事件安排@(posedge)恢复always过程,其他事件发生在NBA区域,然后总是块在下一个活动事件区域恢复执行。
我不能为其他模拟器的行为辩护。在实际硬件中,不允许对相同的触发器进行多次赋值,因此,您的类比并不是那么简单。它有可能有一个不定时的描述,并得到多个(@posedge's),而不需要时间。所以过滤会阻止这种编码方式。
https://stackoverflow.com/questions/40542597
复制相似问题