最近有初学者会问阻塞(=)和非阻塞(<=)到底是有什么区别?
可能确实有很多的文档对这两种语法的定义展开性讲的已经很天花乱坠,但是对于刚刚学习Verilog语法的小伙伴来说,确实有些绕,这边向大家总结一下个人对这两种赋值的一些简单想法。
1. 在组合逻辑中,“=” 与 “<=”是完全相同的,但是assign赋值建议(zhineng)使用阻塞赋值(“=”);
2.在always语句中,同一信号不建议一会使用“=”、一会使用“<=”;
3.在时序逻辑中,建议统一使用非阻塞赋值的方式进行电路的设计。
这里主要以第三条时序逻辑给大家分析一下阻塞和非阻塞情况下的RTL视图:
module test(
input i_sys_clk,
input signal_in,
output out_reg
);
reg r_d1, r_d2, r_d3;
assign out_reg = r_d3;
always@(posedge i_sys_clk)
begin
r_d1 <= signal_in ;
r_d2 <= r_d1 ;
r_d3 <= r_d2 ;
end
endmodule
首先是在时序逻辑电路中,使用非租塞赋值综合前和综合后生成的RTL视图
就以综合后的RTL视图可以看出,非租塞赋值的代码为一个级联电路,非阻塞赋值的左边为下一级的输出。我们再把代码改为阻塞赋值,看一下综合前与综合后的RTL视图:
module test(
input i_sys_clk,
input signal_in,
output out_reg
);
reg r_d1, r_d2, r_d3;
assign out_reg = r_d3;
always@(posedge i_sys_clk)
begin
r_d1 = signal_in ;
r_d2 = r_d1 ;
r_d3 = r_d2 ;
end
endmodul
其实,根据RTL视图结合代码我们可以猜测到,为什么使用阻塞赋值后,我们的电路就没有了级联关系了。因为使用阻塞赋值,相当于只是将输入信号的值赋值给了最好的r_d3,前面的r_d1和r_d2只是相当于一个缓冲器并没要参与级联关系,所以RTL给我们优化掉了另外两个寄存器。
总结:
1. 在assign语句中推荐大家使用阻塞赋值也就是我们的“=”;
2.在always语句中建议大家使用非阻塞赋值也就是“<=”;
3.特别是在时序逻辑电路中一定要使用非阻塞赋值“<=”,延迟一个时钟周期。
当然这只是我个人目前学习FPGA的一些个人理解,希望对大家有些帮助。