wire 和 reg 是Verilog程序里的常见的两种变量类型,它们都是构成verilog程序逻辑最基本的元素。
wire主要起信号间连接作用,用以构成信号的传递或者形成组合逻辑。因为没有时序限定,wire的赋值语句通常和其他block语句并行执行。
wire不保存状态,它的值可以随时改变,不受时钟信号限制。
除了可以在module内声明,所有module的input 和output默认都是wire型的。
reg是寄存器的抽象表达,作用类似通常编程语言中的变量,可以储存数值,作为参与表达式的运算,通常负责时序逻辑,以串行方式执行。
reg可以保存输出状态。状态改变通常在下一个时钟信号边沿翻转时进行。
wire有两种赋值方式
- 普通列表项目在定义变量时赋初值,方式是用 = 。如果之后没有再做赋值,初值会一直保留 wire wire_a = 1’b0;
- 普通列表项目普通列表项目用assign语句赋值,等式右边可以是wire型变量、reg型变量、一个常量或者是逻辑运算
Wire wire_a; Wire wire_b; Wire wire_c; Reg reg_a; assign wire_b = wire_a; assign wire_c =reg_a; assign wire_d =wire_b & wire_c;
如果不赋值,wire的默认状态是高阻态,即z。
对reg的使用通常需要有触发条件,在always的block下进行。触发条件可以是时钟信号上升沿或者下降沿,则构成一个寄存器,形成时序逻辑;触发条件是电平信号的话。则形成组合逻辑
Wire wire_a; Wire wire_b; Reg reg_a; Reg reg_b; Always @( posedge clk) Begin Reg_b =reg_a; Reg_c = wire_a | wire_b; end
Reg在声明时候不赋初值。未赋值的reg变量处于不定态,即x。
使用方式
在引用一个module时,输入端口可以是wire型,也可以reg型。这里可以把对input的赋值看作一个assign语句,使用的变量相当于等号右边的变量,所以两者都可以。
而对于输出端口,必须使用reg型,而不能是wire型。同样用assign的角度考虑,module的输出在等号右边,而使用的变量成了等号左边,assign语句等号左边只能是wire型。
位宽
这是个使用注意事项。所有的wire和reg在声明时如果不做特殊声明,只有1位。这个对于熟悉其他编程语言的人是一个容易犯错的地方。
执行
wire wire_a = 4’he;
语句最后得到的wirea是0x1,而不是0xe。因为wirea只取了0xe的最低位的值而省略掉了其他值。所以正确的语句应该是
wire[3:0] wire_a = 4’he;
这样wire_a输出的结果才是一个0xe。