在Verilog中始终在块内触发的始终块的评估顺序?

时间:2017-10-29 01:58:19

标签: verilog

我理解,对于具有相同触发器的2个始终块,它们的评估顺序是完全不可预测的。

但是,假设我有:

always @(a) begin : blockX 
c = 0;
d = a + 2;
if(c != 1) e = 2;
end

always @(a) begin : blockY 
e = 3;
end

always @(d) begin : blockZ 
c = 1;
e = 1;
end

假设块X首先进行评估。在blockX中更改d会立即跳转到blockZ吗?如果不是,何时对blockY进行blockZ评估?

我的程序员的本能将事件序列视为一个堆栈,其中评估blockX就像对blockZ的函数调用一样,我立即跳转到代码中,然后完成对blockX的评估。

但是,因为我们调用活动事件队列,好吧,一个队列,这表明blockZ在活动事件队列的后面排队,并且我100%保证它将被最后评估(除非有其他触发总是阻止)。

还有中间可能性,它既不是第一个也不是最后一个,而是以随机和不可预测的顺序进行评估。

所以在这个例子中,e的所有可能的最终值都是1,2或3,具体取决于编译器在运行时的感觉?

此外,虽然我理解,当然,这代表了糟糕的风格,我可以在哪里找到这种behvaior的规范?

1 个答案:

答案 0 :(得分:1)

始终阻止不是函数调用。请参阅recent answer我刚才提出的类似问题。这些块是并发进程。 LRM仅保证begin/end块内语句的排序。并发执行begin/end块之间没有定义的顺序(参见章节4.7 1800-2012 LRM中的不确定性)因此,只要模拟器遵循单个块中的顺序,模拟器就可以以任何方式自由交错语句。

所以你是正确的e可能有最终值1,2或3,具体取决于模拟器决定如何实现和优化代码。