diff --git a/src/V3EmitCBase.h b/src/V3EmitCBase.h index 622de7b2f..c87228c0b 100644 --- a/src/V3EmitCBase.h +++ b/src/V3EmitCBase.h @@ -34,74 +34,6 @@ #include "V3File.h" #include "V3Ast.h" -//###################################################################### -// V3OutCFile: A class for abstracting out SystemC/C++ details - -class V3OutCFile : public V3OutFile { - int m_private; -public: - V3OutCFile(const string& filename) : V3OutFile(filename) { - resetPrivate(); - } - virtual ~V3OutCFile() {} - virtual void putsCellDecl(const string& classname, const string& cellname) { - this->printf("%-19s\t%s;\n", - (classname + "*").c_str(),cellname.c_str()); - } - virtual void putsHeader() { puts("// Verilated -*- C++ -*-\n"); } - virtual void putsIntTopInclude() { } - // Print out public/privates - void resetPrivate() { m_private = 0; } - void putsPrivate(bool setPrivate) { - if (setPrivate && m_private!=1) { - puts("private:\n"); - m_private = 1; - } else if (!setPrivate && m_private!=2) { - puts("public:\n"); - m_private = 2; - } - } -}; - -class V3OutScFile : public V3OutCFile { -public: - V3OutScFile(const string& filename) : V3OutCFile(filename) {} - virtual ~V3OutScFile() {} - virtual void putsHeader() { puts("// Verilated -*- SystemC -*-\n"); } - virtual void putsIntTopInclude() { - puts("#include \"systemc.h\"\n"); - puts("#include \"verilated_sc.h\"\n"); - } -}; - -class V3OutSpFile : public V3OutCFile { -public: - V3OutSpFile(const string& filename) : V3OutCFile(filename) {} - virtual ~V3OutSpFile() {} - virtual void putsHeader() { puts("// Verilated -*- SystemC -*-\n"); } - virtual void putsIntTopInclude() { - puts("#include \"systemperl.h\"\n"); - puts("#include \"verilated_sc.h\"\n"); - } -}; - -class V3OutVFile : public V3OutFile { -public: - V3OutVFile(const string& filename) : V3OutFile(filename) {} - virtual ~V3OutVFile() {} - virtual void putsHeader() { puts("// Verilated -*- Verilog -*-\n"); } -}; - -class V3OutMkFile : public V3OutFile { -public: - V3OutMkFile(const string& filename) : V3OutFile(filename) {} - virtual ~V3OutMkFile() {} - virtual void putsHeader() { puts("# Verilated -*- Makefile -*-\n"); } - // No automatic indentation yet. - void puts(const char* strg) { putsNoTracking(strg); } - void puts(const string& strg) { putsNoTracking(strg); } -}; - //###################################################################### // Base Visitor class -- holds output file pointer diff --git a/src/V3EmitV.cpp b/src/V3EmitV.cpp index 2dc7b5234..27ee32b55 100644 --- a/src/V3EmitV.cpp +++ b/src/V3EmitV.cpp @@ -596,7 +596,7 @@ class EmitVStreamVisitor : public EmitVBaseVisitor { virtual void putbs(const string& str) { puts(str); } virtual void putfs(AstNode*, const string& str) { putbs(str); } virtual void putqs(AstNode*, const string& str) { putbs(str); } - public: +public: EmitVStreamVisitor(AstNode* nodep, ostream& os) : m_os(os) { nodep->accept(*this); @@ -635,7 +635,8 @@ public: FileLine* prefixFl() const { return m_prefixFl; } int column() const { return m_column; } EmitVPrefixedFormatter(ostream& os, const string& prefix, int flWidth) - : V3OutFormatter("__STREAM", true), m_os(os), m_prefix(prefix), m_flWidth(flWidth) { + : V3OutFormatter("__STREAM", V3OutFormatter::LA_VERILOG) + , m_os(os), m_prefix(prefix), m_flWidth(flWidth) { m_column = 0; m_prefixFl = v3Global.rootp()->fileline(); // NETLIST's fileline instead of NULL to avoid NULL checks } diff --git a/src/V3Error.cpp b/src/V3Error.cpp index 245bcac9b..2b25d48d1 100644 --- a/src/V3Error.cpp +++ b/src/V3Error.cpp @@ -67,11 +67,24 @@ V3ErrorCode::V3ErrorCode(const char* msgp) { //###################################################################### // FileLineSingleton class functions +const string FileLineSingleton::filenameLetters(int no) { + const int size = 1 + (64 / 4); // Each letter retires more than 4 bits of a > 64 bit number + char out[size]; + char* op = out+size-1; + *--op = '\0'; // We build backwards + int num = no; + do { + *--op = 'a'+num%26; + num /= 26; + } while (num); + return op; +} + int FileLineSingleton::nameToNumber(const string& filename) { // Convert filenames to a filenameno // This lets us assign a nice small identifier for debug messages, but more // importantly lets us use a 4 byte int instead of 8 byte pointer in every FileLine. - map::const_iterator iter = m_namemap.find(filename); + FileNameNumMap::const_iterator iter = m_namemap.find(filename); if (VL_LIKELY(iter != m_namemap.end())) return iter->second; int num = m_names.size(); m_names.push_back(filename); @@ -94,19 +107,6 @@ FileLine::FileLine(FileLine::EmptySecret) { } } -const string FileLine::filenameLetters() const { - const int size = 1 + (64 / 4); // Each letter retires more than 4 bits of a > 64 bit number - char out[size]; - char* op = out+size-1; - *--op = '\0'; // We build backwards - int num = m_filenameno; - do { - *--op = 'a'+num%26; - num /= 26; - } while (num); - return op; -} - string FileLine::lineDirectiveStrg(int enterExit) const { char numbuf[20]; sprintf(numbuf, "%d", lineno()); char levelbuf[20]; sprintf(levelbuf, "%d", enterExit); diff --git a/src/V3Error.h b/src/V3Error.h index 6177f8ed4..bebb96538 100644 --- a/src/V3Error.h +++ b/src/V3Error.h @@ -257,7 +257,10 @@ inline uint32_t cvtToHash(void* vp) { class FileLine; class FileLineSingleton { - map m_namemap; // filenameno for each filename + // TYPES + typedef map FileNameNumMap; + // MEMBERS + FileNameNumMap m_namemap; // filenameno for each filename deque m_names; // filename text for each filenameno // COSNTRUCTORS FileLineSingleton() { } @@ -268,6 +271,7 @@ protected: int nameToNumber(const string& filename); const string numberToName(int filenameno) const { return m_names[filenameno]; } void clear() { m_namemap.clear(); m_names.clear(); } + static const string filenameLetters(int fileno); }; class FileLine { @@ -319,7 +323,7 @@ public: int lineno () const { return m_lineno; } string ascii() const; const string filename () const { return singleton().numberToName(m_filenameno); } - const string filenameLetters() const; + const string filenameLetters() const { return singleton().filenameLetters(m_filenameno); } const string filebasename () const; const string filebasenameNoExt () const; const string profileFuncname() const; diff --git a/src/V3File.cpp b/src/V3File.cpp index 8fe5245d1..632e4b35c 100644 --- a/src/V3File.cpp +++ b/src/V3File.cpp @@ -546,8 +546,8 @@ bool V3InFilter::readWholefile(const string& filename, V3InFilter::StrList& outl //###################################################################### // V3OutFormatter: A class for printing to a file, with automatic indentation of C++ code. -V3OutFormatter::V3OutFormatter(const string& filename, bool verilog) - : m_filename(filename), m_verilog(verilog) +V3OutFormatter::V3OutFormatter(const string& filename, V3OutFormatter::Language lang) + : m_filename(filename), m_lang(lang) , m_lineno(1), m_column(0) , m_nobreak(false), m_prependIndent(true), m_indentLevel(0) , m_declSAlign(0), m_declNSAlign(0), m_declPadNum(0) { @@ -560,7 +560,7 @@ const char* V3OutFormatter::indentStr(int num) { static char str[MAXSPACE+20]; char* cp = str; if (num>MAXSPACE) num=MAXSPACE; - if (!m_verilog) { // verilogPrefixedTree doesn't want tabs + if (!m_lang==LA_VERILOG) { // verilogPrefixedTree doesn't want tabs while (num>=8) { *cp++ = '\t'; num -= 8; @@ -625,8 +625,13 @@ int V3OutFormatter::endLevels (const char *strg) { case ')': levels-=INDBLK; break; + case '<': + if (m_lang==LA_XML) { + if (cp[1] == '/') levels-=INDBLK; + } + break; case 'e': - if (m_verilog && tokenEnd(cp)) { + if (m_lang==LA_VERILOG && tokenEnd(cp)) { levels-=INDBLK; } break; @@ -668,39 +673,53 @@ void V3OutFormatter::puts (const char *strg) { case '{': indentInc(); break; + case '}': + indentDec(); + break; case '(': indentInc(); m_parenVec.push(m_column); break; - case '}': - indentDec(); - break; case ')': if (!m_parenVec.empty()) m_parenVec.pop(); indentDec(); break; + case '<': + if (m_lang==LA_XML) { + if (cp[1] == '/') {} // Zero as the > will result in net decrease by one + else if (cp[1] == '!' || cp[1] == '?') { indentInc(); } // net same indent + else { indentInc(); indentInc(); } // net increase by one + } + break; + case '>': + if (m_lang==LA_XML) { + indentDec(); + if (cp>strg && cp[-1]=='/') indentDec(); // < ..... /> stays same level + } + break; case 'b': - if (wordstart && m_verilog && tokenStart(cp,"begin")) { + if (wordstart && m_lang==LA_VERILOG && tokenStart(cp,"begin")) { indentInc(); } wordstart = false; break; case 'c': - if (wordstart && m_verilog && (tokenStart(cp,"case") - || tokenStart(cp,"casex") - || tokenStart(cp,"casez"))) { + if (wordstart && m_lang==LA_VERILOG + && (tokenStart(cp,"case") + || tokenStart(cp,"casex") + || tokenStart(cp,"casez"))) { indentInc(); } wordstart = false; break; case 'e': - if (wordstart && m_verilog && tokenEnd(cp)) { + if (wordstart && m_lang==LA_VERILOG && tokenEnd(cp)) { indentDec(); } wordstart = false; break; case 'm': - if (wordstart && m_verilog && tokenStart(cp,"module")) { + if (wordstart && m_lang==LA_VERILOG && tokenStart(cp,"module")) { indentInc(); } wordstart = false; @@ -801,8 +820,8 @@ void V3OutFormatter::printf (const char *fmt...) { //###################################################################### // V3OutFormatter: A class for printing to a file, with automatic indentation of C++ code. -V3OutFile::V3OutFile(const string& filename) - : V3OutFormatter(filename, false) { +V3OutFile::V3OutFile(const string& filename, V3OutFormatter::Language lang) + : V3OutFormatter(filename, lang) { if ((m_fp = V3File::new_fopen_w(filename.c_str())) == NULL) { v3fatal("Cannot write "<printf("%-19s\t%s;\n", + (classname + "*").c_str(),cellname.c_str()); + } + virtual void putsHeader() { puts("// Verilated -*- C++ -*-\n"); } + virtual void putsIntTopInclude() { } + // Print out public/privates + void resetPrivate() { m_private = 0; } + void putsPrivate(bool setPrivate) { + if (setPrivate && m_private!=1) { + puts("private:\n"); + m_private = 1; + } else if (!setPrivate && m_private!=2) { + puts("public:\n"); + m_private = 2; + } + } +}; + +class V3OutScFile : public V3OutCFile { +public: + V3OutScFile(const string& filename) : V3OutCFile(filename) {} + virtual ~V3OutScFile() {} + virtual void putsHeader() { puts("// Verilated -*- SystemC -*-\n"); } + virtual void putsIntTopInclude() { + puts("#include \"systemc.h\"\n"); + puts("#include \"verilated_sc.h\"\n"); + } +}; + +class V3OutSpFile : public V3OutCFile { +public: + V3OutSpFile(const string& filename) : V3OutCFile(filename) {} + virtual ~V3OutSpFile() {} + virtual void putsHeader() { puts("// Verilated -*- SystemC -*-\n"); } + virtual void putsIntTopInclude() { + puts("#include \"systemperl.h\"\n"); + puts("#include \"verilated_sc.h\"\n"); + } +}; + +class V3OutVFile : public V3OutFile { +public: + V3OutVFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_VERILOG) {} + virtual ~V3OutVFile() {} + virtual void putsHeader() { puts("// Verilated -*- Verilog -*-\n"); } +}; + +class V3OutXmlFile : public V3OutFile { +public: + V3OutXmlFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_XML) {} + virtual ~V3OutXmlFile() {} + virtual void putsHeader() { puts("\n"); } +}; + +class V3OutMkFile : public V3OutFile { +public: + V3OutMkFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_MK) {} + virtual ~V3OutMkFile() {} + virtual void putsHeader() { puts("# Verilated -*- Makefile -*-\n"); } + // No automatic indentation yet. + void puts(const char* strg) { putsNoTracking(strg); } + void puts(const string& strg) { putsNoTracking(strg); } +}; + #endif // Guard