Add AstVFile and AstTextBlock, towards bug1490.

This commit is contained in:
Todd Strader 2019-09-27 03:44:23 -04:00
parent 9e64be71a7
commit 28b9db1903
8 changed files with 133 additions and 22 deletions

View File

@ -1155,6 +1155,10 @@ void AstNodeText::dump(std::ostream& str) {
str<<" \""<<out<<"\""; str<<" \""<<out<<"\"";
} }
void AstVFile::dump(std::ostream& str) {
this->AstNode::dump(str);
}
void AstCFile::dump(std::ostream& str) { void AstCFile::dump(std::ostream& str) {
this->AstNode::dump(str); this->AstNode::dump(str);
if (source()) str<<" [SRC]"; if (source()) str<<" [SRC]";

View File

@ -334,7 +334,7 @@ public:
}; };
class AstPackArrayDType : public AstNodeArrayDType { class AstPackArrayDType : public AstNodeArrayDType {
// Array data type, ie "some_dtype var_name [2:0]" // Packed array data type, ie "some_dtype [2:0] var_name"
// Children: DTYPE (moved to refDTypep() in V3Width) // Children: DTYPE (moved to refDTypep() in V3Width)
// Children: RANGE (array bounds) // Children: RANGE (array bounds)
public: public:
@ -5772,6 +5772,23 @@ public:
bool tracking() const { return m_tracking; } bool tracking() const { return m_tracking; }
}; };
class AstTextBlock : public AstText {
private:
bool m_commas; // Comma separate emitted children
public:
AstTextBlock(FileLine* fl, const string& textp="", bool tracking=false,
bool commas=false)
: AstText(fl, textp, tracking), m_commas(commas) {}
ASTNODE_NODE_FUNCS(TextBlock)
void commas(bool flag) { m_commas = flag; }
bool commas() const { return m_commas; }
AstNode* nodesp() const { return op1p(); }
void addNodep(AstNode* nodep) { addOp1p(nodep); }
void addText(FileLine* fl, const string& textp, bool tracking=false) {
addNodep(new AstText(fl, textp, tracking));
}
};
class AstScCtor : public AstNodeText { class AstScCtor : public AstNodeText {
public: public:
AstScCtor(FileLine* fl, const string& textp) AstScCtor(FileLine* fl, const string& textp)
@ -5844,29 +5861,58 @@ public:
}; };
//====================================================================== //======================================================================
// Emit C nodes // Emitted file nodes
class AstCFile : public AstNode { class AstFile : public AstNode {
// C++ output file // Emitted Otput file
// Parents: NETLIST // Parents: NETLIST
// Children: nothing yet // Children: AstTextBlock
private: private:
string m_name; ///< Filename string m_name; ///< Filename
public:
AstFile(FileLine* fl, const string& name)
: AstNode(fl) {
m_name = name;
}
ASTNODE_BASE_FUNCS(File)
virtual string name() const { return m_name; }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(const AstNode* samep) const { return true; }
void tblockp(AstTextBlock* tblockp) { setOp1p(tblockp); }
AstTextBlock* tblockp() { return VN_CAST(op1p(), TextBlock); }
};
//======================================================================
// Emit V nodes
class AstVFile : public AstFile {
// Verilog output file
// Parents: NETLIST
public:
AstVFile(FileLine* fl, const string& name)
: AstFile(fl, name) { }
ASTNODE_NODE_FUNCS(VFile)
virtual void dump(std::ostream& str=std::cout);
};
//======================================================================
// Emit C nodes
class AstCFile : public AstFile {
// C++ output file
// Parents: NETLIST
private:
bool m_slow:1; ///< Compile w/o optimization bool m_slow:1; ///< Compile w/o optimization
bool m_source:1; ///< Source file (vs header file) bool m_source:1; ///< Source file (vs header file)
bool m_support:1; ///< Support file (non systemc) bool m_support:1; ///< Support file (non systemc)
public: public:
AstCFile(FileLine* fl, const string& name) AstCFile(FileLine* fl, const string& name)
: AstNode(fl) { : AstFile(fl, name) {
m_name = name;
m_slow = false; m_slow = false;
m_source = false; m_source = false;
m_support = false; m_support = false;
} }
ASTNODE_NODE_FUNCS(CFile) ASTNODE_NODE_FUNCS(CFile)
virtual string name() const { return m_name; }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(const AstNode* samep) const { return true; }
virtual void dump(std::ostream& str=std::cout); virtual void dump(std::ostream& str=std::cout);
bool slow() const { return m_slow; } bool slow() const { return m_slow; }
void slow(bool flag) { m_slow = flag; } void slow(bool flag) { m_slow = flag; }
@ -6232,8 +6278,8 @@ public:
AstNodeModule* topModulep() const { // * = Top module in hierarchy (first one added, for now) AstNodeModule* topModulep() const { // * = Top module in hierarchy (first one added, for now)
return VN_CAST(op1p(), NodeModule); } return VN_CAST(op1p(), NodeModule); }
void addModulep(AstNodeModule* modulep) { addOp1p(modulep); } void addModulep(AstNodeModule* modulep) { addOp1p(modulep); }
AstCFile* filesp() const { return VN_CAST(op2p(), CFile);} // op2 = List of files AstFile* filesp() const { return VN_CAST(op2p(), File);} // op2 = List of files
void addFilesp(AstCFile* filep) { addOp2p(filep); } void addFilesp(AstFile* filep) { addOp2p(filep); }
AstNode* miscsp() const { return op3p(); } // op3 = List of dtypes etc AstNode* miscsp() const { return op3p(); } // op3 = List of dtypes etc
void addMiscsp(AstNode* nodep) { addOp3p(nodep); } void addMiscsp(AstNode* nodep) { addOp3p(nodep); }
AstTypeTable* typeTablep() { return m_typeTablep; } AstTypeTable* typeTablep() { return m_typeTablep; }

View File

@ -533,12 +533,19 @@ public:
puts(",\"\");\n"); puts(",\"\");\n");
} }
virtual void visit(AstText* nodep) { virtual void visit(AstText* nodep) {
if (nodep->tracking()) { if (nodep->tracking() || m_trackText) {
puts(nodep->text()); puts(nodep->text());
} else { } else {
ofp()->putsNoTracking(nodep->text()); ofp()->putsNoTracking(nodep->text());
} }
} }
virtual void visit(AstTextBlock* nodep) {
visit(VN_CAST(nodep, Text));
for (AstNode* childp = nodep->nodesp(); childp; childp = childp->nextp()) {
iterate(childp);
if (nodep->commas() && childp->nextp()) puts(", ");
}
}
virtual void visit(AstCStmt* nodep) { virtual void visit(AstCStmt* nodep) {
putbs(""); putbs("");
iterateAndNextNull(nodep->bodysp()); iterateAndNextNull(nodep->bodysp());
@ -853,13 +860,23 @@ public:
nodep->v3fatalSrc("Unknown node type reached emitter: "<<nodep->prettyTypeName()); nodep->v3fatalSrc("Unknown node type reached emitter: "<<nodep->prettyTypeName());
} }
public: void init() {
EmitCStmts() {
m_suppressSemi = false; m_suppressSemi = false;
m_wideTempRefp = NULL; m_wideTempRefp = NULL;
m_splitSize = 0; m_splitSize = 0;
m_splitFilenum = 0; m_splitFilenum = 0;
} }
public:
EmitCStmts() {
init();
}
EmitCStmts(AstNode* nodep, V3OutCFile* ofp, bool trackText=false) {
init();
m_ofp = ofp;
m_trackText = trackText;
iterate(nodep);
}
virtual ~EmitCStmts() {} virtual ~EmitCStmts() {}
}; };
@ -3229,3 +3246,16 @@ void V3EmitC::emitcTrace() {
{ EmitCTrace fast(false); fast.main(); } { EmitCTrace fast(false); fast.main(); }
} }
} }
void V3EmitC::emitcFiles() {
UINFO(2,__FUNCTION__<<": "<<endl);
for (AstFile* filep = v3Global.rootp()->filesp(); filep;
filep = VN_CAST(filep->nextp(), File)) {
AstCFile* cfilep = VN_CAST(filep, CFile);
if (cfilep && cfilep->tblockp()) {
V3OutCFile of(cfilep->name());
of.puts("// DESCR" "IPTION: Verilator generated C++\n");
EmitCStmts visitor(cfilep->tblockp(), &of, true);
}
}
}

View File

@ -35,6 +35,7 @@ public:
static void emitcInlines(); static void emitcInlines();
static void emitcSyms(bool dpiHdrOnly = false); static void emitcSyms(bool dpiHdrOnly = false);
static void emitcTrace(); static void emitcTrace();
static void emitcFiles();
}; };
#endif // Guard #endif // Guard

View File

@ -38,6 +38,7 @@ class EmitCBaseVisitor : public AstNVisitor {
public: public:
// STATE // STATE
V3OutCFile* m_ofp; V3OutCFile* m_ofp;
bool m_trackText; // Always track AstText nodes
// METHODS // METHODS
V3OutCFile* ofp() const { return m_ofp; } V3OutCFile* ofp() const { return m_ofp; }
void puts(const string& str) { ofp()->puts(str); } void puts(const string& str) { ofp()->puts(str); }
@ -88,6 +89,7 @@ public:
// CONSTRUCTORS // CONSTRUCTORS
EmitCBaseVisitor() { EmitCBaseVisitor() {
m_ofp = NULL; m_ofp = NULL;
m_trackText = false;
} }
virtual ~EmitCBaseVisitor() {} virtual ~EmitCBaseVisitor() {}
}; };

View File

@ -107,11 +107,13 @@ public:
else if (support==2 && slow) { else if (support==2 && slow) {
} }
else { else {
for (AstCFile* nodep = v3Global.rootp()->filesp(); for (AstFile* nodep = v3Global.rootp()->filesp();
nodep; nodep = VN_CAST(nodep->nextp(), CFile)) { nodep; nodep = VN_CAST(nodep->nextp(), File)) {
if (nodep->source() && nodep->slow()==(slow!=0) AstCFile* cfilep = VN_CAST(nodep, CFile);
&& nodep->support()==(support!=0)) { if (cfilep && cfilep->source()
putMakeClassEntry(of, nodep->name()); && cfilep->slow()==(slow!=0)
&& cfilep->support()==(support!=0)) {
putMakeClassEntry(of, cfilep->name());
} }
} }
} }

View File

@ -356,7 +356,18 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
putfs(nodep, "$finish;\n"); putfs(nodep, "$finish;\n");
} }
virtual void visit(AstText* nodep) { virtual void visit(AstText* nodep) {
putsNoTracking(nodep->text()); if (nodep->tracking() || m_trackText) {
puts(nodep->text());
} else {
putsNoTracking(nodep->text());
}
}
virtual void visit(AstTextBlock* nodep) {
visit(VN_CAST(nodep, Text));
for (AstNode* childp = nodep->nodesp(); childp; childp = childp->nextp()) {
iterate(childp);
if (nodep->commas() && childp->nextp()) puts(", ");
}
} }
virtual void visit(AstScopeName* nodep) { virtual void visit(AstScopeName* nodep) {
} }
@ -628,8 +639,9 @@ class EmitVFileVisitor : public EmitVBaseVisitor {
virtual void putqs(AstNode*, const string& str) { putbs(str); } virtual void putqs(AstNode*, const string& str) { putbs(str); }
virtual void putsNoTracking(const string& str) { ofp()->putsNoTracking(str); } virtual void putsNoTracking(const string& str) { ofp()->putsNoTracking(str); }
public: public:
EmitVFileVisitor(AstNode* nodep, V3OutFile* ofp) { EmitVFileVisitor(AstNode* nodep, V3OutFile* ofp, bool trackText=false) {
m_ofp = ofp; m_ofp = ofp;
m_trackText = trackText;
iterate(nodep); iterate(nodep);
} }
virtual ~EmitVFileVisitor() {} virtual ~EmitVFileVisitor() {}
@ -758,3 +770,16 @@ void V3EmitV::verilogPrefixedTree(AstNode* nodep, std::ostream& os,
AstSenTree* domainp, bool user3mark) { AstSenTree* domainp, bool user3mark) {
EmitVPrefixedVisitor(nodep, os, prefix, flWidth, domainp, user3mark); EmitVPrefixedVisitor(nodep, os, prefix, flWidth, domainp, user3mark);
} }
void V3EmitV::emitvFiles() {
UINFO(2,__FUNCTION__<<": "<<endl);
for (AstFile* filep = v3Global.rootp()->filesp(); filep;
filep = VN_CAST(filep->nextp(), File)) {
AstVFile* vfilep = VN_CAST(filep, VFile);
if (vfilep && vfilep->tblockp()) {
V3OutVFile of(vfilep->name());
of.puts("// DESCR" "IPTION: Verilator generated Verilog\n");
EmitVFileVisitor visitor(vfilep->tblockp(), &of, true);
}
}
}

View File

@ -36,6 +36,7 @@ public:
static void verilogPrefixedTree(AstNode* nodep, std::ostream& os, static void verilogPrefixedTree(AstNode* nodep, std::ostream& os,
const string& prefix, int flWidth, const string& prefix, int flWidth,
AstSenTree* domainp, bool user3mark); AstSenTree* domainp, bool user3mark);
static void emitvFiles();
}; };
#endif // Guard #endif // Guard