mirror of
https://github.com/verilator/verilator.git
synced 2025-04-25 01:56:54 +00:00
Internals: Move __Dpi.h writing to EmitCSyms to save a visitor pass
This commit is contained in:
parent
3386466e7a
commit
eb4a686b14
@ -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__<<": "<<endl);
|
||||
if (v3Global.dpi()) {
|
||||
{ EmitCDpi imp; imp.main(); }
|
||||
}
|
||||
}
|
||||
|
@ -35,7 +35,6 @@ public:
|
||||
static void emitcInlines();
|
||||
static void emitcSyms();
|
||||
static void emitcTrace();
|
||||
static void emitcDpi();
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
|
@ -136,6 +136,22 @@ public:
|
||||
v3Global.rootp()->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() {
|
||||
|
@ -44,25 +44,29 @@ class EmitCSyms : EmitCBaseVisitor {
|
||||
// AstNodeModule::user1() -> bool. Set true __Vconfigure called
|
||||
AstUser1InUse m_inuser1;
|
||||
|
||||
// TYPES
|
||||
typedef map<string,AstScopeName*> ScopeNames;
|
||||
|
||||
// STATE
|
||||
AstNodeModule* m_modp; // Current module
|
||||
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 {
|
||||
inline bool operator () (const ScopeModPair& lhsp, const ScopeModPair& rhsp) const {
|
||||
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) {
|
||||
// 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__<<": "<<endl);
|
||||
string filename = v3Global.opt.makeDir()+"/"+symClassName()+".h";
|
||||
newCFile(filename, true/*slow*/, false/*source*/);
|
||||
V3OutCFile hf (filename);
|
||||
@ -199,7 +213,8 @@ void EmitCSyms::emitInt() {
|
||||
puts("#endif /*guard*/\n");
|
||||
}
|
||||
|
||||
void EmitCSyms::emitImp() {
|
||||
void EmitCSyms::emitSymImp() {
|
||||
UINFO(6,__FUNCTION__<<": "<<endl);
|
||||
string filename = v3Global.opt.makeDir()+"/"+symClassName()+".cpp";
|
||||
AstCFile* cfilep = newCFile(filename, true/*slow*/, true/*source*/);
|
||||
cfilep->support(true);
|
||||
@ -281,6 +296,42 @@ void EmitCSyms::emitImp() {
|
||||
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
|
||||
|
||||
|
@ -507,7 +507,6 @@ void process () {
|
||||
V3EmitC::emitcInlines();
|
||||
V3EmitC::emitcSyms();
|
||||
V3EmitC::emitcTrace();
|
||||
V3EmitC::emitcDpi();
|
||||
}
|
||||
// Unfortunately we have some lint checks in emitc.
|
||||
V3EmitC::emitc();
|
||||
|
Loading…
Reference in New Issue
Block a user