前言
SV不同于C/C++等软件语言,虽然最终都可以翻译成运行在CPU上的一条条指令,但软件语言目的是为了控制CPU进行我们想要的运算,而SV目的是对硬件进行仿真建模。
实际硬件很多并行执行的逻辑,我们的SV如何去模拟硬件执行需要一定的标准,目前SV LRM仿真调度算法采用IEEESystemVerilog.std.1800-2012。它是基于一个个时间片进行仿真,将仿真时间串行的一步步的向前推进。由于SV LRM并没有完全详细的规定并行块以具体什么样的顺序来执行,这就引进许多不确定性(Nondeterminism), 不同厂家的仿真器可能有不同的仿真结果。为了在验证代码编写时避免这些问题,需要对Verilog/SV的仿真调度算法进行深刻理解,并且涉及到VHDL的混合仿真,也要理解VHDL和Verilog/SV之间的差异。
提示:以下是本篇文章正文内容,下面案例可供参考
一、SystemVerilog离散事件执行模型
SystemVerilog采用了离散事件执行模型,它是基于一个个时间片进行仿真。这里说的时间片其实没有时间概念,纯粹是工具为了仿真效果而提出的不同任务工作的区域,在一个时钟边沿有效,可以理解为一个时钟边沿上的进程,但不涉及时间的推进,只是进程顺序执行。只有在当前时间片上的所有仿真全部完成,仿真器才会进入下一个时间片。当然,每个时间片还会细分为多个区域,如下图所示:
preponed区域:这个区域中的数值是上一时间片中最终的稳定值。断言所需的数据就是在这个区域采样的。active区域:断言所需数据采样完成以后,就进入本区域了,但是只执行阻塞赋值语句,连续赋值语句,非阻塞赋值中“<=”符号右边的计算,原语计算以及调用系统函数(如$display)等。需要说明的是,不同线程中的上述语句执行顺序是不确定的,仿真结果和仿真器相关。
inactive区域:该区域用的比较少,只有当线程被加上#0延迟才会进入该区域,当active区域中的操作全部执行完,本区域中的零延时线程才会进行操作。因此,零延时操作会延缓线程的操作时间,使用时应当注意,可以用在验证中对事件的执行先后顺序进行调度。
NBA区域:当前面的几个区域都完成以后,就进入NBA区域了,本区域做的事情就是把在active区域计算的非阻塞赋值右侧表达式的值赋给左侧。(非阻塞赋值其实是分成了两个步骤,先计算RHS,再更新LHS,中间会去完成其它事件的调度和计算。而阻塞赋值两步同时执行,不存在中间插入其它事件的情况。)
前面这几个区域其实在Verilog中就定义了,而且基本没有变化,这是专门为RTL代码执行所设立的区域。相对于为RTL代码设立的区域,还有专门为验证平台所设计的区域集合,Reactive Region set。包含了Reactive Region、Re-Inactive Region、Re-NBA Region。Observed Region则是专门为断言所设计的区域。
observed区域:此区域的主要功能是使用在preponed区域中采样的值来评估并发断言中的属性是否成立。属性评估在任何一个时间片中只发生一次。
reactive区域:在上一区域对断言属性进行评估后,本区域对断言表达式中的代码进行操作,看是否成功。当然,本区域还会执行program块中的连续赋值,阻塞赋值,非阻塞赋值的右式计算等。同样需要注意的是,上述这些语句的执行顺序同样是不确定的。
re_inactive区域:同inactive区域类似,执行program块中的#0零延迟阻塞赋值。re_NBA区域:同NBA区域类似,执行program块中的非阻塞赋值左值更新。
re-NBA区域:同上
postponed区域:同下一时钟片中的preponed区域一样的值,代表本时钟片中的最终稳定值。
执行的伪代码如上图所示。
二、在verdi中显示毛刺的region
simv仿真时加上如下参数
+fsdb+region 记录信号的Event Regions(Active、Inactive、NBA)信息。
+fsdb+glitch=num 控制glitch(毛刺)的dump,num取值0~254,0代表将所有的毛刺dump下来。
+fsdb+sequential 记录同一时刻下,信号变化的先后顺序。
可以使用+fsdb+delta更方便
使用Expand Delta