4. 实现矩阵加法模块的覆盖率收集
任务目标
为矩阵加法DUT建立覆盖率收集机制:定义功能覆盖点(矩阵维度、数据范围)与代码覆盖率(行/分支/表达式),在UVM验证环境中完成覆盖率的采样与报告,以量化验证充分性。
环境依赖
本案例基于前序已搭建的UVM验证环境(含driver、monitor、scoreboard),需确保以下组件可用:
- UVM-1.2或IEEE 1800.2兼容库
- 支持覆盖率收集的仿真器(VCS/Xcelium/Questa任选)
- 矩阵加法DUT接口:
input [7:0] a[4][4], b[4][4]; input [1:0] dim; output [8:0] sum[4][4]
覆盖率定义与实现
在UVM环境中新建cov_collector.sv,通过covergroup定义功能覆盖点,并通过bind方式采样DUT内部信号实现代码覆盖率统计。核心覆盖策略:
- 功能覆盖:矩阵维度
dim取值(2×2/3×3/4×4)、输入数据边界(0x00/0xFF/随机中间值) - 代码覆盖:通过
cover property监控加法器进位链分支、饱和溢出路径
// cov_collector.sv - 覆盖率收集器
class cov_collector extends uvm_component;
`uvm_component_utils(cov_collector)
// 功能覆盖组
covergroup cg_matrix_add with function sample(int dim, byte a_val, byte b_val);
// 覆盖点1:矩阵维度
cp_dim: coverpoint dim {
bins dim_2x2 = {2};
bins dim_3x3 = {3};
bins dim_4x4 = {4};
}
// 覆盖点2:输入数据范围
cp_a_data: coverpoint a_val {
bins zero = {0};
bins max = {255};
bins mid = {[1:254]};
}
cp_b_data: coverpoint b_val {
bins zero = {0};
bins max = {255};
bins mid = {[1:254]};
}
// 交叉覆盖:维度×数据边界
cross_dim_data: cross cp_dim, cp_a_data, cp_b_data;
endgroup
// 代码覆盖率属性(通过bind监控DUT内部)
cover property (dut.carry_out && dut.dim == 2);
cover property (dut.sat_overflow);
function new(string name, uvm_component parent);
super.new(name, parent);
cg_matrix_add = new();
endfunction
// 从monitor获取事务并采样
virtual function void write_to_cov(int dim, byte a[4][4], byte b[4][4]);
foreach(a[i,j]) begin
cg_matrix_add.sample(dim, a[i][j], b[i][j]);
end
endfunction
// 覆盖率报告
function void report_phase(uvm_phase phase);
`uvm_info("COV", $sformatf("功能覆盖率: %.2f%%", cg_matrix_add.get_coverage()), UVM_NONE)
`uvm_info("COV", $sformatf("代码覆盖率: 行=%0d%% 分支=%0d%%",
$get_coverage_line(), $get_coverage_branch()), UVM_NONE)
endfunction
endclass
// bind模块:采样DUT内部信号
module cov_bind;
bind matrix_add_dut dut_cov_probe (
.carry_out(dut.carry_out),
.sat_overflow(dut.sat_overflow),
.dim(dut.dim)
);
endmodule
集成到UVM环境
在base_test.sv中创建收集器并连接monitor:
class base_test extends uvm_test;
cov_collector cov;
function void build_phase(uvm_phase phase);
super.build_phase(phase);
cov = cov_collector::type_id::create("cov", this);
endfunction
function void connect_phase(uvm_phase phase);
// 假设env中已有monitor的analysis_port
env.monitor.ap.connect(cov.analysis_export);
endfunction
endclass
运行与验证
- 编译:
vcs -sverilog -uvm dut.sv cov_collector.sv cov_bind.sv testbench.sv - 运行:
./simv +UVM_TESTNAME=base_test - 覆盖率收集:添加
-cm line+cond+branch+assert编译选项,运行后生成simv.vdb目录 - 查看报告:
urg -dir simv.vdb -report coverage_report
通过标准:
- 功能覆盖率≥95%(需确保测试序列覆盖所有dim取值和边界数据)
- 代码覆盖率≥90%(行覆盖),分支覆盖≥85%
- 若未达标,需增加定向测试用例(如全0、全FF、随机边界组合)
常见问题
- 覆盖率始终为0:检查covergroup是否在build_phase后创建,且sample调用是否在事务到达时触发
- 代码覆盖率缺失:确认bind模块中信号名与DUT内部层次一致,且编译时添加了
-cm选项 - 交叉覆盖空洞:使用
cg_matrix_add.get_coverage()打印各bin详情,定位未覆盖组合