Verilog 关于触发always块的问题

Verilog 关于触发always块的问题,verilog,system-verilog,execution,hdl,Verilog,System Verilog,Execution,Hdl,我知道一个always块将在其敏感度列表中的任何元素发生更改时被触发。然而,我的问题是,如果敏感度列表发生更改,而always块中的语句由于之前的触发器仍在执行,会发生什么情况。always块是在并行线程中再次开始执行,还是在第一次执行完成之前触发被阻止?每个always块都是单个线程,除非它包含fork join。因此,如果它正在执行,它不会在敏感度列表中的某些内容发生更改时重新触发。如果它确实包含一个fork-join,那么一旦触发,它将分裂为多个线程,但不会再次触发。除非它包含fork-j

我知道一个always块将在其敏感度列表中的任何元素发生更改时被触发。然而,我的问题是,如果敏感度列表发生更改,而always块中的语句由于之前的触发器仍在执行,会发生什么情况。always块是在并行线程中再次开始执行,还是在第一次执行完成之前触发被阻止?

每个always块都是单个线程,除非它包含fork join。因此,如果它正在执行,它不会在敏感度列表中的某些内容发生更改时重新触发。如果它确实包含一个fork-join,那么一旦触发,它将分裂为多个线程,但不会再次触发。

除非它包含fork-join,否则每个always块都是一个线程。因此,如果它正在执行,它不会在敏感度列表中的某些内容发生更改时重新触发。如果它确实包含fork-join,那么一旦触发,它将分裂为多个线程,但不会再次触发。

一旦触发always块,它将从头到尾执行。Verilog是一个单线程模拟引擎,因此一次只能执行一个块。执行always块时不会发生任何其他情况,除非它包含delay语句或WAIT on事件。在后一种情况下,它只会屈服 若要允许执行其他块,则继续执行

如果“始终”块在执行结束时更改其输入,则下一个模拟行为取决于该块的类型:

所有v95/v2k始终块,例如始终@*将重新触发, 系统verilog块(例如,always_comb)不会在当前增量循环中重新触发。 使用v2k/v95 always块,如果不小心的话,最终可能会出现零延迟循环。换句话说,模拟可以挂起


使用SystemVerilog块,当变量在写入同一块之前被读取时,您可以获得一个有趣的先读后写条件。这可能会造成模拟/合成不匹配

一旦触发always块,它将从头到尾执行。Verilog是一个单线程模拟引擎,因此一次只能执行一个块。执行always块时不会发生任何其他情况,除非它包含delay语句或WAIT on事件。在后一种情况下,它只会屈服 若要允许执行其他块,则继续执行

如果“始终”块在执行结束时更改其输入,则下一个模拟行为取决于该块的类型:

所有v95/v2k始终块,例如始终@*将重新触发, 系统verilog块(例如,always_comb)不会在当前增量循环中重新触发。 使用v2k/v95 always块,如果不小心的话,最终可能会出现零延迟循环。换句话说,模拟可以挂起


使用SystemVerilog块,当变量在写入同一块之前被读取时,您可以获得一个有趣的先读后写条件。这可能会造成模拟/合成不匹配

许多人没有意识到@是一个语句修饰符,而不是自己构造的。它说要推迟接下来的声明,直到发生事件@A或B表示等待,直到A或B的值发生变化,不要与A | B结果的变化混淆。@*表示查看下面的语句,并建立等待变化的信号的隐式灵敏度列表

always @(A or B) C = A + B;
always begin
         @(A or B) C = A + B;
       end
always begin
         @* C = A + B;
       end
always_comb
       begin
         C = A + B;
       end
这4个always块具有相同的行为,但最后一个always_梳除外。无论A或B上有任何更改,它也会在时间0触发

如果您将遵循始终作为执行语句的过程序列来查看代码,则更容易将@construct视为该过程序列的一部分,并且更改必须在执行该构造时发生。仅仅增加一个延迟就表明这个概念是不可合成的

always @(A or B) begin
         #10 C = A + B;
       end

这表示等待a或B上的更改,然后再等待10个时间单位,然后将当前值a+B分配给C。如果a或B在10个时间单位的等待期间更改,则该更改将丢失。在这10个时间单位之后,您必须等待A或B上的另一个更改。

许多人没有意识到@是一个语句修饰符,而不是自己构造的。它说要推迟接下来的声明,直到发生事件@A或B表示等待,直到A或B的值发生变化,不要与A | B结果的变化混淆。@*表示查看下面的语句,并建立等待变化的信号的隐式灵敏度列表

always @(A or B) C = A + B;
always begin
         @(A or B) C = A + B;
       end
always begin
         @* C = A + B;
       end
always_comb
       begin
         C = A + B;
       end
这4个always块具有相同的行为,但最后一个always_梳除外。无论A或B上有任何更改,它也会在时间0触发

如果您将遵循始终作为执行语句的过程序列来查看代码,则更容易将@construct视为该过程序列的一部分,而 在执行构造时必须进行更改。仅仅增加一个延迟就表明这个概念是不可合成的

always @(A or B) begin
         #10 C = A + B;
       end

这表示等待a或B上的更改,然后再等待10个时间单位,然后将当前值a+B分配给C。如果a或B在10个时间单位的等待期间更改,则该更改将丢失。在这10个时间单位之后,您必须等待A或B上的另一个更改。

Verilog和SystemVerilog之间没有区别。如果有任何类型的always block反馈回路,则可能出现零延迟振荡。说明:在v2k/v95中,可以有一个零延迟回路,该回路涉及一个或多个always block和赋值。使用system verilog,您可以使用多个块和仅分配的循环。您从哪里获得这些信息?第9.2.2.2.2节always_comb与always@*的比较明确提到了always_comb和always@*之间的区别,它提到的关于多个always的唯一区别是允许在单独的块中对同一变量进行赋值。这里没有这个区别。仔细阅读9.2.2.2.1。它来自于这个部分。此外,此行为至少在3种工具中实现:vcs、nc和aldera。这指的是没有敏感度列表的始终块,而这不是OP所要求的。Verilog和SystemVerilog之间没有区别。如果有任何类型的always block反馈回路,则可能出现零延迟振荡。说明:在v2k/v95中,可以有一个零延迟回路,该回路涉及一个或多个always block和赋值。使用system verilog,您可以使用多个块和仅分配的循环。您从哪里获得这些信息?第9.2.2.2.2节always_comb与always@*的比较明确提到了always_comb和always@*之间的区别,它提到的关于多个always的唯一区别是允许在单独的块中对同一变量进行赋值。这里没有这个区别。仔细阅读9.2.2.2.1。它来自于这个部分。此外,这种行为至少在3种工具中实现:vcs、nc和aldera。这是指一个始终没有敏感度列表的块,而不是OP所要求的。