Verilog中的延时阻塞与非阻塞赋值仿真.docx
- 文档编号:967671
- 上传时间:2022-10-14
- 格式:DOCX
- 页数:13
- 大小:69.97KB
Verilog中的延时阻塞与非阻塞赋值仿真.docx
《Verilog中的延时阻塞与非阻塞赋值仿真.docx》由会员分享,可在线阅读,更多相关《Verilog中的延时阻塞与非阻塞赋值仿真.docx(13页珍藏版)》请在冰豆网上搜索。
Verilog中的延时阻塞与非阻塞赋值仿真
从仿真语义的角度看Verilog中的延时、阻塞与非阻塞赋值
1Verilog中的延时
Verilog没有和VHDL中类似的最小延时概念,所有的延时都由符号“#”来定义,如果没有这个符号就意味着没有延时,清单1中描述了一个有关延时的简单例子。
清单1简单的延时
wire#5Y=A&B;
清单1中使用持续赋值语句描述了一个两输入端与门逻辑,并且在表达式前插入了5ns〔#5〕的延时,意义为Verilog仿真器会在5ns的延时后将A和B相与赋值给Y。
通过这个例子可以看出,延时的插入只需要在原本的语句中加入“#”关键字即可,但在实际的使用中却经常产生错误,实际中的延时时间是由具体的硬件电路来决定的。
使我们更深入的理解Verilog中的延时,更加关注描述的电路意义而不是描述语句本身,Verilog也是一种机于硬件的语言。
1.1实际中的延时
在实际的电路中,只存在着两种延时行为,一个是惯性延时,另一个是传输延时。
1.1.1惯性延时〔InertialDay〕
惯性延时通常在信号通过逻辑门的时候发生,图1所示是信号通过一个具有5ns延迟的非门时的行为。
图1惯性延时
输入信号WireIn有两个高电平脉冲,一个宽度为3ns,另一个宽度为9ns。
当第一个3ns的脉冲到达非门时,因为其宽度小于非门的本身延时〔5ns〕,输出还来不及建立低电平,输入脉冲就已经过去,所以在输出信号WireOut上没有表达出第一个3ns脉冲的响应。
第二个脉冲宽度为9ns,大于非门的本身延时,所以在脉冲上升沿5ns之后,WireOut输出了一个宽度为9ns的低脉冲,这个脉冲与输入脉冲等宽、反向而且延迟了5ns。
这种延时称为惯性延时或惰性延时。
如果输入的变化过快,小于逻辑门本身的延时,就不会被表达在输出上。
1.1.2传输延时〔TransportDelay〕
传输延时相对于惯性延时更容易理解,相当于信号通过了一条拥有固定延时的传输线。
如图2所示是信号通过一条5ns的延时线地示意图与波形。
图2传输延时
容易看出来,WireOut实际上就是被延迟了5ns的WireIn。
所以传输延时的意义就是将输入信号延迟一定时间后表达在输出上,而且输入信号上的所有细节都不会丧失。
1.2持续赋值语句中的延时
在持续赋值语句只有一种合法的延时描述,如清单2所示:
清单2持续赋值语句中的延时
assign#5WireOut=~WireIn;
这种描述用语表示电路中的惯性延时,任何小于5ns的输入变化都会被过滤而不会表达在输出上。
1.3过程赋值语句中的延时
过程赋值语句中的延时情况比较复杂,但是结论很简单:
●在持续赋值语句中使用正规延时,可以描述惯性延时。
●在非阻塞赋值语句中使用内定延时,可以描述传输延时。
1.3.1正规延时和内定延时
正规延时和内定延时的定义见清单3。
清单3正规延时和内定延时
#Nsum=a+b;//正规延时
sum=#Na+b;//内定延时
定义于赋值语句前面的延时称为正规延时,其意义是:
假设赋值语句的执行条件在T时刻得到满足,该语句并不会立即执行,而是在延时N时间后,也就是在T+N时刻将T+N时刻的a+b赋值给sum。
内定延时定义于赋值语句的右式之前,其意义是:
假设赋值语句的执行条件在T时刻得到满足,立即将T时刻的a与b相加,并不是立即赋值给sum,而是在延时N时间后,也就是在延时N时间后将a+b赋值给sum。
了解了正规延时和内定延时的概念,不难想象出,对应Verilog中的持续性赋值、阻塞性赋值和非阻塞赋值这三种赋值形式,一共有六种插入延时的方法。
但是在持续赋值中插入内定延时是非法的,这是因为内定延时需要将T时刻的结果保持到T+N时刻进行赋值,表现出记忆特性,与持续赋值的意义相冲突。
下文介绍阻塞赋值和非阻塞赋值中的延时。
1.3.2阻塞赋值中的延时
在阻塞赋值中可以插入正规延时和内定延时,例如如清单4所示。
由QuartusII综合后得到时间戳report和RTL图形分别如图3和图4所示,由Modelsim仿真产生的仿真波形如图5所示。
清单4阻塞赋值语句中的延时
moduleDelayDemo(A,B,C,D);
outputA,B,C,D;
reg[3:
0]A,B,C,D;
initial
begin
A=4'd0;B=4'd0;
#4A=4'd2;B=4'd4;
#2A=4'd3;
#2A=4'd4;
#9A=4'd3;
#2A=4'd5;B=4'd5;
#5B=4'd8;
end
always@(AorB)
begin
C=#3A+B;//阻塞赋值中的内定延时
end
always@(AorB)
begin
#3D=A+B;//阻塞赋值中的正规延时
end
endmodule
图3清单4的message
图4清单4的RTL
图5清单4的仿真波形
在图5的仿真图中,对于不断变化的输入A和B,C为插入了3ns内定延时的A+B,D为插入了3ns正规延时的A+B。
先讨论在阻塞赋值中插入内定延时的效果:
●0ns时刻〔Start1〕:
always进程启动,仿真器计算0时刻A+B的值后进程挂起,等待3ns后赋值给C。
●3ns时刻〔Display1〕:
C接受赋值更新,由未知出跳变为0。
●4ns时刻〔Start2〕:
A和B同时变化,启动进程,仿真器计算A+B的值,并在等待3ns后赋值给C。
●6ns时刻:
由于阻塞赋值的特性,A由2到3的跳变被忽略,不会反应在C上。
●7ns时刻〔Start2〕:
C由0跳变为4ns时刻A+B的值6
…
再来讨论在阻塞赋值中插入正规延时的效果:
●0ns时刻〔Start1〕:
always进程启动,由于设定了3ns的正规延时,进程被挂起等待3ns后执行。
●3ns时刻〔Display1〕:
执行赋值,将该时刻的A+B=0赋值给C。
●4ns时刻〔Start2〕:
A和B同时变化,启动进程,仿真器计算A+B的值,并在等待3ns的延时,在7ns时刻再次执行。
●6ns时刻:
由于阻塞赋值的特性,A由2到3的跳变被忽略,不会反应在C上。
●7ns时刻〔Start2〕:
执行赋值,将该时刻的A+B=7赋值给C。
…
由上面的分析可知,在阻塞赋值语句中插入延时的效果是;在语句启动后延时的一段时间输出当前时刻〔正规延时〕或语句启动时刻〔内定延时〕的逻辑结果,并且会忽略这段时间内所有的输入改变事件。
但是这种行为不能模拟实际电路中的惯性延时或者传输延时,因此不适合在阻塞赋值中插入延时。
1.3.3非阻塞赋值中的延时
与阻塞赋值一样,非阻塞赋值也可以插入正规延时和内定延时,例如如清单5,图6和图7分别是QuartusII综合产生的时间戳report和RTL图形,图8是由Modelsim仿真产生的波形。
清单5非阻塞赋值语句中的延时
always@(AorB)
begin
C<=#3A+B;//非阻塞赋值中的内定延时
end
always@(AorB)
begin
#3D<=A+B;//非阻塞赋值中的正规延时
end
/*其余部分与清单4相同*/
图6清单5的时间戳report
图7清单5的RTL图形
图8清单5的仿真波形
在图8的仿真图中,对于不断变化的输入A和B,C为插入了3ns内定延时的A+B,D为插入了3ns正规延时的A+B。
先讨论在非阻塞赋值中插入内定延时的效果:
●0ns时刻〔Start1〕:
always进程启动,计算A+B的值,然后进程挂起,等待3ns后赋值给C。
●3ns时刻〔Display1〕:
C接受赋值更新,由未知出跳变为0。
●4ns时刻〔Start2〕:
A和B同时变化,启动进程,仿真器计算A+B的值,并在等待3ns后赋值给C。
●6ns时刻:
由于非阻塞赋值的左式更新操作在仿真事件中的优先级要低于阻塞赋值的右式计算、左式更新,也低于由于输入改变而启动的非阻塞赋值本身的右式计算,所以在该时刻C的更新操作会被放入执行队列,并在3ns后执行赋值。
●7ns时刻〔Display2〕:
C由0跳变为4ns时刻A+B的值6
●8ns时刻〔Start3〕:
进程再次启动,并会在3ns以后将C赋值为8ns的A+B值
●9ns时刻:
执行6ns时刻放入队列中的赋值操作,C被赋值为7
…
通过上面的分析可以看出在非阻塞赋值中插入内定延时可以很好的描述实际电路行为中的传输延时,这也是在过程赋值中唯一推荐使用的延时描述。
而非阻塞赋值中插入正规延时的效果大致与阻塞赋值中相同,会在当前的语句启动以后,延时一段时间输出当前时刻的逻辑结果,并且会忽略这段时间内的所有输入改变事件,不符合惯性延时和内定延时的行为特点。
2阻塞赋值与非阻塞赋值
2.1说明
阻塞赋值与非阻塞赋值统称为过程赋值。
2.2组合逻辑
Verilog中使用等号“=”来表示阻塞赋值,被赋值的变量放在等号的左边,计算赋值的表达式置于等号右边。
阻塞赋值可以很好的建模电路中的数据流,请考虑清单6中的代码片断。
清单6组合逻辑的阻塞赋值
regtemp1,temp2;
always@(XorYorCIN)
begin
temp1=X^Y;
temp2=temp1&CIN;
SUM=temp1^CIN;
COUT=temp2|(X&Y);
End
清单6是一个全加器的描述,其中所有的赋值语句都是阻塞赋值,特点是:
等号“=”右边表达式的结果计算和将计算结果赋值给左边变量的操作,是一个统一、连续的过程,不允许在其中插入其他动作;阻塞赋值语句会阻塞其后代码中语句的执行,也就是说Verilog仿真器在完成一句阻塞赋值语句前,不会响应其他事件。
由此可见清单6中各语句的意义是:
首先将X异或Y的结果赋值给temp1,接着执行第二条语句将temp1和CIN相与的结果赋值给temp2,并最终计算出SUM和COUT。
很好的反映了组合逻辑中的数据流动顺序。
如果将这里的阻塞赋值替换为非阻塞赋值,如清单7所示。
清单7组合逻辑的非阻塞赋值1
regtemp1,temp2;
always@(XorYorCIN)
begin
temp1<=X^Y;
temp2<=temp1&CIN;
SUM<=temp1^CIN;
COUT<=temp2|(X&Y);
end
Verilog中使用小于等号“<=”来表示非阻塞赋值,被赋值的变量放在等号的左边,计算赋值的表达式置于等号的右边。
与阻塞赋值不同,非阻塞赋值不能反映电路的数据流。
因为在Verilog仿真语义中规定:
非阻塞赋值对于左边赋值变量的更新操作的优先级要低于阻塞赋值,也要低于非阻塞赋值本身等号右边的表达式计算,需要等到当前仿真周期结束时才被执行。
所谓的当前仿真周期结束,指的是某一时刻的所有仿真事件全部完成。
在清单7中,某时刻当敏感事件表中的信号发生变化导致always进程启动,进程中的赋值语句在该时刻被依次执行。
由于非阻塞赋值的特点,X异或Y首先计算,但是所得的结果并不会立刻赋值给temp1,所以第二句中引用的是temp1的原值,不是第一句中X与上Y的结果。
同样,第二句中temp1和CIN相与的结果也不会立刻用于更新temp2。
所有的左侧变量在该仿真时刻的事件执行完毕,也就是5条赋值语句的右侧表达式全部计算完毕后才被更新。
这显然不是我们所期望的逻辑结果,不过可以通过将中间变量temp1和temp2放入always语句的敏感
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Verilog 中的 延时 阻塞 赋值 仿真