文章目录
主要内容
验证需要包含寄存器与存储器
- 如何在某一情况下,scoreboard查看DUT中某些寄存器的状态或者存储器的值?
在scoreboard和virtual sequence中插入触发事件,在某种情况下启动virtual sequence中的寄存器读写sequence,将结果发送给scoreboard。
寄存器抽象层
- 是一套数据结构
- 实例化在env,作为平台组件的一部分
-== scoreboard使用寄存器模型提供的API对寄存器和存储器访问;== - 寄存器模型自动对DUT进行读写
- 寄存器模型和sequencer是通过adapter进行连接的
frontdoor:寄存器模型通过产生事务并借助于agent来访问DUT当中的存储器,消耗仿真时间
backdoor:通过DUT的设计层次路径来直接进行访问
寄存器抽象层的工作原理
- 前门实际过程复杂,使用时只需要一条语句就可实现。
- 后门比较简单
寄存器模型的构成
- 寄存器
一位或者多位具有相同功能的bit称之为field
- 转换器
第一个方法:由寄存器模型产生的uvm_reg_bus_op类型的对象转换为自定义类型的事务对象;然后自动发往sequencer
第二个方法:与第一个作用相反,
通过map实现寄存器模型、转换器、sequencer模型连接起来。
如何将寄存器模型嵌入测试平台
- 为DUT创建寄存器模型;
- 分别建立三个寄存器模型
- 封装三个寄存器模型
configure函数(所在的寄存器块,所在的寄存器页,指定寄存器的HDL路径)
create_map(map名字,寄存器块基地址,系统总线位宽单位字节,存储的大小端模式)
add_reg(要添加的reg名字,reg偏移地址,读写属性)
地址映射为以后的后门操作提供了信息
-
为创建实现前门操作的转换器;
两个函数 reg2bus和bus2reg
-
在测试平台实例化寄存器模型和转换器;
-
将转换器、sequencer与寄存器模型的map建立关联;
connect phase 中
-
在需要进行寄存器读写的地方使用API访问寄存器。
-
运行测试。
寄存器模型的基本数据结构
uvm_reg_field
- value
具有rand属性的变量,用户可以直接进行访问,目的是用于随机。在存储器模型随机化之后,将该值赋给期望值; - m_mirrored
镜像值:专门用于最大可能的与DUT寄存器当前值保持相同的变量;
这个变量为本地变量,用户无法直接访问,但可以通过UVM RAL提供的API进行访问;
== 镜像值不一定与DUT相应的寄存器值相同==
如果DUT通过正常的方式内部修改了寄存器或寄存器中的某个域,那么镜像值就会过时。
存储器没有域也没有镜像值 - m_desired
期望值:存储着用户期望该寄存器的值的变量;
这个变量是本地变量,用户无法直接访问,但可以通过UVM RAL提供的API进行访问。
期望值需要用户指定:在仿真的某一时刻,用户期望DUT中某个寄存器为某一值时,可以通过调用该寄存器的set方法设置期望值,在调用update方法,该方法会检测期望值与镜像值是否一致,如果不一致,那么会把期望值写入DUT中,并且更新镜像值为期望值。
寄存器的访问模式
寄存器模型API
- read&write
均支持前门后门方法
- status:成功返回ok
- value:操作值
- path:指定操作模式是前门还是后门
- map:寄存器所在map的指针,一般不进行指定,为null
- parent:指定item所在sequence的句柄,一般情况下如果在某一sequence中调用该函数,指定该参数为this
- prior:操作的优先级
- 其他三个参数极少使用,默认即可
-
peek&poke
peek几乎相当于read的后门操作,poke几乎相当于write的后门模式
区别:peek/poke不会模拟寄存器的行为,而write/read则会。
表现在wc/wo等读写属性上
-
randomize & updata & mirror
RAL的另一种结构
predictor自动捕获monitor中与寄存器相关的事务
代码实现
reg_adapter_m与reg_predictor相关
内建的寄存器测试sequences
- 基于寄存器模型的自动测试的sequences库;
- 这些sequences可以对DUT中的寄存器和存储器进行基本的测试
- 自动测试主要是针对基本功能的测试,包括检查寄存器的复位值是否成功、读写数据路径是否正常工作(转换/检查每一位/前门和后门访问模式/存储器活动)
内建了coverage
三种方法为RAL添加coverage属性