Verilog始终使用(*)符号阻塞

Verilog始终使用(*)符号阻塞,verilog,Verilog,我有一个关于如何在Verilog模块中编写始终块的简单问题。 如果我的Verilog模块中有以下输入: input [31:0] PCplus4 ; // Value of PC + 4 input [31:0] A; // Value A, i.e. RSbus (Use Forwarded Value) input [31:0] B; // Value B, i.e. RTbus (Use Forwar

我有一个关于如何在Verilog模块中编写
始终
块的简单问题。
如果我的Verilog模块中有以下输入:

input        [31:0] PCplus4 ;       // Value of PC + 4
input        [31:0] A;          // Value A, i.e. RSbus (Use Forwarded Value)
input        [31:0] B;          // Value B, i.e. RTbus (Use Forwarded Value)
input        [31:0] IMM;            // Extended Immediate Value
input        [25:0] TARGET;         // Target Address for Jumps
input         [3:0] BR;         // Branch Selector Input
如果我使用,有什么区别吗

always @ (*)  
而不是

always @ (PCplus4  or A or B or IMM or TARGET or BR)  
始终(*)
语法对所有版本的Verilog有效吗?

始终(*)
语法于2001年添加到IEEE Verilog Std中。所有现代Verilog工具(模拟器、合成等)都支持这种语法

以下是LRM(1800-2009)的报价:

不完整的事件\表达式列表 事件控件是常见的事件源 寄存器传输级别(RTL)中的错误 模拟。含蓄的 event_表达式@*是一个方便的 消除这些问题的速记法 通过添加所有网络和 由 语句(可以是语句) (组)的一个程序性事件_ 控制_语句到 事件\表达式


因此,您的两行代码可能是等效的(这取决于
始终
块体中的代码)。但是,
@*
语法更易于维护。

始终(*)
是2001年标准修订版中语言的补充。所有最新版本的质量工具都支持它。我不担心在用于任意重用的代码中使用构造,但是,可能会遇到不支持
始终@(*)
的旧工具,特别是当涉及内部实用程序时

这只是列出“始终”块所依赖的所有导线的快捷方式。这些电线是“敏感度列表”。使用它的一个优点是,合成代码不太可能关心灵敏度列表中的内容(posedge和NEGDEDGE除外),因为导线将“物理”连接在一起。模拟器可能依赖于列表来选择哪些事件应该导致块执行。如果更改块并忘记更新列表,您的模拟可能会与实际合成行为不同。

虽然两者都是等效的,但使用
始终@(*)
可以避免任何模拟合成不匹配。 假设灵敏度列表中有15个信号,如下所示:

always@( a1 or a2 or ... or a15)

现在假设设计师错误地错过了列表中的a14。合成工具忽略此事实,并假设此块中RHS上的所有信号都在灵敏度列表中,合成代码。然而,模拟工具的行为不同,因为它取决于灵敏度列表。

对于第一个问题……我想说,这取决于在第二个场景中,您是否认为这些是唯一可以更改的输入,这将导致输出触发。理想情况下,使用*会更好,因为它表明“对于输入中的任何更改”,它也有助于避免冗长的代码


对于第二个问题……它是在verilog-2001中引入的,从那以后它被广泛使用。

*
表示包含的所有输入,因此它相当于写入所有输入。
如果您希望您的模块是组合电路而不是顺序的,那么使用
*
符号对always也很有用,因为每当任何输入发生变化时,总会有一些东西发生变化。

值得一提的是,SystemVerilog引入了
always\u comb
(和
always\u ff
/
always\u latch
)这使得工具链能够对设计器意图进行一些额外的检查。