SystemVerilog交叉覆盖率忽略Bin异常:无READ交叉项问题排查
SystemVerilog交叉覆盖率异常问题
问题背景
现有变量定义:
bit [3 : 0] pstrb; write_t pwrite; // WRITE, READ, UNKNOWN secure_t psecure; // SEC, NONSEC, UNKNOWN
需求说明:
- 定义交叉覆盖率,将
pstrb合并为3个bin(对应pstrb_cp覆盖点) - 忽略两类无效交叉情况:
pwrite == READ && pstrb != 0psecure == UNKNOWN || pwrite == UNKNOWN
当前实现代码:
pstrb_cp : coverpoint pstrb { bins pstrb_b[3] = { 0, [1 : 14], 15 }; } apb_req_cross : cross pwrite, pstrb_cp, psecure { ignore_bins invld_rd_strb = binsof(pstrb_cp.pstrb_b) intersect { [1 : 15] } && binsof(pwrite) intersect { READ }; ignore_bins invld_pwrite = binsof(pwrite) intersect { UNKNOWN }; ignore_bins invld_psecure = binsof(psecure) intersect { UNKNOWN }; }
遇到的问题:无法看到任何pwrite == READ的交叉项,即使显式定义感兴趣的bin也无效果。
问题分析与修复方案
问题根源在于invld_rd_strb的bin筛选逻辑错误:原代码试图将pstrb_b这个bin数组直接与数值区间[1:15]做交集,这不符合SystemVerilog覆盖率的语法规则,导致所有pwrite=READ的交叉项都被错误忽略。
修复后的代码
// 先给pstrb的每个bin单独命名,方便交叉覆盖率中精准引用 pstrb_cp : coverpoint pstrb { bins pstrb_0 = {0}; // pstrb全0 bins pstrb_partial = {[1:14]}; // pstrb部分有效 bins pstrb_full = {15}; // pstrb全有效 } apb_req_cross : cross pwrite, pstrb_cp, psecure { // 忽略READ且pstrb非0的情况:只保留READ+pstrb_0的有效组合 ignore_bins invld_rd_strb = binsof(pwrite) intersect {READ} && (binsof(pstrb_cp.pstrb_partial) || binsof(pstrb_cp.pstrb_full)); // 忽略pwrite为UNKNOWN的所有情况 ignore_bins invld_pwrite = binsof(pwrite) intersect {UNKNOWN}; // 忽略psecure为UNKNOWN的所有情况 ignore_bins invld_psecure = binsof(psecure) intersect {UNKNOWN}; }
关键修复点说明
- bin命名优化:将
pstrb_cp的三个bin分别命名,避免使用匿名数组bin,这样在交叉覆盖率中可以精准定位每个bin的范围。 - 修正ignore_bins逻辑:针对
READ的无效情况,明确指定忽略pstrb_partial和pstrb_full这两个bin与READ的交叉组合,确保READ+pstrb_0的有效组合被保留。 - 语法合规性:SystemVerilog中,
binsof引用的是具体的bin实例,不能直接对bin数组进行数值区间交集操作,必须逐个引用具体bin。
内容的提问来源于stack exchange,提问作者mdems
相关产品推荐
相关产品推荐

