如何加载coverage_db?跨测试运行传递功能覆盖问题求助
解决UVM中跨测试传递覆盖数据的问题
我来帮你搞定这个UVM覆盖数据传递的坑!你遇到的两个错误本质都是覆盖组实例化时机和coverage DB加载时机不匹配导致的,咱们一步步拆解解决:
先分析你遇到的两个问题
第一个错误:Covergroup '/t/test/cg' has no instance created in simulation
你最开始在initial块里先调用$load_coverage_db,但此时run_test()还没执行,UVM的test组件都还没实例化——你的cg是在test类的new函数里才创建的,加载DB的时候根本找不到这个实例,工具自然会报错忽略它。
第二个警告:Covergroup instance '/t::test::cg' exists in simulation but not found in database
把$load_coverage_db移到run_phase后,覆盖组实例虽然存在了,但工具找不到DB里对应的条目,这大概率是因为:
- 第一次运行时没正确保存覆盖数据到DB里
- 覆盖组的实例路径在两次运行时不匹配(比如包名、层次结构的细微差异)
正确的解决方案步骤
步骤1:第一次运行时,确保覆盖数据被正确保存
首先要在测试结束时主动保存覆盖数据,而不是只设置DB名称。修改你的test类,添加final_phase来完成保存:
`include "uvm_macros.svh" package t; import uvm_pkg::*; class test extends uvm_test; `uvm_component_utils(test) byte unsigned data; covergroup cg; dat: coverpoint data; endgroup function new(string name, uvm_component parent); super.new(name,parent); cg = new(); endfunction: new task run_phase(uvm_phase phase); phase.raise_objection(this); repeat(5) begin #5 data = $urandom(); #10 cg.sample(); end phase.phase_done.set_drain_time(this, 50ns); phase.drop_objection(this); endtask // 新增final_phase,测试结束时保存覆盖数据 function void final_phase(uvm_phase phase); super.final_phase(phase); $save_coverage_db(); // 把当前覆盖数据写入预设的DB文件 endfunction endclass: test endpackage module top(); import uvm_pkg::*; import t::*; initial begin $set_coverage_db_name("coverage_report.db"); // 设置要保存的DB文件名 run_test(); end endmodule
第一次运行这个代码,测试结束后就会生成包含覆盖数据的coverage_report.db文件。
步骤2:第二次运行时,正确加载覆盖数据
第二次运行时,要等覆盖组实例完全创建后,再加载DB,最佳时机是connect_phase(此时组件层次已经构建完成,cg也在new里实例化好了):
class test extends uvm_test; // ... 其他代码不变 ... // 新增connect_phase,在这里加载覆盖DB function void connect_phase(uvm_phase phase); super.connect_phase(phase); $load_coverage_db("coverage_report.db"); endfunction // ... 其他代码不变 ... endclass: test
如果还是想用run_phase加载,一定要在cg.sample()之前调用,并且可以手动指定覆盖组的实例路径,避免路径匹配问题(路径要和第一次运行时工具日志里显示的完全一致):
task run_phase(uvm_phase phase); // 手动指定覆盖组实例路径,精准匹配DB里的条目 $load_coverage_db("coverage_report.db", "/t/test/cg"); phase.raise_objection(this); repeat(5) begin #5 data = $urandom(); #10 cg.sample(); end phase.phase_done.set_drain_time(this, 50ns); phase.drop_objection(this); endtask
额外注意事项
- 两次运行必须使用完全相同的覆盖组定义(包括覆盖点、交叉点、 bins 设置等),否则工具会因为结构不匹配拒绝加载数据。
- 如果需要累积多个测试的覆盖数据,可以用仿真工具提供的
$merge_coverage_db命令,比多次加载更灵活。 - 运行时可以查看仿真日志里的覆盖组路径,确保加载时指定的路径和日志里的完全一致。
内容的提问来源于stack exchange,提问作者Andrei Solodovnikov
相关产品推荐
相关产品推荐

