寄存器模型2


6.MCDF寄存器设计代码

(1)示意图

(2)代码

  • verilog中数组操作:regs[`SLV0_RW_REG][0:5]指的是32bit数据下的0:5位。


7.adapter

(1)adapter的位置

(2)adapter实现

(3)示例代码

[1]继承与uvm_reg_adapter;

[2]在new()中将provides_responses置1;

[3]将uvm_reg_bus_op类型转换成mcdf_bus_trans类型,但是函数返回的是uvm_sequence_item类型。return t;是隐式的转换。

[4]从函数的参数中看出将uvm_sequence_item类型的bus_item转化为uvm_reg_bus_op类型;但父类句柄但指向的是子类对象;定义了子类型mcdf_bus_trans t,需要将父类转换为子类,毕竟指向的是子类对象。

[5]

(4)示例分析

(5)adapter的集成

[1]一般rgm(reg model)在test层,env通过rgm句柄引用,所以先看顶层有没通过config_db配置,没有的话则在env中创建。

[2]rgm.build():可参考9-1-3(2)。

[3]

rgm.map.set_sequencer(agent.sequencer,reg2mcdf);

句柄关联:rgm_map先与adapter关联,adapter又与agent.sequencer关联。

[4]

rgm.map.set_auto_predict();

auto_predictor不依赖于predictor和monitor。

(6)示例分析



8.寄存器的访问方式

(1)概述

  • DPI访问很快,0时刻就可以访问到。

(2)前门访问简介

  • read()、write()是reg的方法;read_reg()、write_reg()是uvm_reg_sequence的方法。

extern virtual task read(output uvm_status_e      status,

                            output uvm_reg_data_t    value,

                            input  uvm_door_e        path = UVM_DEFAULT_DOOR,

                            input  uvm_reg_map       map = null,

                            input  uvm_sequence_base parent = null,

                            input  int               prior = -1,

                            input  uvm_object        extension = null,

                            input  string            fname = "",

                            input  int               lineno = 0);

status: 表示操作状态,OK or NOT OK

value: 表示读出的值

path: 表示是前门访问还是后门访问

map: 表示 如果是前门访问时用哪个map。

parent:表示哪个sequence来发送RAL item读操作请求

prior:表示item的优先级

extension:表示一些扩展信息

fname和lineno没有什么用,暂时不用去care

(3)前门访问示例

(4)后门访问:HDL路径映射

  • reg_backdoor_access是db.config的名字;路径映射后:reg_backdoor_access.dut.regs[]。

(5)后门访问:add_hdl_path()、add_hdl_path_slice()、peek、poke

(6)后门访问示例

(7)前门和后门比较

  • 因为有些寄存器配置有先后关系,不受时序的话,会出问题。

(8)混合应用

  • 通过随机化寄存器使得各个域处于随机值,再通过前门访问配置我们关注的域的值,这样的好处是不再通过设置复位之后的寄存器,这种更具有确定性的场景,而是一开始就随机化模拟无法预期的硬件配置,在设置了必要的寄存器之后,再看看有没有意想不到的边界情况。

rgm.reg.randomize();

rgm.reg.reg_field.set(值);//设置某个域

rgm.reg.update(status,UVM_FRONTDOOR,.parent(this));

  • 通过前门写后门读/后门写前门读,来检查地址映射到错误寄存器的问题。

rgm.reg.write(status,data,UVM_FRONTDOOR);

rgm.reg.mirror(status,UVM_CHECK,UVM_BACKDOOR,.parent(this));

  • 对于状态寄存器,这种不方便随机以及不方便和硬件值做比较的,往往先使用peek获取(后门访问会用自动预测更新mirror value),然后再调用mirror的方法从前门访问,和更新的镜像值作比较。

rgm.reg.peek(status,data);

rgm.reg.mirror(status,UVM_CHECK,UVM_FRONTDOOR,.parent(this));//要选择UVM_CHECK

  • 比较复位值是不是与硬件一侧的寄存器描述一致,先用get_rest得到软件一侧的复位值,再用后门从硬件里读回硬件复位值(硬件在外部先复位),再比较

@(negedge p_sequencer.vif.rstn);

@(posedge p_sequencer.vif.rstn);

rgm.reg.reset();

value=rgm.reg.get_reset();

value2=rgm.reg.read(status,data,UVM_BACKDOOR);

if(value!=value2) `uvm_error



1.mirror、desired和actual value

(1)

  • 每个filed都有两个值。

(2)


2.prediction分类

(1)跟踪寄存器值的两种方式

(2)自动预测

(3)显式预测:explicit

(4)显式预测示例 

  • uvm_reg_predictor是参数类,并是component,为了保证monitor的ap口和predictor的imp口类型一致,所以参数是必须的。

  • mcdf2reg_predictor.map = rgm.map; mcdf2reg_predictor.adapter = reg2macdf;  是将map和adapter的句柄接到predictor里面,之所以要传递他们的句柄,是将利用两个函数将预测值返给到reg里。


3.uvm_reg的访问方法

(1)uvm_reg_block、uvm_reg、uvm_reg_field三个类提供访问寄存器的方法表格

[1]read/write/peek/poke

uvm_reg而言,四者都是针对硬件的真实值,后门访问都有这四种方法,而对于前门访问没有peek、poke。

[2]由于前门访问时bytes操作的,所以不能按位修改,所以前门访问中field是“否”。

[3]get与set都是软件值。

(2)再将uvm_reg_sequence提供的方法(均是针对寄存器对象的,而不是寄存器块或者寄存器域)整理如下:

(3)reset() 、get_reset()

(4)mirror()

(5)set()、updata()


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值