Support pattern assignments with data type labels, bug618.

This commit is contained in:
Wilson Snyder 2013-02-13 20:52:38 -05:00
parent 49dbfd2131
commit 4386077e2d
6 changed files with 19 additions and 8 deletions

View File

@ -5,9 +5,7 @@ indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.846-devel * Verilator 3.846-devel
**** Support pattern assignments to const variables, bug616. [Ed Lander] **** Support pattern assignment features, bug616, bug617, bug618. [Ed Lander]
**** Support pattern assignments in function calls, bug617. [Ed Lander]
**** Fix DETECTARRAY on packed structures, bug610. [Jeremy Bennett] **** Fix DETECTARRAY on packed structures, bug610. [Jeremy Bennett]

View File

@ -3999,7 +3999,7 @@ struct AstPattern : public AstNodeMath {
// Parents: AstNodeAssign, AstPattern, ... // Parents: AstNodeAssign, AstPattern, ...
// Children: expression, AstPattern, AstPatReplicate // Children: expression, AstPattern, AstPatReplicate
AstPattern(FileLine* fl, AstNode* itemsp) : AstNodeMath(fl) { AstPattern(FileLine* fl, AstNode* itemsp) : AstNodeMath(fl) {
addNOp1p(itemsp); addNOp2p(itemsp);
} }
ASTNODE_NODE_FUNCS(Pattern, PATTERN) ASTNODE_NODE_FUNCS(Pattern, PATTERN)
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
@ -4008,7 +4008,11 @@ struct AstPattern : public AstNodeMath {
virtual string emitSimpleOperator() { V3ERROR_NA; return "";} virtual string emitSimpleOperator() { V3ERROR_NA; return "";}
virtual bool cleanOut() {V3ERROR_NA; return "";} virtual bool cleanOut() {V3ERROR_NA; return "";}
virtual int instrCount() const { return widthInstrs(); } 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 { struct AstPatMember : public AstNodeMath {
// Verilog '{a} or '{a{b}} // Verilog '{a} or '{a{b}}

View File

@ -77,6 +77,7 @@ struct V3ParseBisonYYSType {
AstPackageRef* packagerefp; AstPackageRef* packagerefp;
AstParseRef* parserefp; AstParseRef* parserefp;
AstPatMember* patmemberp; AstPatMember* patmemberp;
AstPattern* patternp;
AstPin* pinp; AstPin* pinp;
AstRange* rangep; AstRange* rangep;
AstSenTree* sentreep; AstSenTree* sentreep;

View File

@ -1130,7 +1130,11 @@ private:
virtual void visit(AstPattern* nodep, AstNUser* vup) { virtual void visit(AstPattern* nodep, AstNUser* vup) {
if (nodep->didWidthAndSet()) return; if (nodep->didWidthAndSet()) return;
UINFO(9,"PATTERN "<<nodep<<endl); UINFO(9,"PATTERN "<<nodep<<endl);
AstNodeDType* vdtypep = vup->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: "<<nodep->backp()->prettyTypeName()); if (!vdtypep) nodep->v3error("Unsupported/Illegal: Assignment pattern member not underneath a supported construct: "<<nodep->backp()->prettyTypeName());
{ {
vdtypep = vdtypep->skipRefp(); vdtypep = vdtypep->skipRefp();

View File

@ -2313,7 +2313,7 @@ patternKey<nodep>: // IEEE: merge structure_pattern_key, array_pattern_key, ass
| yaID__ETC { $$ = new AstText($<fl>1,*$1); } | yaID__ETC { $$ = new AstText($<fl>1,*$1); }
; ;
assignment_pattern<nodep>: // ==IEEE: assignment_pattern assignment_pattern<patternp>: // ==IEEE: assignment_pattern
// This doesn't match the text of the spec. I think a : is missing, or example code needed // This doesn't match the text of the spec. I think a : is missing, or example code needed
// yP_TICKBRA constExpr exprList '}' { $$="'{"+$2+" "+$3"}"; } // yP_TICKBRA constExpr exprList '}' { $$="'{"+$2+" "+$3"}"; }
// // "'{ const_expression }" is same as patternList with one entry // // "'{ const_expression }" is same as patternList with one entry
@ -2875,7 +2875,7 @@ exprOkLvalue<nodep>: // expression that's also OK to use as a variable_lvalue
// // IEEE: [ assignment_pattern_expression_type ] == [ ps_type_id /ps_paremeter_id/data_type] // // IEEE: [ assignment_pattern_expression_type ] == [ ps_type_id /ps_paremeter_id/data_type]
// // We allow more here than the spec requires // // We allow more here than the spec requires
//UNSUP ~l~exprScope assignment_pattern { UNSUP } //UNSUP ~l~exprScope assignment_pattern { UNSUP }
//UNSUP data_type assignment_pattern { UNSUP } | data_type assignment_pattern { $$ = $2; $2->childDTypep($1); }
| assignment_pattern { $$ = $1; } | assignment_pattern { $$ = $1; }
// //
//UNSUP streaming_concatenation { UNSUP } //UNSUP streaming_concatenation { UNSUP }

View File

@ -41,6 +41,9 @@ module t;
const b4_t b4_const_a = '{1'b1, 1'b0, 1'b0, 1'b1}; 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; wire b4_t b4_wire;
assign b4_wire = '{1'b1, 1'b0, 1'b1, 1'b0}; assign b4_wire = '{1'b1, 1'b0, 1'b1, 1'b0};
@ -100,6 +103,7 @@ module t;
end end
if (b4_const_a != 4'b1001) $stop; if (b4_const_a != 4'b1001) $stop;
if (b4_const_b != 4'b1001) $stop;
if (b4_wire != 4'b1010) $stop; if (b4_wire != 4'b1010) $stop;
if (pat(4'b1100, 4'b1100)) $stop; if (pat(4'b1100, 4'b1100)) $stop;
if (pat('{1'b1, 1'b0, 1'b1, 1'b1}, 4'b1011)) $stop; if (pat('{1'b1, 1'b0, 1'b1, 1'b1}, 4'b1011)) $stop;