VerilogHDL中,有两种过程赋值方式,即阻塞赋值(blocking)和非阻塞赋值(nonblocking)。阻塞赋值执行时,RHS(righthandstatement)估值与更新LHS(lefthandstatement)值一次执行完成,计算完毕,立即更新。在执行时阻塞同块中的其他语句的执行。阻塞式(blocking)的操作符为“=”。它的执行很像传统程序设计语言。非阻塞赋值RHS估值与更新LHS值分两步执行。在单位仿真周期开始时RHS估值,在同一单位仿真周期末更新LHS值,不阻塞同块中其他语句的执行。非阻塞式(non-blocking)的操作符为“<=”,它的执行更像并行电路,使描述电路更自然。阻塞赋值与非阻塞赋值是VerilogHDL程序设计的难点,它们既有共同点,也有差异,深入剖析其异同,对于硬件程序的开发具有重大意义。
1Verilog事件处理机制
层积事件列(TheStratifiedEventQueue)是一个事件管理概念模型,而非硬件逻辑。模型内事件的具体实现与EDA软件生产商的算法策略有关。在IEEE-2001中,Verilog把事件分为5个不同部分,按照时间顺序如图1所示。
触发的任何事件可以加入到这5个事件列中的任何事件列中,但只能从活跃事件列中移出。即上面的5个事件列中的事件最后都将被激活而放入活跃事件列中。层积事件列是层次模型,层积事件列的执行顺序是按优先级排列的。任何EDA软件都只能执行活跃事件。其他事件列都按优先级级别依次激活本列事件以供执行。
1.1活跃事件列
由图1可见,大部分事件都被放入活跃事件列。活跃事件列里包括非阻塞赋值RHS估值。但是,非阻塞赋值的更新不是在活跃事件列,它被列成独立的非阻塞更新事件列。活跃事件列是仿真的执行源,从一开始执行活跃事件列到活跃事件列执行完毕称为一个仿真周期。活跃事件列中的事件可以触发活跃或非活跃等其他事件。当活跃事件列中的所有事件执行完后,EDA软件会按优先级依次触发其余事件列以供仿真执行。但在当前活跃事件列中的事件执行顺序是不确定的。
1.2非活跃事件列
发生在当前仿真时间里并且在活跃事件列执行完后执行的事件列,即非活跃事件列执行优先级仅次于活跃事件列。如带PLI例程的回调过程(tf_synchronize()、vpi_register_cb(cb_readwrite))。非活跃事件列中的事件亦可以触发其他事件。如果触发了优先级更高的活跃事件,非活跃事件列中的其余事件执行后移。
1.3非阻塞赋值更新事件列
活跃事件列中的每个非阻塞赋值RHS估值,都会触发一个与之对应的非阻塞赋值更新事件,这些事件被放在非阻塞赋值更新事件列中,执行优先级次于活跃与非活跃事件列。非阻塞赋值更新事件亦可以触发其他事件。若在非阻塞赋值更新事件列中,存在多个对同一变量的先后赋值,只有最后一个有效,其余值将被覆盖。
1.4监控事件列
监控事件列被放在非阻塞赋值更新事件列后。由此可见,用监控事件列中的监控命令监控得到的值都是赋值后的值,活跃事件列$display系统命令则可以查看非阻塞更新前的值。
1.5未来事件列
在执行事件时,如果事件含有延时,为不阻碍仿真的继续执行,该事件将被挂起而放入未来事件列。未来事件包含未来非活跃事件和未来非阻塞赋值更新事件。
理解阻塞与非阻塞赋值就需要深入理解层积事件列,层积事件列反应了Verilog事件处理机制。 |