From 4386077e2dd149f8df7bd4cba7c16bb33f998d1e Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Wed, 13 Feb 2013 20:52:38 -0500 Subject: [PATCH] Support pattern assignments with data type labels, bug618. --- Changes | 4 +--- src/V3AstNodes.h | 8 ++++++-- src/V3ParseImp.h | 1 + src/V3Width.cpp | 6 +++++- src/verilog.y | 4 ++-- test_regress/t/t_struct_init.v | 4 ++++ 6 files changed, 19 insertions(+), 8 deletions(-) diff --git a/Changes b/Changes index d1f6c3d6a..e50176c41 100644 --- a/Changes +++ b/Changes @@ -5,9 +5,7 @@ indicates the contributor was also the author of the fix; Thanks! * Verilator 3.846-devel -**** Support pattern assignments to const variables, bug616. [Ed Lander] - -**** Support pattern assignments in function calls, bug617. [Ed Lander] +**** Support pattern assignment features, bug616, bug617, bug618. [Ed Lander] **** Fix DETECTARRAY on packed structures, bug610. [Jeremy Bennett] diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 727c29c2d..9f29dc752 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -3999,7 +3999,7 @@ struct AstPattern : public AstNodeMath { // Parents: AstNodeAssign, AstPattern, ... // Children: expression, AstPattern, AstPatReplicate AstPattern(FileLine* fl, AstNode* itemsp) : AstNodeMath(fl) { - addNOp1p(itemsp); + addNOp2p(itemsp); } ASTNODE_NODE_FUNCS(Pattern, PATTERN) virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially @@ -4008,7 +4008,11 @@ struct AstPattern : public AstNodeMath { virtual string emitSimpleOperator() { V3ERROR_NA; return "";} virtual bool cleanOut() {V3ERROR_NA; return "";} virtual int instrCount() const { return widthInstrs(); } - AstNode* itemsp() const { return op1p(); } // op1 = AstPatReplicate, AstPatMember, etc + AstNodeDType* getChildDTypep() const { return childDTypep(); } + AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Type assigning to + void childDTypep(AstNodeDType* nodep) { setOp1p(nodep); } + AstNodeDType* subDTypep() const { return dtypep() ? dtypep() : childDTypep(); } + AstNode* itemsp() const { return op2p(); } // op2 = AstPatReplicate, AstPatMember, etc }; struct AstPatMember : public AstNodeMath { // Verilog '{a} or '{a{b}} diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h index f9f2b818d..fb3f661fb 100644 --- a/src/V3ParseImp.h +++ b/src/V3ParseImp.h @@ -77,6 +77,7 @@ struct V3ParseBisonYYSType { AstPackageRef* packagerefp; AstParseRef* parserefp; AstPatMember* patmemberp; + AstPattern* patternp; AstPin* pinp; AstRange* rangep; AstSenTree* sentreep; diff --git a/src/V3Width.cpp b/src/V3Width.cpp index facab62ee..c2a3a7f57 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1130,7 +1130,11 @@ private: virtual void visit(AstPattern* nodep, AstNUser* vup) { if (nodep->didWidthAndSet()) return; UINFO(9,"PATTERN "<c()->dtypep(); + if (nodep->childDTypep()) nodep->dtypep(moveChildDTypeEdit(nodep)); // data_type '{ pattern } + if (!nodep->dtypep() && vup->c()->dtypep()) { // Get it from parent assignment/pin/etc + nodep->dtypep(vup->c()->dtypep()); + } + AstNodeDType* vdtypep = nodep->dtypep(); if (!vdtypep) nodep->v3error("Unsupported/Illegal: Assignment pattern member not underneath a supported construct: "<backp()->prettyTypeName()); { vdtypep = vdtypep->skipRefp(); diff --git a/src/verilog.y b/src/verilog.y index eff366f11..8bd5dd663 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -2313,7 +2313,7 @@ patternKey: // IEEE: merge structure_pattern_key, array_pattern_key, ass | yaID__ETC { $$ = new AstText($1,*$1); } ; -assignment_pattern: // ==IEEE: assignment_pattern +assignment_pattern: // ==IEEE: assignment_pattern // This doesn't match the text of the spec. I think a : is missing, or example code needed // yP_TICKBRA constExpr exprList '}' { $$="'{"+$2+" "+$3"}"; } // // "'{ const_expression }" is same as patternList with one entry @@ -2875,7 +2875,7 @@ exprOkLvalue: // expression that's also OK to use as a variable_lvalue // // IEEE: [ assignment_pattern_expression_type ] == [ ps_type_id /ps_paremeter_id/data_type] // // We allow more here than the spec requires //UNSUP ~l~exprScope assignment_pattern { UNSUP } - //UNSUP data_type assignment_pattern { UNSUP } + | data_type assignment_pattern { $$ = $2; $2->childDTypep($1); } | assignment_pattern { $$ = $1; } // //UNSUP streaming_concatenation { UNSUP } diff --git a/test_regress/t/t_struct_init.v b/test_regress/t/t_struct_init.v index 66f1132ba..939c91c1d 100644 --- a/test_regress/t/t_struct_init.v +++ b/test_regress/t/t_struct_init.v @@ -41,6 +41,9 @@ module t; const b4_t b4_const_a = '{1'b1, 1'b0, 1'b0, 1'b1}; + // Cast to a pattern - note bits are tagged out of order + const b4_t b4_const_b = b4_t'{ b1 : 1'b0, b0 : 1'b1, b3 : 1'b1, b2 : 1'b0 }; + wire b4_t b4_wire; assign b4_wire = '{1'b1, 1'b0, 1'b1, 1'b0}; @@ -100,6 +103,7 @@ module t; end if (b4_const_a != 4'b1001) $stop; + if (b4_const_b != 4'b1001) $stop; if (b4_wire != 4'b1010) $stop; if (pat(4'b1100, 4'b1100)) $stop; if (pat('{1'b1, 1'b0, 1'b1, 1'b1}, 4'b1011)) $stop;