mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
This commit is contained in:
+20
-10
@@ -2115,39 +2115,49 @@ class WidthVisitor final : public VNVisitor {
|
||||
// with a context so a bit/part-select (AstSel) is sized here; otherwise it would
|
||||
// reach assertAtExpr() with m_vup==null and fail as an internal error.
|
||||
userIterateAndNext(nodep->exprp(), WidthVP{SELF, BOTH}.p());
|
||||
userIterateAndNext(nodep->binsp(), nullptr);
|
||||
// Bin values compare against the coverpoint expression
|
||||
userIterateAndNext(nodep->binsp(), WidthVP{nodep->exprp()->dtypep(), BOTH}.p());
|
||||
if (nodep->iffp()) iterateCheckBool(nodep, "iff condition", nodep->iffp(), BOTH);
|
||||
userIterateAndNext(nodep->optionsp(), nullptr);
|
||||
}
|
||||
void widthCovergroupRanges(AstNode* rangesp) {
|
||||
void widthCovergroupRanges(AstNode* rangesp, int fillWidth) {
|
||||
// Bin range/value entries are self-determined expressions (IEEE 1800-2023
|
||||
// 19.5). Width each plain single-value entry self-determined so a referenced
|
||||
// parameter acquires a dtype, then constify so the reference folds to the AstConst
|
||||
// value that V3Covergroup requires. AstInsideRange entries fold their own bounds in
|
||||
// visit(AstInsideRange).
|
||||
// '0/'1 entries then fill to fillWidth, the coverpoint width (IEEE 1800-2023 19.5.7).
|
||||
const auto fill = [&](AstNode* nodep) {
|
||||
if (!fillWidth) return;
|
||||
AstNodeExpr* exprp = VN_AS(nodep, NodeExpr);
|
||||
fixAutoExtend(exprp /*ref*/, fillWidth);
|
||||
};
|
||||
for (AstNode *nextp, *itemp = rangesp; itemp; itemp = nextp) {
|
||||
nextp = itemp->nextp();
|
||||
if (VN_IS(itemp, InsideRange)) {
|
||||
userIterate(itemp, nullptr);
|
||||
if (AstInsideRange* const rangep = VN_CAST(itemp, InsideRange)) {
|
||||
userIterate(rangep, nullptr);
|
||||
fill(rangep->lhsp());
|
||||
fill(rangep->rhsp());
|
||||
} else {
|
||||
itemp = userIterateSubtreeReturnEdits(itemp, WidthVP{SELF, BOTH}.p());
|
||||
V3Const::constifyEdit(itemp);
|
||||
fill(V3Const::constifyEdit(itemp));
|
||||
}
|
||||
}
|
||||
}
|
||||
void visit(AstCoverBinsof* nodep) override {
|
||||
userIterateAndNext(nodep->pointp(), nullptr);
|
||||
widthCovergroupRanges(nodep->rangesp());
|
||||
widthCovergroupRanges(nodep->rangesp(), 0);
|
||||
}
|
||||
void visit(AstCoverBin* nodep) override {
|
||||
widthCovergroupRanges(nodep->rangesp());
|
||||
// No m_vup for a bin directly in a covergroup body (unsupported, already warned)
|
||||
widthCovergroupRanges(nodep->rangesp(), m_vup ? m_vup->dtypep()->width() : 0);
|
||||
if (nodep->iffp()) iterateCheckBool(nodep, "iff condition", nodep->iffp(), BOTH);
|
||||
userIterateAndNext(nodep->arraySizep(), nullptr);
|
||||
userIterateAndNext(nodep->transp(), nullptr);
|
||||
userIterateAndNext(nodep->transp(), m_vup);
|
||||
}
|
||||
void visit(AstCoverTransSet* nodep) override { userIterateAndNext(nodep->itemsp(), nullptr); }
|
||||
void visit(AstCoverTransSet* nodep) override { userIterateAndNext(nodep->itemsp(), m_vup); }
|
||||
void visit(AstCoverTransItem* nodep) override {
|
||||
userIterateAndNext(nodep->valuesp(), WidthVP{SELF, BOTH}.p());
|
||||
widthCovergroupRanges(nodep->valuesp(), m_vup ? m_vup->dtypep()->width() : 0);
|
||||
}
|
||||
void visit(AstPow* nodep) override {
|
||||
// Pow is special, output sign only depends on LHS sign, but
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
cg.cp_b8.hi: 1
|
||||
cg.cp_b8.lo: 1
|
||||
cg.cp_insn.one: 0
|
||||
cg.cp_insn.ones: 1
|
||||
cg.cp_insn.rise: 1
|
||||
cg.cp_insn.zeros: 1
|
||||
cg.cp_mode.m: 2
|
||||
cg.cp_sb.m1: 2
|
||||
cg.cx.m_x_one [cross]: 0
|
||||
cg.cx.m_x_ones [cross]: 1
|
||||
cg.cx.m_x_rise [cross]: 1
|
||||
cg.cx.m_x_zeros [cross]: 1
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env python3
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it
|
||||
# under the terms of either the GNU Lesser General Public License Version 3
|
||||
# or the Perl Artistic License Version 2.0.
|
||||
# SPDX-FileCopyrightText: 2026 Wilson Snyder
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
import vltest_bootstrap
|
||||
|
||||
import coverage_covergroup_common
|
||||
|
||||
test.scenarios('vlt_all')
|
||||
|
||||
coverage_covergroup_common.run(test)
|
||||
@@ -0,0 +1,45 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed under the Creative Commons Public Domain
|
||||
// SPDX-FileCopyrightText: 2026 David Harris
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// Test that '0 and '1 bin values fill to the coverpoint width
|
||||
|
||||
module t;
|
||||
bit [31:0] insn;
|
||||
bit [7:0] b8;
|
||||
bit [1:0] mode;
|
||||
bit signed [7:0] sb;
|
||||
|
||||
covergroup cg;
|
||||
cp_insn: coverpoint insn {
|
||||
bins zeros = {'0};
|
||||
bins ones = {'1};
|
||||
bins one = {1};
|
||||
bins rise = ('0 => '1);
|
||||
}
|
||||
cp_b8: coverpoint b8 {
|
||||
bins hi = {[8'h80 : '1]};
|
||||
bins lo = {['0 : 8'h7f]};
|
||||
}
|
||||
cp_sb: coverpoint sb {bins m1 = {'1};}
|
||||
cp_mode: coverpoint mode {bins m = {3};}
|
||||
cx: cross cp_mode, cp_insn;
|
||||
endgroup
|
||||
|
||||
cg cg_i = new;
|
||||
|
||||
initial begin
|
||||
mode = 3;
|
||||
insn = 32'h0;
|
||||
b8 = 8'h01;
|
||||
sb = -1;
|
||||
cg_i.sample();
|
||||
insn = 32'hffff_ffff;
|
||||
b8 = 8'hff;
|
||||
cg_i.sample();
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
Reference in New Issue
Block a user