激励发生器
概述
-
Stimulator(激励发生器)是验证环境的重要部件,在一些场合中,它也被称为driver(驱动器)、BFM(bus function model,总线功能模型),behavioral(行为模型)或者generator(发生器)
-
Stimulator的主要职责是模拟与DUT相邻设计的接口协议,只需要关注于如何模拟接口信号,使其能够以真实的接口协议来发送激励给DUT 是对边界信号而不是内部信号发送激励
-
Stimulator不应该违反协议,但不拘束于真实的硬件行为,还可以给出更多丰富的只要协议允许的激励场景
-
比真实硬件行为更丰富的激励,会使得在模块级的验证更加充分,因为它不但验证过了硬件普通的接口协议情景,还模拟出更多复杂的、在更高系统级别无法产生出来的场景
-
Stimulator的接口主要是同DUT之间连接,此外,也应该有时钟和复位的输入,确保生成的数据同DUT的接口一侧是同步的关系
-
较精细的Stimulator还可以有其他的配置接口用来控制接口的数据生成
-
Stimulator也可以有存储接口数据生成历史的功能,这可以用来仿真运行时或者结束时后查看数据,方便统计或者调试
-
从Stimulator同DUT的连接关系来看,可以将其进一步分为两种:initiator(发起器)和responder(响应器)
-
就我们要验证的MCDF来看,与下行通道从端(channel slave)的连接或寄存器接口的连接,这两部分的Stimulator都属于initiator,它们的功能是主动发起接口数据传输 还有register
-
与MCDF formatter接口的连接,该Stimulator则属于responder,它的职责是对接口数据发送请求做出响应,而它本身不会主动发送数据
Stimulator实现考虑要素
channel initiator
-
由于channel从端连接协议上有握手信号,我们需要遵照接口时序,确保chx_ready为低时,保证chx_data和chx_valid保持不变
-
相邻数据之间没有数据包的限制,所有相邻数据之间的关系较弱但也应该考虑数据之间是否有空闲周期,以及整体数据的传输速率设定
-
由于每一个数据从端都有对应的FIFO缓存数据,所以也需要考虑如何使得FIFO的状态可遍历。例如,典型的FIFO状态可以分为empty、full以及中间状态即有数据存储但未写满。要是得FIFO可以触发这些状态,就应该控制channel initiator的传输速率
Register initiator
-
寄存器接口上cmd的默认状态为idle,但cmd_addr、cmd_data_in并未指出默认值应该为何值,所以可以考虑给出随机数值测试DUT的接口协议稳定性
-
在寄存器读写传输上,可以考虑连续的写、读或者读写交叉的方式测试寄存器模块的读写功能
-
对于寄存器的所有比特位测试都应该覆盖
-
对于只读状态寄存器需要测试是否为不可写入的设定,同时需要测试读出的数值是否为真实的硬件状态。
Formatter responder
-
作为三种接口协议中相对复杂的一个,首先侧重formatter接口协议是否充分遍历
-
需要详细理解协议的要求,除了按照协议给出fmt_grant的响应以外,也需要检查协议的时序
-
fmt_grant的置高,则代表formatter的从端有足够的储存空间,可以容纳formatter要传输的长度为fmt_length的数据包。为了模拟真实场景,可以考虑让fmt_grant采取立即拉高或者延时拉高的行为,测试formatter接口响应时序
channel initiator、register initiator、formatter responder都是接口上做激励,arbiter initiator则不需要
监测器
概述
-
Monitor(监测器)的主要功能是用来观测DUT的边界或者内部信号,并且经过打包整理传送给其他验证平台的组件,例如checker(比较器)观测数据作检查
-
从监测信号的层次来划分monitor的功能,它们可以分为观察DUT边界信号和观察DUT内部信号
-
观察DUT边界信号。对于系统信号如时钟,可以监测器其频率变化;对于总线信号,可以监测总线的传输类型和数据内容,以及检查总线时序是否符号协议
-
观察DUT内部信号。从灰盒验证的手段来看,往往需要探视DUT内部信号(如内部FIFIO,若用寄存器,则还需要下一拍才知道),用来指导stimulator的激励发送,或者完成覆盖率收集,又或者完成内部功能的检查
monitor不从stimulator获取数据,stimulator发送到接口,monitor是从接口获取数据
-
独立性:倾向于后者(每个stimulattor有一个monitor),即将不同接口信号的采集交给相应的monitor。因为就各个接口的功能而言,它们之间没有联系性,易于切割
-
复用性:仍然是后者,可以考虑如果MCDF的接口也可能会运用到别的验证环境中,那么相对独立的monitor可以更好地作为验证IP被其他验证环境所复用。基于这个考虑,我们也将通道从端数据接口的采集分别对应了3个channel monitor,而每一个monitor只需要负责监视一组总线
-
可维护性:后者也优于前者,设计的外部接口必定先于内部信号趋于稳定。那么平行的monitor组更有利于验证者在验证后期,定向维护MCDF monitor,而不需要考虑其他的monitor。同样到了后期项目,或者设计遇到修改时,更有可能修改的是内部逻辑,而非接口信号,这种情况下只需要更新MCDF monitor,而不必更新其余的接口类型monitor
-
封装性:后者的优势在于可以与各个stimulator一 一对应,形成验证环境的小单元,这些小单元之间的通信可以按照统一的方式实现,但又可以保持各自的独立性。这样的话,各个小单元即一个stimulator对应一个monitor,就可以将其封装为独立的组件,使其提供激励和监测功能
内部信号监测建议
-
如果没有特殊的需求,我们应采取灰盒验证的策略(而非白盒)。
-
观察内部信号应当尽量少,且应当是表示状态的信号。不建议采集中间变量信号的原因在于,这些信号的时序、逻辑甚至留存性不稳定,这种不稳定对于验证环境的收敛是有害的。
-
可以通过接口信息计算的,就尽量少去监测内部信号,因为这种方式有悖于假定设计有缺陷的验证思想。我们观测到的内部信号在被环境采纳之前也有必要确认它们的逻辑正确性,这一要求可以通过动态检查或者断言触发的方式来实现。
比较器
概述
-
无论是从实现难度,还是从维护人力上来讲,checker(比较器)都应当是最需要时间投入的验证组件
-
checker肩负了模拟设计行为和功能检查的任务
功能
-
缓存从各个monitor收集到的数据
-
将DUT输入接口侧的数据汇集给内置的reference model(参考模型)。Reference model在这里扮演了模拟硬件功能角色,也是需要较多精力维护的部分,因为验证者需要在熟悉硬件功能的情况下实现模型,而又不应参考真实硬件的逻辑
-
通过数据比较的方法,检查实际收集到的DUT输出端口数据是否同reference model产生的期望数据一致
-
对于设计内部的关键功能模块,也有相对应的线程进行独立的检查
-
在检查过程中,可以将检查成功的信息统一纳入到检查报告中,便于仿真后的追溯。如果检查失败,也可以采取暂停仿真同时报告错误信息的方式,进行在线调试
实现方式
-
线上比较(online check):在仿真时收集数据和在线比较,并且实时报告
-
线下比较(offline check):将仿真时收集到的数据记录在文件中,在仿真结束后,通过脚本或者其他手段,进行数据比较。
-
在硬件设计发展初期,由于DUT的功能较为简单,采取定向测试(direct test)和线下比较的方式就不足为奇,甚至验证者没有数据处理脚本或者参考模型,进行人为比较(manual check )的古老方式也是存在的
-
而伴随着设计的功能愈加复杂,靠验证者每次进行繁琐检查的方式也缺少可靠性。于是我们将checker添加到验证环境中,需要它分析DUT的边界激励,理解数据的输入,并且按照硬件功能来预测输出的数据内容
-
这种预测(prediction)的过程,发生在reference model中,有时我们也将其称为predictor
-
reference model也内置一些缓存,分别存放从DUT输入端观察到的数据,以及经过功能转换的数据,同时checker也有其他缓存在存放从输入端采集到的数据
比较器组件结构
分散搁置
-
各自检查对应模块的功能
-
checker之间通信需要特殊连接
-
报告信息较难统一
-
对于各个checker的使能控制因其分散变得复杂
集群搁置
-
各自检查对应模块功能
-
checker各自相邻,可以共享monitor的输入,减少复杂的连接关系 集群搁置更简单
-
可以按照统一的报告形式,写入到记录文件
-
集中处理各个checker,例如在前期使能各个模块的checker,在后期可以将其作为黑盒验证,只使能data checker
比较器结构实现建议
-
对于复杂的系统验证,倾向于集中处理管理stimulator和checker,因为它们两者都需要主动给出激励或者判断结果,也需要较多的协调处理
-
而monitor则相对更独立,因为它只是作为监测方,将兢兢业业观察到的数据一字不落地交给checker即可,至少checker怎么使用,monitor并不需要关心
-
因此,monitor和stimulator是一一对应,我们通常将它们进一步封装在agent单元组件中,而checker则最终集群搁置在中心化的位置
顶层验证考虑时序、寄存器配置,模块之间的互动