UVM讲解系列之九:加入RAL

目录

RAL的基本原理

RAL在代码中的集成

RAL提供的寄存器操作方法

列举常用的方法

操作举例

代码举例


前文总体介绍的时候说明了为什么要用ral,今天简单说明ral的基本原理和使用。

RAL的基本原理

UVM关于RAL的定义:UVM中的RAL(Register Abstraction Layer)是一种用于抽象寄存器访问的机制。RAL通过将寄存器和寄存器字段抽象为对象,使得验证工程师可以在更高的层次上进行寄存器操作,而不需要直接与硬件信号交互。

在不使用ral的情况下,对寄存器进行读写等操作都是需要先找到寄存器的地址,加入ral之后,验证环境隐藏了这一底层的操作。带来的优点是,即使寄存器地址发生变化(这在项目中是常有的事情),也不用频繁修改环境。而且在验证环境中显示使用名字进行操作,具有更高的可读性。

RAL的核心思想是将寄存器的读写操作封装为方法,并通过这些方法进行寄存器的配置和状态检查。

RAL在代码中的集成

在UVM中,RAL的集成通常包括以下几个步骤:

  1. 定义寄存器模型:首先需要定义寄存器模型,包括寄存器、寄存器字段、寄存器块等。这些定义通常使用SystemVerilog的uvm_reguvm_reg_fielduvm_reg_block等类来实现。寄存器模型的来源是设计人员编写的寄存器说明文档,基本上每个公司都有脚本来根据寄存器说明文档来生成寄存器模型。如果寄存器发生变更,只需要用脚本重新生成寄存器模型即可。
class my_reg extends uvm_reg;
    `uvm_object_utils(my_reg)

    uvm_reg_field field1;
    uvm_reg_field field2;

    function new(string name = "my_reg");
        super.new(name, 32, UVM_NO_COVERAGE);
    endfunction

    virtual function void build();
        field1 = uvm_reg_field::type_id::create("field1");
        field1.configure(this, 8, 0, "RW", 0, 8'h00, 1, 1, 1);

        field2 = uvm_reg_field::type_id::create("field2");
        field2.configure(this, 8, 8, "RW", 0, 8'h00, 1, 1, 1);
    endfunction
endclass

  1. 创建寄存器块:寄存器块是寄存器的容器,通常包含多个寄存器。寄存器块可以通过继承uvm_reg_block类来创建。
class my_reg_block extends uvm_reg_block;
    `uvm_object_utils(my_reg_block)

    my_reg reg1;
    my_reg reg2;

    function new(string name = "my_reg_block");
        super.new(name, UVM_NO_COVERAGE);
    endfunction

    virtual function void build();
        reg1 = my_reg::type_id::create("reg1");
        reg1.configure(this);
        reg1.build();

        reg2 = my_reg::type_id::create("reg2");
        reg2.configure(this);
        reg2.build();

        default_map = create_map("default_map", 0, 4, UVM_LITTLE_ENDIAN);
        default_map.add_reg(reg1, 'h0);
        default_map.add_reg(reg2, 'h4);
    endfunction
endclass

  1. 连接寄存器模型到硬件:寄存器模型需要与实际的硬件接口进行连接。这通常通过uvm_reg_adapteruvm_reg_predictor来实现。uvm_reg_adapter负责将寄存器操作转换为总线事务,而uvm_reg_predictor则用于预测寄存器的状态。
class my_adapter extends uvm_reg_adapter;
    `uvm_object_utils(my_adapter)

    function new(string name = "my_adapter");
        super.new(name);
    endfunction

    virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);
        my_bus_transaction trans = my_bus_transaction::type_id::create("trans");
        trans.addr = rw.addr;
        trans.data = rw.data;
        trans.kind = rw.kind;
        return trans;
    endfunction

    virtual function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);
        my_bus_transaction trans;
        if (!$cast(trans, bus_item)) begin
            `uvm_fatal("CAST", "Failed to cast bus_item to my_bus_transaction")
        end
        rw.addr = trans.addr;
        rw.data = trans.data;
        rw.kind = trans.kind;
    endfunction
endclass

  1. 在测试环境中集成寄存器模型:最后,将寄存器模型集成到测试环境中,并通过uvm_reg_sequence进行寄存器操作。
class my_test extends uvm_test;
    `uvm_component_utils(my_test)

    my_reg_block reg_block;
    my_adapter adapter;
    uvm_reg_predictor predictor;

    function new(string name, uvm_component parent);
        super.new(name, parent);
    endfunction

    virtual function void build_phase(uvm_phase phase);
        reg_block = my_reg_block::type_id::create("reg_block");
        reg_block.build();
        reg_block.lock_model();

        adapter = my_adapter::type_id::create("adapter");
        predictor = uvm_reg_predictor::type_id::create("predictor");

        predictor.adapter = adapter;
        predictor.map = reg_block.default_map;
    endfunction

    virtual task run_phase(uvm_phase phase);
        uvm_reg_sequence seq = uvm_reg_sequence::type_id::create("seq");
        seq.model = reg_block;
        seq.start(null);
    endtask
endclass

RAL提供的寄存器操作方法

列举常用的方法


 configure()     配置寄存器属性
 add_field()     添加字段到寄存器
 set()               设置寄存器值
 get()               获取寄存器值
 read()             发起读操作
 write()             发起写操作
 mirror()           镜像寄存器值
 update()         更新硬件寄存器

 predict()          预测字段值

操作举例


uvm_reg::read() / write()                             读写单个寄存器
uvm_reg_block::read_reg() / write_reg()   通过层次路径访问寄存器
uvm_reg::peek() / poke()                             直接访问寄存器(绕过总线)

批量操作
uvm_reg_block::mirror()              镜像多个寄存器
uvm_reg_block::update()             更新多个寄存器
uvm_reg_block::reset()                重置寄存器模型

预测与检查方法

uvm_reg::predict()                        预测寄存器值
uvm_reg::get_mirrored_value()    获取镜像值
uvm_reg::needs_update()            检查是否需要更新
uvm_reg::is_known()                    检查值是否已知

代码举例

这些方法共同构成了UVM RAL的强大功能,使得寄存器建模、访问和验证变得更加高效和可靠。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值