Verilog中的延时、阻塞与非阻塞赋值仿真

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

从仿真语义的角度看Verilog中的延时、阻塞与非阻塞赋值

1 Verilog中的延时

Verilog没有和VHDL中类似的最小延时概念,所有的延时都由符号“#”来定义,如果没有这个符号就意味着没有延时,清单1中描述了一个有关延时的简单例子。

清单1 简单的延时

wire #5 Y = A & B;

清单1 中使用持续赋值语句描述了一个两输入端与门逻辑,并且在表达式前插入了5ns (#5)的延时,意义为Verilog仿真器会在5ns的延时后将A和B相与赋值给Y。通过这个例子可以看出,延时的插入只需要在原本的语句中加入“#”关键字即可,但在实际的使用中却经常产生错误,实际中的延时时间是由具体的硬件电路来决定的。使我们更深入的理解Verilog中的延时,更加关注描述的电路意义而不是描述语句本身,Verilog也是一种机于硬件的语言。

1.1 实际中的延时

在实际的电路中,只存在着两种延时行为,一个是惯性延时,另一个是传输延时。

1.1.1 惯性延时(Inertial Day)

惯性延时通常在信号通过逻辑门的时候发生,图1所示是信号通过一个具有5ns延迟的非门时的行为。

图1 惯性延时

输入信号WireIn有两个高电平脉冲,一个宽度为3ns,另一个宽度为9ns。当第一个3ns 的脉冲到达非门时,因为其宽度小于非门的本身延时(5ns),输出还来不及建立低电平,输入脉冲就已经过去,所以在输出信号WireOut上没有体现出第一个3ns脉冲的响应。第二个脉冲宽度为9ns,大于非门的本身延时,所以在脉冲上升沿5ns之后,WireOut输出了一个宽度为9ns的低脉冲,这个脉冲与输入脉冲等宽、反向而且延迟了5ns。

这种延时称为惯性延时或惰性延时。如果输入的变化过快,小于逻辑门本身的延时,就不会被体现在输出上。

1.1.2 传输延时(Transport Delay)

传输延时相对于惯性延时更容易理解,相当于信号通过了一条拥有固定延时的传输线。如图2所示是信号通过一条5ns的延时线地示意图与波形。

图2 传输延时

容易看出来,WireOut实际上就是被延迟了5ns的WireIn。所以传输延时的意义就是将输入信号延迟一定时间后体现在输出上,而且输入信号上的所有细节都不会丢失。

1.2 持续赋值语句中的延时

在持续赋值语句只有一种合法的延时描述,如清单2所示:

清单2 持续赋值语句中的延时

assign #5 WireOut = ~ WireIn;

这种描述用语表示电路中的惯性延时,任何小于5ns的输入变化都会被过滤而不会体现在输出上。

1.3 过程赋值语句中的延时

过程赋值语句中的延时情况比较复杂,但是结论很简单:

●在持续赋值语句中使用正规延时,可以描述惯性延时。

●在非阻塞赋值语句中使用内定延时,可以描述传输延时。

1.3.1 正规延时和内定延时

正规延时和内定延时的定义见清单3。

清单3 正规延时和内定延时

#N sum = a+b; //正规延时

sum = #N a+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所示。由Quartus II综合后得到时间戳report和RTL图形分别如图3和图4所示,由Modelsim仿真产生的仿真波形如图5所示。

清单4阻塞赋值语句中的延时module DelayDemo(A,B,C,D);

output A,B,C,D;

reg [3:0] A,B,C,D;

initial

begin

A=4'd0;B=4'd0;

#4 A=4'd2;B=4'd4;

#2 A=4'd3;

#2 A=4'd4;

#9 A=4'd3;

#2 A=4'd5;B=4'd5;

#5 B=4'd8;

end

always@(A or B)

begin

C =#3 A+B; //阻塞赋值中的内定延时end

always@(A or B)

begin

#3 D= 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

相关文档
最新文档