白皮书---uvm实战笔记(二)

                                                        第七章 寄存器模型        

1.读取寄存器模型的方法

有了寄存器之后,可以在任何耗时的phase中使用寄存器模型以前门访问或后门访问的方式来读取寄存器的值;可以在不耗时的phase中使用后门访问的方式来读取寄存器的值;

前门访问:通常模拟在总线上发出指令,进行读写操作,这个过程中,仿真时间是一直往前走的

后门访问:直接通过层次化的引用来改变寄存器的值;

简而言之,前门访问耗时,后门访问不耗时

2.寄存器的模型的单位

Uvm_reg_field

Uvm_reg

Uvm_reg_block

Uvm_reg_map:每一个reg_block中至少有一个,也通常只有一个ucm_reg_map

Map用以储存每个寄存器的偏移地址;当寄存器模型使用前门访问方式来实现读或写操作时,map就会将地址转换成绝对地址,启动一个读或写的seq,并将结果返回;

3.建造一个寄存器

在new()函数中,要将寄存器的宽度作为参数传递给super.new函数;super.new函数的另一个参数是是否要加入覆盖率的支持;

每一个派生自uvm_reg的类都有一个build函数,他与component的build_phase并不一样,它不会自动执行,需要手工调用;

Configure的参数

第一个参数:此域的父辈,即此域位于哪一个寄存器中,一般填this;

第二个参数:此域的宽度

第三个参数:此域最低位在整个寄存器的位置

第四个参数:字段的存取方式

第五个参数:是否是易失的

第六个参数:此域上电复位后的默认值

第七个参数:此域是否有复位,一般都填1

第八个参数:此域是否可以随机化

第九个参数:这个域是否可以单独存放

4.在reg_block派生的类中将reg例化

5.reg_adapter是服务于前门访问的

寄存器模式的前门访问,寄存器模型会通过seq产生一个uvm_reg_bus_op的变量

转换器要定义好两个函数,第一个是reg2bus,其作用是将寄存器模型通过sequence发出的uvm_reg_bus_op型的变量转化成bus_sequencer能够接受的形式;第二个是bus2reg,其作用是当监测到总线上有操作时,它将收集来的tr转化成寄存器模型能够接受的形式,以便寄存器模型能够更新相应的寄存器的值。

通过前门访问进行读操作:

  1. 参考模型调用寄存器模型的读任务
  2. 寄存器模型产生seq,并产生uvm_reg_item :rw(应该就是产生一个uvm_reg_bus_op的变量)
  3. 产生driver能够接受的tr:bus_req=adapter.reg2bus(rw)
  4. 把bus_req交给bus_sequencer
  5. Driver得到bus_req后驱动它,得到读取的值,并将读取值放入bus_req中,调用item_done
  6. 寄存器模型调用adapter.bus2reg(bus_req,rw)将bus_rq的读取值传递给rw
  7. 将rw中的读数据返回参考模型

6.将寄存器模型集成到base_test中

至少需要在base_test中定义两个成员变量,一是reg_model,另一个是reg_sqr_adapter;

例化reg_model后,第一步要调用configure函数,其中第一个参数是parent block,由于是最顶层的reg_block,因此填写null,第二个参数是后门访问路径;第二步是调用build函数,将所有的寄存器实例化;第三步是调用lock_model函数,调用此函数后,reg_model中就不能在加入新的寄存器;第四个是调用reset函数,如果不调用此函数,那么reg_model中所有寄存器的值都是0,调用此函数后,所有寄存器额值都将变为设置的复位值;第四步需要设置好根路径hdl_root;

寄存器模型的前门访问操作最终都将有uvm_reg_map完成,因此在connect_phase中,需要将转换器和bus_sequencer通过set_sequencer函数告知reg_model的default_map,并将default_map设置为自动预测状态;

7.寄存器模型的读写

通常在refersmodel对寄存器模型进行读操作

首先参考模型中要申明寄存器模型

P_rm.s_reg.read(status,value,UVM_FRONTDOOR);

第一个参数是uvm_status_e型变量,这是一个输出用以表明读操作是否成功;第二个是读取的数值,也是一个输出;第三个是读取的方式,可以选择前门或者后门

在v_seq中对寄存器模型进行写操作

P_sequencer.p_rm.s_reg.write(status,1,UVM_FRONTDOOR);

8.后门访问的操作接口

第一类:UVM_BACKDOOR形式的read和write

第二类:peek读和poke写

二者的区别:1.使用第一类的时候要在参数中写明是前门还是后门访问,第二类是专门提供给后门访问使用的2.第一类会在进行操作时模仿DUT的行为,第二类不会理会DUT的行为;比如,对一个只读的寄存器,第一类是写不进去的,第二类可以写进去;

9.uvm_reg_file的引入主要是区分不同的hdl路径

10.create_map的参数

第一个参数是名字;第二个参数是基地址;第三个参数是系统总线的宽度,这里的单位是byte,第四个参数是大小端,最后一个参数表示是否能够按照byte寻址

11.在寄存器模型中加入一个人1024*16的存储器

12.存储器的读写操作

可以通过调用read,write,peek,poke实现;这四个任务在调用的时候需要额外加入一个offset参数,说明读取此存储器的哪个地址;

13.寄存器模型中的期望值与镜像值

镜像值用以最大可能的与DUT保持同步;

期望值可以用以更改dut中寄存器的值;

如果希望向寄存器中写入一个‘h1,方法一是直接调用write任务,将‘h1写入,这时期望值与镜像值都更新为‘h1;

另一种方法是通过set函数将期望值设置为‘h1,之后调用update任务,该任务会检查期望值和镜像值是否一致,若不一致,那么将会把期望值写入dut中,并且更新镜像值;

Get函数可以得到寄存器的期望值;

Get_mirrored_value可以得到镜像值;

14.常用操作对期望值和镜像值的影响

Read&write操作:无论通过前门还是后门访问对dut进行读写,在操作完成后,寄存器模型会根据读写的结果更新期望值和镜像值;

Peek&poke操作:在操作完成后,寄存器模型会根据读写的结果更新期望值和镜像值;

Get&set操作:set操作会更新期望值,但是镜像值不会改变;get操作会返回寄存器模型中前寄存器的期望值;

Update操作:该任务会检查期望值和镜像值是否一致,若不一致,那么将会把期望值写入dut中,并且更新镜像值;

Randomize操作:一般randomize和update一起使用;如dut上电复位后,需要配置一些寄存器的值。这些寄存器的值通过randomize获得,并使用updata任务配置到dut中

15.寄存器模型中一些内建的sequence

(1)Uvm_reg_mem_hdl_paths_seq 用以检查hdl路径的正确性

这个seq会试图读取hdl所指向的寄存器,如果无法读取,则给出错误提示;

(2)uvm_reg_hw_reset_seq用以检查上电复位后寄存器模型与dut中寄存器的默认值是否相同

(3)uvm_reg_access_seq用于检查寄存器的读写功能;

(4)uvm_mem_access_seq用于检查寄存器的读写功能;

16.predictor的使用

自动预测:依赖于driver,当driver将读取值返回后,寄存器模型会更新寄存器的镜像值和期望值;

主动预测:由monitor将从总线上收集到的transaction交给寄存器模型,后者更新相应寄存器的值

17.寄存器模型的随机化与update

对于rm来说,在uvm_reg_block,uvm_reg,uvm_reg_field级别都可以进行随机化;

但是对于某个field而言,想要随机化需要完成三个步骤;

  1. 在uvm_reg中定义field时,要设置为rand类型
  2. 在调用此field的configure函数时,第八个参数设置为0;
  3. 此field要支持写操作

Randomize会更新寄存器模型中的预期值,randomize完成之后调用updata任务,将随机化后的参数更新到dut中,这特别适用于在仿真开始时随机化配置参数;

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值