Reorder structures to always go through symp

git-svn-id: file://localhost/svn/verilator/trunk/verilator@770 77ca24e4-aefa-0310-84f0-b9a241c72d87
This commit is contained in:
Wilson Snyder
2006-08-30 21:07:55 +00:00
parent c78254503c
commit 3909ba1cef
18 changed files with 168 additions and 123 deletions
+3
View File
@@ -42,6 +42,7 @@
#include "V3Global.h"
#include "V3Active.h"
#include "V3Ast.h"
#include "V3EmitCBase.h"
//***** See below for main transformation engine
@@ -231,6 +232,8 @@ private:
}
if (!m_scopeFinalp) {
m_scopeFinalp = new AstCFunc(nodep->fileline(), "_final", m_namer.scopep());
m_scopeFinalp->argTypes(EmitCBaseVisitor::symClassVar());
m_scopeFinalp->addInitsp(new AstCStmt(nodep->fileline()," "+EmitCBaseVisitor::symTopAssign()+"\n"));
m_scopeFinalp->dontCombine(true);
m_scopeFinalp->formCallTree(true);
m_scopeFinalp->slow(true);
+14 -7
View File
@@ -422,7 +422,7 @@ public:
virtual string name() const { return m_name; } // * = Scope name
void name(const string& name) { m_name = name; }
string nameDotless() const;
string nameVlSym() const { return (((string)"VlSym->") + nameDotless()); }
string nameVlSym() const { return (((string)"vlSymsp->") + nameDotless()); }
AstModule* modp() const { return m_modp; }
void addVarp(AstNode* nodep) { addOp1p(nodep); }
AstNode* varsp() const { return op1p()->castNode(); } // op1 = AstVarScope's
@@ -586,7 +586,6 @@ struct AstModule : public AstNode {
private:
string m_name; // Name of the module
string m_origName; // Name of the module, ignoring name() changes, for dot lookup
bool m_globalSyms:1; // References global symbol table
bool m_modPublic:1; // Module has public references
bool m_modTrace:1; // Tracing this module
bool m_inLibrary:1; // From a library, no error if not used, never top level
@@ -596,7 +595,7 @@ private:
public:
AstModule(FileLine* fl, const string& name)
: AstNode (fl)
,m_name(name), m_origName(name), m_globalSyms(false), m_modPublic(false)
,m_name(name), m_origName(name), m_modPublic(false)
,m_modTrace(false), m_inLibrary(false)
,m_level(0), m_varNum(0), m_clkReqVarp(NULL) { }
virtual ~AstModule() {}
@@ -623,8 +622,6 @@ public:
int varNumGetInc() { return ++m_varNum; }
AstVar* clkReqVarp() const { return m_clkReqVarp; }
void clkReqVarp(AstVar* varp) { m_clkReqVarp = varp; }
void globalSyms(bool flag) { m_globalSyms = flag; }
bool globalSyms() const { return m_globalSyms; }
void modPublic(bool flag) { m_modPublic = flag; }
bool modPublic() const { return m_modPublic; }
void modTrace(bool flag) { m_modTrace = flag; }
@@ -2774,6 +2771,7 @@ private:
bool m_slow:1; // Slow routine, called once or just at init time
bool m_funcPublic:1; // From user public task/function
bool m_isStatic:1; // Function is declared static (no this)
bool m_symProlog:1; // Setup symbol table for later instructions
public:
AstCFunc(FileLine* fl, const string& name, AstScope* scopep, const string& rtnType="")
: AstNode(fl) {
@@ -2788,6 +2786,7 @@ public:
m_slow = false;
m_funcPublic = false;
m_isStatic = false;
m_symProlog = false;
}
virtual ~AstCFunc() {}
virtual AstType type() const { return AstType::CFUNC;}
@@ -2795,7 +2794,9 @@ public:
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
virtual string name() const { return m_name; }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return true; }
virtual bool same(AstNode* samep) const { return ((funcType()==samep->castCFunc()->funcType())
&& (rtnTypeVoid()==samep->castCFunc()->rtnTypeVoid())
&& (argTypes()==samep->castCFunc()->argTypes())); }
//
void name(const string& flag) { m_name = flag; }
AstScope* scopep() const { return m_scopep; }
@@ -2819,6 +2820,8 @@ public:
AstCFuncType funcType() const { return m_funcType; }
bool isStatic() const { return m_isStatic; }
void isStatic(bool flag) { m_isStatic = flag; }
bool symProlog() const { return m_symProlog; }
void symProlog(bool flag) { m_symProlog = flag; }
//
// If adding node accessors, see below
AstNode* argsp() const { return op1p()->castNode(); }
@@ -2840,6 +2843,7 @@ struct AstCCall : public AstNodeStmt {
private:
AstCFunc* m_funcp;
string m_hiername;
string m_argTypes;
public:
AstCCall(FileLine* fl, AstCFunc* funcp, AstNode* argsp=NULL)
: AstNodeStmt(fl) {
@@ -2863,7 +2867,8 @@ public:
virtual int instrCount() const { return instrCountCall(); }
virtual V3Hash sameHash() const { return V3Hash(funcp()); }
virtual bool same(AstNode* samep) const {
return funcp()==samep->castCCall()->funcp(); }
return (funcp()==samep->castCCall()->funcp()
&& argTypes()==samep->castCCall()->argTypes()); }
AstNode* exprsp() const { return op1p()->castNode(); } // op1= expressions to print
virtual bool isGateOptimizable() const { return false; }
virtual bool isPredictOptimizable() const { return false; }
@@ -2872,6 +2877,8 @@ public:
AstCFunc* funcp() const { return m_funcp; }
string hiername() const { return m_hiername; }
void hiername(const string& hn) { m_hiername = hn; }
void argTypes(const string& str) { m_argTypes = str; }
string argTypes() const { return m_argTypes; }
//
AstNode* argsp() const { return op1p()->castNode(); }
void addArgsp(AstNode* nodep) { addOp1p(nodep); }
+1 -1
View File
@@ -393,6 +393,6 @@ void V3Case::caseAll(AstNetlist* nodep) {
CaseVisitor visitor (nodep);
}
void V3Case::caseLint(AstNodeCase* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
UINFO(4,__FUNCTION__<<": "<<endl);
CaseLintVisitor visitor (nodep);
}
+4 -1
View File
@@ -39,8 +39,9 @@
#include <set>
#include "V3Global.h"
#include "V3Changed.h"
#include "V3Ast.h"
#include "V3Changed.h"
#include "V3EmitCBase.h"
//######################################################################
// Changed state, as a visitor of each AstNode
@@ -106,6 +107,8 @@ private:
m_scopetopp = scopep;
// Create change detection function
m_chgFuncp = new AstCFunc(nodep->fileline(), "_change_request", scopep, "bool");
m_chgFuncp->argTypes(EmitCBaseVisitor::symClassVar());
m_chgFuncp->symProlog(true);
m_scopetopp->addActivep(m_chgFuncp);
// We need at least one change detect so we know to emit the correct code
m_chgFuncp->addStmtsp(new AstChangeDet(nodep->fileline(), NULL, NULL, false));
+39 -20
View File
@@ -41,6 +41,7 @@
#include "V3Global.h"
#include "V3Clock.h"
#include "V3Ast.h"
#include "V3EmitCBase.h"
//######################################################################
// Clock state, as a visitor of each AstNode
@@ -186,30 +187,42 @@ private:
AstNode::userClearTree();
// Make top functions
{
m_evalFuncp = new AstCFunc(nodep->fileline(), "_eval", m_scopep);
m_evalFuncp->dontCombine(true);
m_scopep->addActivep(m_evalFuncp);
AstCFunc* funcp = new AstCFunc(nodep->fileline(), "_eval", m_scopep);
funcp->argTypes(EmitCBaseVisitor::symClassVar());
funcp->dontCombine(true);
funcp->symProlog(true);
m_scopep->addActivep(funcp);
m_evalFuncp = funcp;
}
{
m_initFuncp = new AstCFunc(nodep->fileline(), "_eval_initial", m_scopep);
m_initFuncp->dontCombine(true);
m_initFuncp->slow(true);
m_scopep->addActivep(m_initFuncp);
AstCFunc* funcp = new AstCFunc(nodep->fileline(), "_eval_initial", m_scopep);
funcp->argTypes(EmitCBaseVisitor::symClassVar());
funcp->dontCombine(true);
funcp->slow(true);
funcp->symProlog(true);
m_scopep->addActivep(funcp);
m_initFuncp = funcp;
}
{
m_finalFuncp = new AstCFunc(nodep->fileline(), "final", m_scopep);
m_finalFuncp->skipDecl(true);
m_finalFuncp->dontCombine(true);
m_finalFuncp->slow(true);
m_finalFuncp->addStmtsp(new AstCStmt(nodep->fileline(),
" "+v3Global.opt.prefix()+"__Syms::init(this);\n"));
m_scopep->addActivep(m_finalFuncp);
AstCFunc* funcp = new AstCFunc(nodep->fileline(), "final", m_scopep);
funcp->skipDecl(true);
funcp->dontCombine(true);
funcp->slow(true);
funcp->addInitsp(
new AstCStmt(nodep->fileline(),
" "+EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp;\n"));
funcp->addInitsp(new AstCStmt(nodep->fileline()," "+EmitCBaseVisitor::symTopAssign()+"\n"));
m_scopep->addActivep(funcp);
m_finalFuncp = funcp;
}
{
m_settleFuncp = new AstCFunc(nodep->fileline(), "_eval_settle", m_scopep);
m_settleFuncp->dontCombine(true);
m_settleFuncp->slow(true);
m_scopep->addActivep(m_settleFuncp);
AstCFunc* funcp = new AstCFunc(nodep->fileline(), "_eval_settle", m_scopep);
funcp->argTypes(EmitCBaseVisitor::symClassVar());
funcp->dontCombine(true);
funcp->slow(true);
funcp->symProlog(true);
m_scopep->addActivep(funcp);
m_settleFuncp = funcp;
}
// Process the activates
nodep->iterateChildren(*this);
@@ -273,12 +286,16 @@ private:
if (!m_scopep) nodep->v3fatalSrc("Initial Active not under scope\n");
AstCFunc* funcp = new AstCFunc(nodep->fileline(), "_initial__"+m_scopep->nameDotless(),
m_scopep);
funcp->argTypes(EmitCBaseVisitor::symClassVar());
funcp->symProlog(true);
funcp->slow(true);
stmtsp->unlinkFrBackWithNext();
funcp->addStmtsp(stmtsp);
nodep->replaceWith(funcp);
// Add top level call to it
m_initFuncp->addStmtsp(new AstCCall(nodep->fileline(), funcp));
AstCCall* callp = new AstCCall(nodep->fileline(), funcp);
callp->argTypes("vlSymsp");
m_initFuncp->addStmtsp(callp);
} else {
nodep->unlinkFrBack();
}
@@ -290,7 +307,9 @@ private:
if (nodep->formCallTree()) {
if (nodep->name() == "_final") {
UINFO(4, " formCallTree "<<nodep<<endl);
m_finalFuncp->addStmtsp(new AstCCall(nodep->fileline(), nodep));
AstCCall* callp = new AstCCall(nodep->fileline(), nodep);
callp->argTypes("vlSymsp");
m_finalFuncp->addStmtsp(callp);
} else {
nodep->v3fatalSrc("Unknown CFunc name. Make code more generic, with a map of func names");
}
+1
View File
@@ -94,6 +94,7 @@ public:
if (callp->funcp() != oldfuncp) callp->v3fatalSrc("Call list broken, points to call w/different func");
if (newfuncp) {
AstCCall* newp = new AstCCall(callp, newfuncp);
newp->argTypes(callp->argTypes());
callp->replaceWith(newp);
addCall(newp); // Fix the table
} else { // Just deleting empty function
+14 -9
View File
@@ -36,6 +36,7 @@
#include "V3Global.h"
#include "V3Descope.h"
#include "V3Ast.h"
#include "V3EmitCBase.h"
//######################################################################
@@ -61,13 +62,13 @@ private:
hierThisr = true;
if (varp && varp->isFuncLocal()) {
return ""; // Relative to function, not in this
} else if (scopep == m_scopep) {
if (m_modp->isTop()) {
return ""; // Reference to scope we're in, no need to HIER-> it
} else {
m_needThis = true;
return "thisp->"; // this-> but with restricted aliasing
}
} else if (scopep == m_scopep && m_modp->isTop()) {
//return ""; // Reference to scope we're in, no need to HIER-> it
return "vlTOPp->";
} else if (scopep == m_scopep && !m_modp->isTop()
&& 0) { // We no longer thisp-> as still get ambiguation problems
m_needThis = true;
return "thisp->"; // this-> but with restricted aliasing
} else if (scopep->aboveScopep() && scopep->aboveScopep()==m_scopep
&& 0 // DISABLED: GCC considers the pointers ambiguous, so goes ld/store crazy
) {
@@ -81,13 +82,12 @@ private:
return name+"->";
} else {
// Reference to something else, use global variable
m_modp->globalSyms(true);
UINFO(8," Descope "<<scopep<<endl);
UINFO(8," to "<<scopep->name()<<endl);
UINFO(8," under "<<m_scopep->name()<<endl);
hierThisr = false;
if (!scopep->aboveScopep()) { // Top
return "VlSym->TOPp->";
return "vlTOPp->"; // == "vlSymsp->TOPp->", but GCC would suspect aliases
} else {
return scopep->nameVlSym()+".";
}
@@ -111,6 +111,10 @@ private:
if (newfuncp->stmtsp()) newfuncp->stmtsp()->unlinkFrBackWithNext()->deleteTree();
if (newfuncp->finalsp()) newfuncp->finalsp()->unlinkFrBackWithNext()->deleteTree();
newfuncp->name(name);
newfuncp->addInitsp(
new AstCStmt(newfuncp->fileline(),
" "+EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp;\n"));
newfuncp->addInitsp(new AstCStmt(newfuncp->fileline()," "+EmitCBaseVisitor::symTopAssign()+"\n"));
topFuncp->addNextHere(newfuncp);
// In the body, call each function if it matches the given scope
for (FuncMmap::iterator eachIt = it; eachIt!=m_modFuncs.end() && eachIt->first==name; ++eachIt) {
@@ -209,6 +213,7 @@ private:
nodep->iterateChildren(*this);
nodep->user(true);
if (m_needThis) {
nodep->v3fatalSrc("old code");
// Really we should have more node types for backend optimization of this stuff
string text = " "+v3Global.opt.modPrefix() + "_" + m_modp->name()
+"* thisp = &("+m_scopep->nameVlSym()+");\n";
+45 -60
View File
@@ -182,9 +182,12 @@ public:
puts(nodep->hiername());
puts(nodep->funcp()->name());
puts("(");
puts(nodep->argTypes());
bool comma = (nodep->argTypes() != "");
for (AstNode* subnodep=nodep->argsp(); subnodep; subnodep = subnodep->nextp()) {
if (comma) puts(", ");
subnodep->accept(*this);
if (subnodep->nextp()) puts(", ");
comma = true;
}
if (nodep->backp()->castNodeMath() || nodep->backp()->castCReturn()) {
// We should have a separate CCall for math and statement usage, but...
@@ -214,7 +217,7 @@ public:
puts(");\n");
}
virtual void visit(AstCoverInc* nodep, AstNUser*) {
puts("if (Verilated::s_coverageRequest)");
puts("if (VL_LIKELY(vlSymsp->__Vm_coverageRequest))");
puts(" ++__Vcoverage[");
puts(cvtToStr(m_coverIds.remap(nodep->declp()))); puts("];\n");
}
@@ -596,6 +599,8 @@ class EmitCImp : EmitCStmts {
+"<<name()"
+"<<endl; );\n");
if (nodep->symProlog()) puts(EmitCBaseVisitor::symTopAssign()+"\n");
if (nodep->initsp()) puts("// Variables\n");
ofp()->putAlign(V3OutFile::AL_AUTO, 4);
for (AstNode* subnodep=nodep->argsp(); subnodep; subnodep = subnodep->nextp()) {
@@ -1023,8 +1028,6 @@ void EmitCImp::emitVarResets(AstModule* modp) {
puts("// Reset internal values\n");
if (modp->isTop()) {
if (v3Global.opt.inhibitSim()) puts("__Vm_inhibitSim = false;\n");
puts("__Vm_activity = false;\n");
puts("__Vm_didInit = false;\n");
puts("\n");
}
@@ -1201,7 +1204,8 @@ void EmitCImp::emitTextSection(AstType type) {
void EmitCImp::emitCellCtors(AstModule* modp) {
if (modp->isTop()) {
// Must be before other constructors, as __vlCoverInsert calls it
puts("__VlSymsp = new "+symClassName()+"(this, name());\n");
puts(EmitCBaseVisitor::symClassVar()+" = __VlSymsp = new "+symClassName()+"(this, name());\n");
puts(EmitCBaseVisitor::symTopAssign()+"\n");
}
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (AstCell* cellp=nodep->castCell()) {
@@ -1229,48 +1233,48 @@ void EmitCImp::emitSensitives() {
void EmitCImp::emitWrapEval(AstModule* modp) {
puts("\nvoid "+modClassName(modp)+"::eval() {\n");
puts("// Setup global symbol table\n");
puts(symClassName()); puts("::init(this);\n");
puts(EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp; // Setup global symbol table\n");
puts(EmitCBaseVisitor::symTopAssign()+"\n");
puts("// Initialize\n");
puts("if (!__Vm_didInit) eval_initial_loop();\n");
puts("if (VL_UNLIKELY(!vlSymsp->__Vm_didInit)) _eval_initial_loop(vlSymsp);\n");
if (v3Global.opt.inhibitSim()) {
puts("if (__Vm_inhibitSim) return;\n");
puts("if (VL_UNLIKELY(__Vm_inhibitSim)) return;\n");
}
puts("// Evaluate till stable\n");
puts("VL_DEBUG_IF(cout<<\"\\n----TOP Evaluate "+modClassName(modp)+"::eval\"<<endl; );\n");
#ifndef NEW_ORDERING
puts("int __VclockLoop = 0;\n");
puts("IData __Vchange;\n");
puts("for (__Vchange=1; __Vchange; ) {\n");
puts("IData __Vchange=1;\n");
puts("while (VL_LIKELY(__Vchange)) {\n");
puts( "VL_DEBUG_IF(cout<<\" Clock loop\"<<endl;);\n");
#endif
// FIX coverage! w/combo logic interspersed, this is complicated.
// Not exactly correct for coverage. w/combo logic interspersed, this is complicated. Punt.
// Perhaps have temp & each _combo_ turn it on or off
if (v3Global.opt.coverage()) puts( "Verilated::s_coverageRequest = true;\n");
puts( "__Vm_activity = true;\n");
puts( "_eval();\n");
if (v3Global.opt.coverage()) puts( "Verilated::s_coverageRequest = false;\n");
if (v3Global.opt.coverage()) puts( "vlSymsp->__Vm_coverageRequest = true;\n");
puts( "vlSymsp->__Vm_activity = true;\n");
puts( "_eval(vlSymsp);\n");
if (v3Global.opt.coverage()) puts( "vlSymsp->__Vm_coverageRequest = false;\n");
#ifndef NEW_ORDERING
puts( "__Vchange = _change_request();\n");
puts( "__Vchange = _change_request(vlSymsp);\n");
puts( "if (++__VclockLoop > 100) vl_fatal(__FILE__,__LINE__,__FILE__,\"Verilated model didn't converge\");\n");
puts("}\n");
#endif
puts("}\n");
//
puts("\nvoid "+modClassName(modp)+"::eval_initial_loop() {\n");
puts("__Vm_didInit = true;\n");
puts("_eval_initial();\n");
puts("\nvoid "+modClassName(modp)+"::_eval_initial_loop("+EmitCBaseVisitor::symClassVar()+") {\n");
puts("vlSymsp->__Vm_didInit = true;\n");
puts("_eval_initial(vlSymsp);\n");
#ifndef NEW_ORDERING
puts( "__Vm_activity = true;\n");
puts( "vlSymsp->__Vm_activity = true;\n");
puts( "int __VclockLoop = 0;\n");
puts( "IData __Vchange;\n");
puts( "for (__Vchange=1; __Vchange; ) {\n");
puts( "IData __Vchange=1;\n");
puts( "while (VL_LIKELY(__Vchange)) {\n");
#endif
puts( "_eval_settle();\n");
puts( "_eval();\n");
puts( "_eval_settle(vlSymsp);\n");
puts( "_eval(vlSymsp);\n");
#ifndef NEW_ORDERING
puts( "__Vchange = _change_request();\n");
puts( "__Vchange = _change_request(vlSymsp);\n");
puts( "if (++__VclockLoop > 100) vl_fatal(__FILE__,__LINE__,__FILE__,\"Verilated model didn't DC converge\");\n");
puts( "}\n");
#endif
@@ -1414,10 +1418,6 @@ void EmitCImp::emitInt(AstModule* modp) {
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
puts("bool\t__Vm_inhibitSim;\t///< Set true to disable evaluation of module\n");
}
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
puts("bool\t__Vm_activity;\t\t///< Used by trace routines to determine change occurred\n");
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
puts("bool\t__Vm_didInit;\n");
}
ofp()->putAlign(V3OutFile::AL_AUTO, 8);
emitCoverageDecl(modp); // may flip public/private
@@ -1449,6 +1449,11 @@ void EmitCImp::emitInt(AstModule* modp) {
puts("\n// METHODS\n");
ofp()->resetPrivate();
// We don't need a private copy constructor, as VerilatedModule has one for us.
ofp()->putsPrivate(true);
puts(modClassName(modp)+"& operator= (const "+modClassName(modp)+"&);\t///< Copying not allowed\n");
puts(modClassName(modp)+"(const "+modClassName(modp)+"&);\t///< Copying not allowed\n");
ofp()->putsPrivate(false); // public:
if (optSystemC() && modp->isTop()) {
puts("SC_CTOR("+modClassName(modp)+");\n");
@@ -1466,9 +1471,6 @@ void EmitCImp::emitInt(AstModule* modp) {
puts("void\t__Vconfigure("+symClassName()+"* symsp);\n");
if (optSystemPerl()) puts("/*AUTOMETHODS*/\n");
if (modp->isTop()) {
puts("inline bool\tgetClearActivity() { bool r=__Vm_activity; __Vm_activity=false; return r;}\n");
}
emitTextSection(AstType::SCINT);
puts("\n// Sensitivity blocks\n");
@@ -1480,7 +1482,7 @@ void EmitCImp::emitInt(AstModule* modp) {
puts("void\tinhibitSim(bool flag) { __Vm_inhibitSim=flag; }\t///< Set true to disable evaluation of module\n");
}
ofp()->putsPrivate(true); // private:
puts("void\teval_initial_loop();\n");
puts("void\t_eval_initial_loop("+EmitCBaseVisitor::symClassVar()+");\n");
#ifndef NEW_ORDERING
puts("IData\tchange_request();\n");
#endif
@@ -1492,7 +1494,7 @@ void EmitCImp::emitInt(AstModule* modp) {
ofp()->putsPrivate(false); // public:
puts("static void\ttraceInit (SpTraceVcd* vcdp, void* userthis, uint32_t code);\n");
puts("static void\ttraceFull (SpTraceVcd* vcdp, void* userthis, uint32_t code);\n");
puts("static void\ttraceChg (SpTraceVcd* vcdp, void* userthis, uint32_t code);\n");
puts("static void\ttraceChg (SpTraceVcd* vcdp, void* userthis, uint32_t code);\n");
}
puts("} VL_ATTR_ALIGNED(8);\n");
@@ -1515,19 +1517,7 @@ void EmitCImp::emitImp(AstModule* modp) {
(modClassName(modp)+".h\"").c_str());
// Us
if (modp->globalSyms() || modp->isTop() || 1 /*for thisp*/) {
puts("#include \""+ symClassName() +".h\"\n");
puts("#define VlSym "+ symClassName() +"::s_thisp\n");
} else {
// Instantiated modules
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (AstCell* cellp=nodep->castCell()) {
ofp()->printf("#include \"%-20s",
(modClassName(cellp->modp())+".h\"").c_str());
puts(" // For "+cellp->name()+"\n");
}
}
}
puts("#include \""+ symClassName() +".h\"\n");
if (optSystemPerl() && (m_splitFilenum || !m_fast)) {
puts("\n");
@@ -1577,9 +1567,6 @@ void EmitCImp::emitImp(AstModule* modp) {
}
void EmitCImp::emitImpBottom(AstModule* modp) {
if (modp->globalSyms()) {
puts("#undef VlSym\n");
}
}
//######################################################################
@@ -1660,7 +1647,6 @@ class EmitCTrace : EmitCStmts {
}
puts("#include \"SpTraceVcdC.h\"\n");
puts("#include \""+ symClassName() +".h\"\n");
puts("#define VlSym "+ symClassName() +"::s_thisp\n");
puts("\n");
}
@@ -1682,16 +1668,16 @@ class EmitCTrace : EmitCStmts {
puts("void "+topClassName()+"::traceInit(SpTraceVcd* vcdp, void* userthis, uint32_t code) {\n");
puts("// Callback from vcd->open()\n");
puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n");
puts(symClassName()+"::init(t); // Setup global symbol table\n");
puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n");
puts("if (!Verilated::calcUnusedSigs()) vl_fatal(__FILE__,__LINE__,__FILE__,\"Turning on wave traces requires Verilated::traceEverOn(true) call before time 0.\");\n");
puts("t->traceInitThis (vcdp, code);\n");
puts("t->traceInitThis (vlSymsp, vcdp, code);\n");
puts("}\n");
puts("void "+topClassName()+"::traceFull(SpTraceVcd* vcdp, void* userthis, uint32_t code) {\n");
puts("// Callback from vcd->dump()\n");
puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n");
puts(symClassName()+"::init(t); // Setup global symbol table\n");
puts("t->traceFullThis (vcdp, code);\n");
puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n");
puts("t->traceFullThis (vlSymsp, vcdp, code);\n");
puts("}\n");
puts("\n//======================\n\n");
@@ -1703,9 +1689,9 @@ class EmitCTrace : EmitCStmts {
puts("void "+topClassName()+"::traceChg(SpTraceVcd* vcdp, void* userthis, uint32_t code) {\n");
puts("// Callback from vcd->dump()\n");
puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n");
puts("if (t->getClearActivity()) {\n");
puts(symClassName()+"::init(t); // Setup global symbol table\n");
puts("t->traceChgThis (vcdp, code);\n");
puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n");
puts("if (vlSymsp->getClearActivity()) {\n");
puts("t->traceChgThis (vlSymsp, vcdp, code);\n");
puts("}\n");
puts("}\n");
@@ -1879,7 +1865,6 @@ public:
v3Global.rootp()->accept(*this);
puts("#undef VlSym\n");
m_ofp = NULL;
}
};
+2
View File
@@ -108,6 +108,8 @@ public:
bool optSystemC() { return v3Global.opt.systemC(); }
bool optSystemPerl() { return v3Global.opt.systemPerl(); }
static string symClassName() { return v3Global.opt.prefix()+"__Syms"; }
static string symClassVar() { return symClassName()+"* __restrict vlSymsp"; }
static string symTopAssign() { return v3Global.opt.prefix()+"* __restrict vlTOPp = vlSymsp->TOPp;"; }
static string modClassName(AstModule* modp) { // Return name of current module being processed
if (modp->isTop()) {
return v3Global.opt.prefix();
+18 -12
View File
@@ -119,14 +119,23 @@ void EmitCSyms::emitInt() {
puts("\n// SYMS CLASS\n");
puts((string)"class "+symClassName()+" {\n");
puts("public:\n");
ofp()->putsPrivate(false); // public:
puts("// STATIC STATE\n");
puts("static "+symClassName()+"* s_thisp;\n");
//puts("\n// STATIC STATE\n");
puts("\n// LOCAL STATE\n");
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(uint64_t));
puts("const char* __Vm_namep;\n"); // Must be before subcells, as constructor order needed before _vlCoverInsert.
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
puts("bool\t__Vm_activity;\t\t///< Used by trace routines to determine change occurred\n");
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
puts("bool\t__Vm_didInit;\n");
if (v3Global.opt.coverage()) {
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
puts("bool __Vm_coverageRequest;\n");
}
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(uint64_t));
puts("\n// SUBCELL STATE\n");
for (vector<ScopeModPair>::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) {
AstScope* scopep = it->first; AstModule* modp = it->second;
@@ -143,15 +152,10 @@ void EmitCSyms::emitInt() {
puts("\n// CREATORS\n");
puts(symClassName()+"("+topClassName()+"* topp, const char* namep);\n");
puts((string)"~"+symClassName()+"() {};\n");
puts("\n// METHODS\n");
puts("/// Called at top of each eval to setup global pointer to top-of-symbol table\n");
puts((string)"inline static void init ("+symClassName()+"* symsp) {\n");
puts("s_thisp = symsp;\n");
puts("}\n");
puts((string)"inline static void init ("+topClassName()+"* topp) {\n");
puts("s_thisp = topp->__VlSymsp;\n");
puts("}\n");
puts("inline const char* name() { return __Vm_namep; }\n");
puts("inline bool getClearActivity() { bool r=__Vm_activity; __Vm_activity=false; return r;}\n");
puts("\n");
puts("};\n");
puts("#endif /*guard*/\n");
@@ -172,13 +176,15 @@ void EmitCSyms::emitImp() {
puts("#include \""+modClassName(nodep)+".h\"\n");
}
puts("\n// GLOBALS\n");
puts(symClassName()+"* "+symClassName()+"::s_thisp;\n");
//puts("\n// GLOBALS\n");
puts("\n// FUNCTIONS\n");
puts(symClassName()+"::"+symClassName()+"("+topClassName()+"* topp, const char* namep)\n");
puts("\t// Setup locals\n");
puts("\t: __Vm_namep(namep)\n"); // No leak, as we get destroyed when the top is destroyed
puts("\t, __Vm_activity(false)\n");
puts("\t, __Vm_didInit(false)\n");
if (v3Global.opt.coverage()) puts("\t, __Vm_coverageRequest(false)\n");
puts("\t// Setup submodule names\n");
char comma=',';
for (vector<ScopeModPair>::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) {
+4
View File
@@ -106,6 +106,7 @@
#include "V3List.h"
#include "V3SenTree.h"
#include "V3Stats.h"
#include "V3EmitCBase.h"
#include "V3Order.h"
#include "V3OrderGraph.h"
@@ -1380,6 +1381,8 @@ void OrderVisitor::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* d
if (!m_pomNewFuncp && domainp != m_deleteDomainp) {
string name = cfuncName(modp, domainp, scopep, nodep);
m_pomNewFuncp = new AstCFunc(nodep->fileline(), name, scopep);
m_pomNewFuncp->argTypes(EmitCBaseVisitor::symClassVar());
m_pomNewFuncp->symProlog(true);
if (domainp->hasInitial() || domainp->hasSettle()) m_pomNewFuncp->slow(true);
scopep->addActivep(m_pomNewFuncp);
// Where will we be adding the call?
@@ -1387,6 +1390,7 @@ void OrderVisitor::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* d
processMoveLoopStmt(callunderp);
// Add a top call to it
AstCCall* callp = new AstCCall(nodep->fileline(), m_pomNewFuncp);
callp->argTypes("vlSymsp");
callunderp->addStmtsp(callp);
UINFO(6," New "<<m_pomNewFuncp<<endl);
}
+5 -2
View File
@@ -38,6 +38,7 @@
#include "V3Task.h"
#include "V3Inst.h"
#include "V3Ast.h"
#include "V3EmitCBase.h"
//######################################################################
@@ -290,8 +291,10 @@ private:
funcp->funcPublic(true);
// We need to get a pointer to all of our variables (may have eval'ed something else earlier)
funcp->addInitsp(new AstCStmt(nodep->fileline(),
string(" ")+v3Global.opt.prefix()+"__Syms::init(__VlSymsp);\n"));
funcp->addInitsp(
new AstCStmt(nodep->fileline(),
" "+EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp;\n"));
funcp->addInitsp(new AstCStmt(nodep->fileline()," "+EmitCBaseVisitor::symTopAssign()+"\n"));
// Create list of arguments and move to function
for (AstNode* nextp, *stmtp = nodep->stmtsp(); stmtp; stmtp=nextp) {
+6 -3
View File
@@ -76,8 +76,9 @@ private:
{
AstCFunc* funcp = new AstCFunc(nodep->fileline(), "traceInitThis", m_scopetopp);
funcp->slow(true);
funcp->argTypes("SpTraceVcd* vcdp, uint32_t code");
funcp->argTypes(EmitCBaseVisitor::symClassVar()+", SpTraceVcd* vcdp, uint32_t code");
funcp->funcType(AstCFuncType::TRACE_INIT);
funcp->symProlog(true);
m_scopetopp->addActivep(funcp);
m_initFuncp = funcp;
UINFO(5," Newfunc "<<funcp<<endl);
@@ -85,15 +86,17 @@ private:
{
AstCFunc* funcp = new AstCFunc(nodep->fileline(), "traceFullThis", m_scopetopp);
funcp->slow(true);
funcp->argTypes("SpTraceVcd* vcdp, uint32_t code");
funcp->argTypes(EmitCBaseVisitor::symClassVar()+", SpTraceVcd* vcdp, uint32_t code");
funcp->funcType(AstCFuncType::TRACE_FULL);
funcp->symProlog(true);
m_scopetopp->addActivep(funcp);
m_fullFuncp = funcp;
}
{
AstCFunc* funcp = new AstCFunc(nodep->fileline(), "traceChgThis", m_scopetopp);
funcp->argTypes("SpTraceVcd* vcdp, uint32_t code");
funcp->argTypes(EmitCBaseVisitor::symClassVar()+", SpTraceVcd* vcdp, uint32_t code");
funcp->funcType(AstCFuncType::TRACE_CHANGE);
funcp->symProlog(true);
m_scopetopp->addActivep(funcp);
m_chgFuncp = funcp;
}