文章目录
1. 寄存器模型常规方法
1.0 期望值、镜像值、实际值区别
- 寄存器模型中每一个寄存器都有两个值:镜像值、期望值。
- 首先RAL、DUT中的寄存器都会复位,此时值相同。
- mirror value是monitor捕捉到总线上面的行为(对DUT寄存器进行读写)然后做预测(predict)后更新的(也只能这样才能修改),但是对于RAL中的寄存器,在RAL没有去读DUT中的对应的状态REG时候是不会自动更新的(后门读也可以用来更新),但不论前后门,我们必须走出这一步才会更新。
- 随机化针对的是期望值,因为是想让DUT中REG都处于一个不定态,看能不能有什么边界情况,紧接着才会更新mirror value;随机化对mirror value不起作用。
- 若访问寄存器有多重总线访问方式,我们的monitor可能没有都检测到,那就没法即使更新。
1.1 预测
- 前门访问通过显示预测,通过例化predictor并借助monitor检测总线获取DUT寄存器值。
- 显示预测符合硬件行为。
- adapter是object,而predictor是component!
- predictor是一个参数化类,需要指定参数类型为monitor过来的类型
- 将map、adapter句柄赋予predictor,predictor需要用到adapter中的bus2reg的方法,并且还需要借助map将对应的寄存器更新。
- 最后的connect_phase中还需要将monitor的ap和predictor中的bus_in接口相连,二者通过fifo相连。
- predictor只需要指定其参数类型就行,不需要实现什么方法;adapter需要实现两个虚方法bus2reg/reg2bus
1.2 uvm_reg访问方法
- block包含reg包含field,block也可以包block
- block相当于是对其中包含的寄存器做一个批量操作,省的写多行代码对各个寄存器进行操作。
- mirror一般用法:读回来DUT中REG值,更新寄存器的mirror值;还可以在更新的同时检查,对于配置寄存器,我们对其进行了写操作,写操作时候已经借助predictor更新了mirror值,那么可用mirror()对其进行检测,通过总线读回来实际值看是否真的写入了。
- update一般用法:先修改软件期望值(set),之后看期望值和镜像值是否相同,不同则更新DUT中reg值后mirror值再同步actual value。
- get、set都是操作RAL期望值
1.3 mem与reg的联系与差别
1.4 利用内建sequences实现对寄存器的测试
2 寄存器模型的应用场景
寄存器模型作用:
- 优化sequence,提高复用性、可读性
- 方便检查DUT中寄存器
- 新增了寄存器覆盖率
2.1 概述
- 对硬件的配置,同时也写入本地的影子寄存器,那么再次读取配置寄存器时不用通过总线了,直接读取本地的影子寄存器就行,大大节约时间。
- RM模仿DUT的行为,有时候也需要知道DUT中寄存器的值,一般是通过寄存器模型来获取的(拿镜像值即可)。
2.2 寄存器检测
2.3 覆盖率收集
2.3.1 自动收集模式
- has_coerage()表示一个covergroup有条件的例化,在上面set_coverage就是构造这个条件。
- uvm_reg中预定义了一个虚函数 sample(),实现时候形式必须和预定义的一致
2.3.2 手动收集
- subscriber也是参数类,接收monitor的trans。
- 这里覆盖点覆盖的bins是mirror value
- avail中定义了7个bin,0,1,62,63是必须覆盖的边界值,而[2:7],[8:55],[56:61]是定义了3个中间的bin。
- 一旦monitor在总线捕捉到了一个trans,由于fifo存在?,那么就会调用write函数中的reg_value_cg.sample()去采样收集覆盖,捕捉到每一个寄存器。