sv的仿真调度完全支持Verilog的仿真调度,同时又扩展出来支持新的sv结构体,如程序(program)和断言(assertion)。充分理解sv的不同结构体在仿真中的执行的先后顺序,有利于理解testbench中对DUT的驱动和采样的顺序,进而避免不合理的驱动和采样方式。仿真器一般是基于event驱动方式执行,对各类型的event的发生做出合理安排,就可以保证设计与验证环境之间又清晰的事件发生顺序,避免两者间的竞争问题。
这里,时间片(time_slot)是仿真时间中的一个抽象单位TS,该单位内所有的线程和数据对象的赋值(阻塞赋值和非阻塞赋值)被赋予相应的优先级,依次被执行。
active区域:从preponed region进去active region之后,将执行所有处于该调度阶段的线程
,其中,与非阻塞赋值有关的操作执行完毕后,对应的线程进入NBA,而带有#0延时操作的线程进入inactive区域。
inactive区域:所有被进行零延时操作的线程在inactive区域被激活,在被执行之前迁往active区域,因此,零延时的操作会延缓线程的执行时间。
NBA区域:达到该区域后,之前在active区域的非阻塞赋值生效。
Observe区域:这一区域是为了断言准备的。
Reactive区域:经历了信号采样之后,处于testbench区域中的线程也在该区域执行。
如果tb中的数据采样在module内部执行,则可能产生不同的采样结果,可以通过program的采样方式使采样是我们预期的结果。
· 在program执行之前,先进行设计代码相关的仿真调度区域即active,inactive和NBA。
· 设计调度区域执行完后,会通过observed区域,最后至reactive区域,而program会在reactive区域执行,所以program会采用之前已经被阻塞/非阻塞赋值后稳定值进行计算。
由此看来sv介绍program的一个重要部分就是为了将设计和验证的调度区域通过显示的方式来安排。因此,建议将设计部分放置在module中,而将测试采样部分放置在program中。下面是关于program的建议:
·program中不可以出现和硬件行为相关的过程语句和实例,例如always,module,interface,也不应该出现其他program语句。
· 为了使program按照类似软件方式的顺序执行,可以在program内部定义变量,已经发起多个initial块。
· program内部定义的变量赋值的方式应该采用阻塞赋值(软件方式)
· program内部去在驱动外部硬件信号使应该使用非阻塞赋值。
· program中的initial块会在reactive区域执行,而program之外的initial块则会在active区域被执行。