UVM中寄存器模型的构建、集成、应用

本文内容整理自CSDN博主:Starry、 ,UVM实战卷1—张强—机械工业出版社

一、寄存器模型的基本概念

寄存器是硬件模块之间互相交谈的窗口,在验证的过程中,我们需要对寄存器的配置和功能也进行验证。

硬件设计中,一定会用到寄存器对功能进行配置,而我们在进行验证功能模块的时候,需要读出此时寄存器的配置或状态。常规的想法是通过总线直接进入DUT中进行读写,但这样有许多缺点,比如访问速度,占用资源等缺点,UVM提供的寄存器模型,顾名思义,就是可以在验证模块搭建中,搭建寄存器模型,并且这个模型具有自动预测,更新硬件值等功能。


寄存器模型

1.1 寄存器模型组成

uvm_reg_field :寄存器模型中的最小单位;

uvm_reg:比uvm_reg_field高一个级别,但仍然是比较小的一个单位;

uvm_reg_block:顾名思义,uvm_reg的块,可以拥有许多的uvm_reg,也可以加入其他的uvm_reg_block;

uvm_reg_map:每个寄存器在加入寄存器模型时,都必须要有其地址,uvm_reg_map就是储存这些地址并可以转换其真实物理地址的一个成员。每个uvm_reg_block内部都自带一个默认的uvm_reg_map——default_map

1.2 构建寄存器模型的步骤

uvm_reg:

首先,需要从uvm_reg中派生一个类:class reg_invert extends uvm_reg;

    在类中,声明uvm_reg_field的成员变量:rand uvm_reg_field reg_data;

    在这个类中的build()方法中,创建field:reg_data = uvm_reg_field::type_id::create("reg_data");

    配置你的域:reg_data.configure(this, 1, 0, "RW", 1, 0, 1, 1, 0);

最后在new()方法中,使用super.new(name, 16, UVM_NO_COVERAGE);


uvm_reg类的定义

build()方法: 

主要用于域的例化和configure

configure()方法:

主要用于对寄存器域进行配置,各输入变量含义如下

● uvm_reg parent:所属寄存器的句柄

● int unsigned size:域宽

● int unsigned lsb_pos:该域的最低bit在寄存器中的下标bit号。

● string access:该域的存取方式,包括"RO", “RC”, “RS”, “WC”, "WS"等

● bit volatile:是否易失,一般为0

● uvm_reg_data_t reset:复位时的默认值

● bit has_reset:是否有复位,一般为1

● bit is_rand:是否为随机的

● bit individually_accessible:是否可单独存取

new()方法:

string name="":名字

● int unsigned n_bits:寄存器总长度,单位bit

● int has_coverage:是否加入覆盖率

uvm_reg_block:

由uvm_reg_block派生的类就是用户使用的寄存器模型块了,它可包含多个寄存器reg,且必须包含一个寄存器地址map。

首先声明继承自uvm_reg_block:reg_model extends uvm_reg_block;

声明uvm_reg:rand reg_invert invert;

在build()里需要创建uvm_reg和uvm_reg_map:

    default_map = create_map("default_map", 0, 2, UVM_BIG_ENDIAN, 0);

    invert = reg_invert::type_id::create("invert", , get_full_name());

然后配置configure()、build()(注意此处的build是嵌套uvm_reg内的build函数):

    invert. configure(this. null, "");

    invert.build();

最后还需要在map里添加这个reg;

    default_map.add_reg(invert, `h9, "RW");

uvm_reg_block的定义

default_map与create_map():

default_map是uvm_reg_block中的成员,是系统已经默认声明好的default_map,所以寄存器组类定义中不用再创建新的uvm_reg_map成员了,只需要在build中将其例化。

lock_model():

一般在寄存器block定义完之后,要进行锁定,reg_model中就不能再添加新的寄存器了。

1.3 总线适配器 adapter

有了寄存器块reg_block类还不够,还要写一个适配器adapter类。

因为对寄存器模型操作的transaction是uvm_reg_bus_op类的

该类与driver驱动dut的总线bus_trans不一样,uvm_reg_bus_op具有更高的可读性,所以需要一个adapter来作trans类型转换。

uvm_reg_adapter::reg2bus() 与 uvm_reg_adapter::bus2reg():

在通信过程中,无论读或写,寄存器模型都会通过sequence产生一个uvm_reg_bus_op的变量,此变量中存储着操作类型和操作的地址。此变量中的信息要经过一个转换器(adapter)转换后,交给bus_sequencer,随后交给bus_driver,由bus_driver实现最终的前门访问读写操作。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容