diff --git a/src/V3Inline.cpp b/src/V3Inline.cpp index f5937db9d..7a5351179 100644 --- a/src/V3Inline.cpp +++ b/src/V3Inline.cpp @@ -114,6 +114,7 @@ private: // we'll save work, and we can't call pinReconnectSimple in // this loop as it clone()s itself. for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) { + if (!pinp->exprp()) continue; V3Inst::pinReconnectSimple(pinp, nodep, m_modp); } @@ -130,6 +131,7 @@ private: m_modp->addInlinesp(inlinep); // Must be parsed before any AstCells // Create assignments to the pins for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) { + if (!pinp->exprp()) continue; UINFO(6," Pin change from "<modVarp()< ASSIGNW(VARXREF(p),expr) (if sub's input) // or ASSIGNW(expr,VARXREF(p)) (if sub's output) UINFO(4," PIN "<exprp()) return; // No-connect if (debug()>=9) nodep->dumpTree(cout," Pin_oldb: "); if (nodep->modVarp()->isOutOnly() && nodep->exprp()->castConst()) nodep->v3error("Output port is connected to a constant pin, electrical short"); @@ -188,6 +189,7 @@ private: } virtual void visit(AstPin* nodep, AstNUser*) { // Any non-direct pins need reconnection with a part-select + if (!nodep->exprp()) return; // No-connect if (m_cellRangep) { UINFO(4," PIN "<modVarp()->width(); diff --git a/src/V3Link.cpp b/src/V3Link.cpp index 7894c1a7a..608cfa419 100644 --- a/src/V3Link.cpp +++ b/src/V3Link.cpp @@ -656,13 +656,6 @@ private: refp->user5p(nodep); } } - if (!nodep->exprp()) { - // It's an empty pin connection, done with it. - // (We used to not create pins for these, but we'd miss - // warns. Perhaps they should live even further...) - pushDeletep(nodep->unlinkFrBack()); nodep=NULL; - return; - } nodep->iterateChildren(*this); } // Deal with implicit definitions - do before ID_RESOLVE stage as may be referenced above declaration diff --git a/src/V3Param.cpp b/src/V3Param.cpp index 16c6f3dc2..f75edffcc 100644 --- a/src/V3Param.cpp +++ b/src/V3Param.cpp @@ -311,6 +311,7 @@ void ParamVisitor::visit(AstCell* nodep, AstNUser*) { if (debug()>8) nodep->paramsp()->dumpTreeAndNext(cout,"-cellparams:\t"); for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) { if (!pinp) nodep->v3fatalSrc("Non pin under cell params\n"); + if (!pinp->exprp()) continue; // No-connect AstVar* modvarp = pinp->modVarp(); if (!modvarp) { pinp->v3error("Parameter not found in sub-module: Param "<name()<<" of "<prettyName()); @@ -390,7 +391,7 @@ void ParamVisitor::visit(AstCell* nodep, AstNUser*) { // Assign parameters to the constants specified for (AstPin* pinp = nodep->paramsp(); pinp; pinp=pinp->nextp()->castPin()) { AstVar* modvarp = pinp->modVarp(); - if (modvarp) { + if (modvarp && pinp->exprp()) { AstConst* constp = pinp->exprp()->castConst(); // Remove any existing parameter if (modvarp->valuep()) modvarp->valuep()->unlinkFrBack()->deleteTree(); diff --git a/src/V3Tristate.cpp b/src/V3Tristate.cpp index dfe191526..594014581 100644 --- a/src/V3Tristate.cpp +++ b/src/V3Tristate.cpp @@ -475,6 +475,7 @@ class TristateVisitor : public TristateBaseVisitor { // ENABLE: -> (VARREF(trisig__pinen) // SEL(trisig,x) = BUFIF1(enable__temp, trisig__pinen) UINFO(9," "<exprp()) return; // No-connect AstVar* enModVarp = (AstVar*) nodep->modVarp()->user1p(); if (!enModVarp) { // no __en signals on this pin nodep->iterateChildren(*this); diff --git a/src/V3Width.cpp b/src/V3Width.cpp index 0c5cb8c4e..06ecd669e 100644 --- a/src/V3Width.cpp +++ b/src/V3Width.cpp @@ -1097,11 +1097,15 @@ private: if (nodep->modVarp() && nodep->modVarp()->isGParam()) { // Widthing handled as special init() case nodep->iterateChildren(*this,WidthVP(ANYSIZE,0,BOTH).p()); - } else if (!m_paramsOnly){ + } else if (!m_paramsOnly) { if (nodep->modVarp()->width()==0) { // Var hasn't been widthed, so make it so. nodep->modVarp()->iterate(*this); } + if (!nodep->exprp()) { // No-connect + nodep->widthSignedFrom(nodep->modVarp()); + return; + } // Very much like like an assignment, but which side is LH/RHS // depends on pin being a in/output/inout. nodep->exprp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,PRELIM).p());