Add error on ranges with tristate values (#6534).

This commit is contained in:
Wilson Snyder 2025-10-07 20:36:50 -04:00
parent 9d6f127a4e
commit f979e459e8
5 changed files with 21 additions and 6 deletions

View File

@ -23,6 +23,7 @@ Verilator 5.041 devel
* Add IMPLICITSTATIC also on procedure variables.
* Add FUNCTIMCTL error on function invoking task or time-controlling statements (#6385).
* Add error on `virtual new` (#6486). [Alex Solomatnikov]
* Add error on ranges with tristate values (#6534). [Alex Solomatnikov]
* Deprecate sensitivity list on public_flat_rw attributes (#6443). [Geza Lore]
* Deprecate clocker attribute and --clk option (#6463). [Geza Lore]
* Change default `--expand-limit` to 256 (#3419).

View File

@ -956,8 +956,12 @@ class WidthVisitor final : public VNVisitor {
UINFO(6, "RANGE " << nodep);
V3Const::constifyParamsEdit(nodep->leftp()); // May relink pointed to node
V3Const::constifyParamsEdit(nodep->rightp()); // May relink pointed to node
checkConstantOrReplace(nodep->leftp(), "left side of bit range isn't a constant");
checkConstantOrReplace(nodep->rightp(), "right side of bit range isn't a constant");
checkConstantOrReplace(nodep->leftp(), true,
"left side of bit range isn't a two-state constant"
" (IEEE 1800-2023 6.9.1)");
checkConstantOrReplace(nodep->rightp(), true,
"right side of bit range isn't a two-state constant"
" (IEEE 1800-2023 6.9.1)");
if (m_vup->prelim()) {
// Don't need to iterate because V3Const already constified
const int width = nodep->elementsConst();
@ -2643,8 +2647,9 @@ class WidthVisitor final : public VNVisitor {
if (!nodep->varp()) {
if (m_paramsOnly && VN_IS(nodep, VarXRef)) {
checkConstantOrReplace(
nodep, "Parameter-resolved constants must not use dotted references: "
+ nodep->prettyNameQ());
nodep, false,
"Parameter-resolved constants must not use dotted references: "
+ nodep->prettyNameQ());
VL_DANGLING(nodep);
return;
} else {
@ -8831,13 +8836,15 @@ class WidthVisitor final : public VNVisitor {
nodep->v3fatalSrc("No dtype expected at statement " << nodep->prettyTypeName());
}
}
void checkConstantOrReplace(AstNode* nodep, const string& message) {
void checkConstantOrReplace(AstNode* nodep, bool noFourState, const string& message) {
// See also V3WidthSel::checkConstantOrReplace
// Note can't call V3Const::constifyParam(nodep) here, as constify may change nodep on us!
if (!VN_IS(nodep, Const)) {
AstConst* const constp = VN_CAST(nodep, Const);
if (!constp || (noFourState && constp->num().isFourState())) {
nodep->v3error(message);
nodep->replaceWith(new AstConst{nodep->fileline(), AstConst::Unsized32{}, 1});
VL_DO_DANGLING(pushDeletep(nodep), nodep);
return;
}
}
static AstVarRef* newVarRefDollarUnit(AstVar* nodep) {

View File

@ -9,6 +9,7 @@ module t;
type T = bit
);
static function int get_type();
return 0;
endfunction
endclass

View File

@ -7,4 +7,8 @@
: ... note: In instance 't'
9 | int array2_bad[-1];
| ^
%Error: t/t_lint_range_negative_bad.v:11:10: left side of bit range isn't a two-state constant (IEEE 1800-2023 6.9.1)
: ... note: In instance 't'
11 | logic [X:0] x;
| ^
%Error: Exiting due to

View File

@ -7,6 +7,8 @@
module t;
int array_bad[0]; // <--- Error: Must be positive size
int array2_bad[-1]; // <--- Error: Must be positive size
localparam X = 32'bz;
logic [X:0] x; // <--- Error: X range
sub #(1) u_sub();
endmodule