在Verilog模块中,我们应该何时使用reg和何时使用wire?
我还注意到有时会将输出再次声明为reg。例如,在D触发器中的reg Q。我曾经在某个地方读到过这样的话 -“过程赋值语句的目标输出必须是reg数据类型。”
什么是过程赋值语句?
我已经彻底搜索了这个问题,但没有找到清晰的解释。
导线:
导线用于连接不同的元素。它们可以被视为物理导线。它们可以被读取或分配。没有值存储在其中。它们需要通过连续的赋值语句或从模块的端口驱动。
寄存器:
与其名称相反,寄存器不一定对应于物理寄存器。它们代表Verilog/SystemVerilog中的数据存储元素。它们保留其值,直到下一个值被分配给它们(不是通过赋值语句)。它们可以合成为FF、锁存器或组合电路。(它们可能无法合成!)
导线和寄存器存在于Verilog时期。SystemVerilog添加了一个称为逻辑的新数据类型。那么下一个问题是什么是这种逻辑数据类型,它与我们的老朋友导线/寄存器有何不同。
逻辑:
正如我们所见,reg 数据类型在 Verilog 中有一些误导性。System Verilog 的逻辑数据类型的添加是为了消除上述混淆。背后的想法是引入一个称为 logic 的新数据类型,它至少不会给人留下硬件可综合的印象。Logic 数据类型不允许多个驱动器。如果存在多次赋值,它具有最后赋值获胜的行为(这意味着它没有硬件等效性)。Reg/Wire 数据类型会在多个驱动器尝试使用不同值来驱动它们时产生 X。Logic 数据类型仅分配最后的赋值值。reg/wire 和 logic 之间的另一个区别是逻辑可以由 assign 块、端口的输出和像这样的过程块驱动。
logic a;
assign a = b ^ c; // wire style
always (c or d) a = c + d; // reg style
MyModule module(.out(a), .in(xyz)); // wire style
Procedural blocks指的是always
, always_ff
, always_comb
, always_latch
, initial
等块。而过程赋值语句指的是给reg、integer等赋值,但不包括连线(nets)。
由于元素必须被持续驱动,不能存储值。因此,它们使用连续赋值语句来分配值。
reg
可以用于在过程块中创建寄存器。因此,它可以存储一些值。
reg
元素可以在实际模块声明中用作输出内部的一个部分。但是,reg
元素不能连接到模块实例的输出端口。
因此,当一个reg驱动一个wire时,它将作为assign
语句的RHS,而一个wire驱动一个reg时,则作为过程块的RHS。
有关reg
或wire
的声明的明确想法,请参阅下面的图像:
因此,每当涉及存储/保持某些值的顺序逻辑时,将该变量/端口声明为reg
。这里,Q
是模块内部的一个reg
,但是在实例化此模块时,该端口必须连接到一个wire
。
请记住,wire
只能推断组合逻辑,而 reg
可以推断组合逻辑或时序逻辑。
Dave的博客是详细信息的好来源。如需更多信息,请参阅合成区别和Verilog wire-reg链接。
reg和wire的简单区别在于,在Verilog中,reg用于组合或时序电路,而wire用于组合电路。
reg用于存储值,而wire持续驱动某些内容,并且在模块初始化时连接到输出端口,但是reg不能连接。