Fix width extension of operands of `inside` operator (#5685)

This commit is contained in:
Ryszard Rozak 2024-12-19 15:51:51 +01:00 committed by GitHub
parent 29fb82d3b7
commit c093b24342
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 49 additions and 6 deletions

View File

@ -2670,33 +2670,37 @@ class WidthVisitor final : public VNVisitor {
}
AstBasicDType* dtype = VN_CAST(nodep->exprp()->dtypep(), BasicDType);
AstNodeDType* subDTypep = nullptr;
AstNodeDType* expDTypep = nullptr;
if (dtype && dtype->isString()) {
nodep->dtypeSetString();
subDTypep = nodep->findStringDType();
expDTypep = nodep->findStringDType();
} else if (dtype && dtype->isDouble()) {
nodep->dtypeSetDouble();
subDTypep = nodep->findDoubleDType();
expDTypep = nodep->findDoubleDType();
} else {
// Take width as maximum across all items
int width = nodep->exprp()->width();
int mwidth = nodep->exprp()->widthMin();
bool isFourstate = nodep->exprp()->dtypep()->isFourstate();
for (const AstNode* itemp = nodep->itemsp(); itemp; itemp = itemp->nextp()) {
width = std::max(width, itemp->width());
mwidth = std::max(mwidth, itemp->widthMin());
isFourstate |= itemp->dtypep()->isFourstate();
}
nodep->dtypeSetBit();
subDTypep = nodep->findLogicDType(width, mwidth, nodep->exprp()->dtypep()->numeric());
const VSigning numeric = nodep->exprp()->dtypep()->numeric();
expDTypep = isFourstate ? nodep->findLogicDType(width, mwidth, numeric)
: nodep->findBitDType(width, mwidth, numeric);
}
iterateCheck(nodep, "Inside expression", nodep->exprp(), CONTEXT_DET, FINAL, subDTypep,
iterateCheck(nodep, "Inside expression", nodep->exprp(), CONTEXT_DET, FINAL, expDTypep,
EXTEND_EXP);
for (AstNode *nextip, *itemp = nodep->itemsp(); itemp; itemp = nextip) {
nextip = itemp->nextp(); // iterate may cause the node to get replaced
// InsideRange will get replaced with Lte&Gte and finalized later
if (!VN_IS(itemp, InsideRange))
iterateCheck(nodep, "Inside Item", itemp, CONTEXT_DET, FINAL, subDTypep,
iterateCheck(nodep, "Inside Item", itemp, CONTEXT_DET, FINAL, expDTypep,
EXTEND_EXP);
}

View File

@ -0,0 +1,18 @@
#!/usr/bin/env python3
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2024 by Wilson Snyder. 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-License-Identifier: LGPL-3.0-only OR Artistic-2.0
import vltest_bootstrap
test.scenarios('simulator')
test.compile(verilator_flags2=["-Wno-WIDTH"])
test.execute()
test.passes()

View File

@ -0,0 +1,21 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2024 by Antmicro.
// SPDX-License-Identifier: CC0-1.0
typedef enum bit [4:0] {V0 = 1} my_enum;
class Cls;
my_enum sp = V0;
endclass
module t (/*AUTOARG*/);
initial begin
Cls c = new;
int i = 0;
if (i inside {c.sp}) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
endmodule