From 7e54281e263ea707cddde6c7f197c8c7480fbfb1 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Thu, 31 Oct 2013 22:39:26 -0400 Subject: [PATCH] Fix array assignment from const var, bug693. --- Changes | 2 ++ src/V3Ast.h | 3 +++ src/V3AstNodes.h | 16 +++++++++++++--- src/V3Width.cpp | 2 +- test_regress/t/t_cover_toggle.v | 2 ++ test_regress/t/t_var_const.v | 5 +++++ 6 files changed, 26 insertions(+), 4 deletions(-) diff --git a/Changes b/Changes index 2bceb7247..810fe7db9 100644 --- a/Changes +++ b/Changes @@ -23,6 +23,8 @@ indicates the contributor was also the author of the fix; Thanks! **** Fix crash with coverage of structures, bug691. [Eivind Liland] +**** Fix array assignment from const var, bug693. [Jie Xu] + * Verilator 3.853 2013-09-30 diff --git a/src/V3Ast.h b/src/V3Ast.h index 00a176347..4fa392460 100644 --- a/src/V3Ast.h +++ b/src/V3Ast.h @@ -1542,6 +1542,7 @@ public: virtual bool hasDType() const { return true; } virtual AstBasicDType* basicp() const = 0; // (Slow) recurse down to find basic data type virtual AstNodeDType* skipRefp() const = 0; // recurses over typedefs to next non-typeref type + virtual AstNodeDType* skipRefToConstp() const = 0; // recurses over typedefs to next non-typeref-or-const type virtual int widthAlignBytes() const = 0; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) virtual int widthTotalBytes() const = 0; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... virtual bool maybePointedTo() const { return true; } @@ -1591,6 +1592,7 @@ public: // For basicp() we reuse the size to indicate a "fake" basic type of same size virtual AstBasicDType* basicp() const { return findLogicDType(width(),width(),numeric())->castBasicDType(); } virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; } + virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } virtual int widthAlignBytes() const; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) virtual int widthTotalBytes() const; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... // op1 = members @@ -1646,6 +1648,7 @@ public: // METHODS virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; } + virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } virtual int widthTotalBytes() const { return elementsConst() * subDTypep()->widthTotalBytes(); } int msb() const; diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index a93a0bb81..147501b76 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -227,6 +227,7 @@ public: AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); } // op1 = Range of variable virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; } + virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } virtual int widthAlignBytes() const { return dtypep()->widthAlignBytes(); } virtual int widthTotalBytes() const { return dtypep()->widthTotalBytes(); } virtual string name() const { return m_name; } @@ -368,6 +369,7 @@ public: // METHODS virtual AstBasicDType* basicp() const { return (AstBasicDType*)this; } // (Slow) recurse down to find basic data type virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; } + virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } virtual int widthAlignBytes() const; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this) virtual int widthTotalBytes() const; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,... AstBasicDTypeKwd keyword() const { return m.m_keyword; } // Avoid using - use isSomething accessors instead @@ -427,7 +429,8 @@ public: virtual void virtRefDTypep(AstNodeDType* nodep) { refDTypep(nodep); } // METHODS virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type - virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; } + virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); } + virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); } }; @@ -456,6 +459,7 @@ public: virtual void cloneRelink(); virtual AstBasicDType* basicp() const { return NULL; } virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; } + virtual AstNodeDType* skipRefToConstp() const { return (AstNodeDType*)this; } virtual int widthAlignBytes() const { return 1; } virtual int widthTotalBytes() const { return 1; } string cellName() const { return m_cellName; } @@ -506,6 +510,10 @@ public: if (defp()) return defp()->skipRefp(); else { v3fatalSrc("Typedef not linked"); return NULL; } } + virtual AstNodeDType* skipRefToConstp() const { + if (defp()) return defp()->skipRefToConstp(); + else { v3fatalSrc("Typedef not linked"); return NULL; } + } virtual int widthAlignBytes() const { return dtypeSkipRefp()->widthAlignBytes(); } virtual int widthTotalBytes() const { return dtypeSkipRefp()->widthTotalBytes(); } void name(const string& flag) { m_name = flag; } @@ -573,7 +581,8 @@ public: // virtual AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType) 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 dtypeSkipRefp(); } + virtual AstNodeDType* skipRefp() const { return subDTypep()->skipRefp(); } + virtual AstNodeDType* skipRefToConstp() const { return subDTypep()->skipRefToConstp(); } 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 @@ -662,6 +671,7 @@ public: // METHODS 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 subDTypep()->skipRefToConstp(); } virtual int widthAlignBytes() const { return subDTypep()->widthAlignBytes(); } virtual int widthTotalBytes() const { return subDTypep()->widthTotalBytes(); } }; @@ -961,7 +971,7 @@ public: void combineType(AstVarType type); AstNodeDType* getChildDTypep() const { return childDTypep(); } AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable - AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); } // op1 = Range of variable (Note don't need virtual - AstVar isn't a NodeDType) + AstNodeDType* dtypeSkipRefp() const { return subDTypep()->skipRefp(); } AstBasicDType* basicp() const { return subDTypep()->basicp(); } // (Slow) recurse down to find basic data type (Note don't need virtual - AstVar isn't a NodeDType) AstNode* valuep() const { return op3p()->castNode(); } // op3 = Initial value that never changes (static const) void valuep(AstNode* nodep) { setOp3p(nodep); } // It's valuep, not constp, as may be more complicated than an AstConst diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 6fe52453b..d5e49de4b 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -852,7 +852,7 @@ private: || nodep->dtypeSkipRefp()->castNodeClassDType())) { nodep->v3error("Unsupported: Inputs and outputs must be simple data types"); } - if (nodep->dtypeSkipRefp()->castConstDType()) { + if (nodep->dtypep()->skipRefToConstp()->castConstDType()) { nodep->isConst(true); } // Parameters if implicit untyped inherit from what they are assigned to diff --git a/test_regress/t/t_cover_toggle.v b/test_regress/t/t_cover_toggle.v index fab11247a..8dce8e3c8 100644 --- a/test_regress/t/t_cover_toggle.v +++ b/test_regress/t/t_cover_toggle.v @@ -22,6 +22,8 @@ module t (/*AUTOARG*/ str_t stoggle; initial stoggle='0; + const reg aconst = '0; + reg [1:0][1:0] ptoggle; initial ptoggle=0; integer cyc; initial cyc=1; diff --git a/test_regress/t/t_var_const.v b/test_regress/t/t_var_const.v index 6a3808445..2eebf5b49 100644 --- a/test_regress/t/t_var_const.v +++ b/test_regress/t/t_var_const.v @@ -12,8 +12,13 @@ module t (/*AUTOARG*/ const logic [2:0] five = 3'd5; + const logic unsigned [31:0] var_const = 22; + logic [7:0] res_const; + assign res_const = var_const[7:0]; // bug693 + always @ (posedge clk) begin if (five !== 3'd5) $stop; + if (res_const !== 8'd22) $stop; $write("*-* All Finished *-*\n"); $finish; end