UVM学习记录之内建序列

目录

uvm_reg_access_seq

uvm_reg_single_access_seq


uvm_reg_access_seq

      if (model == null) begin
         `uvm_error("uvm_reg_access_seq", "No register model specified to run sequence on")
         return;
      end

      uvm_reg_block model;

      reg_seq = uvm_reg_single_access_seq::type_id::create("single_reg_access_seq");

      this.reset_blk(model);
      model.reset();

      do_block(model);

 需要指定进行寄存器测试的model,随后例化uvm_reg_single_access_seq。

reset_blk是一个空函数,具体不清楚

随后进行model的reset,依次调用下层reg或是blk的reset

reset函数链接

https://blog.csdn.net/weixin_60687833/article/details/126566806?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22126566806%22%2C%22source%22%3A%22weixin_60687833%22%7D

reset函数链接:

function void uvm_reg_block::reset(string kind = "HARD");

   foreach (regs[rg_]) begin
     uvm_reg rg = rg_;
     rg.reset(kind);
   end

   foreach (blks[blk_]) begin
     uvm_reg_block blk = blk_;
     blk.reset(kind);
   end
endfunction

reg又依次调用field的reset函数

function void uvm_reg::reset(string kind = "HARD");
   foreach (m_fields[i])
      m_fields[i].reset(kind);
   // Put back a key in the semaphore if it is checked out
   // in case a thread was killed during an operation
   void'(m_atomic.try_get(1));
   m_atomic.put(1);
   m_process = null;
   Xset_busyX(0);
endfunction: reset

接下来看一些do_block内容

如果在seq中使用了uvm_resource_db来禁用了该blk那么会直接退出该函数

blk.get_registers(regs, UVM_NO_HIER);

顺便看一下uvm_resource_db,链接如下

UVM源码学习笔记_一眼顶真的博客-CSDN博客

调用get_registers来获取该blk例化的所有寄存器,但不会获取子blk中例化的寄存器,因为是UVM_NO_HIER

      foreach (regs[i]) begin
         // Registers with some attributes are not to be tested
         if (uvm_resource_db#(bit)::get_by_name({"REG::",regs[i].get_full_name()},
                                                "NO_REG_TESTS", 0) != null ||
	     uvm_resource_db#(bit)::get_by_name({"REG::",regs[i].get_full_name()},
                                                "NO_REG_ACCESS_TEST", 0) != null )
              continue;
         
         // Can only deal with registers with backdoor access
         if (regs[i].get_backdoor() == null && !regs[i].has_hdl_path()) begin
            `uvm_warning("uvm_reg_access_seq", {"Register '",regs[i].get_full_name(),
                   "' does not have a backdoor mechanism available"})
            continue;
         end
         
         reg_seq.rg = regs[i];
         reg_seq.start(null,this);
      end

遍历得到的寄存器队列,首先还是检查是否设置了屏蔽寄存器

检查寄存器是否设置后门路径

将uvm_reg_single_access_seq的rg变量指向实例化的寄存器,start seq。

uvm_reg_single_access_seq

uvm_resource_db不再多说,没有为rg设置后门路径直接return,无法执行该test,因为该test后续需要对寄存器进行后门读操作

     if (rg.get_backdoor() == null && !rg.has_hdl_path()) begin
         `uvm_error("uvm_reg_access_seq", {"Register '",rg.get_full_name(),
         "' does not have a backdoor mechanism available"})
         return;
      end

得到该rg所在的map数,一个寄存器可以被包含在多个map中,对应多个物理接口

rg.get_maps(maps);

 获取寄存器域,遍历包含的所有map

遍历寄存器域,get_access后去域属性,对RO属性进行计数

如果寄存器属性是未知的return

      begin
         uvm_reg_field fields[$];

         rg.get_fields(fields);
         foreach (maps[k]) begin
	        int ro;
	       	ro=0;
	     	foreach (fields[j]) begin    
               if (fields[j].get_access(maps[k]) == "RO") begin
                  ro++;
               end
               if (!fields[j].is_known_access(maps[k])) begin
                  `uvm_warning("uvm_reg_access_seq", {"Register '",rg.get_full_name(),
                    "' has field with unknown access type '",
                    fields[j].get_access(maps[k]),"', skipping"})
                  return;
               end
	     	end
	     	if(ro==fields.size()) begin
	     		`uvm_warning("uvm_reg_access_seq", {"Register '",
                rg.get_full_name(),"' has only RO fields in map ",maps[k].get_full_name(),", skipping"})
                return;
	     	end	
         end
      end

如果ro变量等于寄存器域数量,也就是该寄存器是RO属性return

test部分

get获取寄存器的期望值(寄存器复位后期望值就是默认值)

前门给寄存器写入按位取反的期望值

mirror函数将寄存器的镜像值与后门读到的值进行相比,保证前门写入的值从后门能够正确读出来

后门给寄存器写入期望值,随后前门mirror

      foreach (maps[j]) begin
         uvm_status_e status;
         uvm_reg_data_t  v, exp;
         
         `uvm_info("uvm_reg_access_seq", {"Verifying access of register '",
             rg.get_full_name(),"' in map '", maps[j].get_full_name(),
             "' ..."}, UVM_LOW)
         
         v = rg.get();
         
         rg.write(status, ~v, UVM_FRONTDOOR, maps[j], this);

         if (status != UVM_IS_OK) begin
            `uvm_error("uvm_reg_access_seq", {"Status was '",status.name(),
                                 "' when writing '",rg.get_full_name(),
                                 "' through map '",maps[j].get_full_name(),"'"})
         end
         #1;
         
         rg.mirror(status, UVM_CHECK, UVM_BACKDOOR, uvm_reg_map::backdoor(), this);
         if (status != UVM_IS_OK) begin
            `uvm_error("uvm_reg_access_seq", {"Status was '",status.name(),
                                 "' when reading reset value of register '",
                                 rg.get_full_name(), "' through backdoor"})
         end
         
         rg.write(status, v, UVM_BACKDOOR, maps[j], this);
         if (status != UVM_IS_OK) begin
            `uvm_error("uvm_reg_access_seq", {"Status was '",status.name(),
                                 "' when writing '",rg.get_full_name(),
                                 "' through backdoor"})
         end
         
         rg.mirror(status, UVM_CHECK, UVM_FRONTDOOR, maps[j], this);
         if (status != UVM_IS_OK) begin
            `uvm_error("uvm_reg_access_seq", {"Status was '",status.name(),
                                 "' when reading reset value of register '",
                                 rg.get_full_name(), "' through map '",
                                 maps[j].get_full_name(),"'"})
         end
      end
   endtask:

但是在测试的时候RO域怎么办呢?

对于RO寄存器来说,期望值是0吗?

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值