Initial block和final block有什么区别?
Initial block在仿真开始时即运行,final block在仿真结束时运行。initial block内部可以有延时语句,可以消耗时间,而final block不行。final block通常用于在结束仿真时,显示一些信息。
Simulation phases of SystemVerilog verification
Build phase:generate configuration, build environment, reset the dut, configure the dut
Run phase: start environment, run the test,
Wrap-up phase: sweep, report
Packed / Unpacked array
合并数组与非合并数组在声明上有区别,元素存放方式有区别。合并数组元素是以整体的比特集合来存放,而非合并数组元素则是分散的。
当需要整体访问数据,又要分解数据时,用合并数组是更方便的。
/*合并*/
bit [3:0] parr;
/*非合并*/
bit uparr[4];
This 的含义
this是一种指针,它可以指向当前所在的类,引用其属性和方法。
哪种数据类型适合构建内存?
关联数组。关联数组适用于数据量大的情况。内存通常可以有很大的数据量,但是并不是每时每刻都是填满的,有时候甚至消耗的很少。使用关联数组就可以很好匹配这种情况,关联数组同时储存数据以及其索引,没有数据的地址就不为其分配索引,可以节省实际空间,同时又提高数据读取效率。
如何避免DUT与验证平台之间的竞争
利用时钟块,设置input和output的提前或延时可以避免。设置了input提前后,验证平台采样提前一定时间,确保DUT的数据变化能在时钟边沿到来时被读取;设置output延时后,确保验证平台能够有足够时间得到最新的值。
程序块有什么优点
程序块作为验证平台的入口,将DUT即验证平台分割开来,程序块的运行在时间片上是位于Reactive区域,而设计代码在Active区域,这样可以一定程度上避免设计与验证之间的竞争。
程序块为什么不允许使用always
always块在仿真一开始就会等待信号变化然后执行。但是验证往往是有序配置策划的,always块会导致验证平台的行为失控,常常也不需要一开始就执行。
logic 和 bit
logic是四状态,bit是双状态。bit最好不要用于储存采样自RTL设计的数据,因为容易造成数据遗失;同时双状态一定程度上可以提高运行速度。
抽象类和纯虚方法
抽象类,不能被直接实例化,但可以被扩展,用virtual定义;纯虚方法,没有实体的方法原型,由抽象类扩展而得来的类,只有在所有虚方法都有实体的时候才能被例化,用pure定义。
$urandom / $random
前者随机返回一个32位无符号数,后者返回有符号数。
DPI
Direct programming interface 直接编程接口,用于连接sv与其他语言。可以让验证平台方便地调用其他语言的函数。
== 与 ===
==用于比较双状态数据,如果两边出现x或z,结果为0;===可以比较四状态数据,两边是x,也可返回1。
always_comb 和 always@(*)
前者是sv中新添加的关键字,它直接指明这个always块内描述的是组合逻辑,比起使用后者,更加明确,可以减少失误。always_comb会自动检测块内的数据变化。
shallow copy / deep copy
前者只是复制属性和方法,如果包含嵌套类,则只是复制了句柄,不会生成新的对象。后者则可以在复制时,再生成新的嵌套类实例。
接口的优点
便于设计重用;减少连接错误的可能。
modport / clocking block
modport 接口中用于将信号分组,并指明方向的一个关键字。clocking block 用于指定同步信号相对于时钟的时序。
验证平台的构成及分层
以及测试层及功能覆盖率
$rose(a)和@(posedge a) ?
前者是任务,会返回1或0;后者实时检测a,是一个事件。
socpe randomization
std::randomize(a) a是局部变量,这个函数可以随机化不在类中的参数,如在这个作用域内的a。
local / protected
local 只有在定义它的类中可见,在模块和派生类中都不可见;protected 在派生类中可见,在模块中不可见。
覆盖率类型
代码,功能,断言