Ral model常用API介绍

1.概述

dut值:寄存器的硬件真实值

镜像值&期望值:存在于寄存器模型中,是软件设置的值。镜像值(m_mirrored)会尽可能保证与DUT值一致(也有不一致的情况),期望值(m_desired)是我们希望设置修改的值。寄存器模型会为每一个寄存器创建并保存这两个值。

不同的API函数对DUT值、镜像值和期望值的影响不同。同时,不同API函数可操作的范围不同:

2. 原理介绍

2.1 read&write

read()和write()分别是对DUT寄存器进行读操作和写操作。

read()和write()完成操作后,会将DUT值更新到寄存器模型的镜像值和期望值中去。

2.1.1 read

(1)格式

前门

***.reg_block.register.read(参数列表);

后门

***.reg_block.register.read(参数列表);

***.reg_block.register.field.read(参数列表);

(2)举例

(3)参数分析

status:表示操作的状态,包含三种状态:

value:表示从DUT读取到的值,是一个64bit的无符号数据

path:通常表示通过前门访问还是后门访问

(4)read工作流程(前门)

read(frontdoor)工作流程可大致分为10个步骤:

1.在程序的某处调用该方法时首先进入uvm_reg的read(frontdoor)任务,该任务的核心方法是XreadX()

2.进入到uvm_reg::XreadX()任务,核心方法是do_read()。进入到do_read()任务,首先会生成一个uvm_reg_item类型的transaction:rw,这个transaction是ral model内建的一种transaction,存储着很多寄存器相关的信息,包含地址、数值等,接着会调用map的do_read()方法,传入uvm_reg_item类型的transaction:rw

3.进入到uvm_reg_map::do_read()任务,在map里会获取到配对的adapter和sequencer,这是由用户自己设置,如:

这样,就将map、sequencer和apapter进行了绑定。接着会调用的核心方法是do_bus_read()。

4.进入到uvm_reg_map::do_bus_read()任务,这个任务首先会将传进来的uvm_reg_item类型的rw对象里的value按照bus_width切分成很多个bytes,每一byte的value存入uvm_reg_bus_op 类型的rw_access对象的data里,并组成一个队列。如下:

bus_width也是由用户自己设置,如:

ceate_map的第三个参数8就是bus_width。所以,传输给adapter的transaction并不是原始的uvm_reg_item类型的rw对象,而是切片后的uvm_reg_bus_op 类型的rw_access对象。

该对象产生之后,调用reg2bus()利用adapter传输信息。

5.adapter里的reg2bus会将uvm_reg_bus_op 类型的rw_access对象转换成uvm_sequence_item类型的tr。

6.uvm_sequence_item类型的tr通过sequencer发送给driver,driver通过get_next_item()从sequencer获取transaction并将其驱动到DUT

7.driver从DUT拿到读取的数据经过sequencer传回,apapter的bus2reg()将其转化为uvm_reg_bus_op 类型的transaction,返回到uvm_reg_map::do_bus_read()后多个以bus_width为单位的transaction里的data会合并成uvm_reg_item类型的rw对象里的value,组成从DUT寄存器读取到的值。

8.value值拿到后标志着总线操作的完成,接着会进入到更新寄存器模型的镜像值和期望值过程中。该更新过程被称为预测机制,预测机制一般分为自动预测和显示预测两种。当设置了:

采用的便是自动预测方式。自动预测方式会调用do_predict()

9.进入到uvm_reg::do_predict(),会针对寄存器的不同field遍历,每一个field都会do_predict()

10.进入到uvm_reg_field::do_predict(),会将读取的value值对应的filed_val更新给m_mirrored和m_desired

2.1.2 write

(1)格式

前门

***.reg_block.register.write(参数列表);

后门

***.reg_block.register.write(参数列表);

***.reg_block.register.field.write(参数列表);

(2)举例

(3)参数分析

常用前三个参数。第二个参数是需要向DUT寄存器写入的值,其他参数见read参数分析。

2.2 set&get&update

set()和get()操作的对象只是寄存器模型中的期望值。并不会更新其他值。要想将期望值更新到DUT中,需要借助update()。

update()的作用是先比较寄存器模型中期望值和镜像值是否一致,如若不一致,则将期望值写入DUT中,并同步更新寄存器模型的镜像值。

2.2.1 set

(1)格式

***.reg_block.register.set(参数列表);

***.reg_block.register.field.set(参数列表);

(2)举例

2.2.2 get

调用get()的对象可以是uvm_reg,也可以是uvm_reg_field,不能是uvm_reg_block。

(1)格式

***.reg_block.register.get();

***.reg_block.register.field.get();

注:无论是register还是field调用get,返回的均是64bit的无符号数据。

(2)举例

2.2.3 update

(1)格式

前门

***.reg_block.register. update(参数列表);

***.reg_block. update(参数列表);

后门

***.reg_block.register. update(参数列表);

***.reg_block. update(参数列表);

(2)举例

(3)update()工作流程

1.update()首先会判断是否needs_update,比较的是期望值和镜像值,不相等时才会执行后续动作。

2.调用write()方法(见write()工作流程),写入的是期望值,即将期望值写入DUT,并同步更新镜像值。

2.3 mirror&predict

mirror()和read()操作十分相似,也会从DUT中读取值,读取后也会将读取到的DUT值更新到寄存器模型的期望值和镜像值中。不同的是,mirror()不会将读取到的DUT值输出,同时,mirror还有check功能,当check打开时,比较DUT值和镜像值,若不同,会给出error信息。需要注意的是,无论是否check,无论check的结果是一致还是不一致,mirror()都会更新镜像值和期望值。

在一些具有计数功能的寄存器中,DUT计数器会不断累加,但是配对的寄存器模型中的寄存器是静止的,为了保证DUT寄存器和寄存器模型的寄存器计数保持一致,需要另一种专门的方法只对寄存器模型的镜像值和期望值更新,而不会对DUT值更新,这就是predict。

2.3.1 mirror

(1)格式

前门

***.reg_block.register. mirror(参数列表);

***.reg_block. mirror(参数列表);

后门

***.reg_block.register. mirror(参数列表);

***.reg_block. mirror(参数列表);

(2)举例

(3)mirror()工作流程
  1. mirror()读取镜像值(旧)
  2. mirror()调用XreadX()方法(见read工作流程),读取DUT值,并更新镜像值和期望值
  3. 是否check?是,将镜像值(旧)和DUT值进行比较,不一致给出error

2.3.2 predict

1)格式

***.reg_block.register.predict(参数列表);

***.reg_block.register.field.predict(参数列表);

(2)举例

(3)predict()工作流程

(1)predict()将要写入的值写入到m_mirrored和m_desired。

2.4 peek&poke

peek&poke可以理解为后门操作的read&write,不同的是,前两者对DUT寄存器的访问不管寄存器的属性,后者的后门访问需要考虑寄存器的属性,即需要根据DUT寄存器的属性读写合适的值(例如:寄存器是RC类型的,poke也能写进去,但是write backdoor写不进去;寄存器是RC类型的,peek会读但不会清,read backdoor会读清)。

2.4.1 peek

(1)格式

后门

***.reg_block.register.peek(参数列表);

***.reg_block.register.field.peek(参数列表);

(2)举例

2.4.2 poke

(1)格式

后门

***.reg_block.register.poke(参数列表);

***.reg_block.register.field.poke(参数列表);

(2)举例

2.5 get_registers

作用:得到ral model的所有寄存器

举例:

2.6 get_name

作用:得到寄存器的名字

举例:

2.7 get_reset

作用:得到ral model寄存器的复位值

举例:

2.8 get_fields

作用:获取寄存器的所有域

举例:

2.9 get_access

作用:获取寄存器域的访问属性

举例:

2.10 get_n_bits

作用:获取域的width

举例:

2.11 get_reg_by_offset

作用:通过给出寄存器地址的形式获取寄存器

举例:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值