diff --git a/Changes b/Changes index aae3e08e5..e4594ab08 100644 --- a/Changes +++ b/Changes @@ -16,7 +16,7 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix expansion of back-slashed escaped macros, bug441. [Alberto Del Rio] -**** Fix inheriting real type across untyped parameters. +**** Fix inheriting real and signed type across untyped parameters. **** Fix core dump with over 100 deep UNOPTFLAT, bug432. [Joe Eiler] diff --git a/src/V3Ast.h b/src/V3Ast.h index 3454d279f..29e8aa047 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -335,7 +335,7 @@ public: enum AstSignedState { // This can't be in the fancy class as the lexer union will get upset - signedst_NOP=0, signedst_SIGNED=1, signedst_UNSIGNED=2 + signedst_NOSIGNED=0, signedst_UNSIGNED=1, signedst_SIGNED=2 }; //###################################################################### diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 01867533c..d88fbc2b0 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -248,19 +248,20 @@ struct AstBasicDType : public AstNodeDType { private: AstBasicDTypeKwd m_keyword; // What keyword created it bool m_implicit; // Implicitly declared + bool m_nosigned; // Implicit without sign int m_msb; // MSB when no range attached public: - AstBasicDType(FileLine* fl, AstBasicDTypeKwd kwd, AstSignedState signst=signedst_NOP) + AstBasicDType(FileLine* fl, AstBasicDTypeKwd kwd, AstSignedState signst=signedst_NOSIGNED) : AstNodeDType(fl) { init(kwd, signst, 0, NULL); } AstBasicDType(FileLine* fl, AstLogicPacked, int wantwidth) : AstNodeDType(fl) { - init(AstBasicDTypeKwd::LOGIC, signedst_NOP, wantwidth, NULL); + init(AstBasicDTypeKwd::LOGIC, signedst_NOSIGNED, wantwidth, NULL); } AstBasicDType(FileLine* fl, AstBitPacked, int wantwidth) : AstNodeDType(fl) { - init(AstBasicDTypeKwd::BIT, signedst_NOP, wantwidth, NULL); + init(AstBasicDTypeKwd::BIT, signedst_NOSIGNED, wantwidth, NULL); } // See also addRange in verilog.y private: @@ -269,11 +270,15 @@ private: m_msb = 0; // Implicitness: // "parameter X" is implicit and sized from initial value, "parameter reg x" not m_implicit = false; + m_nosigned = false; if (keyword()==AstBasicDTypeKwd::LOGIC_IMPLICIT) { if (!rangep && !wantwidth) m_implicit = true; // Also cleared if range added later m_keyword = AstBasicDTypeKwd::LOGIC; } - if (signst == signedst_NOP && keyword().isSigned()) signst = signedst_SIGNED; + if (signst == signedst_NOSIGNED) { + if (keyword().isSigned()) signst = signedst_SIGNED; + else m_nosigned = true; + } if (keyword().isDouble()) dtypeChgDouble(); else setSignedState(signst); if (!rangep && wantwidth) { // Constant width @@ -321,6 +326,7 @@ public: bool littleEndian() const { return (rangep() && rangep()->littleEndian()); } bool implicit() const { return m_implicit; } void implicit(bool flag) { m_implicit = flag; } + bool nosigned() const { return m_nosigned; } void cvtRangeConst() {} // Convert to smaller represenation - disabled }; diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 258693d59..26a6f8d7e 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -709,7 +709,8 @@ private: nodep->valuep()->iterateAndNext(*this,WidthVP(width,0,FINAL).p()); } else { nodep->valuep()->iterateAndNext(*this,WidthVP(width,0,FINAL).p()); - rs = nodep->numeric(); + if (bdtypep->nosigned()) rs = nodep->valuep()->numeric(); + else rs = nodep->numeric(); if (nodep->valuep()->widthSized()) { width = nodep->valuep()->width(); } else { diff --git a/src/verilog.y b/src/verilog.y index f39ae088f..6344bbe6c 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -1093,7 +1093,7 @@ non_integer_type: // ==IEEE: non_integer_type ; signingE: // IEEE: signing - plus empty - /*empty*/ { $$ = signedst_NOP; } + /*empty*/ { $$ = signedst_NOSIGNED; } | signing { $$ = $1; } ; diff --git a/test_regress/t/t_param_value.v b/test_regress/t/t_param_value.v index b7950b703..a3ffaf618 100644 --- a/test_regress/t/t_param_value.v +++ b/test_regress/t/t_param_value.v @@ -23,10 +23,8 @@ module t (/*AUTOARG*/); localparam A2_REAL = REAL; `ASSERT(A2_REAL == 1.234); -`ifdef VERILATOR_BROKEN localparam A3_SIGNED = SIGNED; `ASSERT($bits(A3_SIGNED)==64 && A3_SIGNED < 0); -`endif localparam A4_EXPR = (2'b01 + 2'b10); `ASSERT($bits(A4_EXPR)==2 && A4_EXPR==2'b11);