From b71b9ccb57e69bf83a83f51199325d9d1588be1d Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 24 Dec 2014 19:27:46 -0500 Subject: [PATCH] Fix member select error broke in 3.868, bug867. --- Changes | 2 ++ src/V3AstNodes.h | 4 ++-- src/V3Width.cpp | 7 +++++-- src/V3WidthCommit.h | 2 +- test_regress/t/t_bitsel_struct3.v | 30 +++++++++++++++++++++++------- 5 files changed, 33 insertions(+), 12 deletions(-) diff --git a/Changes b/Changes index 332753d5c..4727bfad1 100644 --- a/Changes +++ b/Changes @@ -9,6 +9,8 @@ indicates the contributor was also the author of the fix; Thanks! **** Support cast operator with expression size, bug865. [Iztok Jeras] +**** Fix member select error broke in 3.868, bug867. [Iztok Jeras] + * Verilator 3.868 2014-12-20 diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index b6761847a..e734f2d3e 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -434,7 +434,7 @@ public: virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); } virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } - virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; } + virtual AstNodeDType* skipRefToEnump() const { return subDTypep()->skipRefToEnump(); } virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); } }; @@ -594,7 +594,7 @@ public: AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); } // op1 = Range of variable (Note don't need virtual - AstVar isn't a NodeDType) virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); } virtual AstNodeDType* skipRefToConstp() const { return subDTypep()->skipRefToConstp(); } - virtual AstNodeDType* skipRefToEnump() const { return (AstNodeDType*)this; } + virtual AstNodeDType* skipRefToEnump() const { return subDTypep()->skipRefToEnump(); } virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); } // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... // METHODS diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 3cba1036f..c18ae61a2 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1326,8 +1326,9 @@ private: } virtual void visit(AstMemberSel* nodep, AstNUser* vup) { UINFO(5," MEMBERSEL "<=9) nodep->dumpTree("-ms-in-"); + if (debug()>=9) nodep->dumpTree("-mbs-in: "); nodep->iterateChildren(*this,WidthVP(SELF,BOTH).p()); + if (debug()>=9) nodep->dumpTree("-mbs-ic: "); // Find the fromp dtype - should be a class AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefToEnump(); UINFO(9," from dt "<dtypep(memberp); UINFO(9," MEMBERSEL(attr) -> "< "<dtypep()<fileline(), nodep->fromp()->unlinkFrBack(), memberp->lsb(), memberp->width()); newp->dtypep(memberp->skipRefp()); // Must skip over the member to find the union; as the member may disappear later newp->didWidth(true); // Don't replace dtype with basic type UINFO(9," MEMBERSEL -> "< "<dtypep()<replaceWith(newp); pushDeletep(nodep); nodep=NULL; // Should be able to treat it as a normal-ish nodesel - maybe. The lhsp() will be strange until this stage; create the number here? @@ -1375,7 +1378,7 @@ private: virtual void visit(AstMethodSel* nodep, AstNUser* vup) { UINFO(5," METHODSEL "<=9) nodep->dumpTree("-ms-in-"); + if (debug()>=9) nodep->dumpTree("-mts-in: "); // Should check types the method requires, but at present we don't do much nodep->fromp()->accept(*this,WidthVP(SELF,BOTH).p()); for (AstArg* argp = nodep->pinsp()->castArg(); argp; argp = argp->nextp()->castArg()) { diff --git a/src/V3WidthCommit.h b/src/V3WidthCommit.h index e2deb28fe..303196d03 100644 --- a/src/V3WidthCommit.h +++ b/src/V3WidthCommit.h @@ -74,7 +74,7 @@ public: static AstConst* newIfConstCommitSize (AstConst* nodep) { if (((nodep->dtypep()->width() != nodep->num().width()) || !nodep->num().sized()) - && !nodep->num().isString()) { // Need to force the number rrom unsized to sized + && !nodep->num().isString()) { // Need to force the number from unsized to sized V3Number num (nodep->fileline(), nodep->dtypep()->width()); num.opAssign(nodep->num()); num.isSigned(nodep->isSigned()); diff --git a/test_regress/t/t_bitsel_struct3.v b/test_regress/t/t_bitsel_struct3.v index 1c10278e8..444b29da5 100644 --- a/test_regress/t/t_bitsel_struct3.v +++ b/test_regress/t/t_bitsel_struct3.v @@ -8,6 +8,8 @@ // This file ONLY is placed into the Public Domain, for any use, without // warranty, 2013 by Jie Xu. +`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0); + module t(/*AUTOARG*/ // Inputs clk @@ -25,18 +27,32 @@ module t(/*AUTOARG*/ reg [7:0] c; reg [7:0] d; + union packed { + logic [31:0] [7:0] idx; + struct packed { + logic [15:0] z, y, x; + logic [25:0] [7:0] r; + } nam; + } gpr; + + reg [14:0] gpr_a; + initial begin b = {16'h8765,16'h4321}; a = b[19:12]; // This works c = b[8+:8]; // This fails d = b[11-:8]; // This fails - if ((a == 8'h54) && (c == 8'h43) && (d == 8'h32)) begin - $write("*-* All Finished *-*\n"); - $finish; - end - else begin - $stop; - end + `checkh(a, 8'h54); + `checkh(c, 8'h43); + `checkh(d, 8'h32); + + gpr = 256'h12346789_abcdef12_3456789a_bcdef123_456789ab_cdef1234_56789abc_def12345; + `checkh (gpr[255:255-14], 15'h091a); + gpr_a = gpr.nam.z[15:1]; + `checkh (gpr_a, 15'h091a); + + $write("*-* All Finished *-*\n"); + $finish; end endmodule