总结:
using an assign statement, | 连续赋值 | 给wire类型赋值 | assign |
a combinational always block, | 组合逻辑 always 块 | 给wire类型赋值 | always @(*) |
and a clocked always block. | 时序逻辑always 块 | 给reg类型赋值 | always @(posedge clk) |
组合逻辑:使用assign always @(*)
时序逻辑:使用always @(posedge clk)
不得不说,刷完题后,在开发板实战环节,代码编写及对verilog的理解有了一个质的提高。
verilog三种赋值的使用场景:下面这段话,五星重要
Blocking vs. Non-Blocking Assignment
There are three types of assignments in Verilog:
- Continuous assignments (assign x = y;). Can only be used when not inside a procedure ("always block").
- Procedural blocking assignment: (x = y;). Can only be used inside a procedure.
- Procedural non-blocking assignment: (x <= y;). Can only be used inside a procedure.
In a combinational always block, use blocking assignments. In a clocked always block, use non-blocking assignments. A full understanding of why is not particularly useful for hardware design and requires a good understanding of how Verilog simulators keep track of events. Not following this rule results in extremely hard to find errors that are both non-deterministic and differ between simulation and synthesized hardware.
英文原汁原味,解释得特别清晰,
1.连续赋值assign x=y;不能放在always块里使用
2.阻塞赋值 x=y;只能用在组合always块always @(*) 的场景
先执行x=1,再执行y=2,语句顺序执行,像C语言
x=1;
y=2;
3.非阻塞赋值 x<=y;只能用在时序always块always@(posedge clk) 的场景
两条语句同时执行,并行
x<=1;
y<=2;
一. always block (combinational)
连续赋值assign 与wire类型对应
always @(*)与 reg类型对应
// synthesis verilog_input_version verilog_2001
module top_module(input a, input b,output wire out_assign,output reg out_alwaysblock
);
assign out_assign = a & b;
always @(*) out_alwaysblock = a & b;
endmodule
二. always block (clocked)
下面3条语句描述的电路功能是一样的
assign out_assign = a^b;always @(*) out_always_comb = a^b;always @(posedge clk) out_always_ff = a^b;
完整代码
// synthesis verilog_input_version verilog_2001
module top_module(input clk,input a,input b,output wire out_assign,output reg out_always_comb,output reg out_always_ff );assign out_assign = a^b;always @(*) out_always_comb = a^b;always @(posedge clk) out_always_ff = a^b;
endmodule