wire和reg作为输出的区别
-
组合逻辑 vs 时序逻辑:
- 如果输出信号直接由输入信号通过组合逻辑电路计算得到,应该使用
wire
类型。例如门电路、算术运算等。 - 如果输出信号需要存储某个状态,通常在时钟的控制下改变,应该使用
reg
类型。例如触发器、计数器等。
- 如果输出信号直接由输入信号通过组合逻辑电路计算得到,应该使用
-
赋值方式:
wire
类型的信号只能通过连续赋值语句(assign
)或实例化的子模块驱动。reg
类型的信号只能在过程块(如always
块)中赋值。
wire
类型作为输出
wire
类型的输出信号主要用于组合逻辑电路。它们的值由连续赋值语句(assign
语句)或者实例化的模块、门电路直接驱动。
-
连续赋值:
wire
类型的信号使用assign
语句进行连续赋值。 -
组合逻辑:通常用于描述组合逻辑电路,因为
wire
类型信号的值总是由驱动它的表达式直接确定。 -
//组合逻辑示例 module and_gate ( input wire a, input wire b, output wire y ); assign y = a & b; endmodule //没有时钟触发的always也属于组合逻辑,但是always块要求输出类型为reg module combinational_example ( input wire a, input wire b, output reg y ); always @(*) begin y = a & b; end endmodule
-
无存储功能:
wire
类型的信号不保存状态,它们的值仅仅是驱动它们的表达式的当前值。
reg
类型作为输出
reg
类型的输出信号用于存储逻辑(即时序逻辑)。它们的值在过程块(如always
块)中赋值。
-
过程赋值:
reg
类型的信号在always
块或初始块中赋值。例如: -
时序逻辑:通常用于描述时序逻辑电路,因为
reg
类型信号的值可以在时钟信号的控制下改变,并保持其状态。 -
//时序逻辑示例 module d_ff ( input wire clk, input wire d, output reg q ); always @ (posedge clk) begin q <= d; end endmodule
-
存储功能:
reg
类型的信号具有存储功能,可以保存之前赋予的值,直到下一次赋值。
例化
例化一个模块相当于将被例化模块当作模板进行调用。
为区别多次调用,使用(被例化模块名 例化模块名)的方式编写例化,参数的传递与模块名一致,采用(被例化模块参数,例化参数)方式编写。例如:
//----------------------顶层代码------------------//
module top_key (
input wire clk,
input wire sys_rst_n,
input wire key,
output bee
);
parameter MAX_NUM = 1_000_000;
wire key_filter;
//---------模块1例化-----------//
beep u_beep (
.sys_rst_n (sys_rst_n),
.key_filter(key_filter),
.bee (bee)
);
//---------模块2例化-----------//
key_ctl_beep #(
.MAX_NUM(MAX_NUM)
) u_key_ctl_beep (
.clk (clk),
.sys_rst_n(sys_rst_n),
.key (key),
.key_filter(key_filter)
);
endmodule
//被例化模块1
module beep (
// input wire clk,
input wire sys_rst_n,
input wire key_filter,
output reg bee
);
......
endmodule
//被例化模块2
module key_ctl_beep (
input wire clk,
input wire sys_rst_n,
input wire key,
output reg key_filter
);
parameter MAX_NUM = 1_000_000;
......
endmodule
在模块外部:模块例化时顶层模块对例化模块的输入可以是reg或者wire
在模块内部:被例化模块内部的输入必须是wire
在模块外部:顶层模块需要使用wire类型连接例化模块的输出
在模块内部:被例化模块内部的输出则根据实际情况选择,见第一部分(组合逻辑,assign语句使用wire,反之,带always使用reg(无论是否带触发))