diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 3c8a92602..a5162832e 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -632,6 +632,8 @@ void AstVar::dump(ostream& str) { else if (isOutput()) str<<" [O]"; } if (isConst()) str<<" [CONST]"; + if (isPullup()) str<<" [PULLUP]"; + if (isPulldown()) str<<" [PULLDOWN]"; if (isUsedClock()) str<<" [CLK]"; if (isSigPublic()) str<<" [P]"; if (isUsedLoopIdx()) str<<" [LOOP]"; diff --git a/src/V3Inst.cpp b/src/V3Inst.cpp index ef98f2baf..932d3d6af 100644 --- a/src/V3Inst.cpp +++ b/src/V3Inst.cpp @@ -237,7 +237,7 @@ public: //###################################################################### // Inst class functions -AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule* modp, bool forTristate) { +AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModule*, bool forTristate) { // If a pin connection is "simple" leave it as-is // Else create a intermediate wire to perform the interconnect // Return the new assignment, if one was made @@ -269,7 +269,8 @@ AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModu AstNode* pinexprp = pinp->exprp()->unlinkFrBack(); string newvarname = "__Vcellinp__"+cellp->name()+"__"+pinp->name(); AstVar* newvarp = new AstVar (pinVarp->fileline(), AstVarType::MODULETEMP, newvarname, pinVarp); - modp->addStmtp(newvarp); + // Important to add statement next to cell, in case there is a generate with same named cell + cellp->addNextHere(newvarp); if (pinVarp->isInout()) { pinVarp->v3fatalSrc("Unsupported: Inout connections to pins must be direct one-to-one connection (without any expression)"); } else if (pinVarp->isOutput()) { @@ -296,7 +297,7 @@ AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModu pinp->exprp(new AstVarRef (pinexprp->fileline(), newvarp, false)); } pinp->widthSignedFrom(pinp->exprp()); - if (assignp) modp->addStmtp(assignp); + if (assignp) cellp->addNextHere(assignp); //if (1||debug()) { pinp->dumpTree(cout," out:"); } //if (1||debug()) { assignp->dumpTree(cout," aout:"); } } diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index 7caa3efea..60ef533b3 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -591,6 +591,7 @@ class TristateVisitor : public TristateBaseVisitor { // Propagate any pullups/pulldowns upwards if necessary if (refp) { if (AstPull* pullp = (AstPull*) nodep->modVarp()->user3p()) { + UINFO(9, "propagate pull to "<varp()); if (!refp->varp()->user3p()) { refp->varp()->user3p(pullp); } else { @@ -636,6 +637,7 @@ class TristateVisitor : public TristateBaseVisitor { AstNode* newp = new AstPull(nodep->fileline(), new AstVarRef(nodep->fileline(), nodep, true), nodep->isPullup()); + UINFO(9,"New pull "<addStmtp(newp); // We'll iterate on the new AstPull later } @@ -725,6 +727,7 @@ class TristateVisitor : public TristateBaseVisitor { // outvarp->user1p(envarp); outvarp->user3p(invarp->user3p()); + if (invarp->user3p()) UINFO(9, "propagate pull to "<user1p()) { envarp = invarp->user1p()->castNode()->castVar(); // From CASEEQ, foo === 1'bz } @@ -788,6 +791,7 @@ class TristateVisitor : public TristateBaseVisitor { AstPull* pullp = (AstPull*)lhsp->user3p(); if (pullp && pullp->direction() == 1) { pull.setAllBits1(); + UINFO(9,"Has pullup "<1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_tri_gen.v b/test_regress/t/t_tri_gen.v new file mode 100644 index 000000000..ad70726ba --- /dev/null +++ b/test_regress/t/t_tri_gen.v @@ -0,0 +1,43 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2012 by Wilson Snyder. + +module t (/*AUTOARG*/ + // Inputs + clk + ); + input clk; + + tri z0; + tri z1; + + updown #(0) updown0 (.z(z0)); + updown #(1) updown1 (.z(z1)); + + always @ (posedge clk) begin + if (z0 !== 0) $stop; + if (z1 !== 1) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end + +endmodule + +module updown #(parameter UP=0) + (inout z); + generate + if (UP) begin + t_up sub (.z); + end + else begin + t_down sub (.z); + end + endgenerate +endmodule + +module t_up (inout tri1 z); +endmodule + +module t_down (inout tri0 z); +endmodule