Verilog: wire
和 reg
的区别
1 引言
看Verilog例子过程中,总是分不清 wire
和 reg
的区别。这篇文章把两者放在一起总结一下,并且对比何时使用它们。
1.1 wire
:组合逻辑
wire
是 Verilog 设计中的简单导线(或任意宽度的总线)。使用 wire
时的语法规则如下:
wire
用于连接模块实例化的输入和输出端口以及设计中的其他元素。wire
用作实际模块声明中的输入和输出。wire
必须由其他信号驱动,不能自行存储值。wire
不能用作always@
块中的左值(=
或<=
)。wire
是assign
语句左侧的唯一合法类型。wire
是一种无状态的连接方式,仅用于组合逻辑。
程序 1 显示了 wire
的各种合法用法。
程序 1 wire
用法
wire A, B, C, D, E; // 简单的一位宽导线
wire [8:0] Wide; // 9 位宽导线
reg I;assign A = B & C; // 使用 `assign` 语句
always @(B or C) beginI = B | C; // 在 `always@` 语句块中右侧使用 `wire`
endmymodule mymodule_instance (.In (D), .Out(E)); // 模块输出使用 `wire`
1.2 reg
:组合逻辑和时序逻辑
reg
与 wire
类似,但可以像寄存器一样存储信息(“状态”)。使用 reg
的语法规则如下:
reg
可以连接到模块实例化的输入端口。reg
不能连接到模块实例化的输出端口。reg
可以用作实际模块声明中的输出。reg
不能用作实际模块声明中的输入。reg
是always@
块中左值(=
或<=
)的唯一合法类型。reg
是initial
块中左值(用于测试平台)的唯一合法类型。reg
不能用作assign
语句的左值。reg
可以与always@(posedge Clock)
块一起使用来创建寄存器。- 因此,
reg
可以用于创建组合逻辑和时序逻辑。
程序 2 显示了 reg
元素的各种合法用法。
程序 2 reg
用法
wire A, B;
reg I, J, K; // 简单的一位宽寄存器
reg [8:0] Wide; // 9 位宽寄存器always @(A or B) beginI = A | B; // 在 `always@` 语句块中左侧使用 `reg`
endinitial begin // 在 `initial` 块中使用 `reg`J = 1'b1;#1J = 1'b0;
endalways @(posedge Clock) beginK <= I; // 使用 `reg` 创建正边沿触发寄存器
end
1.3 wire
和 reg
何时可互换
在某些情况下,wire
和 reg
可以互换使用:
- 两者都可以出现在
assign
语句和always@
块的右侧(=
或<=
)。 - 两者都可以连接到模块实例化的输入端口。