非阻塞和阻塞赋值???

初学者在学习Verilog的初期,非常喜欢纠结这个问题,当然这个问题总容易搞错和误用,直到.....了解了。

给初学者的建议:在进行时序逻辑电路时,基本采用的是非阻塞赋值。组合逻辑电路设计时,基本采用的是阻塞赋值。下面来简单来看一下,为何在时序电路里面要用非阻塞赋值。

---电路层面来说:当待赋值的寄存器位置不同时,有时可以综合出正确的电路,有时又不能综合出正确电路。

[方式1] 不正确地使用的阻塞赋值来描述移位寄存器。

module pipeb1 (q3, d, clk);
output [7:0] q3;
input [7:0] d;
input clk;
reg [7:0] q3, q2, q1;
always @(posedge clk)
begin
q1 = d;
q2 = q1;
q3 = q2;
end
endmodule

                                                                                         图1 没有交换位置时的阻塞赋值方式


如图1所示,D的值赋给Q1以后,再执行Q2 = Q1;同样在Q2的值更新以后,才执行Q3 = Q2。这样,最终的计算结果就是Q3 = D。即在每一个clk边沿,输入值被无延迟地传到q3的输出。这很明显并没有建立一个流水线而只是为一个寄存器建模。


[方式2] 用阻塞赋值来描述移位寄存器也是可行的,但这种风格并不好。

module pipeb2 (q3, d, clk);
output [7:0] q3;
input [7:0] d;
input clk;
reg [7:0] q3, q2, q1;
always @(posedge clk)
begin
q3 = q2;
q2 = q1;
q1 = d;
end
endmodule

                                                                                                                 图2 交换位置后的阻塞赋值方式


如图2所示,阻塞赋值被仔细地安排了次序以使得行为仿真正确,这种建模同样也可以得到正确的综合结果 。


[例] 正确的用非阻塞赋值来描述时序逻辑的设计风格 #1

module pipen1 (q3, d, clk);
output [7:0] q3;
input [7:0] d;
input clk;
reg [7:0] q3, q2, q1;
always @(posedge clk) begin
q1 <= d;
q2 <= q1;
q3 <= q2;
end
endmodule

如图3所示,颠倒了一下赋值次序,对实际仿真次序却不产生决定作用 ,综合结果是对的,仿真结果是正确的。

                                                                                                                                 图3 采用非阻塞赋值


喜欢本文的同学欢迎收藏点赞多多留言,本文原发于【FPGA hdl


#读书笔记##C/C++#
全部评论
太高端了,看不懂。。
点赞 回复 分享
发布于 2022-04-26 11:14

相关推荐

评论
4
11
分享

创作者周榜

更多
牛客网
牛客企业服务