From eb4a686b1432e2e57282554531aea1a9183ab915 Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 8 Dec 2009 22:12:59 -0500 Subject: [PATCH] Internals: Move __Dpi.h writing to EmitCSyms to save a visitor pass --- src/V3EmitC.cpp | 84 --------------------------------------------- src/V3EmitC.h | 1 - src/V3EmitCBase.h | 16 +++++++++ src/V3EmitCSyms.cpp | 81 +++++++++++++++++++++++++++++++++++-------- src/Verilator.cpp | 1 - 5 files changed, 82 insertions(+), 101 deletions(-) diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 5c985ed16..534911b86 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -82,23 +82,6 @@ public: void emitOpName(AstNode* nodep, const string& format, AstNode* lhsp, AstNode* rhsp, AstNode* thsp); - string cFuncArgs(AstCFunc* nodep) { - // Return argument list for given C function - string args = nodep->argTypes(); - // Might be a user function with argument list. - for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp=stmtp->nextp()) { - if (AstVar* portp = stmtp->castVar()) { - if (portp->isIO() && !portp->isFuncReturn()) { - if (args != "") args+= ", "; - if (nodep->dpiImport()) args += portp->dpiArgType(true,false); - else if (nodep->funcPublic()) args += portp->cPubArgType(true,false); - else args += portp->vlArgType(true,false); - } - } - } - return args; - } - // VISITORS virtual void visit(AstNodeAssign* nodep, AstNUser*) { bool paren = true; bool decind = false; @@ -2131,66 +2114,6 @@ public: } }; -//###################################################################### -// DPI definitions - -class EmitCDpi : EmitCStmts { - // METHODS - void newOutCFile() { - string filename = (v3Global.opt.makeDir()+"/"+ topClassName() - + "__Dpi.h"); - - AstCFile* cfilep = newCFile(filename, false/*slow*/, false/*source*/); - cfilep->support(true); - - if (m_ofp) v3fatalSrc("Previous file not closed"); - m_ofp = new V3OutCFile (filename); - m_ofp->putsHeader(); - } - - void emitTop() { - puts("// DESCR" "IPTION: Verilator output: Prototypes for DPI import and export functions.\n"); - puts("//\n"); - puts("// Verilator includes this file in all generated .cpp files that use DPI functions.\n"); - puts("// Manually include this file where DPI .c import functions are declared to insure\n"); - puts("// the C functions match the expectations of the DPI imports.\n"); - puts("\n"); - puts("#ifdef __cplusplus\n"); - puts("extern \"C\" {\n"); - puts("#endif\n"); - puts("\n"); - } - - void emitBottom() { - puts("\n"); - puts("#ifdef __cplusplus\n"); - puts("}\n"); - puts("#endif\n"); - } - - // VISITORS - virtual void visit(AstNodeModule* nodep, AstNUser*) { - nodep->iterateChildren(*this); - } - virtual void visit(AstCFunc* nodep, AstNUser*) { - if (nodep->dpiImport()) { - puts("// dpi import at "+nodep->fileline()->ascii()+"\n"); - puts("extern "+nodep->rtnTypeVoid()+" "+nodep->name()+" ("+cFuncArgs(nodep)+");\n"); - } - } -public: - EmitCDpi() {} - virtual ~EmitCDpi() {} - void main() { - // Put out the file - newOutCFile(); - emitTop(); - v3Global.rootp()->accept(*this); - emitBottom(); - delete m_ofp; m_ofp=NULL; - } -}; - //###################################################################### // EmitC class functions @@ -2214,10 +2137,3 @@ void V3EmitC::emitcTrace() { { EmitCTrace imp (false); imp.main(); } } } - -void V3EmitC::emitcDpi() { - UINFO(2,__FUNCTION__<<": "<addFilesp(cfilep); return cfilep; } + string cFuncArgs(AstCFunc* nodep) { + // Return argument list for given C function + string args = nodep->argTypes(); + // Might be a user function with argument list. + for (AstNode* stmtp = nodep->argsp(); stmtp; stmtp=stmtp->nextp()) { + if (AstVar* portp = stmtp->castVar()) { + if (portp->isIO() && !portp->isFuncReturn()) { + if (args != "") args+= ", "; + if (nodep->dpiImport()) args += portp->dpiArgType(true,false); + else if (nodep->funcPublic()) args += portp->cPubArgType(true,false); + else args += portp->vlArgType(true,false); + } + } + } + return args; + } // CONSTRUCTORS EmitCBaseVisitor() { diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index 0880adedc..7e25f3f1d 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -44,25 +44,29 @@ class EmitCSyms : EmitCBaseVisitor { // AstNodeModule::user1() -> bool. Set true __Vconfigure called AstUser1InUse m_inuser1; + // TYPES typedef map ScopeNames; - - // STATE - AstNodeModule* m_modp; // Current module typedef pair ScopeModPair; - vector m_scopes; // Every scope by module - ScopeNames m_scopeNames; // Each unique AstScopeName - V3LanguageWords m_words; // Reserved word detector - int m_coverBins; // Coverage bin number - - // METHODS - void emitInt(); - void emitImp(); struct CmpName { inline bool operator () (const ScopeModPair& lhsp, const ScopeModPair& rhsp) const { return lhsp.first->name() < rhsp.first->name(); } }; + // STATE + AstNodeModule* m_modp; // Current module + vector m_scopes; // Every scope by module + vector m_dpis; // DPI functions + ScopeNames m_scopeNames; // Each unique AstScopeName + V3LanguageWords m_words; // Reserved word detector + int m_coverBins; // Coverage bin number + + // METHODS + void emitSymHdr(); + void emitSymImp(); + void emitDpiHdr(); + void emitDpiImp(); + void nameCheck(AstNode* nodep) { // Prevent GCC compile time error; name check all things that reach C++ code if (nodep->name() != "") { @@ -84,8 +88,11 @@ class EmitCSyms : EmitCBaseVisitor { sort(m_scopes.begin(), m_scopes.end(), CmpName()); // Output - emitInt(); - emitImp(); + emitSymHdr(); + emitSymImp(); + if (v3Global.dpi()) { + emitDpiHdr(); + } } virtual void visit(AstNodeModule* nodep, AstNUser*) { nameCheck(nodep); @@ -109,6 +116,12 @@ class EmitCSyms : EmitCBaseVisitor { nodep->binNum(m_coverBins++); } } + virtual void visit(AstCFunc* nodep, AstNUser*) { + nodep->iterateChildren(*this); + if (nodep->dpiImport()) { + m_dpis.push_back(nodep); + } + } // NOPs virtual void visit(AstConst*, AstNUser*) {} // Default @@ -126,7 +139,8 @@ public: } }; -void EmitCSyms::emitInt() { +void EmitCSyms::emitSymHdr() { + UINFO(6,__FUNCTION__<<": "<support(true); @@ -281,6 +296,42 @@ void EmitCSyms::emitImp() { puts("\n"); } +//###################################################################### + +void EmitCSyms::emitDpiHdr() { + UINFO(6,__FUNCTION__<<": "<support(true); + V3OutCFile hf (filename); + m_ofp = &hf; + + m_ofp->putsHeader(); + puts("// DESCR" "IPTION: Verilator output: Prototypes for DPI import and export functions.\n"); + puts("//\n"); + puts("// Verilator includes this file in all generated .cpp files that use DPI functions.\n"); + puts("// Manually include this file where DPI .c import functions are declared to insure\n"); + puts("// the C functions match the expectations of the DPI imports.\n"); + puts("\n"); + puts("#ifdef __cplusplus\n"); + puts("extern \"C\" {\n"); + puts("#endif\n"); + puts("\n"); + + for (vector::iterator it = m_dpis.begin(); it != m_dpis.end(); ++it) { + AstCFunc* nodep = *it; + if (nodep->dpiImport()) { + puts("// dpi import at "+nodep->fileline()->ascii()+"\n"); + puts("extern "+nodep->rtnTypeVoid()+" "+nodep->name()+" ("+cFuncArgs(nodep)+");\n"); + } + } + + puts("\n"); + puts("#ifdef __cplusplus\n"); + puts("}\n"); + puts("#endif\n"); +} + //###################################################################### // EmitC class functions diff --git a/src/Verilator.cpp b/src/Verilator.cpp index 2dcd36a1e..7b2bca4cc 100644 --- a/src/Verilator.cpp +++ b/src/Verilator.cpp @@ -507,7 +507,6 @@ void process () { V3EmitC::emitcInlines(); V3EmitC::emitcSyms(); V3EmitC::emitcTrace(); - V3EmitC::emitcDpi(); } // Unfortunately we have some lint checks in emitc. V3EmitC::emitc();