// -*- mode: C++; c-file-style: "cc-mode" -*- //************************************************************************* // DESCRIPTION: Verilator: Change names for __PVT__'s // // Code available from: http://www.veripool.org/verilator // //************************************************************************* // // Copyright 2003-2016 by Wilson Snyder. This program is free software; you can // redistribute it and/or modify it under the terms of either the GNU // Lesser General Public License Version 3 or the Perl Artistic License // Version 2.0. // // Verilator is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // //************************************************************************* // V3Name's Transformations: // // Cell/Var's // Prepend __PVT__ to variable names //************************************************************************* #include "config_build.h" #include "verilatedos.h" #include #include #include #include #include "V3Global.h" #include "V3Name.h" #include "V3Ast.h" #include "V3LanguageWords.h" //###################################################################### // Name state, as a visitor of each AstNode class NameVisitor : public AstNVisitor { private: // NODE STATE // Cleared on Netlist // AstCell::user1() -> bool. Set true if already processed // AstScope::user1() -> bool. Set true if already processed // AstVar::user1() -> bool. Set true if already processed AstUser1InUse m_inuser1; // STATE AstNodeModule* m_modp; V3LanguageWords m_words; // Reserved word detector // METHODS static int debug() { static int level = -1; if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__); return level; } void rename(AstNode* nodep, bool addPvt) { if (!nodep->user1()) { // Not already done if (addPvt) { string newname = (string)"__PVT__"+nodep->name(); nodep->name(newname); } else { string rsvd = m_words.isKeyword(nodep->name()); if (rsvd != "") { nodep->v3warn(SYMRSVDWORD,"Symbol matches "+rsvd+": '"<prettyName()<<"'"); string newname = (string)"__SYM__"+nodep->name(); nodep->name(newname); } } nodep->user1(1); } } // VISITORS virtual void visit(AstNodeModule* nodep, AstNUser*) { m_modp = nodep; nodep->iterateChildren(*this); m_modp = NULL; } // Add __PVT__ to names of local signals virtual void visit(AstVar* nodep, AstNUser*) { // Don't iterate... Don't need temps for RANGES under the Var. rename(nodep, (!m_modp->isTop() && !nodep->isSigPublic() && !nodep->isFuncLocal() // Isn't exposed, and would mess up dpi import wrappers && !nodep->isTemp())); // Don't bother to rename internal signals } virtual void visit(AstCFunc* nodep, AstNUser*) { if (!nodep->user1()) { nodep->iterateChildren(*this); rename(nodep, false); } } virtual void visit(AstVarRef* nodep, AstNUser*) { if (nodep->varp()) { nodep->varp()->iterate(*this); nodep->name(nodep->varp()->name()); } } virtual void visit(AstCell* nodep, AstNUser*) { if (!nodep->user1()) { rename(nodep, !nodep->modp()->modPublic()); nodep->iterateChildren(*this); } } virtual void visit(AstMemberDType* nodep, AstNUser*) { if (!nodep->user1()) { rename(nodep, false); nodep->iterateChildren(*this); } } virtual void visit(AstMemberSel* nodep, AstNUser*) { if (!nodep->user1()) { rename(nodep, false); nodep->iterateChildren(*this); } } virtual void visit(AstScope* nodep, AstNUser*) { if (!nodep->user1SetOnce()) { if (nodep->aboveScopep()) nodep->aboveScopep()->iterate(*this); if (nodep->aboveCellp()) nodep->aboveCellp()->iterate(*this); // Always recompute name (as many level above scope may have changed) // Same formula as V3Scope nodep->name(nodep->isTop() ? "TOP" : (nodep->aboveScopep()->name()+"."+nodep->aboveCellp()->name())); nodep->iterateChildren(*this); } } //-------------------- virtual void visit(AstNode* nodep, AstNUser*) { nodep->iterateChildren(*this); } public: // CONSTUCTORS explicit NameVisitor(AstNetlist* nodep) { nodep->accept(*this); } virtual ~NameVisitor() {} }; //###################################################################### // Name class functions void V3Name::nameAll(AstNetlist* nodep) { UINFO(2,__FUNCTION__<<": "<= 6); }