virtual void visit(AstPin* nodep, AstNUser*) { // Check to see if any output pins have __en pins and create the __en pins to match AstVarRef* refp = findVarRef(nodep); if (refp && refp->lvalue() && nodep->modVarp()->user1p()) { AstVar* enchildp = (AstVar*)nodep->modVarp()->user1p(); UINFO(9, " Pulling __en var" << enchildp << endl); AstVar* enp = new AstVar(enchildp->fileline(), AstVarType::OUTPUT, enchildp->name()+cvtToStr(m_unique++), enchildp); enp->user2(enchildp->user2()); m_modp->addStmtp(enp); AstPin* pinp = new AstPin(nodep->fileline(), nodep->pinNum(), enp->name(), new AstVarRef(nodep->fileline(), enp, true)); AstVarRef *rp = findVarRef(pinp); rp->replaceWith(new AstVarRef(nodep->fileline(), enp, true)); rp->deleteTree(); rp=NULL; pinp->width(enp->width(),enp->width()); // minwidth==width pinp->modVarp(enchildp); m_cellp->addPinsp(pinp); refp->user1p(enp); refp->varp()->user1p(enp); } // Simplify interconnect in preperation for V3Inst // (This could be a separate visitor, but we're in the neighborhood) V3Inst::pinReconnectSimple(nodep, m_cellp, m_modp); }
void V3LinkLevel::wrapTopCell(AstNetlist* netlistp) { AstNodeModule* newmodp = netlistp->modulesp(); if (!newmodp || !newmodp->isTop()) netlistp->v3fatalSrc("No TOP module found to process"); AstNodeModule* oldmodp = newmodp->nextp()->castNodeModule(); if (!oldmodp) netlistp->v3fatalSrc("No module found to process"); // Add instance AstCell* cellp = new AstCell(newmodp->fileline(), ((v3Global.opt.l2Name()!="") ? v3Global.opt.l2Name() : oldmodp->name()), oldmodp->name(), NULL, NULL, NULL); cellp->modp(oldmodp); newmodp->addStmtp(cellp); // Add pins for (AstNode* subnodep=oldmodp->stmtsp(); subnodep; subnodep = subnodep->nextp()) { if (AstVar* oldvarp=subnodep->castVar()) { UINFO(8,"VARWRAP "<<oldvarp<<endl); if (oldvarp->isIO()) { AstVar* varp = oldvarp->cloneTree(false); newmodp->addStmtp(varp); varp->sigPublic(true); // User needs to be able to get to it... if (oldvarp->isIO()) { oldvarp->primaryIO(true); varp->primaryIO(true); } if (varp->isIO() && v3Global.opt.systemC()) { varp->sc(true); // User can see trace one level down from the wrapper // Avoids packing & unpacking SC signals a second time varp->trace(false); } AstPin* pinp = new AstPin(oldvarp->fileline(),0,oldvarp->name(), new AstVarRef(varp->fileline(), varp, oldvarp->isOutput())); // Skip length and width comp; we know it's a direct assignment pinp->modVarp(oldvarp); cellp->addPinsp(pinp); } } } }
virtual void visit(AstPin* nodep, AstNUser*) { if (m_state == CONVERT_PINS) { if (nodep->modVarp()->user1p()) { // create the input pin AstVarRef* refp = nodep->exprp()->castVarRef(); if (!refp) nodep->v3fatal("Unsupported: Tristate pin not connected to simple net"); AstVar* inp; if (refp->varp()->user1p()) { // this is a tristate inp = (AstVar*) refp->varp()->user1p(); } else { inp = refp->varp(); } AstPin* pinp = new AstPin(nodep->fileline(), nodep->pinNum(), nodep->name() + "__in", new AstVarRef(nodep->fileline(), inp, false)); m_cellp->addPinsp(pinp); // now link it pinp->modVarp((AstVar*) nodep->modVarp()->user1p()); } } }