Internals: Fix assignment pattern replication. From bug355 branch.

This commit is contained in:
Wilson Snyder 2014-03-30 10:20:12 -04:00
parent 40bceea68a
commit 17b8b660f0
5 changed files with 29 additions and 13 deletions

View File

@ -606,6 +606,7 @@ struct VNumRange {
int lo() const { return m_lo; }
int left() const { return littleEndian()?lo():hi(); } // How to show a declaration
int right() const { return littleEndian()?hi():lo(); }
int leftToRightInc() const { return littleEndian()?1:-1; }
int elements() const { return hi()-lo()+1; }
bool ranged() const { return m_ranged; }
bool littleEndian() const { return m_littleEndian; }

View File

@ -4201,15 +4201,15 @@ private:
bool m_default;
public:
AstPatMember(FileLine* fl, AstNode* lhsp, AstNode* keyp, AstNode* repp) : AstNodeMath(fl) {
setOp1p(lhsp), setNOp2p(keyp), setNOp3p(repp); m_default = false; }
addOp1p(lhsp), setNOp2p(keyp), setNOp3p(repp); m_default = false; }
ASTNODE_NODE_FUNCS(PatMember, PATMEMBER)
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; }
virtual string emitVerilog() { return lhsp()?"%f{%r{%k%l}}":"%l"; }
virtual string emitVerilog() { return lhssp()?"%f{%r{%k%l}}":"%l"; }
virtual string emitC() { V3ERROR_NA; return "";}
virtual string emitSimpleOperator() { V3ERROR_NA; return "";}
virtual bool cleanOut() {V3ERROR_NA; return "";}
virtual int instrCount() const { return widthInstrs()*2; }
AstNode* lhsp() const { return op1p(); } // op1 = expression to assign or another AstPattern
AstNode* lhssp() const { return op1p(); } // op1 = expression to assign or another AstPattern (list if replicated)
AstNode* keyp() const { return op2p(); } // op2 = assignment key (Const, id Text)
AstNode* repp() const { return op3p(); } // op3 = replication count, or NULL for count 1
bool isDefault() const { return m_default; }

View File

@ -1177,8 +1177,8 @@ private:
nodep->dtypep(vdtypep);
UINFO(9," adtypep "<<vdtypep<<endl);
nodep->dtypep(vdtypep);
// Determine replication count, and replicate initial value as widths need to be individually determined
for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) {
// Determine replication count, and replicate initial value as widths need to be individually determined
int times = visitPatMemberRep(patp);
for (int i=1; i<times; i++) {
AstNode* newp = patp->cloneTree(false);
@ -1186,6 +1186,20 @@ private:
// This loop will see the new elements as part of nextp()
}
}
// Convert any PatMember with multiple items to multiple PatMembers
for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) {
if (patp->lhssp()->nextp()) {
// Can't just addNext, as would add to end of all members. So detach, add next and reattach
AstNRelinker relinkHandle;
patp->unlinkFrBack(&relinkHandle);
while (AstNode* movep = patp->lhssp()->nextp()) {
movep->unlinkFrBack(); // Not unlinkFrBackWithNext, just one
AstPatMember* newp = new AstPatMember(patp->fileline(), movep, patp->keyp()->cloneTree(true), NULL);
patp->addNext(newp);
}
relinkHandle.relink(patp);
}
}
AstPatMember* defaultp = NULL;
for (AstPatMember* patp = nodep->itemsp()->castPatMember(); patp; patp = patp->nextp()->castPatMember()) {
if (patp->isDefault()) {
@ -1255,9 +1269,9 @@ private:
patp->dtypep(memp);
patp->accept(*this,WidthVP(memp,BOTH).p());
// Convert to concat for now
if (!newp) newp = patp->lhsp()->unlinkFrBack();
if (!newp) newp = patp->lhssp()->unlinkFrBack();
else {
AstConcat* concatp = new AstConcat(patp->fileline(), newp, patp->lhsp()->unlinkFrBack());
AstConcat* concatp = new AstConcat(patp->fileline(), newp, patp->lhssp()->unlinkFrBack());
newp = concatp;
newp->dtypeSetLogicSized(concatp->lhsp()->width()+concatp->rhsp()->width(),
concatp->lhsp()->width()+concatp->rhsp()->width(),
@ -1277,9 +1291,10 @@ private:
AstNodeDType* vdtypep = vup->c()->dtypep();
if (!vdtypep) nodep->v3fatalSrc("Pattern member type not assigned by AstPattern visitor");
nodep->dtypep(vdtypep);
nodep->lhsp()->dtypeFrom(nodep);
if (nodep->lhssp()->nextp()) nodep->v3fatalSrc("PatMember value should be singular w/replicates removed");
nodep->lhssp()->dtypeFrom(nodep);
nodep->iterateChildren(*this,WidthVP(nodep->dtypep(),BOTH).p());
widthCheck(nodep,"LHS",nodep->lhsp(),nodep->width(),nodep->width());
widthCheck(nodep,"LHS",nodep->lhssp(),nodep->width(),nodep->width());
}
int visitPatMemberRep(AstPatMember* nodep) {
uint32_t times = 1;

View File

@ -30,7 +30,7 @@ module t (/*AUTOARG*/
if (array_simp !== 32'h3210_1234) $stop;
// Doesn't seem to work for unpacked arrays in other simulators
//array_simp <= '{2 { '{4 { 4'd3, 4'd2, 4'd1, 4'd0 }} } };
array_simp = '{2 { '{4 { 4'd3, 4'd2, 4'd1, 4'd0 }} } };
$write("*-* All Finished *-*\n");
$finish;
@ -86,8 +86,8 @@ module t (/*AUTOARG*/
else if (cnt[30:2]== 2) array_bg <= '{default:13};
else if (cnt[30:2]== 3) array_bg <= '{0:4, 1:5, 2:6, 3:7};
else if (cnt[30:2]== 4) array_bg <= '{2:15, default:13};
else if (cnt[30:2]== 5) array_bg <= '{WA { {WB {2'b10}} }};
else if (cnt[30:2]== 6) array_bg <= '{cnt+0, cnt+1, cnt+2, cnt+3};
else if (cnt[30:2]== 5) array_bg <= '{WA { {WB/2 {2'b10}} }};
else if (cnt[30:2]== 6) array_bg <= '{cnt[3:0]+0, cnt[3:0]+1, cnt[3:0]+2, cnt[3:0]+3};
end else if (cnt[1:0]==2'd2) begin
// chack array agains expected value
if (cnt[30:2]== 0) begin if (array_bg !== 16'b0000000000000000) begin $display("%b", array_bg); $stop(); end end
@ -122,7 +122,7 @@ module t (/*AUTOARG*/
else if (cnt[30:2]== 3) array_lt <= '{3:4, 2:5, 1:6, 0:7};
else if (cnt[30:2]== 4) array_lt <= '{1:15, default:13};
else if (cnt[30:2]== 5) array_lt <= '{WA { {WB/2 {2'b10}} }};
else if (cnt[30:2]==10) array_lt <= '{cnt+0, cnt+1, cnt+2, cnt+3};
else if (cnt[30:2]==10) array_lt <= '{cnt[3:0]+0, cnt[3:0]+1, cnt[3:0]+2, cnt[3:0]+3};
end else if (cnt[1:0]==2'd2) begin
// chack array agains expected value
if (cnt[30:2]== 0) begin if (array_lt !== 16'b0000000000000000) begin $display("%b", array_lt); $stop(); end end

View File

@ -25,7 +25,7 @@ module t (/*AUTOARG*/);
array_simp[0][3],array_simp[0][2],array_simp[0][1],array_simp[0][0]} !== 32'h3210_1234) $stop;
// Doesn't seem to work for unpacked arrays in other simulators
//array_simp <= '{2{ '{4{ 4'd3, 4'd2, 4'd1, 4'd0 }} }};
array_simp = '{2 { '{4 { 4'd3, 4'd2, 4'd1, 4'd0 }} } };
$write("*-* All Finished *-*\n");
$finish;