实验3 的部分我们主要就随机约束和环境结构做实践。在这一个试验中,大家将升级实验2 部分中对generator 和initiator 之间的数据生成和数据传输的处理,同时我们也将完善何时结束测试,将其主动权交于generator 而不再是test 组件。在组件结构实践部分中,大家将在原有的initiator、generator、agent 和test 组件的基础上再认识monitor 和checker,并且使其构成一个有机的整体,最终可以通过在线比较数据的方式完成对MCDT 的测试。
马上开启我们的lab03之旅吧!
代码链接:https://pan.baidu.com/s/1eVeWM82Hyd9vteeggyzqqw?pwd=9a0b
提取码:9a0b
为了更早习惯各个验证文件独立放置的原则,我们已经先将chnl_pkg1.sv文件和tb1.sv 文件独立开来,所以tb1 需要编译两个文件即chnl_ pkg1.sv 和tb1.sv。在这个试验中我们会进一步了解随机约束在类中定义方式、如何随机化对象、随机种子的使用方法、对象的产生等等。接下来,按照实验要求开始练习吧。
要求1.1.
我们继承了大部分实验2 的代码,包括chnl_basic_test 类,而对于这个类所需要生成的数据包我们提出了新的约束要求。需要注意的是,与实验2不同的是,这次数据类chnl_trans 的定义发生了很大的变化,它不再只局限于包含一个数据,而是多个数据,同时跟数据之间时间间隔的控制变量也在该类中声明为随机成员变量,那么请按照代码中具体的约束来定义chnl_basic_test 类,注意该代码的修改需要在chnl_trans 类中实现,因为目前的代码结构只有chnl_trans 类的更新是较为合适的办法。
lab2关于chnl_trans的声明:
lab03关于chnl_trans的声明:
要求1.2.
我们需要将原本在chnl_root_test 类中用来结束仿真的$finish()变迁到generator 中,那么请将它放置到合适的地方,然后由generator 来结束仿真吧。
将$finish放到generator里边,实际上还是受顶层test模块的控制。
要求1.3.
大家尝试着多次重新启动仿真,可以使用"restart" 命令来重启,再对比连续两次生成的随机数据,看看它们之间是否相同呢?然后再在仿真器命令行处使用命令"vsim -novopt -solvefaildebug -sv_seed 0 work.tb1"来加载仿真。这里我们多传递了两个必须的仿真参数,-solvefaildebug.是为了调试随机变量的,而-SV seed NUM 则是为了传递随机的种子。那么使用这个命令再看,是否与之前没有使用-sv_ seed 0 的命令产生了相同的数据呢?最后,请改为使用"vsim -novopt -solvefaildebug -sv seed random work.tb1"命令再来比较前后两次的数据,是否相同呢?那么,你对-sv seed random 的仿真选项的认识是什么?
以上为两次仿真结果对比,可以发现:两次仿真结果完全相同,说好的随机为什么会出现连词完全相同的随机结果呢?这主要是随机种子固定造成的,接下来我们更换随机种子,是否会有不同的结果呢?
上边两次仿真是更改随机种子后的结果,可以看到nidles和pkt_nidle的结果是不一样的。
要求1.4.
在仿真的最后,大家可以发现最后一个打印出来的chnl_trans 对象的obj. id 值是1200,那么这代表什么含义?为什么会有1200 个chnl_obj 对象产生呢?整个仿真过程中,在同一时刻,最多的时候一同有几个chnl _trans 对象在仿真器内存中存在呢?这么做对内存的利用是否合理?你是否还有更好的办法使得在同一时间chnl _trans 对象的数量比代码中用到的更少呢?
实验代码中三个test给定的ntrans都是200,理应为600,现在打印出来的结果显示obj_id为1200,主要是因为mailbox数据传递过程中的双向握手造成的。
如果要实现不同的test 类,例如chnl_basic_test、chnl_burst_test 和chnl_fifo_full_test,那么我们对于不同的test 需要对chnl_generator 的随机变量做出不同的控制,继而进一步控制其内部随机的chnl_trans 对象。也就是说,随机化也是可以分层次的,例如在test 层可以随机化generator 层,而依靠generator 被随机化的成员变量,再来利用它们进一步随机化generator 中的chnl_trans 对象,由此来达到顶层到底层的随机化灵活控制。那么从这个角度出发,我们就需要将generator 从agent 单元中搬迁出来,并且搁置在test 层中来方便test 层的随机控制,因此我们在chnl_pkg2.sv 和tb2.sv 中主要带领大家认识如何更好的组织验证结构,从而实现更加方便的测试控制。
要求2.1.
由于我们将generator 搬迁到test 层次中,所以在要求2.1 中需要将gen 和agent中组件的mailbox 连接起来,方便gen 与agent 中init 的数据通信。
要求2.2.
在领略了如何在test 中的do_ config 对gen[0]进行随机化控制后,你需要对gen[1]也按照代码中的具体要求进行随机控制。要求2.3.
请按照代码中的具体要求对gen[2]进行随机控制。
要求2.4.
请按照代码中的具体要求,在chnl burst test::do_ config()任务中对三个generator进行随机控制。
要求2.5
请按照代码中的具体要求,在chnl fifo_ full test:do_ config()任务中对三个generator 进行随机控制。
要求2.6.
在tb2.sv 中,我们对于测试的选择将由仿真时的参数传递来完成。这意味着,以后的递归测试,即创建脚本命令,由仿真器读入,分别传递不同的随机种子和测试名称即可完成对应的随机测试,而这种方式即是回归测试的雏形。按照之前的仿真命令,在命令窗口中添加额外的命令"+TESTNAME=testname" ,这里的+ TESTNAME=表示的仿真命令项,在由内部解析之后,testname 会被捕捉并且识别,例如你可以传递命令 "+TESTNAME= chnl_burst_test" 来在仿真时运行测试chnl_burst_test。
最后一个实验部分即指导大家认识验证环境的其它组件,monitor 和checker。并且通过合理的方式来构成最终用来测试MCDT 的验证环境,在这个环境中大家需要再回顾generator、initiator、monitor 和checker 各自的作用。在顶层环境中,我们将checker 置于test 层中,而不是agent 中,思考这么做的好处在什么地方。同时需要在认识generator 和Initiator 有数据通信的同时,可以掌握monitor 与checker之间的数据通信,还有checker 如何针对MCDT 利用内部的数据缓存进行数据比较。
要求3.1.
在chnl_monitor 类和mcdt_monitor 类各自的mon_trans()方法中需要采集正确的数据,将它们写入mailbox 缓存,同时将捕捉的数据也打印出来,便于我们的调试。
要求3.2.
在chnl_agent 中,参考如何例化的initiator 对象,也对chnl_monitor 对象开始例化、传递虚接口和使其运行。
要求3.3.
在chnl_checker 的任务do_compare()中, 大家需要从checker 自己的数据缓存mailbox 中分别取得一个输出端的采集数据和一个输入端的采集数据,继而将它们的内容进行比较,需要注意的是,输出端的缓存只有一个,而输入端的缓存有三个,大家需要考虑好从哪个输入端获取数据与输出端缓存的数据进行比对。
要求3.4.
在顶层环境chnl_root_test 中。大家先要对mcdt_monitor 和chnl_checker 进行例化。传递虚接口,并且将chnl_monitor. mcdt_monitor 的邮箱句柄分别指向chnl_checker 中的邮箱实例。
环境结构图(待补充):