Fix coredump after huge enum warning.

This commit is contained in:
Wilson Snyder 2021-12-10 23:08:03 -05:00
parent 694cf371f9
commit 748fa4cb80
4 changed files with 74 additions and 7 deletions

View File

@ -216,6 +216,8 @@ private:
std::map<const AstNodeDType*, AstQueueDType*> std::map<const AstNodeDType*, AstQueueDType*>
m_queueDTypeIndexed; // Queues with given index type m_queueDTypeIndexed; // Queues with given index type
static constexpr int ENUM_LOOKUP_BITS = 16; // Maximum # bits to make enum lookup table
// ENUMS // ENUMS
enum ExtendRule : uint8_t { enum ExtendRule : uint8_t {
EXTEND_EXP, // Extend if expect sign and node signed, e.g. node=y in ADD(x,y), "x + y" EXTEND_EXP, // Extend if expect sign and node signed, e.g. node=y in ADD(x,y), "x + y"
@ -5910,10 +5912,10 @@ private:
UASSERT_OBJ(vconstp, errNodep, "Enum item without constified value"); UASSERT_OBJ(vconstp, errNodep, "Enum item without constified value");
if (vconstp->toUQuad() >= maxval) maxval = vconstp->toUQuad(); if (vconstp->toUQuad() >= maxval) maxval = vconstp->toUQuad();
} }
if (adtypep->itemsp()->width() > 64 || maxval >= (1 << 16)) { if (adtypep->itemsp()->width() > 64 || maxval >= (1 << ENUM_LOOKUP_BITS)) {
errNodep->v3warn(E_UNSUPPORTED, errNodep->v3warn(E_UNSUPPORTED,
"Unsupported: enum next/prev method on enum with > 10 bits"); "Unsupported: enum next/prev method on enum with > 10 bits");
return 0; return ENUM_LOOKUP_BITS;
} }
return maxval; return maxval;
} }
@ -5962,9 +5964,7 @@ private:
// Find valid values and populate // Find valid values and populate
UASSERT_OBJ(nodep->itemsp(), nodep, "enum without items"); UASSERT_OBJ(nodep->itemsp(), nodep, "enum without items");
std::vector<AstNode*> values; std::map<vluint64_t, AstNode*> values;
values.resize(msbdim + 1);
for (unsigned i = 0; i < (msbdim + 1); ++i) values[i] = nullptr;
{ {
AstEnumItem* const firstp = nodep->itemsp(); AstEnumItem* const firstp = nodep->itemsp();
const AstEnumItem* prevp = firstp; // Prev must start with last item const AstEnumItem* prevp = firstp; // Prev must start with last item
@ -5973,7 +5973,7 @@ private:
AstEnumItem* const nextp = VN_AS(itemp->nextp(), EnumItem); AstEnumItem* const nextp = VN_AS(itemp->nextp(), EnumItem);
const AstConst* const vconstp = VN_AS(itemp->valuep(), Const); const AstConst* const vconstp = VN_AS(itemp->valuep(), Const);
UASSERT_OBJ(vconstp, nodep, "Enum item without constified value"); UASSERT_OBJ(vconstp, nodep, "Enum item without constified value");
const uint32_t i = vconstp->toUInt(); const vluint64_t i = vconstp->toUQuad();
if (attrType == AstAttrType::ENUM_NAME) { if (attrType == AstAttrType::ENUM_NAME) {
values[i] = new AstConst(nodep->fileline(), AstConst::String(), itemp->name()); values[i] = new AstConst(nodep->fileline(), AstConst::String(), itemp->name());
} else if (attrType == AstAttrType::ENUM_NEXT) { } else if (attrType == AstAttrType::ENUM_NEXT) {
@ -5990,7 +5990,7 @@ private:
} }
} }
// Add all specified values to table // Add all specified values to table
for (unsigned i = 0; i < (msbdim + 1); ++i) { for (vluint64_t i = 0; i < (msbdim + 1); ++i) {
if (values[i]) initp->addIndexValuep(i, values[i]); if (values[i]) initp->addIndexValuep(i, values[i]);
} }
userIterate(varp, nullptr); // May have already done $unit so must do this var userIterate(varp, nullptr); // May have already done $unit so must do this var

View File

@ -0,0 +1,9 @@
%Error: t/t_enum_huge_methods_bad.v:15:11: Value too wide for 64-bits expected in this context 160'h12344567abcd12344567abcd
15 | ELARGE = 160'h1234_4567_abcd_1234_4567_abcd
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
%Error-UNSUPPORTED: t/t_enum_huge_methods_bad.v:30:14: Unsupported: enum next/prev method on enum with > 10 bits
: ... In instance t
30 | $display(e.name);
| ^~~~
... For error description see https://verilator.org/warn/UNSUPPORTED?v=latest
%Error: Exiting due to

View File

@ -0,0 +1,19 @@
#!/usr/bin/env perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2008 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
scenarios(vlt => 1);
lint(
fails => 1,
expect_filename => $Self->{golden_filename},
);
ok(1);
1;

View File

@ -0,0 +1,39 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed under the Creative Commons Public Domain, for
// any use, without warranty, 2014 by Wilson Snyder.
// SPDX-License-Identifier: CC0-1.0
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
typedef enum logic [159:0] {
E01 = 160'h1,
ELARGE = 160'h1234_4567_abcd_1234_4567_abcd
} my_t;
my_t e;
int cyc;
// Check runtime
always @ (posedge clk) begin
cyc <= cyc + 1;
if (cyc==0) begin
// Setup
e <= E01;
end
else if (cyc==1) begin
$display(e.name);
e <= ELARGE;
end
else if (cyc==99) begin
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule