关于在Verilog中阻塞和非阻塞的知识是一个需要重点理解的地方。
首先谈及一下 赋值的概念 : 将某一数值赋给某个变量的过程。 其中赋值分为三个步骤 1、对RHS(Right Hand Side)进行计算 2、将RHS运算结果赋值到LHS(Left Hand Side)3、LHS更新
赋值的符号 一般用 = 表示 但在Verilog中一般有两种赋值形式的语句 = 称作阻塞赋值 <= 称作非阻塞赋值 。下面我们通过两个具体的例子来说明二者的区别
非阻塞赋值:
1 module feizuse (input a,input clk, input b, output reg c,output reg d); 2 3 always@(posedge clk) begin 4 c<=a&b; //非阻塞赋值 5 d<=c; //非阻塞赋值 6 end 7 endmodule
阻塞赋值:
1 module zuse(input a,input clk, input b, output reg c,output reg d); 2 3 always@(posedge clk) begin 4 c=a&b; //阻塞赋值 5 d=c; //阻塞赋值 6 end 7 endmodule
非阻塞赋值综合后的电路:
我们可以通过综合的电路可以看出 :c<=a&b; //非阻塞赋值 d<=c; //非阻塞赋值 这两条赋值语句并不是直接赋值,第一句非阻塞赋值语句 首先将 a&b 的结果赋值给 c ,而 d 的值是来自于上一状态的c,也就是说 c和d 之间是存在一个时钟的延时,从电路中可以看出 c、d 之间存在着一个寄存器 用来保存c上一时刻的状态。
阻塞赋值综合后的电路:
我们可以通过综合的电路可以看出 :c=a&b; //阻塞赋值 d=c; //阻塞赋值 这两条赋值语句是直接赋值,第一句阻塞赋值语句 首先将 a&b 的结果赋值给 c ,而 d 的值是来自于现在状态的c,也就是说 c和d 之间是不存在任何的延时,以上的语句也可以等效为 d=a&b; c和d 无任何差别,来自于a&b的运算结果,从电路中可以看出 c、d 几乎是来自同一个寄存器的输出端 。
简单谈及作者对阻塞和非阻塞的理解,阻塞从字面意思都好理解 ,阻断、阻隔某种关系或者过程。从赋值的定义上我们看,阻塞实际上是阻断的第三步:LHS的更新,在阻塞赋值中我们可以看出是对所有的赋值语句的RHS计算完成,并开始赋值,但不立即更新,而是在最后一个阻塞赋值完成后,对LHS进行更新。关于阻塞和非阻塞还有一个重要的区别是 阻塞赋值语句一般是顺序执行,从上到下,一级一级的执行,而非阻塞赋值语句则是并行执行,多级非阻塞一起执行。这就是为什么时序电路一般采用非阻塞赋值,组合电路一般采用阻塞赋值。
最后再来看一下 阻塞和非阻塞混用的例子 再次体会阻塞和非阻塞之间的区别。
例子1
1 module hunyong1(input a,input clk, input b, output reg c,output reg d); 2 3 always@(posedge clk) begin 4 c=a&b; 5 d<=c; 6 end 7 endmodule
综合后电路:
例子2
1 module hunyong2(input a,input clk, input b, output reg c,output reg d); 2 3 always@(posedge clk) begin 4 c<=a&b;5 d=c; 6 end 7 endmodule
综合后电路:
例子3
1 module zuhe(input a, input b, output c,output d); 2 3 4 assign c=a&b; 5 assign d=c; 6 7 endmodule
综合后电路:
例子4
1 module zuhe(input a, input b, output c,output d); 2 3 assign c<=a&b; // 报错,不会通过编译。 4 assign d=c; 5 6 endmodule
一定要注意 不能在 assign中使用 非阻塞赋值,只能用阻塞赋值。
结语:第一次开始用博客的方式来记录所学到的知识,作者才疏学浅,难免有疏漏地方,希望大家批评指正、不吝赐教,希望能和大家一起学习交流。2021-12-14 18:19:54