Verilog系列:赋值过程中的不同延迟
0 概念
传输延迟(Transport Delay):一般为输入信号变化到对应输出信号变化经过的时间,不会对输入信号进行滤除处理,所以传输延迟是一种绝对延迟,这种延迟类似于物理传输线的延迟,在仿真中用于模拟连线延迟。
1 连续赋值语句
-
在线网声明时指定.在该种情形下,任何给该线网赋值的语句中,任何值变化都要等待指定的延迟时间后才能将值赋予给该线网,其特点是使用该线网的语句都会受到该延迟值的影响.
【示例】
【仿真结果】
-
在具体的连续赋值过程中指定延迟:延迟时间在LHS设定,用于指定RHS值变化体现到LHS需要延迟的时间;
【示例】
【仿真结果】
-
以上两种延迟方式的组合,即在线网声明和连续赋值语句中同时指定延迟,此时当输入信号宽度大于等于指定延迟中最大的延迟时将可以传递到LHS;
【示例】
【仿真结果】
【示例】
注:此例与上例延迟值进行了交换。
【仿真结果】
通过上述两个示例的仿真结果可以观测到,当线网声明和连续赋值的过程中都是指定了延迟,且输入信号的宽度小于指定延迟中最大的延迟值时,连续赋值表达式中的RHS将不能传递到LHS。如果RHS能够传递到LHS,此时输出至LHS的信号相对于输入信号的延迟为声明和赋值过程中指定的延迟之和。另外,这里需要注意,在连续赋值语句中,延迟值只能在赋值语句的左侧出现,不能出现在右侧,如下式指定的延迟是错误的:
【示例】
通过上述几个示例还可以得到以下结论,当指定延迟后,在延迟的过程中输入发生多次变化时,连续赋值的最终结果按照如下规则确定:
-
解析RHS表达式;
-
如果重新解析的RHS的值与当前将要发送给LHS的值不同,那么当前将要发送给LHS的值的事件将会被取消,而被重新解析新的RHS值的事件替换;
-
如果重新解析的RHS的值与当前将要发送给LHS的值相同,那么当前事件队列将会保持不变,即原有已经安排将要发送给LHS的值不会被更新;
-
如果重新解析的RHS的值与当前将要发送的LHS的值不同,且赋值过程中指定了延迟,那么原有的事件队列中将要发送给LHS值的事件将会被替换,并且延迟值也将重新开始延迟;
2 阻塞赋值语句
阻塞赋值语句在顺序结构(begin-end)中,其后的语句执行将发生在阻塞语句执行完之后,但是在并行结构(fork-join)中,阻塞赋值语句与其前后的语句是并行执行的。在过程语句结构中使用的阻塞赋值语句中经常也需要增加延迟用于模拟特定的仿真行为,常见的增加延迟的方式有如下两种:
-
延迟出现在赋值语句左侧,即延迟位于LHS;
- 延迟出现在赋值语句右侧,即延迟位于RHS;
【示例】延迟出现在赋值语句左侧,即延迟位于LHS。
【仿真结果】
【示例】
【仿真结果】
【示例】延迟出现在赋值语句右侧
【仿真结果】
3 非阻塞赋值语句
非阻塞赋值与阻塞赋值最大的不同之处在于其执行并不阻塞进程当执行。也因为这个特点,Verilog本身对于两者的处理机制也存在不同,特别是在赋值过程中延迟的处理方式上。在对应的进程触发后,非阻塞赋值过程一般可以分为两部分理解:
-
解析RHS表达式并且将赋值操作排在non-blockingassign update event队列的最后;
-
当前时间槽最后non-blockingassign update event被激活,仿真器更新LHS;
【示例】延迟出现在赋值语句左侧
【仿真结果】
当in1第一次发生变化时进程触发,进入begin-end后等待DLY个时间单位,在这DLY个时间单位的等待过程中,“in1,in2,ci”的值发生了变化,但是发生变化的过程中并没有执行到“#DLY”个时间单位后的非阻塞赋值语句,也即非阻塞赋值语句的RHS并没有解析执行,那么在DLY个时间单位后开始执行非阻塞赋值语句,此时按照非阻塞赋值语句执行的两步进行,第一步,对RHS进行解析,此时RHS中“in1,in2,ci”的值并不是in1第一次发生变化时的值“in1='ha,in2='h0,ci=0”,而是“in1='hf,in2='h3,ci=1”,所以此时计算的值为仿真所示结果。
【示例】延迟出现在赋值语句右侧
【仿真结果】
4 总结
在任何的过程语句或者行为建模中,尽量不要使用具体的延迟在赋值语句中,虽然在仿真时可能能够模拟出具体的硬件行为,但是这些延迟在物理综合的过程中是不支持的(将会被综合掉),并且很有可能导致综合后结果与行为仿真时不一致,但是在实际的仿真环境构建过程中,恰当的使用延迟,往往可以构建出期望的时序激励。因此,在实际的设计和验证过程中,正确使用延迟可以避免一些不必要的错误。