forked from github/verilator
Internals: Fix assignment pattern replication. From bug355 branch.
This commit is contained in:
parent
40bceea68a
commit
17b8b660f0
@ -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; }
|
||||
|
@ -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; }
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user