覆盖率测试模块
🪬

覆盖率测试模块

Created
Jul 31, 2024 03:32 PM
Tags
`ifndef COVERAGE `define COVERAGE class coverage; mailbox mon2cov; bit[7:0] A; bit[7:0] B; operation_t op_set; covergroup op_cov; coverpoint op_set { bins single_cycle[] = {[add_op : xor_op], rst_op,no_op}; bins multi_cycle = {mul_op, div_op}; bins opn_rst[] = ([add_op:div_op] => rst_op); bins rst_opn[] = (rst_op => [add_op:div_op]); bins sngl_mul[] = ([add_op:xor_op],no_op => mul_op); bins mul_sngl[] = (mul_op => [add_op:xor_op], no_op); bins sngl_div[] = ([add_op:xor_op],no_op => div_op); bins div_sngl[] = (div_op => [add_op:xor_op], no_op); bins mul_div[] = (mul_op => div_op); bins div_mul[] = (div_op => mul_op); bins twoops[] = ([add_op:div_op] [* 2]); bins manymul = (mul_op [* 3:5]); bins manydiv = (div_op [* 3:5]); } endgroup covergroup zeros_or_ones_on_ops; all_ops : coverpoint op_set { ignore_bins null_ops = {rst_op, no_op};} a_leg: coverpoint A { bins zeros = {'h00}; bins others= {['h01:'hFE]}; bins ones = {'hFF}; } b_leg: coverpoint B { bins zeros = {'h00}; bins others= {['h01:'hFE]}; bins ones = {'hFF}; } op_00_FF: cross a_leg, b_leg, all_ops { bins add_00 = binsof (all_ops) intersect {add_op} && (binsof (a_leg.zeros) || binsof (b_leg.zeros)); bins add_FF = binsof (all_ops) intersect {add_op} && (binsof (a_leg.ones) || binsof (b_leg.ones)); bins and_00 = binsof (all_ops) intersect {and_op} && (binsof (a_leg.zeros) || binsof (b_leg.zeros)); bins and_FF = binsof (all_ops) intersect {and_op} && (binsof (a_leg.ones) || binsof (b_leg.ones)); bins xor_00 = binsof (all_ops) intersect {xor_op} && (binsof (a_leg.zeros) || binsof (b_leg.zeros)); bins xor_FF = binsof (all_ops) intersect {xor_op} && (binsof (a_leg.ones) || binsof (b_leg.ones)); bins mul_00 = binsof (all_ops) intersect {mul_op} && (binsof (a_leg.zeros) || binsof (b_leg.zeros)); bins mul_FF = binsof (all_ops) intersect {mul_op} && (binsof (a_leg.ones) || binsof (b_leg.ones)); bins mul_max = binsof (all_ops) intersect {mul_op} && (binsof (a_leg.ones) && binsof (b_leg.ones)); bins div_00 = binsof (all_ops) intersect {div_op} && (binsof (a_leg.zeros) || binsof (b_leg.zeros)); bins div_FF = binsof (all_ops) intersect {div_op} && (binsof (a_leg.ones) || binsof (b_leg.ones)); bins div_max = binsof (all_ops) intersect {div_op} && (binsof (a_leg.ones) && binsof (b_leg.ones)); ignore_bins others_only = binsof(a_leg.others) && binsof(b_leg.others); } endgroup function new (mailbox mon2cov_new); op_cov = new(); zeros_or_ones_on_ops = new(); if(mon2cov_new == null)begin $display("%0t -> coverage : ERROR -> mon2cov is null",$time); $finish; end else this.mon2cov = mon2cov_new; endfunction task run(); transaction tr; forever begin mon2cov.get(tr); A = tr.A; B = tr.B; op_set = tr.op; op_cov.sample(); zeros_or_ones_on_ops.sample(); $display("%0t -> coverage : tr is %s",$time,tr.convert2string()); end endtask endclass `endif
关于覆盖率的测试一定要自己研究一下,以应对面试。
覆盖率测试主要测试三个参数,分别是A、B以及操作指令op_set,为此定义了两个覆盖组:op_cov以及zeros_or_ones_ops

覆盖组 op_cov

  • coverpoint op_set:定义了一个覆盖点 op_set,用于收集操作类型的覆盖率。
  • bins single_cycle[]:单周期操作的bins。
  • bins multi_cycle:多周期操作的bins。
  • bins opn_rst[] 和 bins rst_opn[]:操作和复位操作之间的转换。
  • bins sngl_mul[] 和 bins mul_sngl[]:单周期操作和乘法操作之间的转换。
  • bins sngl_div[] 和 bins div_sngl[]:单周期操作和除法操作之间的转换。
  • bins mul_div[] 和 bins div_mul[]:乘法和除法操作之间的转换。
  • bins twoops[]:连续两个操作。
  • bins manymul 和 bins manydiv:连续多个乘法或除法操作。

覆盖组 zeros_or_ones_on_ops

  • all_ops:覆盖点 op_set,忽略 rst_op 和 no_op
  • a_leg 和 b_leg:覆盖点 A 和 B,分别定义了 zerosothers 和 ones 的bins。
  • op_00_FF:交叉覆盖点 a_legb_leg 和 all_ops,定义了不同操作类型下 A 和 B 为 00 或 FF 的bins。
这两个覆盖组定义了许多覆盖点,总归来说就是就是尽可能覆盖到所有可能的情况,比如单周期,多周期,乘法除法转换等等。更详细地说一下这两个覆盖组的区别,op_cov 着重考虑所有操作类型都覆盖到,而且强调对连续操作的覆盖测试;zeros_or_ones_ops 更看重操作数A和B取值以及操作类型组合的覆盖测试率,重点表征边缘边界部分的覆盖效果。
⚠️
我的程序主要是功能覆盖率