Add AstVFile and AstTextBlock, towards bug1490.
This commit is contained in:
parent
9e64be71a7
commit
28b9db1903
|
|
@ -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]";
|
||||||
|
|
|
||||||
|
|
@ -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; }
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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() {}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue