You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在covergroup中使用阻塞表达式时,是否仍需调用.sample()指令?

Covergroup触发方式的疑问

Covergroup既可以通过过程代码中的.sample()采样指令触发,也可以通过其内部的@(clk)或@(signal)这类阻塞表达式触发。如果在covergroup中已经实现了阻塞表达式,还需要调用.sample()采样指令吗?

用户提供的示例代码:

class func_cov extends uvm_subscriber #(seq_item);
  covergroup cg @(posedge clk);
    option.per_instance = 1; // Per instance coverage
    option.auto_bin_max = 256; // Set maximum number of bins
    option.type_option = UVM_UNSIGNED; // Set coverage type to unsigned
    option.weight = 1; // Set coverage weight
    // Add coverage points to the covergroup
    coverpoint req.addr {
      bins range[] = {0, 255, 512, 1023};
    }
    coverpoint req.data {
      bins data_range[] = {[0:255], [256:511], [512:767], [768:1023]};
    }
  endgroup

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

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    cg = new("cg", this);
  endfunction

  function void write(seq_item req);
    // Collect coverage data
    cg.sample();
  endfunction
endclass

解答

不需要再调用.sample(),两种触发方式二选一即可,同时使用会导致重复采样,干扰覆盖统计结果。

两种触发方式的逻辑差异

  • 带事件触发的covergroup:当定义时指定了@(posedge clk)这类触发事件,每当事件发生时,covergroup会自动对内部coverpoint的变量进行采样,无需额外调用.sample()。这种方式适合需要严格对齐时钟沿的采样场景。
  • 显式调用.sample()的covergroup:如果covergroup定义时没有指定触发事件,必须通过主动调用.sample()来触发采样,通常在数据更新完成后执行(比如UVM subscriber拿到新的事务时)。

针对示例代码的修正

示例代码同时使用了时钟触发和.sample(),属于重复触发,需要调整:

方案1:保留时钟触发,移除.sample()

需要把传入的事务存到类的成员变量中,让covergroup在时钟沿到来时采样这个变量:

class func_cov extends uvm_subscriber #(seq_item);
  seq_item req; // 定义成员变量存储事务
  covergroup cg @(posedge clk);
    option.per_instance = 1; // 每个实例独立统计覆盖
    option.auto_bin_max = 256; // 设置自动分箱最大数量
    option.type_option = UVM_UNSIGNED; // 覆盖类型设为无符号
    option.weight = 1; // 设置覆盖权重
    // 覆盖点定义
    coverpoint req.addr {
      bins range[] = {0, 255, 512, 1023};
    }
    coverpoint req.data {
      bins data_range[] = {[0:255], [256:511], [512:767], [768:1023]};
    }
  endgroup

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

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    cg = new("cg", this);
  endfunction

  function void write(seq_item t);
    // 将传入事务赋值给成员变量,供时钟沿触发采样
    req = t;
  endfunction
endclass

方案2:移除时钟触发,保留.sample()

适合需要在拿到事务时立即采样的场景:

class func_cov extends uvm_subscriber #(seq_item);
  covergroup cg; // 移除时钟触发事件
    option.per_instance = 1; // 每个实例独立统计覆盖
    option.auto_bin_max = 256; // 设置自动分箱最大数量
    option.type_option = UVM_UNSIGNED; // 覆盖类型设为无符号
    option.weight = 1; // 设置覆盖权重
    // 覆盖点定义
    coverpoint req.addr {
      bins range[] = {0, 255, 512, 1023};
    }
    coverpoint req.data {
      bins data_range[] = {[0:255], [256:511], [512:767], [768:1023]};
    }
  endgroup

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

  function void build_phase(uvm_phase phase);
    super.build_phase(phase);
    cg = new("cg", this);
  endfunction

  function void write(seq_item req);
    // 拿到事务后立即触发采样
    cg.sample();
  endfunction
endclass

总结

根据采样时机需求选择一种触发方式即可:

  • 若需对齐时钟沿采样:使用事件触发,不要调用.sample()
  • 若需在数据更新时立即采样:移除事件触发,显式调用.sample()

内容的提问来源于stack exchange,提问作者bu-ral

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 08:25:10