当前位置: 首页 > news >正文

UVM寄存器模型:uvm_reg_adapter

文章目录

  • 一、什么是uvm_reg_adapter
    • 1、what
    • 2、Example
    • 2.1、代码详解
  • 二、如何使用uvm_reg_adapter
  • 三、为什么要引入uvm_reg_adapter

一、什么是uvm_reg_adapter

1、what

  1. uvm_reg_adapter继承于uvm_object,定义了用于在 uvm_reg_bus_op特定总线事务之间进行转换的接口,使得寄存器模型和总线之间能够有效地进行通信。
  2. uvm_reg_bus_op:定义用于寄存器和内存访问的通用总线事务的结构,具有类型(读或写)、地址、数据和字节启用信息。
类型                成员
uvm_access_e        kind          UVM_READ or UVM_WRITE.
uvm_reg_addr_t      addr          地址;默认64位
uvm_reg_data_t      data          数据:默认64位
int                 n_bits        传输的bit位
uvm_reg_byte_en_t   byte_en       使能byte操作
uvm_status_e        status        传输的结果:UVM_IS_OK, UVM_HAS_X, UVM_NOT_OK.

2、Example

class rkv_ahbmtx_reg_adapter extends uvm_reg_adapter;`uvm_object_utils(rkv_ahbmtx_reg_adapter)
function new(string name = "rkv_ahbmtx_reg_adapter");super.new(name);provides_responses = 1;  // 如果总线要返回response数据,则应当使能provides_responses
endfunctionfunction uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw); //函数原型需要一字不改svt_ahb_transaction t;t.xact_type = (rw.kind == UVM_WRITE) ? svt_ahb_master_transaction::WRITE :svt_ahb_master_transaction::READ;t.addr = rw.addr;t.burst_type = svt_ahb_master_transaction::SINGLE;t.burst_size = svt_ahb_master_transaction::BURST_SIZE_32BIT;t.data = new[1];  //svt_ahb_transaction 中的data是数组,这里是single传输,所以设置size为1t.data[0] = rw.data;return t;    //隐形转换
endfunctionfunction void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw); //函数原型需要一字不改svt_ahb_transaction t;if (!$cast(t, bus_item)) begin`uvm_fatal("CASTFAIL", "Provided bus_item is not of the correct type")return;endrw.kind = (t.xact_type == svt_ahb_master_transaction::WRITE) ? UVM_WRITE : UVM_READ;rw.addr = t.addr;rw.data = t.data[0];rw.status = UVM_IS_OK;
endfunction
endclass

2.1、代码详解

  1. provides_responses:如果总线要返回response数据,则应当使能provides_responses;若总线不支持返回response数据(没有调用put_response(RSP)或者item_done(RSP)),则不应设置,负责会使得环境挂起

  2. supports_byte_enable:总线支持byte访问,则使能

  3. reg2bus

    1. 函数原型: pure virtual function uvm_sequence_item reg2bus( const ref uvm_reg_bus_op rw)
    2. pure virtual :纯虚方法,即没有实体的方法原型,它只可以在抽象类中定义(uvm_reg_adapter 是抽象类(virtual class uvm_reg_adapter extends uvm_object )
    3. 函数声明的返回类型是 uvm_sequence_itemuvm_sequence_item 是父类类型,但是最后 return t返回的是子类句柄(svt_ahb_transaction 实例的句柄),这里存在一个隐形转换:子类句柄转换为父类句柄并返回;也就是说最后返回的是父类句柄指向的父类类型;( 在svt_ahb_master_driver中其参数的数据类型是svt_ahb_master_transaction svt_sequencersvt_driver的参数都是 uvm_sequence_item,所以将其返回为 uvm_sequence_item)在这里插入图片描述
    4. const refconst 关键字用于声明一个变量为常量,意味着该变量的值在初始化后不能被修改。const ref 表示一个常量引用,指向一个对象,但不允许通过这个引用修改该对象
    5. reg2bus()完成的桥接场景是,如果用户在寄存器级别做了操作,那么寄存器级别操作的信息uvm_reg_bus_op会被记录,同时调用uvm_reg_adapter::reg2bus()函数。在完成了将uvm_reg_bus_op的信息映射到bus_trans之后,函数将bus_trans实例返回。而在返回bus_trans之后,该实例将通过bus_seqeuncer传入到bus_driver。这里的transaction传输是后台隐式调用的,不需要主动发起。
  4. bus2reg

    1. 函数原型: pure virtual function void bus2reg(uvm_sequence_item bus_item,ref uvm_reg_bus_op rw)
    2. 父类句柄bus_item指向了子类对象(实际传输的类型就是子类类型),所以要把父类句柄bus_item指向的子类对象转换为uvm_reg_bus_op 类型;父类句柄是无法访问子类对象,需要先把父类句柄转换为子类句柄
vt_ahb_transaction t;
if (!$cast(t, bus_item)) begin`uvm_fatal("CASTFAIL", "Provided bus_item is not of the correct type")return;end
  1. bus2reg函数的功能与reg2bus相反,完成了从bus_transuvm_reg_bus_op的内容映射。在完成映射之后,更新的uvm_reg_bus_op数据最终返回至寄存器操作场景层。

  2. 对于寄存器操作,无论读操作还是写操作,都需要经历调用reg2bus,继而发起总线事务,而完成总线事务发回反馈之后,又需要调用bus2reg,将总线的数据返回至寄存器操作层面。

二、如何使用uvm_reg_adapter

  1. 集成在env
  2. 例化后,需要在connect_phase中做必要的连接
rgm.map.set_sequencer(agt.sequencer, adapter);
predictor.adapter = adapter;

三、为什么要引入uvm_reg_adapter

  1. 通过使用适配器,验证环境中的不同组件可以相互独立开发和修改,减少了对其他组件的依赖。

  2. 提高可重用性:适配器可以在不同的项目或测试环境中复用,从而节省开发时间和资源。

  3. 简化复杂性:在复杂的验证环境中,适配器有助于简化不同协议之间的交互,使得设计和验证人员可以专注于各自的任务,而不必担心接口细节。

  4. 没有适配器,组件无法轻松适应不同的协议或接口,降低了验证环境的灵活性和可重用性。

http://www.lryc.cn/news/470895.html

相关文章:

  • 总结OpenGL和pyrender安装和使用过程中的坑
  • 温湿传感器(学习笔记下)
  • 期刊论文写作之word模板
  • 雷池社区版OPEN API使用教程
  • LSTM(Long Short-Term Memory,长短期记忆网络)在高端局效果如何
  • 模组操作宝典:4种关机重启技巧,让你的设备运行无忧
  • 利用API接口实现旺店通和金蝶系统的无缝数据对接
  • 热题100(hash)
  • Ubuntu下Mysql修改默认存储路径
  • LVGL移植教程(超详细)——基于GD32F303X系列MCU
  • 《计算机原理与系统结构》学习系列——处理器(中)
  • 深入解析 OceanBase 数据库中的局部索引和全局索引
  • 2024防晒衣市场社媒营销洞察报告
  • 【Ubuntu20.04 Visual Studio Code安装】【VSCODE】
  • 贪心算法day(1)
  • 窗口函数sql使用总结
  • python单因素分析
  • 「C/C++」C++ STL容器库 之 std::list 双向链表容器
  • 应用程序框架进阶<HarmonyOS第一课>
  • 【C++】vector<string>-动态数组存储多个string
  • 66Analytics 汉化版,网站统计分析源码,汉化前台后台
  • 蓝桥杯单片机STC15F2K60S2第十四届省赛代码详细讲解(附完整代码)
  • [免费]SpringBoot+Vue智慧校园(校园管理)系统[论文+源码+SQL脚本]
  • 景区导航地图怎么实现?基于LBS与3D GIS的智慧景区导航导览系统技术路线
  • RedisIO多路复用
  • C++的相关习题(2)
  • C++《vector的模拟实现》
  • 无人机避障——路径规划篇(一) JPS跳点搜索算法A*算法对比
  • OpenCV ORB角点检测匹配和偏移计算
  • 图文详解ChatGPT-o1完成论文写作的全流程