get_reg_by_offset函数

get_reg_by_offset函数如下:

在建立了寄存器模型后,可以直接通过层次引用的方式访问寄存器:

rm.invert.read(...);

但是出于某些原因,如果依然要使用地址来访问寄存器模型,那么此时可以使用get_reg_by_offset函数通过寄存器的地址得到 一个uvm_reg的指针,再调用此uvm_reg的read或者write就可以进行读写操作:

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));
     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

通过调用最顶层的reg_block的get_reg_by_offset,即可以得到任一寄存器的指针。

如果如7.4.1节(白皮书)那样使用了层次的寄存器模型,从最顶层的reg_block的get_reg_by_offset也可以得到子reg_block中的寄存器。即假如buf_blk的地址偏移是'h1000,其中有偏移为'h3的寄存器(即此寄存器的实际物理地址是'h1003),那么可以直接由p_rm.get_reg_by_offset('h1003)得到此寄存器,而不必使用p_rm.buf_blk.get_reg_by_offset('h3)。

如果没有使用7.4.4节所示的多地址寄存器,那么情况比较简单,上述代码会运行第39行的分支。当存在多个地址的情况下, 通过get_addresses函数可以得到这个函数的所有地址,其返回值是一个动态数组addrs。其中无论是大端还是小端,addrs[0]是LSB 对应的地址。即对于7.3.2节DUT中的counter(此DUT是大端),那么addrs[0]中存放的是‘h6。而假如是小端,两个地址分别 是'h1005和'h1006,那么addrs[0]中存放的是'h1005。第41到48行通过比较addrs中的地址与目标地址,最终得到要访问的数据。

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值