1、基本
测试项 |
语法测试结果 |
说明 |
组合:= |
|
assign用且仅用=,左值用且仅用wire initial和always左值用且仅用reg,=和<=都可以,但是一般情况下,组合用=,时序用<= |
时序:<= |
| |
assign |
assign只能用=,只能对wire |
reg用于且仅用于always、initial的左值; wire用于且仅用于assign的左值。 assign:只要右边表达式任一个变量有变化,表达式立即被计算,计算的结果立即赋给左边信号。也即assign行为上等价于组合always。 |
always |
always不管敏感量是posedge(时序逻辑)或者是一个信号(组合逻辑): 可以用<=,也可以用=; always里面赋值的左值必须是reg。 | |
initial |
initial跟always一样 可以用<=,也可以用=; initial里面赋值的左值必须是reg。 | |
wire初值 |
wire不可以赋初值,但是可以赋初reg |
wire w1=1'b0,w2;不合法 但是 reg r2; wire w1=r2,w2;合法 |
reg可赋初值 |
reg可以赋初值 |
reg r1=1'b0,r2;合法 |
综上,得到的基本概念用图形描述如下:
l 注1:右侧组合逻辑使用=,时序逻辑使用<=:是经验法则,否则容易导致综合出来的电路功能不合乎要求。
l 注2:其他的是语法要求,不按照做会出语法错误。
2、赋值
测试项 |
语法测试结果 |
说明 |
wire可做右值给reg |
语法正确 |
always reg<=wire//clk always reg=wire//no_clk |
wire可做右值给wire |
语法正确 |
assign wire=wire |
reg可做右值给wire |
语法正确 |
assign wire=reg |
reg可做右值给reg |
语法正确 |
always reg<=reg//clk always reg=reg//no_clk |
reg可用常数驱动 |
语法正确 |
always reg<=1’b0//clk always reg=1’b0//no_clk |
wire可用常数驱动 |
语法正确 |
assign wire<= 1’b0 |
|
|
|
3、端口
测试项 |
语法测试结果 |
说明 |
wire可做in端口 |
语法正确 |
input wire rstw |
reg可做in端口 |
语法错误 |
input reg rstr |
wire可做out端口 |
语法正确 |
output wire outw |
reg可做out端口 |
语法正确 |
output reg outr |
wire可做inout端口 |
语法正确 |
|
reg可做inout端口 |
语法错误 |
|
|
|
|
input和inout只能是wire,output可以使reg或者wire。
4、例化
测试项 |
语法测试结果 |
说明 |
wire可做例化的input的wire |
语法正确 |
目前的实验说明: 对于module的input,使用wire和reg都可以,功能上没有一点区别; 对于module的output,只能使用wire。 |
reg可做例化的input的wire |
语法正确 | |
wire可做例化的output的wire |
语法正确 | |
wire可做例化的output的reg |
语法正确 | |
reg可做例化的output的reg |
语法错误 | |
reg可做例化的output的wire |
语法错误 | |
|
|
|
wire肯定描述组合逻辑;reg有可能描述组合,也有可能描述时序。电路的行为从组合还是时序上就可以判断出来。
对于例化的模块,输入根据情况使用reg或wire(灵活起见,使用reg,这样能够用always实现组合或时序的赋值;但是,如果两模块互联,那么都是用wire就会省事),输出使用wire。
把3和4两个测试结合起来,如图所示:
简化记忆:外面的输入(源)可以使reg或wire,但是里面只能用wire接收(目的地);里面的输出(源)可以使reg或wire,但是外面只能用wire接收(目的地)。
总结1:
1、行为上:
wire或是reg并不会导致电路行为的改变,而是组合逻辑还是时许逻辑改变了电路的行为。加上reg或是wire并没有影响电路,电路并不会因为加上了一个reg而改变,而是有clk的always中的reg才会影响电路。
2、语法上:(端口和例化)
源是reg和wire,目的地是wire。
3、语法上:(做右值)
wire和reg在任何情况下都可以做右值,也即在左值允许的情况下可以相互赋值。
4、语法上:(做左值)
wire仅用于assign,reg仅用于initial和always。
5、语法上:(初始化)
wire在声明的时候(可以用reg、wire初始化,不可以用常数)初始化。
reg在声明的时候(可以用reg、wire、常数)初始化。
列表如下:
项目 |
wire |
reg | |
端口和例化 |
可以做源、目的地 |
只能作源 | |
做右值 |
可以 | ||
做左值 |
assign |
initial和always | |
声明时初始化 |
可以用reg、wire、常数,但是最好不要初始化wire,否则在综合的时候可能会报错:multi-driver。 |
只能用常数 | |
但是,初始化时不能再一行声明多个变量.即:不允许 wire w1=1’b0,w2;但是可以wire w1=1’b0;wire w2; |
总结2:
|
assign |
initial和always |
赋值符 |
用且仅用= |
=和<=都可以,但是一般情况下,组合用=,时序用<= |
左值 |
左值用且仅用wire |
左值用且仅用reg |
描述电路类型 |
组合 |
initial:组合 always:组合或时序 |
(有@(posedge clk)的才是时序,否则都是组合) | ||
|
|
|
注意:
1、一般情况下,要将一个模块的所有输入设为wire,将输出设为wire和reg都行。
但是,当输出用assign赋值或者作为其子模块的输出时,必须为wire。
2、模块端口的output和input信号,在模块内部都是可读的。可作为右值,可以