From 28b9db1903e106e03aa8b2fbd25d6c1b9df8c155 Mon Sep 17 00:00:00 2001 From: Todd Strader Date: Fri, 27 Sep 2019 03:44:23 -0400 Subject: [PATCH] Add AstVFile and AstTextBlock, towards bug1490. --- src/V3AstNodes.cpp | 4 +++ src/V3AstNodes.h | 70 ++++++++++++++++++++++++++++++++++++++-------- src/V3EmitC.cpp | 36 ++++++++++++++++++++++-- src/V3EmitC.h | 1 + src/V3EmitCBase.h | 2 ++ src/V3EmitMk.cpp | 12 ++++---- src/V3EmitV.cpp | 29 +++++++++++++++++-- src/V3EmitV.h | 1 + 8 files changed, 133 insertions(+), 22 deletions(-) diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp index 8d46ee86b..b4bc43ef1 100644 --- a/src/V3AstNodes.cpp +++ b/src/V3AstNodes.cpp @@ -1155,6 +1155,10 @@ void AstNodeText::dump(std::ostream& str) { str<<" \""<AstNode::dump(str); +} + void AstCFile::dump(std::ostream& str) { this->AstNode::dump(str); if (source()) str<<" [SRC]"; diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h index 226c3b7f4..63d9acba2 100644 --- a/src/V3AstNodes.h +++ b/src/V3AstNodes.h @@ -334,7 +334,7 @@ public: }; 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: RANGE (array bounds) public: @@ -5772,6 +5772,23 @@ public: 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 { public: AstScCtor(FileLine* fl, const string& textp) @@ -5844,29 +5861,58 @@ public: }; //====================================================================== -// Emit C nodes +// Emitted file nodes -class AstCFile : public AstNode { - // C++ output file +class AstFile : public AstNode { + // Emitted Otput file // Parents: NETLIST - // Children: nothing yet + // Children: AstTextBlock private: 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_source:1; ///< Source file (vs header file) bool m_support:1; ///< Support file (non systemc) public: AstCFile(FileLine* fl, const string& name) - : AstNode(fl) { - m_name = name; + : AstFile(fl, name) { m_slow = false; m_source = false; m_support = false; } 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); bool slow() const { return m_slow; } void slow(bool flag) { m_slow = flag; } @@ -6232,8 +6278,8 @@ public: AstNodeModule* topModulep() const { // * = Top module in hierarchy (first one added, for now) return VN_CAST(op1p(), NodeModule); } void addModulep(AstNodeModule* modulep) { addOp1p(modulep); } - AstCFile* filesp() const { return VN_CAST(op2p(), CFile);} // op2 = List of files - void addFilesp(AstCFile* filep) { addOp2p(filep); } + AstFile* filesp() const { return VN_CAST(op2p(), File);} // op2 = List of files + void addFilesp(AstFile* filep) { addOp2p(filep); } AstNode* miscsp() const { return op3p(); } // op3 = List of dtypes etc void addMiscsp(AstNode* nodep) { addOp3p(nodep); } AstTypeTable* typeTablep() { return m_typeTablep; } diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index 0257df134..33198b36d 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -533,12 +533,19 @@ public: puts(",\"\");\n"); } virtual void visit(AstText* nodep) { - if (nodep->tracking()) { + if (nodep->tracking() || m_trackText) { puts(nodep->text()); } else { 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) { putbs(""); iterateAndNextNull(nodep->bodysp()); @@ -853,13 +860,23 @@ public: nodep->v3fatalSrc("Unknown node type reached emitter: "<prettyTypeName()); } -public: - EmitCStmts() { + void init() { m_suppressSemi = false; m_wideTempRefp = NULL; m_splitSize = 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() {} }; @@ -3229,3 +3246,16 @@ void V3EmitC::emitcTrace() { { EmitCTrace fast(false); fast.main(); } } } + +void V3EmitC::emitcFiles() { + UINFO(2,__FUNCTION__<<": "<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); + } + } +} diff --git a/src/V3EmitC.h b/src/V3EmitC.h index a509526e5..8af484050 100644 --- a/src/V3EmitC.h +++ b/src/V3EmitC.h @@ -35,6 +35,7 @@ public: static void emitcInlines(); static void emitcSyms(bool dpiHdrOnly = false); static void emitcTrace(); + static void emitcFiles(); }; #endif // Guard diff --git a/src/V3EmitCBase.h b/src/V3EmitCBase.h index f5d1c7ed0..66917fda0 100644 --- a/src/V3EmitCBase.h +++ b/src/V3EmitCBase.h @@ -38,6 +38,7 @@ class EmitCBaseVisitor : public AstNVisitor { public: // STATE V3OutCFile* m_ofp; + bool m_trackText; // Always track AstText nodes // METHODS V3OutCFile* ofp() const { return m_ofp; } void puts(const string& str) { ofp()->puts(str); } @@ -88,6 +89,7 @@ public: // CONSTRUCTORS EmitCBaseVisitor() { m_ofp = NULL; + m_trackText = false; } virtual ~EmitCBaseVisitor() {} }; diff --git a/src/V3EmitMk.cpp b/src/V3EmitMk.cpp index 5339e7953..67515d673 100644 --- a/src/V3EmitMk.cpp +++ b/src/V3EmitMk.cpp @@ -107,11 +107,13 @@ public: else if (support==2 && slow) { } else { - for (AstCFile* nodep = v3Global.rootp()->filesp(); - nodep; nodep = VN_CAST(nodep->nextp(), CFile)) { - if (nodep->source() && nodep->slow()==(slow!=0) - && nodep->support()==(support!=0)) { - putMakeClassEntry(of, nodep->name()); + for (AstFile* nodep = v3Global.rootp()->filesp(); + nodep; nodep = VN_CAST(nodep->nextp(), File)) { + AstCFile* cfilep = VN_CAST(nodep, CFile); + if (cfilep && cfilep->source() + && cfilep->slow()==(slow!=0) + && cfilep->support()==(support!=0)) { + putMakeClassEntry(of, cfilep->name()); } } } diff --git a/src/V3EmitV.cpp b/src/V3EmitV.cpp index 9d248c7d1..25d28d635 100644 --- a/src/V3EmitV.cpp +++ b/src/V3EmitV.cpp @@ -356,7 +356,18 @@ class EmitVBaseVisitor : public EmitCBaseVisitor { putfs(nodep, "$finish;\n"); } 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) { } @@ -628,8 +639,9 @@ class EmitVFileVisitor : public EmitVBaseVisitor { virtual void putqs(AstNode*, const string& str) { putbs(str); } virtual void putsNoTracking(const string& str) { ofp()->putsNoTracking(str); } public: - EmitVFileVisitor(AstNode* nodep, V3OutFile* ofp) { + EmitVFileVisitor(AstNode* nodep, V3OutFile* ofp, bool trackText=false) { m_ofp = ofp; + m_trackText = trackText; iterate(nodep); } virtual ~EmitVFileVisitor() {} @@ -758,3 +770,16 @@ void V3EmitV::verilogPrefixedTree(AstNode* nodep, std::ostream& os, AstSenTree* domainp, bool user3mark) { EmitVPrefixedVisitor(nodep, os, prefix, flWidth, domainp, user3mark); } + +void V3EmitV::emitvFiles() { + UINFO(2,__FUNCTION__<<": "<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); + } + } +} diff --git a/src/V3EmitV.h b/src/V3EmitV.h index d031945ef..0f624523d 100644 --- a/src/V3EmitV.h +++ b/src/V3EmitV.h @@ -36,6 +36,7 @@ public: static void verilogPrefixedTree(AstNode* nodep, std::ostream& os, const string& prefix, int flWidth, AstSenTree* domainp, bool user3mark); + static void emitvFiles(); }; #endif // Guard