Verilog中reg和wire的区别总结

不少Verilog初学者都搞不清楚reg和wire的用法区别。对此,berkeley的CS150中总结得很清楚,源文件地址见参考小节。

一、关于 wire (可描述组合逻辑)

在Verilog中, wire 可以纯粹看作一根导线(或者任意位宽的总线)。在使用 wire 时需要注意以下几点语法规则:

  1. wire 类型用于将模块例化时的输入输出端口连接到你设计的电路的其他地方。
  2. wire 类型在模块声明也作为输入输出。
  3. wire 类型必须被其他东西驱动而不能用于存储数据。
  4. wire 类型在 always@ 块中不能作为 =<= 的左值。(即always块中必须用reg赋值,下面例1)🔑
  5. wire 类型是 assign 语句中左值的唯一合法类型。🔑
  6. wire 类型可以将两个基于Verilog的设计相结合,是一种无状态的方法(并不是很明白这里指的是什么意思)。
  7. wire 类型只能用于组合逻辑建模。

下面这段程序给出了几种 wire 类型合法使用的例子

wire		A, B, C, D, E; 	// simple 1-bit wide wires
wire [8:0] 	Wide;			// a 9-bit wide wire
reg I;

assign A = B & C;			// using a wire with an assign statement

always @(B or C) begin
	I = B | C;				// using wires on the right-hand side of an always@
							// assignment
end

mymodule mymodule_instance(
	.In 	(D	),
	.Out	(E	)
); // using a wire as the output of a module

二、关于 reg (既可描述组合逻辑也可描述时序逻辑)

reg 和wire有点类似,但能够存储信息(状态),类似寄存器。在使用 reg 时有以下这些语法规则:

  1. reg 类型可以用于连接模块例化时的输入。
  2. reg 类型不能用于连接模块例化时的输出。
  3. reg 类型可以在模块声明时作为输出。
  4. reg 类型不能在模块声明时作为输入。
  5. reg 类型是 always@ 块中作为 =<= 左值的唯一合法类型。🔑
  6. reg 类型是 initial 块中作为 = 左值的唯一合法类型(用于Test Bench)。
  7. reg 类型不能作为 assign 语句的左值。
  8. reg 类型能用于创建寄存器,以用于 always@(posedge Clock) 块。
  9. reg 类型既可以描述组合逻辑也可以描述时序逻辑。🔑

下面这段程序给出了几种 reg 类型合法使用的例子

wire 		A,B;
reg			I,J,K; 	// simple 1-bit wide reg elements .
reg [8:0]	Wide ;		// a 9-bit wide reg element

always @(A or B) begin
	I =	A | B;			// using a reg as the left-hand side of an always@
						// assignment
end

initial begin			//using a reg in an initial block .
	J=1'b1;
	#1
	J =1'b0;
end

always @(posedge Clock) begin
	K<=I;				// using a reg to create a positive -edge - triggered register
end

三、wirereg 的共性

在下面这几种情况下 wirereg 可以通用:

  1. 都可以作为 assign 语句的右值以及 always@ 块中作为 =<= 的右值。
  2. 都可以接到模块例化的输入端口。

以上就是Verilog中wire和reg的主要区别了,有不少观点认为Verilog中会出现这样的区别是由于历史遗留原因,无从解释。对于我们使用者而言,只能强行记住它们之间的区别了,多写写自然就记住了。

例1

错误写法(对应上面一第四点,二第五点):会有报错 Illegal reference to net "sout".

module mux4to1(
    input [1:0]     sel ,
    input [1:0]     p0 ,
    input [1:0]     p1 ,
    input [1:0]     p2 ,
    input [1:0]     p3 ,
    output [1:0]    sout
);

    always @(*)
        case(sel)
            2'b00:       sout = p0 ;
            2'b01:       sout = p1 ;
            2'b10:       sout = p2 ;
            default:     sout = p3 ;
        endcase
endmodule

修改后正确写法:

module mux4to1(
    input [1:0]     sel ,
    input [1:0]     p0 ,
    input [1:0]     p1 ,
    input [1:0]     p2 ,
    input [1:0]     p3 ,
    output [1:0]    sout);
 
    reg [1:0]     sout_t ;
    always @(*)
        case(sel)
            2'b00:   begin      
                    sout_t = p0 ;
                end
            2'b01:       sout_t = p1 ;
            2'b10:       sout_t = p2 ;
            default:     sout_t = p3 ;
        endcase
    assign sout = sout_t ;
 
endmodule

参考

Nets.pdf (berkeley.edu)
Verilog中reg和wire的区别总结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值