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信号,在模块内部都是可读的。可作为右值,可以