Verilog语言中讲的阻塞赋值与非阻塞赋值,但从字面意思来看,阻塞就是执行的时候在某个地方卡住了,等这个操作执行完在继续执行下面的语句,而非阻塞就是不管执行完没有,我不管执行的结果是什么,反正我继续下面的事情。而Verilog中的阻塞赋值与非阻塞赋值正好也是这个意思,通过执行一个例子,就可以简单地明白了:
1、阻塞赋值可以理解为语句的顺序执行,因此语句的执行顺序很重要
2、非阻塞赋值可以理解为语句的并行执行,所以语句的执行不考虑顺序
3、在assign的结构中,必须使用的是阻塞赋值
下面给出实例来说明:
给出相应的案例来帮助理解:
module prj1(in,b,c,d,clk,rst_n); input in; input clk; input rst_n; output b,c,d; reg b,c,d; always @(posedge clk or negedge rst_n) begin if(!rst_n) begin b <=0; c <=0; d <=0; end else begin b <=in; c <=b; d <=c; end end endmodule
这个目的是为了展示非阻塞赋值过程中的时序变化,对应的RTL电路图和仿真波形如下图:
从仿真图可以看书,b,c,d是在每个时钟后依次传递的,如果采用阻塞赋值,如果in改变,那么b,c,d立刻改变,这个就在这里不给出仿真。
阻塞赋值和非阻塞赋值的另外一个区别在于综合的时候,如果输出只有d,bc作为中间变量,阻塞赋值在综合的过程中会自动省略掉中间过程。给出如下仿真,理解更为清楚
module prj1(in,b,c,clk,rst_n); input in; input clk; input rst_n; output b,c; reg b,c, e,f, m,n; /* <= */ always @(posedge clk or negedge rst_n) begin if(!rst_n) b <=0; else begin e <=in; f <=e; b <=f; end end /* = */ always @(posedge clk or negedge rst_n) begin if(!rst_n) c=0; else begin m = in; n = m; c = n; end end endmodule
综合后结果如图,可以看出,采用阻塞赋值,综合后的逻辑单元只有一个,中间变量m,n直接省去了。
时间: 2024-09-30 06:55:02