学习:
For hardware synthesis, there are two types of always blocks that are relevant:
- Combinational: always @(*)
- Clocked: always @(posedge clk)
Clocked always blocks create a blob of combinational logic just like combinational always blocks, but also creates a set of flip-flops (or "registers") at the output of the blob of combinational logic. Instead of the outputs of the blob of logic being visible immediately, the outputs are visible only immediately after the next (posedge clk).
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.
译:
针对硬件综合,有两种类型的 always
块是相关的:
组合逻辑:always @(*)
时钟控制逻辑:always @(posedge clk)
组合逻辑 always
块创建了一块组合逻辑,就像组合逻辑 always
块一样,但它也在组合逻辑块的输出处创建了一组触发器(或称为“寄存器”)。与组合逻辑块的输出立即可见不同,只有在下一个时钟上升沿(posedge clk
)之后,输出才会立即可见。
阻塞赋值与非阻塞赋值 在Verilog中有三种赋值类型:
连续赋值(assign x = y;
)。只能在程序("always块")外部使用。 程序化阻塞赋值:(x = y;)
。只能在程序内部使用。 程序化非阻塞赋值:(x <= y;)
。只能在程序内部使用。 在组合逻辑 always
块中,应使用阻塞赋值。在时钟控制 always
块中,应使用非阻塞赋值。完全理解为什么这样做并不特别有助于硬件设计,并且需要很好地理解Verilog模拟器如何跟踪事件。不遵循这一规则会导致极其难以发现的错误,这些错误既是非确定性的,又在仿真和综合硬件之间存在差异。
练习:
Build an XOR gate three ways, using an assign statement, a combinational always block, and a clocked always block. Note that the clocked always block produces a different circuit from the other two: There is a flip-flop so the output is delayed.。
用三种方式构建一个异或门(XOR gate):使用赋值语句(assign statement)、组合逻辑 always 块和时钟控制的 always 块。请注意,时钟控制的 always 块产生的电路与另外两个不同:由于存在触发器,输出会有延迟。
// 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) begin
out_always_ff <= a^b;
end
endmodule
运行结果:
分析:
主要关注三种赋值方式,以及使用方式;
另外要注意 Clocked方式,会慢一个时钟输出;