2012-04-13 03:08:20 +02:00
|
|
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
2006-08-26 13:35:28 +02:00
|
|
|
//*************************************************************************
|
|
|
|
|
// DESCRIPTION: Verilator: File stream wrapper that understands indentation
|
|
|
|
|
//
|
2019-11-08 04:33:59 +01:00
|
|
|
// Code available from: https://verilator.org
|
2006-08-26 13:35:28 +02:00
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
//
|
2019-01-04 01:17:22 +01:00
|
|
|
// Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
|
2006-08-26 13:35:28 +02:00
|
|
|
// redistribute it and/or modify it under the terms of either the GNU
|
2009-05-04 23:07:57 +02:00
|
|
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
|
|
|
|
// Version 2.0.
|
2006-08-26 13:35:28 +02:00
|
|
|
//
|
|
|
|
|
// Verilator is distributed in the hope that it will be useful,
|
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
2019-10-05 02:17:11 +02:00
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
#ifndef _V3FILE_H_
|
|
|
|
|
#define _V3FILE_H_ 1
|
2018-10-14 19:43:24 +02:00
|
|
|
|
2006-12-18 20:20:45 +01:00
|
|
|
#include "config_build.h"
|
|
|
|
|
#include "verilatedos.h"
|
2018-10-14 19:43:24 +02:00
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
#include "V3Error.h"
|
2018-10-14 19:43:24 +02:00
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
#include <stack>
|
|
|
|
|
#include <set>
|
2010-04-07 02:20:44 +02:00
|
|
|
#include <list>
|
2019-10-18 01:44:10 +02:00
|
|
|
#include <vector>
|
2006-08-26 13:35:28 +02:00
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
|
// V3File: Create streams, recording dependency information
|
|
|
|
|
|
|
|
|
|
class V3File {
|
|
|
|
|
public:
|
2018-02-02 03:24:41 +01:00
|
|
|
static std::ifstream* new_ifstream(const string& filename) {
|
2019-05-19 22:13:13 +02:00
|
|
|
addSrcDepend(filename);
|
2018-08-25 15:52:45 +02:00
|
|
|
return new_ifstream_nodepend(filename);
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2018-02-02 03:24:41 +01:00
|
|
|
static std::ifstream* new_ifstream_nodepend(const string& filename) {
|
|
|
|
|
return new std::ifstream(filename.c_str());
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2018-02-02 03:24:41 +01:00
|
|
|
static std::ofstream* new_ofstream(const string& filename, bool append=false) {
|
2019-05-19 22:13:13 +02:00
|
|
|
addTgtDepend(filename);
|
2018-08-25 15:52:45 +02:00
|
|
|
return new_ofstream_nodepend(filename, append);
|
2006-10-12 16:01:06 +02:00
|
|
|
}
|
2018-02-02 03:24:41 +01:00
|
|
|
static std::ofstream* new_ofstream_nodepend(const string& filename, bool append=false) {
|
2019-11-01 02:17:05 +01:00
|
|
|
createMakeDirFor(filename);
|
2019-05-19 22:13:13 +02:00
|
|
|
if (append) {
|
2018-02-02 03:24:41 +01:00
|
|
|
return new std::ofstream(filename.c_str(), std::ios::app);
|
2019-05-19 22:13:13 +02:00
|
|
|
} else {
|
2018-02-02 03:24:41 +01:00
|
|
|
return new std::ofstream(filename.c_str());
|
2019-05-19 22:13:13 +02:00
|
|
|
}
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
|
|
|
|
static FILE* new_fopen_w(const string& filename) {
|
2019-11-01 02:17:05 +01:00
|
|
|
createMakeDirFor(filename);
|
2019-05-19 22:13:13 +02:00
|
|
|
addTgtDepend(filename);
|
|
|
|
|
return fopen(filename.c_str(), "w");
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2008-01-31 14:50:06 +01:00
|
|
|
|
2006-08-26 13:35:28 +02:00
|
|
|
// Dependencies
|
|
|
|
|
static void addSrcDepend(const string& filename);
|
|
|
|
|
static void addTgtDepend(const string& filename);
|
|
|
|
|
static void writeDepend(const string& filename);
|
2019-10-18 01:44:10 +02:00
|
|
|
static std::vector<string> getAllDeps();
|
2018-10-15 00:39:33 +02:00
|
|
|
static void writeTimes(const string& filename, const string& cmdlineIn);
|
|
|
|
|
static bool checkTimes(const string& filename, const string& cmdlineIn);
|
2008-01-31 14:50:06 +01:00
|
|
|
|
|
|
|
|
// Directory utilities
|
2019-11-01 02:17:05 +01:00
|
|
|
static void createMakeDirFor(const string& filename);
|
2008-01-31 14:50:06 +01:00
|
|
|
static void createMakeDir();
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//============================================================================
|
2019-10-05 13:54:14 +02:00
|
|
|
// VInFilter: Read a input file, possibly filtering it, and caching contents
|
2010-01-20 13:15:51 +01:00
|
|
|
|
2019-10-05 13:54:14 +02:00
|
|
|
class VInFilterImp;
|
2010-01-20 13:15:51 +01:00
|
|
|
|
2019-10-05 13:54:14 +02:00
|
|
|
class VInFilter {
|
2010-01-20 13:15:51 +01:00
|
|
|
public:
|
2010-04-07 02:20:44 +02:00
|
|
|
// TYPES
|
2018-02-02 03:24:41 +01:00
|
|
|
typedef std::list<string> StrList;
|
2010-04-07 02:20:44 +02:00
|
|
|
|
2017-11-01 23:51:41 +01:00
|
|
|
private:
|
2019-10-05 13:54:14 +02:00
|
|
|
VInFilterImp* m_impp;
|
2010-01-20 13:15:51 +01:00
|
|
|
|
|
|
|
|
// CONSTRUCTORS
|
2019-10-05 13:54:14 +02:00
|
|
|
VL_UNCOPYABLE(VInFilter);
|
2017-11-01 23:51:41 +01:00
|
|
|
public:
|
2019-10-05 13:54:14 +02:00
|
|
|
explicit VInFilter(const string& command);
|
|
|
|
|
~VInFilter();
|
2017-11-01 23:51:41 +01:00
|
|
|
|
|
|
|
|
// METHODS
|
|
|
|
|
// Read file contents and return it. Return true on success.
|
|
|
|
|
bool readWholefile(const string& filename, StrList& outl);
|
2010-01-20 13:15:51 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//============================================================================
|
2010-01-07 16:50:23 +01:00
|
|
|
// V3OutFormatter: A class for automatic indentation of C++ or Verilog code.
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2010-01-07 16:50:23 +01:00
|
|
|
class V3OutFormatter {
|
2006-08-29 02:58:48 +02:00
|
|
|
// TYPES
|
|
|
|
|
enum MiscConsts {
|
2019-05-19 22:13:13 +02:00
|
|
|
MAXSPACE = 80}; // After this indent, stop indenting more
|
2006-08-29 02:58:48 +02:00
|
|
|
public:
|
|
|
|
|
enum AlignClass {
|
2019-05-19 22:13:13 +02:00
|
|
|
AL_AUTO = 0,
|
|
|
|
|
AL_STATIC = 1};
|
2012-03-20 20:57:29 +01:00
|
|
|
enum Language {
|
2019-05-19 22:13:13 +02:00
|
|
|
LA_C = 0,
|
|
|
|
|
LA_VERILOG = 1,
|
|
|
|
|
LA_MK = 2,
|
|
|
|
|
LA_XML = 3,
|
2012-03-20 20:57:29 +01:00
|
|
|
};
|
2006-08-29 02:58:48 +02:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
// MEMBERS
|
2019-05-19 22:13:13 +02:00
|
|
|
string m_filename;
|
|
|
|
|
Language m_lang; // Indenting Verilog code
|
|
|
|
|
int m_blockIndent; // Characters per block indent
|
|
|
|
|
int m_commaWidth; // Width after which to break at ,'s
|
|
|
|
|
int m_lineno;
|
|
|
|
|
int m_column;
|
|
|
|
|
int m_nobreak; // Basic operator or begin paren, don't break next
|
|
|
|
|
bool m_prependIndent;
|
|
|
|
|
int m_indentLevel; // Current {} indentation
|
2018-02-02 03:24:41 +01:00
|
|
|
std::stack<int> m_parenVec; // Stack of columns where last ( was
|
2018-10-08 03:23:45 +02:00
|
|
|
int m_bracketLevel; // Intenting = { block, indicates number of {'s seen.
|
2006-08-26 13:35:28 +02:00
|
|
|
|
2019-05-19 22:13:13 +02:00
|
|
|
int endLevels(const char* strg);
|
2010-01-07 16:50:23 +01:00
|
|
|
void putcNoTracking(char chr);
|
2006-08-26 13:35:28 +02:00
|
|
|
|
|
|
|
|
public:
|
2012-03-20 20:57:29 +01:00
|
|
|
V3OutFormatter(const string& filename, Language lang);
|
2010-01-07 16:50:23 +01:00
|
|
|
virtual ~V3OutFormatter() {}
|
2006-08-26 13:35:28 +02:00
|
|
|
// ACCESSORS
|
2015-10-21 03:22:00 +02:00
|
|
|
int column() const { return m_column; }
|
|
|
|
|
int blockIndent() const { return m_blockIndent; }
|
2019-05-19 22:13:13 +02:00
|
|
|
void blockIndent(int flag) { m_blockIndent = flag; }
|
2006-08-26 13:35:28 +02:00
|
|
|
// METHODS
|
|
|
|
|
void printf(const char* fmt...) VL_ATTR_PRINTF(2);
|
|
|
|
|
void puts(const char* strg);
|
|
|
|
|
void puts(const string& strg) { puts(strg.c_str()); }
|
2015-11-11 00:59:48 +01:00
|
|
|
void putsNoTracking(const string& strg);
|
|
|
|
|
void putsQuoted(const string& strg);
|
2006-08-26 13:35:28 +02:00
|
|
|
void putBreak(); // Print linebreak if line is too wide
|
|
|
|
|
void putBreakExpr(); // Print linebreak in expression if line is too wide
|
|
|
|
|
void putbs(const char* strg) { putBreakExpr(); puts(strg); }
|
|
|
|
|
void putbs(const string& strg) { putBreakExpr(); puts(strg); }
|
2016-09-14 04:53:09 +02:00
|
|
|
bool exceededWidth() const { return m_column > m_commaWidth; }
|
2006-08-26 13:35:28 +02:00
|
|
|
bool tokenStart(const char* cp, const char* cmp);
|
|
|
|
|
bool tokenEnd(const char* cp);
|
2015-10-21 03:22:00 +02:00
|
|
|
void indentInc() { m_indentLevel += m_blockIndent; }
|
2008-06-30 20:31:58 +02:00
|
|
|
void indentDec() {
|
2019-05-19 22:13:13 +02:00
|
|
|
m_indentLevel -= m_blockIndent;
|
2018-06-14 00:05:00 +02:00
|
|
|
UASSERT(m_indentLevel>=0, ": "<<m_filename<<": Underflow of indentation");
|
2006-08-26 13:35:28 +02:00
|
|
|
}
|
2015-10-21 03:22:00 +02:00
|
|
|
void blockInc() { m_parenVec.push(m_indentLevel + m_blockIndent); }
|
2006-08-26 13:35:28 +02:00
|
|
|
void blockDec() { if (!m_parenVec.empty()) m_parenVec.pop(); }
|
|
|
|
|
// STATIC METHODS
|
2018-10-15 00:39:33 +02:00
|
|
|
static const string indentSpaces(int num);
|
2019-05-17 03:44:01 +02:00
|
|
|
// Add escaped characters to strings
|
|
|
|
|
static string quoteNameControls(const string& namein, Language lang = LA_C);
|
2010-01-07 16:50:23 +01:00
|
|
|
|
|
|
|
|
// CALLBACKS - MUST OVERRIDE
|
|
|
|
|
virtual void putcOutput(char chr) = 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
//============================================================================
|
|
|
|
|
// V3OutFile: A class for printing to a file, with automatic indentation of C++ code.
|
|
|
|
|
|
|
|
|
|
class V3OutFile : public V3OutFormatter {
|
|
|
|
|
// MEMBERS
|
2019-05-19 22:13:13 +02:00
|
|
|
FILE* m_fp;
|
2010-01-07 16:50:23 +01:00
|
|
|
public:
|
2012-03-20 20:57:29 +01:00
|
|
|
V3OutFile(const string& filename, V3OutFormatter::Language lang);
|
2010-01-07 16:50:23 +01:00
|
|
|
virtual ~V3OutFile();
|
2017-02-09 13:43:43 +01:00
|
|
|
void putsForceIncs();
|
2006-08-26 13:35:28 +02:00
|
|
|
private:
|
2010-01-07 16:50:23 +01:00
|
|
|
// CALLBACKS
|
|
|
|
|
virtual void putcOutput(char chr) { fputc(chr, m_fp); }
|
2006-08-26 13:35:28 +02:00
|
|
|
};
|
|
|
|
|
|
2012-03-20 20:57:29 +01:00
|
|
|
class V3OutCFile : public V3OutFile {
|
2019-05-19 22:13:13 +02:00
|
|
|
int m_private;
|
2012-03-20 20:57:29 +01:00
|
|
|
public:
|
2015-10-04 04:33:06 +02:00
|
|
|
explicit V3OutCFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_C) {
|
2019-05-19 22:13:13 +02:00
|
|
|
resetPrivate();
|
2012-03-20 20:57:29 +01:00
|
|
|
}
|
|
|
|
|
virtual ~V3OutCFile() {}
|
|
|
|
|
virtual void putsHeader() { puts("// Verilated -*- C++ -*-\n"); }
|
2017-02-09 13:43:43 +01:00
|
|
|
virtual void putsIntTopInclude() {
|
2019-05-19 22:13:13 +02:00
|
|
|
putsForceIncs();
|
2017-02-09 13:43:43 +01:00
|
|
|
}
|
2012-03-20 20:57:29 +01:00
|
|
|
// Print out public/privates
|
|
|
|
|
void resetPrivate() { m_private = 0; }
|
|
|
|
|
void putsPrivate(bool setPrivate) {
|
2019-05-19 22:13:13 +02:00
|
|
|
if (setPrivate && m_private!=1) {
|
|
|
|
|
puts("private:\n");
|
|
|
|
|
m_private = 1;
|
|
|
|
|
} else if (!setPrivate && m_private!=2) {
|
|
|
|
|
puts("public:\n");
|
|
|
|
|
m_private = 2;
|
|
|
|
|
}
|
2012-03-20 20:57:29 +01:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class V3OutScFile : public V3OutCFile {
|
|
|
|
|
public:
|
2015-10-04 04:33:06 +02:00
|
|
|
explicit V3OutScFile(const string& filename) : V3OutCFile(filename) {}
|
2012-03-20 20:57:29 +01:00
|
|
|
virtual ~V3OutScFile() {}
|
|
|
|
|
virtual void putsHeader() { puts("// Verilated -*- SystemC -*-\n"); }
|
|
|
|
|
virtual void putsIntTopInclude() {
|
2019-05-19 22:13:13 +02:00
|
|
|
putsForceIncs();
|
|
|
|
|
puts("#include \"systemc.h\"\n");
|
|
|
|
|
puts("#include \"verilated_sc.h\"\n");
|
2012-03-20 20:57:29 +01:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class V3OutVFile : public V3OutFile {
|
|
|
|
|
public:
|
2019-05-19 22:13:13 +02:00
|
|
|
explicit V3OutVFile(const string& filename)
|
|
|
|
|
: V3OutFile(filename, V3OutFormatter::LA_VERILOG) {}
|
2012-03-20 20:57:29 +01:00
|
|
|
virtual ~V3OutVFile() {}
|
|
|
|
|
virtual void putsHeader() { puts("// Verilated -*- Verilog -*-\n"); }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class V3OutXmlFile : public V3OutFile {
|
|
|
|
|
public:
|
2019-05-19 22:13:13 +02:00
|
|
|
explicit V3OutXmlFile(const string& filename)
|
|
|
|
|
: V3OutFile(filename, V3OutFormatter::LA_XML) {
|
|
|
|
|
blockIndent(2);
|
2015-10-21 03:22:00 +02:00
|
|
|
}
|
2012-03-20 20:57:29 +01:00
|
|
|
virtual ~V3OutXmlFile() {}
|
|
|
|
|
virtual void putsHeader() { puts("<?xml version=\"1.0\" ?>\n"); }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class V3OutMkFile : public V3OutFile {
|
|
|
|
|
public:
|
2019-05-19 22:13:13 +02:00
|
|
|
explicit V3OutMkFile(const string& filename)
|
|
|
|
|
: V3OutFile(filename, V3OutFormatter::LA_MK) {}
|
2012-03-20 20:57:29 +01:00
|
|
|
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); }
|
|
|
|
|
};
|
|
|
|
|
|
2019-10-06 19:24:21 +02:00
|
|
|
//============================================================================
|
|
|
|
|
// VIdProtect: Hash identifier names in output files to protect them
|
|
|
|
|
|
|
|
|
|
class VIdProtectImp;
|
|
|
|
|
|
|
|
|
|
class VIdProtect {
|
|
|
|
|
public:
|
|
|
|
|
// METHODS
|
|
|
|
|
// Rename to a new encoded string (unless earlier passthru'ed)
|
|
|
|
|
static string protect(const string& old) { return protectIf(old, true); }
|
|
|
|
|
static string protectIf(const string& old, bool doIt=true);
|
|
|
|
|
// Rename words to a new encoded string
|
|
|
|
|
static string protectWordsIf(const string& old, bool doIt=true);
|
|
|
|
|
// Write map of renames to output file
|
|
|
|
|
static void writeMapFile(const string& filename);
|
|
|
|
|
};
|
|
|
|
|
|
2019-05-19 22:13:13 +02:00
|
|
|
#endif // Guard
|