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
**** 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]

View File

@ -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}}

View File

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

View File

@ -1130,7 +1130,11 @@ private:
virtual void visit(AstPattern* nodep, AstNUser* vup) {
if (nodep->didWidthAndSet()) return;
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());
{
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); }
;
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
// yP_TICKBRA constExpr exprList '}' { $$="'{"+$2+" "+$3"}"; }
// // "'{ 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]
// // 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 }

View File

@ -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;