From 5d7ce096c6fdf403f055376005eb24bdadd3f2ae Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 13 Apr 2011 19:34:14 -0400 Subject: [PATCH] Fix error on enum references to other packages, bug339. --- Changes | 8 ++++++-- src/V3AstNodes.h | 7 +++++-- src/V3Dead.cpp | 6 ++++++ src/V3Link.cpp | 2 +- src/V3Width.cpp | 9 ++++++--- test_regress/t/t_enum.v | 11 +++++++++++ 6 files changed, 35 insertions(+), 8 deletions(-) diff --git a/Changes b/Changes index dc8fceb16..7fd23e17a 100644 --- a/Changes +++ b/Changes @@ -3,9 +3,13 @@ Revision history for Verilator The contributors that suggested a given feature are shown in []. [by ...] indicates the contributor was also the author of the fix; Thanks! +* Verilator 3.813**** + +**** Fix error on enum references to other packages, bug339. [Alex Solomatnikov] + * Verilator 3.812 2011/04/06 -*** Add --trace-max-width and --trace-max-array, bug 319. [Alex Solomatnikov] +*** Add --trace-max-width and --trace-max-array, bug319. [Alex Solomatnikov] *** Add --Wno-fatal to turn off abort on warnings. [by Stefan Wallentowitz] @@ -13,7 +17,7 @@ indicates the contributor was also the author of the fix; Thanks! **** Support $bits(data_type), bug327. [Alex Solomatnikov] -**** Support loop unrolling on width mismatches, bug 333. [Joe Eiler] +**** Support loop unrolling on width mismatches, bug333. [Joe Eiler] **** Support simple cast operators, bug335. [Alex Solomatnikov] diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 10909bfd0..b2260f8b6 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -364,9 +364,10 @@ public: struct AstEnumItemRef : public AstNodeMath { private: AstEnumItem* m_itemp; // [AfterLink] Pointer to item + AstPackage* m_packagep; // Package hierarchy public: - AstEnumItemRef(FileLine* fl, AstEnumItem* itemp) - : AstNodeMath(fl), m_itemp(itemp) { + AstEnumItemRef(FileLine* fl, AstEnumItem* itemp, AstPackage* packagep) + : AstNodeMath(fl), m_itemp(itemp), m_packagep(packagep) { if (m_itemp) widthSignedFrom(m_itemp); } ASTNODE_NODE_FUNCS(EnumItemRef, ENUMITEMREF) @@ -381,6 +382,8 @@ public: virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual string emitC() { V3ERROR_NA; return ""; } virtual bool cleanOut() { return true; } + AstPackage* packagep() const { return m_packagep; } + void packagep(AstPackage* nodep) { m_packagep=nodep; } }; struct AstEnumDType : public AstNodeDType { diff --git a/src/V3Dead.cpp b/src/V3Dead.cpp index 28beed7e3..8d7d855e5 100644 --- a/src/V3Dead.cpp +++ b/src/V3Dead.cpp @@ -122,6 +122,12 @@ private: nodep->packagep()->user1Inc(); } } + virtual void visit(AstEnumItemRef* nodep, AstNUser*) { + nodep->iterateChildren(*this); + if (nodep->packagep()) { + nodep->packagep()->user1Inc(); + } + } virtual void visit(AstVarScope* nodep, AstNUser*) { nodep->iterateChildren(*this); m_vscsp.push_back(nodep); diff --git a/src/V3Link.cpp b/src/V3Link.cpp index bc028aa83..6b20c5288 100644 --- a/src/V3Link.cpp +++ b/src/V3Link.cpp @@ -134,7 +134,7 @@ private: nodep->packagep(packageFor(varp)); } else if (AstEnumItem* valuep = foundp->castEnumItem()) { - AstNode* newp = new AstEnumItemRef(nodep->fileline(), valuep); + AstNode* newp = new AstEnumItemRef(nodep->fileline(), valuep, packageFor(valuep)); nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL; return true; // Edited diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 807f394a2..4673b6cb6 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -616,6 +616,7 @@ private: } virtual void visit(AstEnumDType* nodep, AstNUser* vup) { + UINFO(5," ENUMDTYPE "<dtypep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p()); nodep->widthFrom(nodep->dtypep()); // Assign widths @@ -646,6 +647,7 @@ private: } } virtual void visit(AstEnumItem* nodep, AstNUser* vup) { + UINFO(5," ENUMITEM "<c()->width(); int mwidth = vup->c()->widthMin(); nodep->width(width, mwidth); @@ -657,12 +659,13 @@ private: virtual void visit(AstEnumItemRef* nodep, AstNUser* vup) { if (nodep->itemp()->width()==0) { // We need to do the whole enum en-mass - AstNode* enump = nodep; + AstNode* enump = nodep->itemp(); + if (!enump) nodep->v3fatalSrc("EnumItemRef not linked"); for (; enump; enump=enump->backp()) { if (enump->castEnumDType()) break; } - if (!enump) nodep->v3fatalSrc("EnumItem not under a Enum"); - enump->iterate(*this); + if (!enump) nodep->v3fatalSrc("EnumItemRef can't deref back to a Enum"); + enump->iterate(*this,vup); } nodep->widthFrom(nodep->itemp()->valuep()); } diff --git a/test_regress/t/t_enum.v b/test_regress/t/t_enum.v index a6f4c46d2..9548fc9a3 100644 --- a/test_regress/t/t_enum.v +++ b/test_regress/t/t_enum.v @@ -3,6 +3,13 @@ // This file ONLY is placed into the Public Domain, for any use, // without warranty, 2009 by Wilson Snyder. +typedef enum logic [4:0] + { + BIT0 = 5'd0, + BIT1 = 5'd1, + BIT2 = 5'd2 + } three_t; + module t (/*AUTOARG*/); localparam FIVE = 5; @@ -50,6 +57,10 @@ module t (/*AUTOARG*/); if ($bits(sized_based_on_enum) != 8) $stop; if ($bits(three_t) != 3) $stop; + if (FIVE[BIT0] != 1'b1) $stop; + if (FIVE[BIT1] != 1'b0) $stop; + if (FIVE[BIT2] != 1'b1) $stop; + $write("*-* All Finished *-*\n"); $finish; end