UVM register model 寄存器模型中:peek()与reg_model.reg_name.value获取的值不同的原因

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/evolone/article/details/80701041

最近因为项目需要,负责给基于UVM验证平台添加寄存器模型。
参考了张强的《UVM实战:卷1》中第七章的内容,并借鉴了其他项目的code。
总算实现了寄存器模型,利用predictor和adapter,实现了寄存器模型的前门访问。
然后进而实现后门访问。代码实现比较简单。但是之后验证功能时,发现与自己的预估有出入。
发现,对UVM寄存器模型的认识,更深入了。
特此将碰到情况及理解记录下来。

首先说明遇到的问题。
在实现寄存器模型的后门访问后,采用了几种读取值的办法去验证代码功能,但是竟然发现有些方法读取的值并不是我期望的。
首先用寄存器模型的前门访问方式,给模型的某个寄存器写值,然后分别用
(1)get_reg_by_offset() 获取寄存器模型中的寄存器指针,由 get_mirrored_value() 从该指针获取值
(2)reg_model.reg_name.value 通过层次结构直接获取寄存器模型中寄存器的值
(3)reg_model.reg_name.peek() 利用peek()函数直接后门读取dut的reg(或者poke(),功能是写dut的reg)

在代码中的形式如下:

xx.get_reg_by_offset()                                     //  获取寄存器模型中的寄存器指针
value1 = xx.get_mirrored_value()                           //  从该指针获取值
value2 = reg_model.reg_name.value                          //  通过层次结构直接获取寄存器模型中寄存器的值
value3 = reg_model.reg_name.peek(status, reg_value)        //  利用peek()函数直接后门读取dut的reg(或者poke(),功能是写dut的reg)

发现value1和value2的值保持一致,value3有时与value1/value2不同。

纠结了一番后,总算明白了其中缘由。

首先明白一个概念,这里涉及到了两个地方的值,一个是寄存器模型中的寄存器的值,一个是dut内部真正的寄存器的值,要搞清楚上面提到的现象,就得时刻区分读取的值,到底是dut内部的寄存器的值,还是寄存器模型中的寄存器的值。

value1和value2,都是读取的寄存器模型中的寄存器的值。
value3读取的dut中寄存器的值。

先说说,实际仿真看到的波形。
最起初,三者的值相同。
然后利用predictor更新寄存器模型中寄存器的值,注意,这个操作只更新寄存器模型中的值,并不更新dut中寄存器的值。
于是乎,此时,value1和value2的值相同是更新后的值,value3的值依旧是刚开始的值。
然后用poke()功能,给dut的该寄存器写一个值。
此时,value1,value2和value3的值都是新写的值。

那么问题就来了,为什么中间会出现value1和value2的值相同,和value3的值不同?

其实并没有真正发生value1和value2的值相同,和value3的值不同的情况。
由于测试激励写的不够充分,在测试激励文件的initial模块中,每次查看值的时候,都会按顺序调用上面的代码片段。在systemverilog的initial块中,代码是顺序执行的。
因为value1和value2都是读取的寄存器模型的值,所以二者是一样的。
value3读取的是dut的值,因为predictor只更新寄存器模型的值,并不修改dut的值,所以,value3自然还是保持之前的值。
另外,调用peek()函数读取dut中的值,会顺带更新寄存器模型中的值,如果写激励时在获取value3后,再次获取value1和value2的值,就会发现value1与value2的值也变得和value3相同。

说到底,还是一开始不知道peek()函数执行后,会更新寄存器模型的值。

猜你喜欢

转载自blog.csdn.net/evolone/article/details/80701041