文章内容主要来自于以下文档,然后对自己平时遇到的一些现象作出了思考。
1、IEEE systemverilog.std.1800-2012
2、SystemVerilog Event Regions & Race Avoidance & Guidelines
===================================悲伤的分割线===================================
我们设计的硬件、仿真环境抽象意义上是可以并行运行的。但是在实际仿真时,不过是运行在cpu上的串行执行的程序而已(先不讨论多核)。systemverilog专门为这种并行到串行的转换定义了调度机制。但IEEE在制定规范时,并未规定一部分并行的事件执行的先后顺序,这点会引入不确定性(Nondeterminism),这种不确定性往往会体现在不同厂家的仿真器上(因为不同的厂家采用的调度算法是不一样的),最严重的后果就是在不同仿真器上看到的最终结果是不一样的。所以作为一名合格的工程师,应该对sv仿真器的调度机制、确定性与不确定性有基础的了解。
systemverilog是为离散事件执行模型(discrete event execution)所定义的一种语言。怎么理解呢?离散指的是仿真时间(simulation time)上的离散性,仿真基于时间片(time slot)进行,只对有效的时刻点进行仿真。事件执行模型指的是仿真基于事件进行建模和整体的调度。
下面先介绍几个概念:
进程(Processes)是sv中并发调度的单元,比如:原语(Primitives)、initial过程块、always过程块、连续赋值(continuous assign)、异步任务(asynchronous tasks)、过程赋值(procedural assignment)等。进程是可以被执行的,有相应的状态标志(state,比如挂起)。进程会响应输入的变化并产生对应的输出。sv的描述的对象也正是这些进程。
更新事件(update event):仿真中,net或者variable上每次的变化被认为是一次更新事件。
求值事件(evaluation event):进程对更新事件敏感!当一个更新事件被执行时,所有对该更新事件敏感的进程都会被求值,但是顺序是任意的。进程的求值本身也被认为是一种事件,即求值事件(evaluation event)。更新事件和求值事件的相互交替执行,推动了仿真时间的前移。
时间片(time slot):这个真的没啥好解释的,知道仿真是基于离散的时刻点来进行的就可以了。只有在每个时间片上的仿真活动全部完成,仿真器才会进行下一个时间片,也就是说仿真时间是不可逆的。在早期的IEEE描述里面,time slot也叫做timestep,只不过现在不这么叫了。每个时间片都会被划分成很多个区域,下面会详细介绍。划分的目的是为了保证仿真执行的正确性和清晰性。
再看sv的Event Regions之前,我们先看下verilog-2001里面定义的Event Regions。
嗯,看上去还不是很复杂。总共也就定义了4个regions(Active、Inactive、NBA、Postponed),而且一般对于我们而言,Inactive域是不会用到的(后面会解释)。
Active Region:
Inactive Region:
NBA Region:
Postponed Region:
这里有两个有趣的东西:
1、非阻塞赋值其实是分成了两个步骤,先计算RHS,再更新LHS,中间会去完成其它事件的调度和计算。而阻塞赋值两步同时执行,不存在中间插入其它事件的情况。
2、有一些工程师喜欢用#0延迟去消除对同一变量赋值所引起的竞争,但是其实按照编码规范来,你就不应该在多个always对同一个变量进行阻塞赋值,所以理论上就不应该用到#0的阻塞赋值,所以也就用不到Inavtive Region了。
我们再来看看systemverilog-2005里面定义的Event Regions。
我第一次看到内心其实也是崩溃的,卧槽,数了下,总共有17个Event Regions。但是,如果把8个PLI(Programming Language Interface,用来调用其它语言的函数的接口,比如C/C++)的Event Regions剔除,看上去也还好。
Active Region、Inactive Region、NBA Region统称为Active Region set,这是专门为RTL代码执行所设立的区域集合(set),实际上就是上面介绍的verilog代码的区域,只不过在sv中需要限定一下事件是在module中定义的,而不是program中定义的(verilog不存在program)。在sv中,相对于为RTL代码设立的区域,还有专门为验证平台所设计的区域集合,Reactive Region set。包含了Reactive Region、Re-Inactive Region、Re-NBA Region。Observed Region则是专门为断言所设计的区域。
Preponed Region:
Observed Region:
Reactive Region:
其实仔细看下,和Active Region内执行事件是很类似的,只不过加了program的限定。
Re-Inactive Region:
虽然Inactive Region不推荐使用,但是Re-Inactive Region还是有一些独特的价值的,比如开一些后台fork时,你希望新开的子进程优先于父进程执行。
program test;
initial begin
fork
process1;
process2;
process3;
join_none
#0;
// parent process continues
end
endprogram
Re-NBA Region:
Postponed Region:
比较一下,systemverilog的Postponed Region比verilog的Postponed Region多了功能覆盖率的收集功能。
#1step是systemverilog引入的一种新的能力,主要为了解决采样的问题。step时间单位其实就是我们定义的最小的时间精度,换句话说,这也是仿真器在时间上进行调度的最小单位,在#1step的delay时间内,是不存在事件的。
IEEE定义了#1step延迟会在当前time slot的Preponed Region进行采样,但这样实际上的效果和在上一个time slot的Postponed Region采样是一样的(有可能两个time slot之间差了无数个#1step)。所以个人猜测,很多EDA的厂家会对这里进行优化,但最终呈现的效果是在当前time slot的Preponed Region采样的就行。
在时钟块(clocking block)里面默认的input skew就是#1step,而output skew是0。
Q1:interface中应该怎么去定义`SETUP和`HOLD时间比较好?
A1:
Q2:整个仿真所消耗的CPU时间和定义的`timescale有没有关系?
A2:个人观点:如果改变`timescale能够减少我们的time slot数量或者总的事件量,那么对仿真时间就是有收益的。
Q3:为什么设计写代码时不建议采用always@(*)的方式赋常值,而是建议使用assign的方式给常值?always@(*)赋常值在仿真时的行为是什么样的?
A3:参考下图,sv标准里面写了,连续赋值语句会在0时刻进行触发,以便传递常值;而always的阻塞赋值没有这个效果。
Q4:ucli中,按下ctrl-c后程序是停在了哪里?
A4:没有找到明显的答案,这里只是一些猜测。ucli交互时我们需要看到的是一个明确的结果,所以程序不应当处于设计代码的迭代的过程中,因此,可以排除是Active Regions。
Q5:systemverilog引入program块的意义?
A5:引入了Reactive Region set(Reactive、Re-Inactive、Re-NBA),将验证代码和设计代码区域区分,减少了竞争冒险。
Q6:有时候写代码时会加入#0的延迟,有什么作用吗?
A6:参考文章,设计中不要使用,验证时可以使用来对事件执行先后进行调度。
Q7:uvm的run_test()在应该在module里面例化,还是应该在program里面例化?
A7:两种例化方式都是可以的。在module中例化就相当于没有了program块,自然也就没有了program块相关的Regions,如果你的代码风格不是很诡异的话,当然是完全没有问题的。事实上cadence也是推荐我们在module中例化run_test(),而synopsys则建议我们在program块内例化run_test,利用program块来对设计代码和验证平台进行区分。曾经有人也说过program块完全是多余的垃圾,因为对于代码风格良好的设计而言,即使没有program块也是不会存在验证的竞争冒险。所以个人观点,萝卜青菜,各有所爱,你习惯用哪个就用哪个。
Q8:uvm中的函数uvm_wait_for_nba_region()有什么作用?
A8:顾名思义,这里需要等待NBA Region之前的进程被执行完。源代码有解释,如下:
===================================悲伤的分割线===================================
写在最后:
1、双11撸了一台腾讯云主机(真良心价!2C4G 3M 3年只要688),已经基于xfce+vnc装好图形界面,试了下vcs和verdi都可以正常运行。而且手机上的vnc viewer也挺好用的。开心。
2、其实搞验证搞了这么久,觉得最有用的资料还是IEEE的标准和软件的user guide,其它的知识点很多都是衍生出去的(有一种天下武功出少林的感觉),建议大家有空还是多看看。
3、TMD,周天还要让我去公司协助定位问题,真是够了,能不能给人留点私人时间啊。