验证环境结构
验证平台是整个验证系统的总称。它包括验证结构中的各个组件,组件之间的连接关系,测试平台的配置和控制。更系统来讲,它还包括编译仿真的流程、结果分析报告和覆盖率检查等。狭义上说,主要关注验证平台的结构和组件部分,他们可以产生设计所需要的各种输入,也会在此基础上进行设计功能的检查。
各个组件之间是相互独立的,验证组件与设计之间需要连接,验证组件之间也需要通信,验证环境也需要时钟和复位信号驱动。
验证环境组件
激励发生器
stimulator 激励发生器:是验证环境中的重要部件,有些时候也称为driver(驱动器),bfm(总线功能模型),behavioral(行为模型)或者generator(发生器)。
主要职责是模拟和DUT相邻设计的接口协议。需要关注如何模拟接口信号使得可以以真实的接口协议来发送激励给DUT,并且stimulator不应该违反协议。stimulator的接口主要是同DUT之间的连接,也可以有其他的配置接口用来控制接口的数据生成。也可以有存储接口数据生成历史的功能。
分类
从stimulator同DUT的连接关系来说,可以进一步分为initiator(发起器) 和responder( 响应器)。
检测器
monitor(监测器)的主要功能是用来观察DUT的边界或者内部信号,并且经过打包整理传送给其他验证平台的组件,例如checker(比较器)。
分类
从检测信号的层次来划分monitor的功能,它们可以分为观察DUT边界信号和观察DUT内部信号。
观察DUT边界信号 :对于系统信号如时钟,可以检测其频率变化,对于总线信号,可以检测总线的传输类型和数据内容,以及检查总线时许是否符合协议。
观察DUT内部信号 :从灰盒验证的手段来看,往往需要窥探DUT内部信号,用来指导stimulator的激励发送,或者完成覆盖率收集,又或者完成内部功能的检查。
没有特别需要,应该采用灰盒验证的策略。观察内部信号应当尽量少,应当是表示状态的信号。不建议采集中间变量信号的原因 在于,这些信号的时序、逻辑甚至留存性都不稳定,这种不稳定对于验证环境的收敛是有害的。
可以通过接口信息计算的,就尽量少去监测内部信号,因为这种方式也有悖于假定设计有缺陷的验证思想。观测到的内部信号在被环境采纳之前也有必要确认它们的逻辑正确性,这一要求可以通过动态检查或者断言触发的方式来实现。
比较器
checker 是最需要时间投入的验证组件。checker肩负来模拟设计行为和功能验证检查的任务,缓存从各个monitor收集到数据,将DUT输入接口测的数据汇集给内置的reference model(参考模型)。reference model模拟了硬件功能。
通过数据比较的方法,检查世纪收集到的DUT输出端口的数据是否与reference model产生的期望数据一致。
比较方式
对于设计内部关键功能模块,也有相应的线程进行独立的检查。
线上比较(online check) :在仿真时收集数据和在线比较,并且实时报告。
线下比较(offline check) :将仿真时收集到的数据记录在文件中,仿真结束后通过脚本或者其他手段进行比较。
预测
将checker添加到验证环境中,需要它分析DUT的边界激励,理解数据的输入,并且按照硬件功能来预测输出的数据内容。这种预测(prediction)的过程,发生在reference model中,有时我们也将其称为predictor。
reference model也会内置一些缓存,分别存放从DUT输入端观察到的数据,以及经过功能转换的数据,同时checker也有其它缓存来存放从输出端采集到的数据。
比较器实现建议
对于复杂的系统验证,倾向于集中管理stimulator和checker,因为它们两者都需要主动给出激励或者判断结果,也需要较多的协调处理。
而monitor则相对更独立,因为它只是作为监测方,将其观察到的数据—交给checker即可,monitor并不需要关心checker的用法。
因此,stimulator和monitor是——对应,我们通常将它们进—步封装在agent单元组件中,而checker则最终集群搁置在中心化的位置。
任务和函数
任务和函数可以提高代码的复用性和整洁性。任务和函数的参数列表都可以为空。目的都在于将大的过程块切分为小片段,而便于阅读和代码维护。
区别
- function不会消耗仿真时间,而task则可能会消耗仿真时间。
- function无法调用task,而task可以调用function。
- 一个可以返回数据的function只能返回一个单一数值,而任务或者void function不会返回数值。
- —个可以返回数据的function可以作为一个表达式中的操作数,而该操作数的值即function的返回值。
任务task
任务定义可以指定参数,input,output,inout,ref都可。任务可以消耗仿真时间。任务可以调用其他任务或者函数。task没有返回值,但是可以利用return来使得task结束。
函数
函数不可以调用任务,函数可以调用函数。void函数不会返回数值。函数列表方向同任务,没有给出方向和第一个默认保持一致。
函数的返回类型有两种,return 或者声明函数名。 如果调用函数有返回值,但是又不打算用该返回值时,建议添加void'()进行转换。
参数传递
input 参数方向在方法调用时,属于值传递。即传递的过程中,外部变量的值会经过拷贝,赋值于形式参数。output、inout也会在传入或者传出的时候发生值传递的过程。值传递的过程值发生在方法调用时和返回时。
ref参数在传递时不会发生值拷贝,而是指针传递到方法中,在方法内部对该参数的操作将会影响外部变量。为了避免外部传入的ref参数会被方法修改,可以添加const修饰符,来表示变量是只读变量。
SV允许方法声明参数的默认值,参数的方向可以是input,inout,output和ref。带有参数默认值的方法被调用时,如果这些参数没有被传递值,那么编译器将会为这些参数传入对应的默认值。SV允许类似于模块例化,可由参数位置顺序在调用方法时传递参数,也可以由参数名字调用方式时绑定参数。
reference
- 西电路科验证PPT