Internals: Move __Dpi.h writing to EmitCSyms to save a visitor pass

This commit is contained in:
Wilson Snyder 2009-12-08 22:12:59 -05:00
parent 3386466e7a
commit eb4a686b14
5 changed files with 82 additions and 101 deletions

View File

@ -82,23 +82,6 @@ public:
void emitOpName(AstNode* nodep, const string& format, void emitOpName(AstNode* nodep, const string& format,
AstNode* lhsp, AstNode* rhsp, AstNode* thsp); 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 // VISITORS
virtual void visit(AstNodeAssign* nodep, AstNUser*) { virtual void visit(AstNodeAssign* nodep, AstNUser*) {
bool paren = true; bool decind = false; 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 // EmitC class functions
@ -2214,10 +2137,3 @@ void V3EmitC::emitcTrace() {
{ EmitCTrace imp (false); imp.main(); } { EmitCTrace imp (false); imp.main(); }
} }
} }
void V3EmitC::emitcDpi() {
UINFO(2,__FUNCTION__<<": "<<endl);
if (v3Global.dpi()) {
{ EmitCDpi imp; imp.main(); }
}
}

View File

@ -35,7 +35,6 @@ public:
static void emitcInlines(); static void emitcInlines();
static void emitcSyms(); static void emitcSyms();
static void emitcTrace(); static void emitcTrace();
static void emitcDpi();
}; };
#endif // Guard #endif // Guard

View File

@ -136,6 +136,22 @@ public:
v3Global.rootp()->addFilesp(cfilep); v3Global.rootp()->addFilesp(cfilep);
return 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 // CONSTRUCTORS
EmitCBaseVisitor() { EmitCBaseVisitor() {

View File

@ -44,25 +44,29 @@ class EmitCSyms : EmitCBaseVisitor {
// AstNodeModule::user1() -> bool. Set true __Vconfigure called // AstNodeModule::user1() -> bool. Set true __Vconfigure called
AstUser1InUse m_inuser1; AstUser1InUse m_inuser1;
// TYPES
typedef map<string,AstScopeName*> ScopeNames; typedef map<string,AstScopeName*> ScopeNames;
// STATE
AstNodeModule* m_modp; // Current module
typedef pair<AstScope*,AstNodeModule*> ScopeModPair; typedef pair<AstScope*,AstNodeModule*> ScopeModPair;
vector<ScopeModPair> 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 { struct CmpName {
inline bool operator () (const ScopeModPair& lhsp, const ScopeModPair& rhsp) const { inline bool operator () (const ScopeModPair& lhsp, const ScopeModPair& rhsp) const {
return lhsp.first->name() < rhsp.first->name(); return lhsp.first->name() < rhsp.first->name();
} }
}; };
// STATE
AstNodeModule* m_modp; // Current module
vector<ScopeModPair> m_scopes; // Every scope by module
vector<AstCFunc*> 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) { void nameCheck(AstNode* nodep) {
// Prevent GCC compile time error; name check all things that reach C++ code // Prevent GCC compile time error; name check all things that reach C++ code
if (nodep->name() != "") { if (nodep->name() != "") {
@ -84,8 +88,11 @@ class EmitCSyms : EmitCBaseVisitor {
sort(m_scopes.begin(), m_scopes.end(), CmpName()); sort(m_scopes.begin(), m_scopes.end(), CmpName());
// Output // Output
emitInt(); emitSymHdr();
emitImp(); emitSymImp();
if (v3Global.dpi()) {
emitDpiHdr();
}
} }
virtual void visit(AstNodeModule* nodep, AstNUser*) { virtual void visit(AstNodeModule* nodep, AstNUser*) {
nameCheck(nodep); nameCheck(nodep);
@ -109,6 +116,12 @@ class EmitCSyms : EmitCBaseVisitor {
nodep->binNum(m_coverBins++); nodep->binNum(m_coverBins++);
} }
} }
virtual void visit(AstCFunc* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (nodep->dpiImport()) {
m_dpis.push_back(nodep);
}
}
// NOPs // NOPs
virtual void visit(AstConst*, AstNUser*) {} virtual void visit(AstConst*, AstNUser*) {}
// Default // Default
@ -126,7 +139,8 @@ public:
} }
}; };
void EmitCSyms::emitInt() { void EmitCSyms::emitSymHdr() {
UINFO(6,__FUNCTION__<<": "<<endl);
string filename = v3Global.opt.makeDir()+"/"+symClassName()+".h"; string filename = v3Global.opt.makeDir()+"/"+symClassName()+".h";
newCFile(filename, true/*slow*/, false/*source*/); newCFile(filename, true/*slow*/, false/*source*/);
V3OutCFile hf (filename); V3OutCFile hf (filename);
@ -199,7 +213,8 @@ void EmitCSyms::emitInt() {
puts("#endif /*guard*/\n"); puts("#endif /*guard*/\n");
} }
void EmitCSyms::emitImp() { void EmitCSyms::emitSymImp() {
UINFO(6,__FUNCTION__<<": "<<endl);
string filename = v3Global.opt.makeDir()+"/"+symClassName()+".cpp"; string filename = v3Global.opt.makeDir()+"/"+symClassName()+".cpp";
AstCFile* cfilep = newCFile(filename, true/*slow*/, true/*source*/); AstCFile* cfilep = newCFile(filename, true/*slow*/, true/*source*/);
cfilep->support(true); cfilep->support(true);
@ -281,6 +296,42 @@ void EmitCSyms::emitImp() {
puts("\n"); puts("\n");
} }
//######################################################################
void EmitCSyms::emitDpiHdr() {
UINFO(6,__FUNCTION__<<": "<<endl);
string filename = v3Global.opt.makeDir()+"/"+topClassName()+"__Dpi.h";
AstCFile* cfilep = newCFile(filename, false/*slow*/, false/*source*/);
cfilep->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<AstCFunc*>::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 // EmitC class functions

View File

@ -507,7 +507,6 @@ void process () {
V3EmitC::emitcInlines(); V3EmitC::emitcInlines();
V3EmitC::emitcSyms(); V3EmitC::emitcSyms();
V3EmitC::emitcTrace(); V3EmitC::emitcTrace();
V3EmitC::emitcDpi();
} }
// Unfortunately we have some lint checks in emitc. // Unfortunately we have some lint checks in emitc.
V3EmitC::emitc(); V3EmitC::emitc();