• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

SOC/IP验证工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

寄存器模型中get_reg_by_offset函数的用法

在建立寄存器模型后,一般都是通过层次引用的方式访问寄存器;
但是出于某些原因,如果依然要使用地址来访问寄存器模型,那么可以使用get_reg_by_offset函数通过寄存器地址得到一个uvm_reg的指针,再调用此uvm_reg的read或write就可以进行读写操作;

class case0_cfg_vseq extends uvm_sequence;
   `uvm_object_utils(case0_cfg_vseq)
   `uvm_declare_p_sequencer(my_vsqr)
   function  new(string name= "case0_cfg_vseq");
      super.new(name);
   endfunction 
   virtual task read_reg(input bit[15:0] addr, output bit[15:0] value);
      uvm_status_e   status;
      uvm_reg target;
      uvm_reg_data_t data;
      uvm_reg_addr_t addrs[];
      target = p_sequencer.p_rm.default_map.get_reg_by_offset(addr);//得到某个寄存器的指针
      if(target == null) 
         `uvm_error("case0_cfg_vseq", $sformatf("can't find reg in register model with address: 'h%0h", addr))
      target.read(status, data, UVM_FRONTDOOR);
      void'(target.get_addresses(null,addrs));//得到这个函数的所有地址,返回值是一个动态数据addrs
      if(addrs.size() == 1)
         value = data[15:0]; //如果没有使用多地址的寄存器,则允许此行代码
      else begin//多地址的寄存器
         int index;
         for(int i = 0; i < addrs.size(); i++) begin
            if(addrs[i] == addr) begin
               data = data >> (16*(addrs.size() - i));
               value = data[15:0];
               break;
            end
         end
      end 
   endtask
   virtual task body();
      uvm_status_e   status;
      uvm_reg_data_t value;
      if(starting_phase != null) 
         starting_phase.raise_objection(this);
      p_sequencer.p_rm.gb_ins.invert.read(status, value, UVM_FRONTDOOR);
      `uvm_info("case0_cfg_vseq", $sformatf("invert's initial value is %0h", value), UVM_LOW)
      p_sequencer.p_rm.gb_ins.invert.write(status, 1, UVM_FRONTDOOR);
      p_sequencer.p_rm.gb_ins.invert.read(status, value, UVM_FRONTDOOR);
      `uvm_info("case0_cfg_vseq", $sformatf("after set, invert's value is %0h", value), UVM_LOW)
      p_sequencer.p_rm.bb_ins.depth.read(status, value, UVM_FRONTDOOR);
      `uvm_info("case0_cfg_vseq", $sformatf("not existed reg depth's read value is %0h", value), UVM_LOW)
      read_reg('h0005, value);
      `uvm_info("case0_cfg_vseq", $sformatf("'h0005's value is %0h", value), UVM_LOW)
      read_reg('h0006, value);
      `uvm_info("case0_cfg_vseq", $sformatf("'h0006's value is %0h", value), UVM_LOW)
      if(starting_phase != null) 
         starting_phase.drop_objection(this);
   endtask
endclass

posted on 2023-06-18 11:05  SOC验证工程师  阅读(595)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3