UVM 验证平台收集覆盖

1. 定义coverage文件,文件名ut_cov.sv

//文件名可和class名字不一样,以防找不到命名为一致,找不到环境会报错

class ut_cov extends uvm_component;
  `uvm_component_utils(ut_cov)
  cpu_transfer cpu_tr;
  virtual interface cpu_if  cfgif;

  covergroup top_cfg @(cfgif.cpu_cast_sample_cov);
  // cpu_cast_sample_cov 为自定义的触发事件,定义在cup_if 中
    option.per_instance = 1;
    cpu_addr: coverpoint cpu_tr.addr 
    // cpu_addr为cpu_tr.addr的别名,cpu_tr.addr对应cpu_transfer的addr信号
    {
       bins addr0 = {32'h00};
       bins addr1 = {32'h04};
       bins addr2 = {32'h08};
       bins addr3 = {32'h0c};
       ... // 根据验证需求设置bins 个数和取值
    }
     cpu_wd: coverpoint cpu_tr.datain
    {
       bins datain = {[32'h0:32'hffff]};
    }

    .... //根据验证需求添加coverpoint
   endgroup

   function new(string name="ut_cov", uvm_component parent);
     super.new(name, parent);
     top_cfg = new(); //一定要创建covergroup,否则覆盖率收集会失败,并且不显示error
       if(!uvm_config_db#(virtual cpu_if)::get(null, "*", "cfgif", cfgif))begin
          //该uvm_config_db 与top 层相连
          `uvm_fatal(get_type_name(), "no virtual interface specified for cpu_cast")
       end

   endfunction

   function void build_phase(uvm_phase phase);
     super.build_phase(phase);
   endfunction
endclass

2. 完善top.sv文件的uvm_config_db

//在top.sv 里,uvm_config_db必须写进initial begin中

initial

   ...// 验证平台所需的其它uvm_config_db
   uvm_config_db#(virtual cpu_if)::set(uvm_root::get(), "*", "cfgif", cfgif);

begin

3. 在env.sv中实例化ut_cov.sv文件

class ut_env extends uvm_env;

  ... //给env其它成员创建句柄
  
  ut_cov   ut_fcov;//句柄名字随意定义,后续实例化保持一致即可

  `uvm_component_utils(efuse_env)

  function new(string name = "cov_env", uvm_component parent = null)
    super.new(name, parent);
  endfunction

  virtual function void build_phase(uvm_phase phase);
    super.connect_phase(phase);

    ...//实例化env其它句柄
    ut_fcov = ut_cov ::type_id::create("ut_fcov", this);
    uvm_config_db#(ut_cov)::set(null, "*", "ut_fcov", ut_fcov); 
    //在哪里收覆盖,哪里就设置get()操作,本文在sequnce中收覆盖率

  endfunction
  
  ... //环境所需其它phase

endclass

4. 在cpu_if .sv 中 定义触发事件

interface cpu_if(input clk, input rst_n);
   
   ...//定义Interface 信号

   event cpu_cast_sample_cov; //名字与ut_cov.sv中一致
endinterface

5. 在tb1_seq.sv 中触发覆盖率收集事件 

class tb1_seq extends base_sequence;
 
   `uvm_object_utils(tb1_seq)

   ut_cov             ut_fcov;
   cpu_transfer       cpu_tr;
   virtual  cpu_if    cfgif;

   function new(string name="tb1");
     super.new(name);
     cpu_tr = cpu_transfer::type_id::create("cpu_tr");
     
     if(!uvm_config_db#(ut_cov)::get(null, "*", "ut_fcov", ut_fcov))begin
          `uvm_fatal(get_type_name(), "no ut_fcov getted for tb1_seq")
     end

     if(!uvm_config_db#(virtual cpu_if)::get(null, "*", "cfgif", cfgif))begin
        // 与env相连
          `uvm_fatal(get_type_name(), "no virtual interface getted for  tb1_seq")
     end
   endfunction

   virtual task usr_body();
     bit  [31:0] rdata;
     assert(cpu_tr.randomize() with {addr==`REG_0;});//`REG_0是宏定义,可直接设置值
     CPU_RD(cpu_tr.addr, rdata); //CPU_RD  为自定义的发激励task
     //发激励一定要用到coverpoint中的cpu_tr信号,否则收不到
     $cast(ut_fcov.cpu_tr, cpu_tr);//类型转换
     -> cfgif.cpu_cast_samplele_cov; //触发覆盖率收集事件
     ...
    endtask

endclass

6. 启动环境运行tb1_seq对应的test case,即可收到覆盖率

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值