Merge branch 'master' into develop-v5
This commit is contained in:
commit
af305bf280
|
|
@ -284,6 +284,7 @@ detailed descriptions of these arguments.
|
|||
--bbox-unsup Blackbox unsupported language features
|
||||
--bin <filename> Override Verilator binary
|
||||
--build Build model executable/library after Verilation
|
||||
--build-jobs <jobs> Parallelism for --build
|
||||
--cc Create C++ output
|
||||
--cdc Clock domain crossing analysis
|
||||
-CFLAGS <flags> C++ compiler arguments for makefile
|
||||
|
|
@ -334,7 +335,7 @@ detailed descriptions of these arguments.
|
|||
+incdir+<dir> Directory to search for includes
|
||||
--inline-mult <value> Tune module inlining
|
||||
--instr-count-dpi <value> Assumed dynamic instruction count of DPI imports
|
||||
-j <jobs> Parallelism for --build
|
||||
-j <jobs> Parallelism for --build (alias to --build-jobs)
|
||||
--l2-name <value> Verilog scope name of the top module
|
||||
--language <lang> Default language standard to parse
|
||||
-LDFLAGS <flags> Linker pre-object arguments for makefile
|
||||
|
|
|
|||
|
|
@ -129,6 +129,15 @@ Summary:
|
|||
is also used). Verilator manages the build itself, and for this --build
|
||||
requires GNU Make to be available on the platform.
|
||||
|
||||
.. option:: --build-jobs [<value>]
|
||||
|
||||
Specify the level of parallelism for :vlopt:`--build`. If zero, uses the
|
||||
number of threads in the current hardware. Otherwise, the <value> must
|
||||
be a positive integer specifying the maximum number of parallel build
|
||||
jobs.
|
||||
|
||||
See also :vlopt:`-j`.
|
||||
|
||||
.. option:: --cc
|
||||
|
||||
Specifies C++ without SystemC output mode; see also :vlopt:`--sc`
|
||||
|
|
@ -612,11 +621,10 @@ Summary:
|
|||
|
||||
.. option:: -j [<value>]
|
||||
|
||||
Specify the level of parallelism for :vlopt:`--build`. The <value> must
|
||||
be a positive integer specifying the maximum number of parallel build
|
||||
jobs, or can be omitted. When <value> is omitted, the build will not try
|
||||
to limit the number of parallel build jobs but attempt to execute all
|
||||
independent build steps in parallel.
|
||||
Specify the level of parallelism for :vlopt:`--build` if
|
||||
:vlopt:`--build-jobs` isn't provided. If zero, uses the number of threads
|
||||
in the current hardware. Otherwise, the <value> must be a positive
|
||||
integer specifying the maximum number of parallel build jobs.
|
||||
|
||||
.. option:: --l2-name <value>
|
||||
|
||||
|
|
|
|||
|
|
@ -1003,22 +1003,22 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
|||
}
|
||||
}
|
||||
|
||||
static inline bool _vl_vsss_eof(FILE* fp, int floc) VL_MT_SAFE {
|
||||
static bool _vl_vsss_eof(FILE* fp, int floc) VL_MT_SAFE {
|
||||
if (VL_LIKELY(fp)) {
|
||||
return std::feof(fp) ? true : false; // true : false to prevent MSVC++ warning
|
||||
} else {
|
||||
return floc < 0;
|
||||
}
|
||||
}
|
||||
static inline void _vl_vsss_advance(FILE* fp, int& floc) VL_MT_SAFE {
|
||||
static void _vl_vsss_advance(FILE* fp, int& floc) VL_MT_SAFE {
|
||||
if (VL_LIKELY(fp)) {
|
||||
std::fgetc(fp);
|
||||
} else {
|
||||
floc -= 8;
|
||||
}
|
||||
}
|
||||
static inline int _vl_vsss_peek(FILE* fp, int& floc, const WDataInP fromp,
|
||||
const std::string& fstr) VL_MT_SAFE {
|
||||
static int _vl_vsss_peek(FILE* fp, int& floc, const WDataInP fromp,
|
||||
const std::string& fstr) VL_MT_SAFE {
|
||||
// Get a character without advancing
|
||||
if (VL_LIKELY(fp)) {
|
||||
const int data = std::fgetc(fp);
|
||||
|
|
@ -1035,17 +1035,16 @@ static inline int _vl_vsss_peek(FILE* fp, int& floc, const WDataInP fromp,
|
|||
}
|
||||
}
|
||||
}
|
||||
static inline void _vl_vsss_skipspace(FILE* fp, int& floc, const WDataInP fromp,
|
||||
const std::string& fstr) VL_MT_SAFE {
|
||||
static void _vl_vsss_skipspace(FILE* fp, int& floc, const WDataInP fromp,
|
||||
const std::string& fstr) VL_MT_SAFE {
|
||||
while (true) {
|
||||
const int c = _vl_vsss_peek(fp, floc, fromp, fstr);
|
||||
if (c == EOF || !std::isspace(c)) return;
|
||||
_vl_vsss_advance(fp, floc);
|
||||
}
|
||||
}
|
||||
static inline void _vl_vsss_read_str(FILE* fp, int& floc, const WDataInP fromp,
|
||||
const std::string& fstr, char* tmpp,
|
||||
const char* acceptp) VL_MT_SAFE {
|
||||
static void _vl_vsss_read_str(FILE* fp, int& floc, const WDataInP fromp, const std::string& fstr,
|
||||
char* tmpp, const char* acceptp) VL_MT_SAFE {
|
||||
// Read into tmp, consisting of characters from acceptp list
|
||||
char* cp = tmpp;
|
||||
while (true) {
|
||||
|
|
@ -1059,9 +1058,8 @@ static inline void _vl_vsss_read_str(FILE* fp, int& floc, const WDataInP fromp,
|
|||
*cp++ = '\0';
|
||||
// VL_DBG_MSGF(" _read got='"<<tmpp<<"'\n");
|
||||
}
|
||||
static inline char* _vl_vsss_read_bin(FILE* fp, int& floc, const WDataInP fromp,
|
||||
const std::string& fstr, char* beginp, std::size_t n,
|
||||
const bool inhibit = false) {
|
||||
static char* _vl_vsss_read_bin(FILE* fp, int& floc, const WDataInP fromp, const std::string& fstr,
|
||||
char* beginp, std::size_t n, const bool inhibit = false) {
|
||||
// Variant of _vl_vsss_read_str using the same underlying I/O functions but optimized
|
||||
// specifically for block reads of N bytes (read operations are not demarcated by
|
||||
// whitespace). In the fp case, except descriptor to have been opened in binary mode.
|
||||
|
|
@ -1073,12 +1071,11 @@ static inline char* _vl_vsss_read_bin(FILE* fp, int& floc, const WDataInP fromp,
|
|||
}
|
||||
return beginp;
|
||||
}
|
||||
static inline void _vl_vsss_setbit(WDataOutP owp, int obits, int lsb, int nbits,
|
||||
IData ld) VL_MT_SAFE {
|
||||
static void _vl_vsss_setbit(WDataOutP owp, int obits, int lsb, int nbits, IData ld) VL_MT_SAFE {
|
||||
for (; nbits && lsb < obits; nbits--, lsb++, ld >>= 1) { VL_ASSIGNBIT_WI(lsb, owp, ld & 1); }
|
||||
}
|
||||
static inline void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const char* strp,
|
||||
size_t posstart, size_t posend) VL_MT_SAFE {
|
||||
static void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const char* strp,
|
||||
size_t posstart, size_t posend) VL_MT_SAFE {
|
||||
// Read in base "2^^baseLog2" digits from strp[posstart..posend-1] into owp of size obits.
|
||||
int lsb = 0;
|
||||
for (int i = 0, pos = static_cast<int>(posend) - 1;
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ protected:
|
|||
public:
|
||||
/// Returns the VerilatedContext this model is instantiated under
|
||||
/// Used to get to e.g. simulation time via contextp()->time()
|
||||
inline VerilatedContext* contextp() const { return &m_context; }
|
||||
VerilatedContext* contextp() const { return &m_context; }
|
||||
/// Returns the hierarchical name of this module instance.
|
||||
virtual const char* hierName() const = 0;
|
||||
/// Returns the name of this model (the name of the generated model class).
|
||||
|
|
@ -457,9 +457,9 @@ public:
|
|||
VerilatedCovContext* coveragep() VL_MT_SAFE;
|
||||
/// Set debug level
|
||||
/// Debug is currently global, but for forward compatibility have a per-context method
|
||||
static void debug(int val) VL_MT_SAFE;
|
||||
static inline void debug(int val) VL_MT_SAFE;
|
||||
/// Return debug level
|
||||
static int debug() VL_MT_SAFE;
|
||||
static inline int debug() VL_MT_SAFE;
|
||||
/// Set current number of errors/assertions
|
||||
void errorCount(int val) VL_MT_SAFE;
|
||||
/// Increment current number of errors/assertions
|
||||
|
|
@ -521,7 +521,7 @@ public:
|
|||
///
|
||||
/// * Else, time comes from the legacy 'double sc_time_stamp()' which
|
||||
/// must be a function defined by the user's wrapper.
|
||||
uint64_t time() const VL_MT_SAFE;
|
||||
inline uint64_t time() const VL_MT_SAFE;
|
||||
/// Set current simulation time. See time() for side effect details
|
||||
void time(uint64_t value) VL_MT_SAFE { m_s.m_time = value; }
|
||||
/// Advance current simulation time. See time() for side effect details
|
||||
|
|
@ -652,13 +652,13 @@ public: // But internals only - called from VerilatedModule's
|
|||
const char* name() const { return m_namep; }
|
||||
const char* identifier() const { return m_identifierp; }
|
||||
int8_t timeunit() const { return m_timeunit; }
|
||||
inline VerilatedSyms* symsp() const { return m_symsp; }
|
||||
VerilatedSyms* symsp() const { return m_symsp; }
|
||||
VerilatedVar* varFind(const char* namep) const VL_MT_SAFE_POSTINIT;
|
||||
VerilatedVarNameMap* varsp() const VL_MT_SAFE_POSTINIT { return m_varsp; }
|
||||
void scopeDump() const;
|
||||
void* exportFindError(int funcnum) const;
|
||||
static void* exportFindNullError(int funcnum) VL_MT_SAFE;
|
||||
static inline void* exportFind(const VerilatedScope* scopep, int funcnum) VL_MT_SAFE {
|
||||
static void* exportFind(const VerilatedScope* scopep, int funcnum) VL_MT_SAFE {
|
||||
if (VL_UNLIKELY(!scopep)) return exportFindNullError(funcnum);
|
||||
if (VL_LIKELY(funcnum < scopep->m_funcnumMax)) {
|
||||
// m_callbacksp must be declared, as Max'es are > 0
|
||||
|
|
@ -727,7 +727,7 @@ public:
|
|||
/// Return debug level
|
||||
/// When multithreaded this may not immediately react to another thread
|
||||
/// changing the level (no mutex)
|
||||
static inline int debug() VL_MT_SAFE { return s_debug; }
|
||||
static int debug() VL_MT_SAFE { return s_debug; }
|
||||
#else
|
||||
/// Return constant 0 debug level, so C++'s optimizer rips up
|
||||
static constexpr int debug() VL_PURE { return 0; }
|
||||
|
|
@ -933,8 +933,8 @@ private:
|
|||
#endif
|
||||
};
|
||||
|
||||
inline void VerilatedContext::debug(int val) VL_MT_SAFE { Verilated::debug(val); }
|
||||
inline int VerilatedContext::debug() VL_MT_SAFE { return Verilated::debug(); }
|
||||
void VerilatedContext::debug(int val) VL_MT_SAFE { Verilated::debug(val); }
|
||||
int VerilatedContext::debug() VL_MT_SAFE { return Verilated::debug(); }
|
||||
|
||||
//=========================================================================
|
||||
// Data Types
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ void svPutPartselLogic(svLogicVecVal* dp, const svLogicVecVal s, int lbit, int w
|
|||
//======================================================================
|
||||
// Open array internals
|
||||
|
||||
static inline const VerilatedDpiOpenVar* _vl_openhandle_varp(const svOpenArrayHandle h) {
|
||||
static const VerilatedDpiOpenVar* _vl_openhandle_varp(const svOpenArrayHandle h) {
|
||||
if (VL_UNLIKELY(!h)) {
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "",
|
||||
"%%Error: DPI svOpenArrayHandle function called with nullptr handle");
|
||||
|
|
|
|||
|
|
@ -161,13 +161,13 @@ class VerilatedFstBuffer VL_NOT_FINAL {
|
|||
|
||||
// Implementations of duck-typed methods for VerilatedTraceBuffer. These are
|
||||
// called from only one place (the full* methods), so always inline them.
|
||||
VL_ATTR_ALWINLINE inline void emitBit(uint32_t code, CData newval);
|
||||
VL_ATTR_ALWINLINE inline void emitCData(uint32_t code, CData newval, int bits);
|
||||
VL_ATTR_ALWINLINE inline void emitSData(uint32_t code, SData newval, int bits);
|
||||
VL_ATTR_ALWINLINE inline void emitIData(uint32_t code, IData newval, int bits);
|
||||
VL_ATTR_ALWINLINE inline void emitQData(uint32_t code, QData newval, int bits);
|
||||
VL_ATTR_ALWINLINE inline void emitWData(uint32_t code, const WData* newvalp, int bits);
|
||||
VL_ATTR_ALWINLINE inline void emitDouble(uint32_t code, double newval);
|
||||
VL_ATTR_ALWINLINE void emitBit(uint32_t code, CData newval);
|
||||
VL_ATTR_ALWINLINE void emitCData(uint32_t code, CData newval, int bits);
|
||||
VL_ATTR_ALWINLINE void emitSData(uint32_t code, SData newval, int bits);
|
||||
VL_ATTR_ALWINLINE void emitIData(uint32_t code, IData newval, int bits);
|
||||
VL_ATTR_ALWINLINE void emitQData(uint32_t code, QData newval, int bits);
|
||||
VL_ATTR_ALWINLINE void emitWData(uint32_t code, const WData* newvalp, int bits);
|
||||
VL_ATTR_ALWINLINE void emitDouble(uint32_t code, double newval);
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
|
|
@ -232,7 +232,7 @@ public:
|
|||
}
|
||||
|
||||
// Internal class access
|
||||
inline VerilatedFst* spTrace() { return &m_sptrace; }
|
||||
VerilatedFst* spTrace() { return &m_sptrace; }
|
||||
};
|
||||
|
||||
#endif // guard
|
||||
|
|
|
|||
|
|
@ -52,35 +52,35 @@ public:
|
|||
}
|
||||
spTrace()->set_time_resolution(sc_get_time_resolution().to_string());
|
||||
}
|
||||
virtual ~VerilatedFstSc() /*override*/ { close(); }
|
||||
~VerilatedFstSc() override { close(); }
|
||||
|
||||
// METHODS
|
||||
/// Called by SystemC simulate()
|
||||
virtual void cycle(bool delta_cycle) {
|
||||
void cycle(bool delta_cycle) override {
|
||||
if (!delta_cycle) { this->dump(sc_time_stamp().to_double()); }
|
||||
}
|
||||
|
||||
// Override VerilatedFstC. Must be called after starting simulation.
|
||||
// cppcheck-suppress missingOverride // GCC won't accept override
|
||||
virtual void open(const char* filename) /*override*/ VL_MT_SAFE;
|
||||
// Note: this is not a virtual function in the base class, so no 'override'
|
||||
virtual void open(const char* filename) VL_MT_SAFE;
|
||||
|
||||
private:
|
||||
/// Fake outs for linker
|
||||
|
||||
#ifdef NC_SYSTEMC
|
||||
// Cadence Incisive has these as abstract functions so we must create them
|
||||
virtual void set_time_unit(int exponent10_seconds) {} // deprecated
|
||||
void set_time_unit(int exponent10_seconds) override {} // deprecated
|
||||
#endif
|
||||
virtual void set_time_unit(double v, sc_time_unit tu) {} // LCOV_EXCL_LINE
|
||||
void set_time_unit(double v, sc_time_unit tu) override {} // LCOV_EXCL_LINE
|
||||
|
||||
//--------------------------------------------------
|
||||
// SystemC 2.1.v1
|
||||
#define DECL_TRACE_METHOD_A(tp) virtual void trace(const tp& object, const std::string& name);
|
||||
#define DECL_TRACE_METHOD_A(tp) void trace(const tp& object, const std::string& name) override;
|
||||
#define DECL_TRACE_METHOD_B(tp) \
|
||||
virtual void trace(const tp& object, const std::string& name, int width);
|
||||
void trace(const tp& object, const std::string& name, int width) override;
|
||||
|
||||
virtual void write_comment(const std::string&);
|
||||
virtual void trace(const unsigned int&, const std::string&, const char**);
|
||||
void write_comment(const std::string&) override;
|
||||
void trace(const unsigned int&, const std::string&, const char**) override;
|
||||
|
||||
// clang-format off
|
||||
// Formatting matches that of sc_trace.h
|
||||
|
|
|
|||
|
|
@ -282,7 +282,7 @@ inline uint64_t vl_time_stamp64() {
|
|||
# endif
|
||||
#endif
|
||||
|
||||
inline uint64_t VerilatedContext::time() const VL_MT_SAFE {
|
||||
uint64_t VerilatedContext::time() const VL_MT_SAFE {
|
||||
// When using non-default context, fastest path is return time
|
||||
if (VL_LIKELY(m_s.m_time)) return m_s.m_time;
|
||||
#if defined(SYSTEMC_VERSION) || (!defined(VL_TIME_CONTEXT) && !defined(VL_NO_LEGACY))
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ public: // But only for verilated*.cpp
|
|||
}
|
||||
}
|
||||
}
|
||||
inline FILE* fdToFp(IData fdi) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
||||
FILE* fdToFp(IData fdi) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
||||
const VerilatedLockGuard lock{m_fdMutex};
|
||||
const VerilatedFpList fdlist = fdToFpList(fdi);
|
||||
if (VL_UNLIKELY(fdlist.size() != 1)) return nullptr;
|
||||
|
|
@ -466,7 +466,7 @@ public:
|
|||
// There's often many more scopes than userdata's and thus having a ~48byte
|
||||
// per map overhead * N scopes would take much more space and cache thrashing.
|
||||
// As scopep's are pointers, this implicitly handles multiple Context's
|
||||
static inline void userInsert(const void* scopep, void* userKey, void* userData) VL_MT_SAFE {
|
||||
static void userInsert(const void* scopep, void* userKey, void* userData) VL_MT_SAFE {
|
||||
const VerilatedLockGuard lock{s().m_userMapMutex};
|
||||
const auto it = s().m_userMap.find(std::make_pair(scopep, userKey));
|
||||
if (it != s().m_userMap.end()) {
|
||||
|
|
@ -475,7 +475,7 @@ public:
|
|||
s().m_userMap.emplace(std::make_pair(scopep, userKey), userData);
|
||||
}
|
||||
}
|
||||
static inline void* userFind(const void* scopep, void* userKey) VL_MT_SAFE {
|
||||
static void* userFind(const void* scopep, void* userKey) VL_MT_SAFE {
|
||||
const VerilatedLockGuard lock{s().m_userMapMutex};
|
||||
const auto& it = vlstd::as_const(s().m_userMap).find(std::make_pair(scopep, userKey));
|
||||
if (VL_UNLIKELY(it == s().m_userMap.end())) return nullptr;
|
||||
|
|
|
|||
|
|
@ -45,8 +45,7 @@ class VlThreadPool;
|
|||
|
||||
//=============================================================================
|
||||
// Return high-precision counter for profiling, or 0x0 if not available
|
||||
VL_ATTR_ALWINLINE
|
||||
inline QData VL_CPU_TICK() {
|
||||
VL_ATTR_ALWINLINE QData VL_CPU_TICK() {
|
||||
uint64_t val;
|
||||
VL_GET_CPU_TICK(val);
|
||||
return val;
|
||||
|
|
@ -171,9 +170,9 @@ public:
|
|||
// METHODS
|
||||
|
||||
// Is profiling enabled
|
||||
inline bool enabled() const { return m_enabled; }
|
||||
bool enabled() const { return m_enabled; }
|
||||
// Append a trace record to the trace buffer of the current thread
|
||||
static inline VlExecutionRecord& addRecord() {
|
||||
static VlExecutionRecord& addRecord() {
|
||||
t_trace.emplace_back();
|
||||
return t_trace.back();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -103,7 +103,7 @@ public:
|
|||
// Upstream mtasks must call this when they complete.
|
||||
// Returns true when the current MTaskVertex becomes ready to execute,
|
||||
// false while it's still waiting on more dependencies.
|
||||
inline bool signalUpstreamDone(bool evenCycle) {
|
||||
bool signalUpstreamDone(bool evenCycle) {
|
||||
if (evenCycle) {
|
||||
const uint32_t upstreamDepsDone
|
||||
= 1 + m_upstreamDepsDone.fetch_add(1, std::memory_order_release);
|
||||
|
|
@ -116,11 +116,11 @@ public:
|
|||
return (upstreamDepsDone_prev == 1);
|
||||
}
|
||||
}
|
||||
inline bool areUpstreamDepsDone(bool evenCycle) const {
|
||||
bool areUpstreamDepsDone(bool evenCycle) const {
|
||||
const uint32_t target = evenCycle ? m_upstreamDepCount : 0;
|
||||
return m_upstreamDepsDone.load(std::memory_order_acquire) == target;
|
||||
}
|
||||
inline void waitUntilUpstreamDone(bool evenCycle) const {
|
||||
void waitUntilUpstreamDone(bool evenCycle) const {
|
||||
unsigned ct = 0;
|
||||
while (VL_UNLIKELY(!areUpstreamDepsDone(evenCycle))) {
|
||||
VL_CPU_RELAX();
|
||||
|
|
@ -171,7 +171,7 @@ public:
|
|||
|
||||
// METHODS
|
||||
template <bool SpinWait>
|
||||
inline void dequeWork(ExecRec* workp) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
void dequeWork(ExecRec* workp) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
// Spin for a while, waiting for new data
|
||||
if VL_CONSTEXPR_CXX17 (SpinWait) {
|
||||
for (unsigned i = 0; i < VL_LOCK_SPINS; ++i) {
|
||||
|
|
@ -191,7 +191,7 @@ public:
|
|||
m_ready.erase(m_ready.begin());
|
||||
m_ready_size.fetch_sub(1, std::memory_order_relaxed);
|
||||
}
|
||||
inline void addTask(VlExecFnp fnp, VlSelfP selfp, bool evenCycle = false)
|
||||
void addTask(VlExecFnp fnp, VlSelfP selfp, bool evenCycle = false)
|
||||
VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
bool notify;
|
||||
{
|
||||
|
|
@ -223,8 +223,8 @@ public:
|
|||
~VlThreadPool() override;
|
||||
|
||||
// METHODS
|
||||
inline int numThreads() const { return m_workers.size(); }
|
||||
inline VlWorkerThread* workerp(int index) {
|
||||
int numThreads() const { return m_workers.size(); }
|
||||
VlWorkerThread* workerp(int index) {
|
||||
assert(index >= 0);
|
||||
assert(index < m_workers.size());
|
||||
return m_workers[index];
|
||||
|
|
|
|||
|
|
@ -318,8 +318,8 @@ protected:
|
|||
void flushBase();
|
||||
|
||||
#ifdef VL_THREADED
|
||||
inline bool offload() const { return m_offload; }
|
||||
inline bool parallel() const { return m_parallel; }
|
||||
bool offload() const { return m_offload; }
|
||||
bool parallel() const { return m_parallel; }
|
||||
#else
|
||||
static constexpr bool offload() { return false; }
|
||||
static constexpr bool parallel() { return false; }
|
||||
|
|
@ -425,7 +425,7 @@ public:
|
|||
// duck-typed void emitWData(uint32_t code, const WData* newvalp, int bits) = 0;
|
||||
// duck-typed void emitDouble(uint32_t code, double newval) = 0;
|
||||
|
||||
VL_ATTR_ALWINLINE inline uint32_t* oldp(uint32_t code) { return m_sigs_oldvalp + code; }
|
||||
VL_ATTR_ALWINLINE uint32_t* oldp(uint32_t code) { return m_sigs_oldvalp + code; }
|
||||
|
||||
// Write to previous value buffer value and emit trace entry.
|
||||
void fullBit(uint32_t* oldp, CData newval);
|
||||
|
|
@ -441,27 +441,27 @@ public:
|
|||
// thread and are called chg*Impl
|
||||
|
||||
// Check previous dumped value of signal. If changed, then emit trace entry
|
||||
VL_ATTR_ALWINLINE inline void chgBit(uint32_t* oldp, CData newval) {
|
||||
VL_ATTR_ALWINLINE void chgBit(uint32_t* oldp, CData newval) {
|
||||
const uint32_t diff = *oldp ^ newval;
|
||||
if (VL_UNLIKELY(diff)) fullBit(oldp, newval);
|
||||
}
|
||||
VL_ATTR_ALWINLINE inline void chgCData(uint32_t* oldp, CData newval, int bits) {
|
||||
VL_ATTR_ALWINLINE void chgCData(uint32_t* oldp, CData newval, int bits) {
|
||||
const uint32_t diff = *oldp ^ newval;
|
||||
if (VL_UNLIKELY(diff)) fullCData(oldp, newval, bits);
|
||||
}
|
||||
VL_ATTR_ALWINLINE inline void chgSData(uint32_t* oldp, SData newval, int bits) {
|
||||
VL_ATTR_ALWINLINE void chgSData(uint32_t* oldp, SData newval, int bits) {
|
||||
const uint32_t diff = *oldp ^ newval;
|
||||
if (VL_UNLIKELY(diff)) fullSData(oldp, newval, bits);
|
||||
}
|
||||
VL_ATTR_ALWINLINE inline void chgIData(uint32_t* oldp, IData newval, int bits) {
|
||||
VL_ATTR_ALWINLINE void chgIData(uint32_t* oldp, IData newval, int bits) {
|
||||
const uint32_t diff = *oldp ^ newval;
|
||||
if (VL_UNLIKELY(diff)) fullIData(oldp, newval, bits);
|
||||
}
|
||||
VL_ATTR_ALWINLINE inline void chgQData(uint32_t* oldp, QData newval, int bits) {
|
||||
VL_ATTR_ALWINLINE void chgQData(uint32_t* oldp, QData newval, int bits) {
|
||||
const uint64_t diff = *reinterpret_cast<QData*>(oldp) ^ newval;
|
||||
if (VL_UNLIKELY(diff)) fullQData(oldp, newval, bits);
|
||||
}
|
||||
VL_ATTR_ALWINLINE inline void chgWData(uint32_t* oldp, const WData* newvalp, int bits) {
|
||||
VL_ATTR_ALWINLINE void chgWData(uint32_t* oldp, const WData* newvalp, int bits) {
|
||||
for (int i = 0; i < (bits + 31) / 32; ++i) {
|
||||
if (VL_UNLIKELY(oldp[i] ^ newvalp[i])) {
|
||||
fullWData(oldp, newvalp, bits);
|
||||
|
|
@ -469,7 +469,7 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
VL_ATTR_ALWINLINE inline void chgDouble(uint32_t* oldp, double newval) {
|
||||
VL_ATTR_ALWINLINE void chgDouble(uint32_t* oldp, double newval) {
|
||||
// cppcheck-suppress invalidPointerCast
|
||||
if (VL_UNLIKELY(*reinterpret_cast<double*>(oldp) != newval)) fullDouble(oldp, newval);
|
||||
}
|
||||
|
|
@ -498,48 +498,48 @@ public:
|
|||
// Hot path internal interface to Verilator generated code
|
||||
|
||||
// Offloaded tracing. Just dump everything in the offload buffer
|
||||
inline void chgBit(uint32_t code, CData newval) {
|
||||
void chgBit(uint32_t code, CData newval) {
|
||||
m_offloadBufferWritep[0] = VerilatedTraceOffloadCommand::CHG_BIT_0 | newval;
|
||||
m_offloadBufferWritep[1] = code;
|
||||
m_offloadBufferWritep += 2;
|
||||
VL_DEBUG_IF(assert(m_offloadBufferWritep <= m_offloadBufferEndp););
|
||||
}
|
||||
inline void chgCData(uint32_t code, CData newval, int bits) {
|
||||
void chgCData(uint32_t code, CData newval, int bits) {
|
||||
m_offloadBufferWritep[0] = (bits << 4) | VerilatedTraceOffloadCommand::CHG_CDATA;
|
||||
m_offloadBufferWritep[1] = code;
|
||||
m_offloadBufferWritep[2] = newval;
|
||||
m_offloadBufferWritep += 3;
|
||||
VL_DEBUG_IF(assert(m_offloadBufferWritep <= m_offloadBufferEndp););
|
||||
}
|
||||
inline void chgSData(uint32_t code, SData newval, int bits) {
|
||||
void chgSData(uint32_t code, SData newval, int bits) {
|
||||
m_offloadBufferWritep[0] = (bits << 4) | VerilatedTraceOffloadCommand::CHG_SDATA;
|
||||
m_offloadBufferWritep[1] = code;
|
||||
m_offloadBufferWritep[2] = newval;
|
||||
m_offloadBufferWritep += 3;
|
||||
VL_DEBUG_IF(assert(m_offloadBufferWritep <= m_offloadBufferEndp););
|
||||
}
|
||||
inline void chgIData(uint32_t code, IData newval, int bits) {
|
||||
void chgIData(uint32_t code, IData newval, int bits) {
|
||||
m_offloadBufferWritep[0] = (bits << 4) | VerilatedTraceOffloadCommand::CHG_IDATA;
|
||||
m_offloadBufferWritep[1] = code;
|
||||
m_offloadBufferWritep[2] = newval;
|
||||
m_offloadBufferWritep += 3;
|
||||
VL_DEBUG_IF(assert(m_offloadBufferWritep <= m_offloadBufferEndp););
|
||||
}
|
||||
inline void chgQData(uint32_t code, QData newval, int bits) {
|
||||
void chgQData(uint32_t code, QData newval, int bits) {
|
||||
m_offloadBufferWritep[0] = (bits << 4) | VerilatedTraceOffloadCommand::CHG_QDATA;
|
||||
m_offloadBufferWritep[1] = code;
|
||||
*reinterpret_cast<QData*>(m_offloadBufferWritep + 2) = newval;
|
||||
m_offloadBufferWritep += 4;
|
||||
VL_DEBUG_IF(assert(m_offloadBufferWritep <= m_offloadBufferEndp););
|
||||
}
|
||||
inline void chgWData(uint32_t code, const WData* newvalp, int bits) {
|
||||
void chgWData(uint32_t code, const WData* newvalp, int bits) {
|
||||
m_offloadBufferWritep[0] = (bits << 4) | VerilatedTraceOffloadCommand::CHG_WDATA;
|
||||
m_offloadBufferWritep[1] = code;
|
||||
m_offloadBufferWritep += 2;
|
||||
for (int i = 0; i < (bits + 31) / 32; ++i) { *m_offloadBufferWritep++ = newvalp[i]; }
|
||||
VL_DEBUG_IF(assert(m_offloadBufferWritep <= m_offloadBufferEndp););
|
||||
}
|
||||
inline void chgDouble(uint32_t code, double newval) {
|
||||
void chgDouble(uint32_t code, double newval) {
|
||||
m_offloadBufferWritep[0] = VerilatedTraceOffloadCommand::CHG_DOUBLE;
|
||||
m_offloadBufferWritep[1] = code;
|
||||
// cppcheck-suppress invalidPointerCast
|
||||
|
|
|
|||
|
|
@ -966,7 +966,7 @@ struct VlUnpacked final {
|
|||
|
||||
// *this != that, which might be used for change detection/trigger computation, but avoid
|
||||
// operator overloading in VlUnpacked for safety in other contexts.
|
||||
inline bool neq(const VlUnpacked<T_Value, T_Depth>& that) const { return neq(*this, that); }
|
||||
bool neq(const VlUnpacked<T_Value, T_Depth>& that) const { return neq(*this, that); }
|
||||
// Similar to 'neq' above, *this = that used for change detection
|
||||
void assign(const VlUnpacked<T_Value, T_Depth>& that) { *this = that; }
|
||||
|
||||
|
|
@ -992,7 +992,7 @@ private:
|
|||
}
|
||||
|
||||
template <typename T_Other> //
|
||||
inline static bool neq(const T_Other& a, const T_Other& b) {
|
||||
static bool neq(const T_Other& a, const T_Other& b) {
|
||||
// Base case (T_Other is not VlUnpacked<_, _>), fall back on !=
|
||||
return a != b;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -632,10 +632,10 @@ void VerilatedVcd::commitTraceBuffer(VerilatedVcd::Buffer* bufp) {
|
|||
//=============================================================================
|
||||
// Trace rendering primitives
|
||||
|
||||
static inline void
|
||||
VerilatedVcdCCopyAndAppendNewLine(char* writep, const char* suffixp) VL_ATTR_NO_SANITIZE_ALIGN;
|
||||
static void VerilatedVcdCCopyAndAppendNewLine(char* writep,
|
||||
const char* suffixp) VL_ATTR_NO_SANITIZE_ALIGN;
|
||||
|
||||
static inline void VerilatedVcdCCopyAndAppendNewLine(char* writep, const char* suffixp) {
|
||||
static void VerilatedVcdCCopyAndAppendNewLine(char* writep, const char* suffixp) {
|
||||
// Copy the whole suffix (this avoid having hard to predict branches which
|
||||
// helps a lot). Note: The maximum length of the suffix is
|
||||
// VL_TRACE_MAX_VCD_CODE_SIZE + 2 == 7, but we unroll this here for speed.
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ private:
|
|||
|
||||
void bufferResize(size_t minsize);
|
||||
void bufferFlush() VL_MT_UNSAFE_ONE;
|
||||
inline void bufferCheck() {
|
||||
void bufferCheck() {
|
||||
// Flush the write buffer if there's not enough space left for new information
|
||||
// We only call this once per vector, so we need enough slop for a very wide "b###" line
|
||||
if (VL_UNLIKELY(m_writep > m_wrFlushp)) bufferFlush();
|
||||
|
|
@ -210,13 +210,13 @@ class VerilatedVcdBuffer VL_NOT_FINAL {
|
|||
// Implementation of VerilatedTraceBuffer interface
|
||||
// Implementations of duck-typed methods for VerilatedTraceBuffer. These are
|
||||
// called from only one place (the full* methods), so always inline them.
|
||||
VL_ATTR_ALWINLINE inline void emitBit(uint32_t code, CData newval);
|
||||
VL_ATTR_ALWINLINE inline void emitCData(uint32_t code, CData newval, int bits);
|
||||
VL_ATTR_ALWINLINE inline void emitSData(uint32_t code, SData newval, int bits);
|
||||
VL_ATTR_ALWINLINE inline void emitIData(uint32_t code, IData newval, int bits);
|
||||
VL_ATTR_ALWINLINE inline void emitQData(uint32_t code, QData newval, int bits);
|
||||
VL_ATTR_ALWINLINE inline void emitWData(uint32_t code, const WData* newvalp, int bits);
|
||||
VL_ATTR_ALWINLINE inline void emitDouble(uint32_t code, double newval);
|
||||
VL_ATTR_ALWINLINE void emitBit(uint32_t code, CData newval);
|
||||
VL_ATTR_ALWINLINE void emitCData(uint32_t code, CData newval, int bits);
|
||||
VL_ATTR_ALWINLINE void emitSData(uint32_t code, SData newval, int bits);
|
||||
VL_ATTR_ALWINLINE void emitIData(uint32_t code, IData newval, int bits);
|
||||
VL_ATTR_ALWINLINE void emitQData(uint32_t code, QData newval, int bits);
|
||||
VL_ATTR_ALWINLINE void emitWData(uint32_t code, const WData* newvalp, int bits);
|
||||
VL_ATTR_ALWINLINE void emitDouble(uint32_t code, double newval);
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
|
|
@ -313,7 +313,7 @@ public:
|
|||
}
|
||||
|
||||
// Internal class access
|
||||
inline VerilatedVcd* spTrace() { return &m_sptrace; }
|
||||
VerilatedVcd* spTrace() { return &m_sptrace; }
|
||||
};
|
||||
|
||||
#endif // guard
|
||||
|
|
|
|||
|
|
@ -55,35 +55,34 @@ public:
|
|||
spTrace()->set_time_resolution(sc_get_time_resolution().to_string());
|
||||
}
|
||||
/// Destruct, flush, and close the dump
|
||||
virtual ~VerilatedVcdSc() /*override*/ { close(); }
|
||||
~VerilatedVcdSc() override { close(); }
|
||||
|
||||
// METHODS - for SC kernel
|
||||
// Called by SystemC simulate()
|
||||
virtual void cycle(bool delta_cycle) {
|
||||
void cycle(bool delta_cycle) override {
|
||||
if (!delta_cycle) this->dump(sc_time_stamp().to_double());
|
||||
}
|
||||
|
||||
// Override VerilatedVcdC. Must be called after starting simulation.
|
||||
// cppcheck-suppress missingOverride // GCC won't accept override
|
||||
virtual void open(const char* filename) /*override*/ VL_MT_SAFE;
|
||||
void open(const char* filename) override VL_MT_SAFE;
|
||||
|
||||
private:
|
||||
// METHODS - Fake outs for linker
|
||||
|
||||
#ifdef NC_SYSTEMC
|
||||
// Cadence Incisive has these as abstract functions so we must create them
|
||||
virtual void set_time_unit(int exponent10_seconds) {} // deprecated
|
||||
void set_time_unit(int exponent10_seconds) override {} // deprecated
|
||||
#endif
|
||||
virtual void set_time_unit(double v, sc_time_unit tu) {} // LCOV_EXCL_LINE
|
||||
void set_time_unit(double v, sc_time_unit tu) override {} // LCOV_EXCL_LINE
|
||||
|
||||
//--------------------------------------------------
|
||||
// SystemC 2.1.v1
|
||||
#define DECL_TRACE_METHOD_A(tp) virtual void trace(const tp& object, const std::string& name);
|
||||
#define DECL_TRACE_METHOD_A(tp) void trace(const tp& object, const std::string& name) override;
|
||||
#define DECL_TRACE_METHOD_B(tp) \
|
||||
virtual void trace(const tp& object, const std::string& name, int width);
|
||||
void trace(const tp& object, const std::string& name, int width) override;
|
||||
|
||||
virtual void write_comment(const std::string&);
|
||||
virtual void trace(const unsigned int&, const std::string&, const char**);
|
||||
void write_comment(const std::string&) override;
|
||||
void trace(const unsigned int&, const std::string&, const char**) override;
|
||||
|
||||
// clang-format off
|
||||
// Formatting matches that of sc_trace.h
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ public:
|
|||
static VerilatedVpio* castp(vpiHandle h) {
|
||||
return dynamic_cast<VerilatedVpio*>(reinterpret_cast<VerilatedVpio*>(h));
|
||||
}
|
||||
inline vpiHandle castVpiHandle() { return reinterpret_cast<vpiHandle>(this); }
|
||||
vpiHandle castVpiHandle() { return reinterpret_cast<vpiHandle>(this); }
|
||||
// ACCESSORS
|
||||
virtual const char* name() const { return "<null>"; }
|
||||
virtual const char* fullname() const { return "<null>"; }
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
#ifdef __GNUC__
|
||||
# define VL_ATTR_ALIGNED(alignment) __attribute__((aligned(alignment)))
|
||||
# define VL_ATTR_ALWINLINE __attribute__((always_inline))
|
||||
# define VL_ATTR_ALWINLINE __attribute__((always_inline)) inline
|
||||
# define VL_ATTR_NOINLINE __attribute__((noinline))
|
||||
# define VL_ATTR_COLD __attribute__((cold))
|
||||
# define VL_ATTR_HOT __attribute__((hot))
|
||||
|
|
@ -548,8 +548,8 @@ struct reverse_wrapper {
|
|||
|
||||
explicit reverse_wrapper(const T& a_v)
|
||||
: m_v(a_v) {}
|
||||
inline auto begin() -> decltype(m_v.rbegin()) { return m_v.rbegin(); }
|
||||
inline auto end() -> decltype(m_v.rend()) { return m_v.rend(); }
|
||||
auto begin() -> decltype(m_v.rbegin()) { return m_v.rbegin(); }
|
||||
auto end() -> decltype(m_v.rend()) { return m_v.rend(); }
|
||||
};
|
||||
|
||||
// C++20's std::ranges::reverse_view
|
||||
|
|
|
|||
|
|
@ -66,8 +66,8 @@ public:
|
|||
: V3GraphVertex{graphp}
|
||||
, m_name{name}
|
||||
, m_type{type} {}
|
||||
virtual string name() const override { return m_name + " " + typestr(); }
|
||||
virtual string dotColor() const override { return user() ? "green" : "black"; }
|
||||
string name() const override { return m_name + " " + typestr(); }
|
||||
string dotColor() const override { return user() ? "green" : "black"; }
|
||||
virtual int type() const { return m_type; }
|
||||
};
|
||||
|
||||
|
|
@ -120,7 +120,7 @@ protected:
|
|||
|
||||
public:
|
||||
LatchDetectGraph() { clear(); }
|
||||
virtual ~LatchDetectGraph() override { clear(); }
|
||||
~LatchDetectGraph() override { clear(); }
|
||||
// ACCESSORS
|
||||
LatchDetectGraphVertex* currentp() { return m_curVertexp; }
|
||||
void currentp(LatchDetectGraphVertex* vertex) { m_curVertexp = vertex; }
|
||||
|
|
@ -222,7 +222,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstScope* nodep) override {
|
||||
void visit(AstScope* nodep) override {
|
||||
m_scopep = nodep;
|
||||
m_sActivep = nullptr;
|
||||
m_iActivep = nullptr;
|
||||
|
|
@ -232,13 +232,13 @@ private:
|
|||
iterateChildren(nodep);
|
||||
// Don't clear scopep, the namer persists beyond this visit
|
||||
}
|
||||
virtual void visit(AstSenTree* nodep) override {
|
||||
void visit(AstSenTree* nodep) override {
|
||||
// Simplify sensitivity list
|
||||
VL_DO_DANGLING(V3Const::constifyExpensiveEdit(nodep), nodep);
|
||||
}
|
||||
//--------------------
|
||||
virtual void visit(AstNodeStmt*) override {} // Accelerate
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNodeStmt*) override {} // Accelerate
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
// Specialized below for the special sensitivity classes
|
||||
template <typename SenItemKind>
|
||||
|
|
@ -280,7 +280,7 @@ public:
|
|||
|
||||
// CONSTRUCTORS
|
||||
ActiveNamer() = default;
|
||||
virtual ~ActiveNamer() override = default;
|
||||
~ActiveNamer() override = default;
|
||||
void main(AstScope* nodep) { iterate(nodep); }
|
||||
};
|
||||
|
||||
|
|
@ -313,13 +313,13 @@ private:
|
|||
// STATE
|
||||
LatchDetectGraph m_graph; // Graph used to detect latches in combo always
|
||||
// VISITORS
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
const AstVar* const varp = nodep->varp();
|
||||
if (nodep->access().isWriteOrRW() && varp->isSignal() && !varp->isUsedLoopIdx()) {
|
||||
m_graph.addAssignment(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeIf* nodep) override {
|
||||
void visit(AstNodeIf* nodep) override {
|
||||
if (!nodep->isBoundsCheck()) {
|
||||
LatchDetectGraphVertex* const parentp = m_graph.currentp();
|
||||
LatchDetectGraphVertex* const branchp = m_graph.addPathVertex(parentp, "BRANCH", true);
|
||||
|
|
@ -331,7 +331,7 @@ private:
|
|||
}
|
||||
}
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
@ -355,7 +355,7 @@ private:
|
|||
const CheckType m_check; // Process type we are checking
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstAssignDly* nodep) override {
|
||||
void visit(AstAssignDly* nodep) override {
|
||||
// Non-blocking assignments are OK in sequential processes
|
||||
if (m_check == CT_SEQ) return;
|
||||
|
||||
|
|
@ -381,7 +381,7 @@ private:
|
|||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstAssign* nodep) override {
|
||||
void visit(AstAssign* nodep) override {
|
||||
// Blocking assignments are always OK in combinational (and initial/final) processes
|
||||
if (m_check != CT_SEQ) return;
|
||||
|
||||
|
|
@ -404,7 +404,7 @@ private:
|
|||
}
|
||||
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
@ -505,36 +505,30 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstScope* nodep) override {
|
||||
void visit(AstScope* nodep) override {
|
||||
m_namer.main(nodep); // Clear last scope's names, and collect this scope's existing names
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstActive* nodep) override {
|
||||
void visit(AstActive* nodep) override {
|
||||
// Actives are being formed, so we can ignore any already made
|
||||
}
|
||||
|
||||
virtual void visit(AstInitialStatic* nodep) override {
|
||||
moveUnderSpecial<AstSenItem::Static>(nodep);
|
||||
}
|
||||
virtual void visit(AstInitial* nodep) override {
|
||||
void visit(AstInitialStatic* nodep) override { moveUnderSpecial<AstSenItem::Static>(nodep); }
|
||||
void visit(AstInitial* nodep) override {
|
||||
const ActiveDlyVisitor dlyvisitor{nodep, ActiveDlyVisitor::CT_INITIAL};
|
||||
visitSenItems(nodep);
|
||||
moveUnderSpecial<AstSenItem::Initial>(nodep);
|
||||
}
|
||||
virtual void visit(AstFinal* nodep) override {
|
||||
void visit(AstFinal* nodep) override {
|
||||
const ActiveDlyVisitor dlyvisitor{nodep, ActiveDlyVisitor::CT_INITIAL};
|
||||
moveUnderSpecial<AstSenItem::Final>(nodep);
|
||||
}
|
||||
virtual void visit(AstAssignAlias* nodep) override {
|
||||
moveUnderSpecial<AstSenItem::Combo>(nodep);
|
||||
}
|
||||
virtual void visit(AstCoverToggle* nodep) override {
|
||||
moveUnderSpecial<AstSenItem::Combo>(nodep);
|
||||
}
|
||||
virtual void visit(AstAssignW* nodep) override {
|
||||
void visit(AstAssignAlias* nodep) override { moveUnderSpecial<AstSenItem::Combo>(nodep); }
|
||||
void visit(AstCoverToggle* nodep) override { moveUnderSpecial<AstSenItem::Combo>(nodep); }
|
||||
void visit(AstAssignW* nodep) override {
|
||||
visitAlways(nodep, nullptr, VAlwaysKwd::ALWAYS_COMB);
|
||||
}
|
||||
virtual void visit(AstAlways* nodep) override {
|
||||
void visit(AstAlways* nodep) override {
|
||||
if (!nodep->bodysp()) { // Empty always. Remove it now.
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
return;
|
||||
|
|
@ -542,18 +536,17 @@ private:
|
|||
visitSenItems(nodep);
|
||||
visitAlways(nodep, nodep->sensesp(), nodep->keyword());
|
||||
}
|
||||
virtual void visit(AstAlwaysPostponed* nodep) override {
|
||||
void visit(AstAlwaysPostponed* nodep) override {
|
||||
// Might be empty with later optimizations, so this assertion can be removed,
|
||||
// but for now it is guaranteed to be not empty.
|
||||
UASSERT_OBJ(nodep->bodysp(), nodep, "Should not be empty");
|
||||
visitAlways(nodep, nullptr, VAlwaysKwd::ALWAYS);
|
||||
}
|
||||
virtual void visit(AstAlwaysPublic* nodep) override {
|
||||
void visit(AstAlwaysPublic* nodep) override {
|
||||
visitAlways(nodep, nodep->sensesp(), VAlwaysKwd::ALWAYS);
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) override { visitSenItems(nodep); }
|
||||
|
||||
virtual void visit(AstSenItem* nodep) override {
|
||||
void visit(AstCFunc* nodep) override { visitSenItems(nodep); }
|
||||
void visit(AstSenItem* nodep) override {
|
||||
UASSERT_OBJ(!m_walkingBody, nodep,
|
||||
"Should not reach here when walking body without --timing");
|
||||
if (!nodep->sensp()) return; // Ignore sequential items (e.g.: initial, comb, etc.)
|
||||
|
|
@ -563,6 +556,7 @@ private:
|
|||
|
||||
if (const auto* const dtypep = nodep->sensp()->dtypep()) {
|
||||
if (const auto* const basicp = dtypep->basicp()) {
|
||||
|
||||
if (basicp->isEvent()) nodep->edgeType(VEdgeType::ET_EVENT);
|
||||
}
|
||||
}
|
||||
|
|
@ -573,7 +567,7 @@ private:
|
|||
});
|
||||
}
|
||||
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
AstVarScope* const vscp = nodep->varScopep();
|
||||
if (nodep->access().isWriteOnly()) {
|
||||
vscp->user2(true);
|
||||
|
|
@ -584,24 +578,24 @@ private:
|
|||
if (!vscp->user2() && !vscp->user1()) m_canBeComb = false;
|
||||
}
|
||||
}
|
||||
virtual void visit(AstAssignDly* nodep) override {
|
||||
void visit(AstAssignDly* nodep) override {
|
||||
m_canBeComb = false;
|
||||
if (nodep->isTimingControl()) m_clockedProcess = true;
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstFireEvent* nodep) override {
|
||||
void visit(AstFireEvent* nodep) override {
|
||||
m_canBeComb = false;
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstAssignForce* nodep) override {
|
||||
void visit(AstAssignForce* nodep) override {
|
||||
m_canBeComb = false;
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstRelease* nodep) override {
|
||||
void visit(AstRelease* nodep) override {
|
||||
m_canBeComb = false;
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstFork* nodep) override {
|
||||
void visit(AstFork* nodep) override {
|
||||
if (nodep->isTimingControl()) {
|
||||
m_canBeComb = false;
|
||||
m_clockedProcess = true;
|
||||
|
|
@ -610,9 +604,9 @@ private:
|
|||
}
|
||||
|
||||
//--------------------
|
||||
virtual void visit(AstVar*) override {} // Accelerate
|
||||
virtual void visit(AstVarScope*) override {} // Accelerate
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstVar*) override {} // Accelerate
|
||||
void visit(AstVarScope*) override {} // Accelerate
|
||||
void visit(AstNode* nodep) override {
|
||||
if (!v3Global.opt.timing().isSetTrue() && m_walkingBody && !m_canBeComb) {
|
||||
return; // Accelerate
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,13 +60,13 @@ class ActiveTopVisitor final : public VNVisitor {
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
// Create required actives and add to module
|
||||
// We can start ordering at a module, or a scope
|
||||
UINFO(4, " MOD " << nodep << endl);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstActive* nodep) override {
|
||||
void visit(AstActive* nodep) override {
|
||||
UINFO(4, " ACTIVE " << nodep << endl);
|
||||
// Remove duplicate clocks and such; sensesp() may change!
|
||||
V3Const::constifyExpensiveEdit(nodep);
|
||||
|
|
@ -115,27 +115,27 @@ class ActiveTopVisitor final : public VNVisitor {
|
|||
if (initialp) nodep->addHereThisAsNext(initialp);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeProcedure* nodep) override { // LCOV_EXCL_LINE
|
||||
void visit(AstNodeProcedure* nodep) override { // LCOV_EXCL_LINE
|
||||
nodep->v3fatalSrc("Node should have been under ACTIVE");
|
||||
}
|
||||
virtual void visit(AstAssignAlias* nodep) override { // LCOV_EXCL_LINE
|
||||
void visit(AstAssignAlias* nodep) override { // LCOV_EXCL_LINE
|
||||
nodep->v3fatalSrc("Node should have been under ACTIVE");
|
||||
}
|
||||
virtual void visit(AstAssignW* nodep) override { // LCOV_EXCL_LINE
|
||||
void visit(AstAssignW* nodep) override { // LCOV_EXCL_LINE
|
||||
nodep->v3fatalSrc("Node should have been under ACTIVE");
|
||||
}
|
||||
virtual void visit(AstAlwaysPublic* nodep) override { // LCOV_EXCL_LINE
|
||||
void visit(AstAlwaysPublic* nodep) override { // LCOV_EXCL_LINE
|
||||
nodep->v3fatalSrc("Node should have been under ACTIVE");
|
||||
}
|
||||
//--------------------
|
||||
virtual void visit(AstNodeMath*) override {} // Accelerate
|
||||
virtual void visit(AstVarScope*) override {} // Accelerate
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNodeMath*) override {} // Accelerate
|
||||
void visit(AstVarScope*) override {} // Accelerate
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit ActiveTopVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
virtual ~ActiveTopVisitor() override = default;
|
||||
~ActiveTopVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstIf* nodep) override {
|
||||
void visit(AstIf* nodep) override {
|
||||
if (nodep->user1SetOnce()) return;
|
||||
if (nodep->uniquePragma() || nodep->unique0Pragma()) {
|
||||
const AstNodeIf* ifp = nodep;
|
||||
|
|
@ -260,7 +260,7 @@ private:
|
|||
}
|
||||
|
||||
//========== Case assertions
|
||||
virtual void visit(AstCase* nodep) override {
|
||||
void visit(AstCase* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (!nodep->user1SetOnce()) {
|
||||
bool has_default = false;
|
||||
|
|
@ -329,7 +329,7 @@ private:
|
|||
}
|
||||
|
||||
//========== Past
|
||||
virtual void visit(AstPast* nodep) override {
|
||||
void visit(AstPast* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
uint32_t ticks = 1;
|
||||
if (nodep->ticksp()) {
|
||||
|
|
@ -362,7 +362,7 @@ private:
|
|||
}
|
||||
|
||||
//========== Move $sampled down to read-only variables
|
||||
virtual void visit(AstSampled* nodep) override {
|
||||
void visit(AstSampled* nodep) override {
|
||||
if (nodep->user1()) return;
|
||||
VL_RESTORER(m_inSampled);
|
||||
{
|
||||
|
|
@ -372,7 +372,7 @@ private:
|
|||
nodep->replaceWith(nodep->exprp()->unlinkFrBack());
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (m_inSampled) {
|
||||
if (!nodep->access().isReadOnly()) {
|
||||
|
|
@ -388,7 +388,7 @@ private:
|
|||
}
|
||||
}
|
||||
// Don't sample sensitivities
|
||||
virtual void visit(AstSenItem* nodep) override {
|
||||
void visit(AstSenItem* nodep) override {
|
||||
VL_RESTORER(m_inSampled);
|
||||
{
|
||||
m_inSampled = false;
|
||||
|
|
@ -397,7 +397,7 @@ private:
|
|||
}
|
||||
|
||||
//========== Statements
|
||||
virtual void visit(AstDisplay* nodep) override {
|
||||
void visit(AstDisplay* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
// Replace the special types with standard text
|
||||
if (nodep->displayType() == VDisplayType::DT_INFO) {
|
||||
|
|
@ -448,32 +448,32 @@ private:
|
|||
m_modp->addStmtp(newp);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstMonitorOff* nodep) override {
|
||||
void visit(AstMonitorOff* nodep) override {
|
||||
const auto newp
|
||||
= new AstAssign(nodep->fileline(), newMonitorOffVarRefp(nodep, VAccess::WRITE),
|
||||
new AstConst(nodep->fileline(), AstConst::BitTrue{}, nodep->off()));
|
||||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
virtual void visit(AstAssert* nodep) override {
|
||||
void visit(AstAssert* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
newPslAssertion(nodep, nodep->failsp());
|
||||
}
|
||||
virtual void visit(AstAssertIntrinsic* nodep) override {
|
||||
void visit(AstAssertIntrinsic* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
newPslAssertion(nodep, nodep->failsp());
|
||||
}
|
||||
virtual void visit(AstCover* nodep) override {
|
||||
void visit(AstCover* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
newPslAssertion(nodep, nullptr);
|
||||
}
|
||||
virtual void visit(AstRestrict* nodep) override {
|
||||
void visit(AstRestrict* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
// IEEE says simulator ignores these
|
||||
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
VL_RESTORER(m_modp);
|
||||
VL_RESTORER(m_modPastNum);
|
||||
VL_RESTORER(m_modStrobeNum);
|
||||
|
|
@ -484,7 +484,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstBegin* nodep) override {
|
||||
void visit(AstBegin* nodep) override {
|
||||
// This code is needed rather than a visitor in V3Begin,
|
||||
// because V3Assert is called before V3Begin
|
||||
VL_RESTORER(m_beginp);
|
||||
|
|
@ -494,12 +494,12 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit AssertVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
virtual ~AssertVisitor() override {
|
||||
~AssertVisitor() override {
|
||||
V3Stats::addStat("Assertions, assert non-immediate statements", m_statAsNotImm);
|
||||
V3Stats::addStat("Assertions, assert immediate statements", m_statAsImm);
|
||||
V3Stats::addStat("Assertions, cover statements", m_statCover);
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ private:
|
|||
|
||||
// VISITORS
|
||||
//========== Statements
|
||||
virtual void visit(AstClocking* nodep) override {
|
||||
void visit(AstClocking* nodep) override {
|
||||
UINFO(8, " CLOCKING" << nodep << endl);
|
||||
// Store the new default clock, reset on new module
|
||||
m_seniDefaultp = nodep->sensesp();
|
||||
|
|
@ -81,14 +81,14 @@ private:
|
|||
}
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
virtual void visit(AstAlways* nodep) override {
|
||||
void visit(AstAlways* nodep) override {
|
||||
iterateAndNextNull(nodep->sensesp());
|
||||
if (nodep->sensesp()) m_seniAlwaysp = nodep->sensesp()->sensesp();
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
m_seniAlwaysp = nullptr;
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeCoverOrAssert* nodep) override {
|
||||
void visit(AstNodeCoverOrAssert* nodep) override {
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
clearAssertInfo();
|
||||
// Find Clocking's buried under nodep->exprsp
|
||||
|
|
@ -96,7 +96,7 @@ private:
|
|||
if (!nodep->immediate()) nodep->sentreep(newSenTree(nodep));
|
||||
clearAssertInfo();
|
||||
}
|
||||
virtual void visit(AstFell* nodep) override {
|
||||
void visit(AstFell* nodep) override {
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
iterateChildren(nodep);
|
||||
FileLine* const fl = nodep->fileline();
|
||||
|
|
@ -110,12 +110,12 @@ private:
|
|||
nodep->sentreep(newSenTree(nodep));
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
virtual void visit(AstPast* nodep) override {
|
||||
void visit(AstPast* nodep) override {
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
iterateChildren(nodep);
|
||||
nodep->sentreep(newSenTree(nodep));
|
||||
}
|
||||
virtual void visit(AstRose* nodep) override {
|
||||
void visit(AstRose* nodep) override {
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
iterateChildren(nodep);
|
||||
FileLine* const fl = nodep->fileline();
|
||||
|
|
@ -129,7 +129,7 @@ private:
|
|||
nodep->sentreep(newSenTree(nodep));
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
virtual void visit(AstStable* nodep) override {
|
||||
void visit(AstStable* nodep) override {
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
iterateChildren(nodep);
|
||||
FileLine* const fl = nodep->fileline();
|
||||
|
|
@ -143,7 +143,7 @@ private:
|
|||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstImplication* nodep) override {
|
||||
void visit(AstImplication* nodep) override {
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
|
||||
FileLine* const fl = nodep->fileline();
|
||||
|
|
@ -161,7 +161,7 @@ private:
|
|||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstPropClocked* nodep) override {
|
||||
void visit(AstPropClocked* nodep) override {
|
||||
// No need to iterate the body, once replace will get iterated
|
||||
iterateAndNextNull(nodep->sensesp());
|
||||
if (m_senip)
|
||||
|
|
@ -183,12 +183,12 @@ private:
|
|||
nodep->replaceWith(blockp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
// Reset defaults
|
||||
m_seniDefaultp = nullptr;
|
||||
}
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
@ -197,7 +197,7 @@ public:
|
|||
// Process
|
||||
iterate(nodep);
|
||||
}
|
||||
virtual ~AssertPreVisitor() override = default;
|
||||
~AssertPreVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -212,8 +212,7 @@ string AstNode::prettyTypeName() const {
|
|||
//######################################################################
|
||||
// Insertion
|
||||
|
||||
inline void AstNode::debugTreeChange(const AstNode* nodep, const char* prefix, int lineno,
|
||||
bool next) {
|
||||
void AstNode::debugTreeChange(const AstNode* nodep, const char* prefix, int lineno, bool next) {
|
||||
#ifdef VL_DEBUG
|
||||
// Called on all major tree changers.
|
||||
// Only for use for those really nasty bugs relating to internals
|
||||
|
|
@ -927,7 +926,7 @@ AstNode* AstNode::iterateSubtreeReturnEdits(VNVisitor& v) {
|
|||
} else if (!nodep->backp()) {
|
||||
// Calling on standalone tree; insert a shim node so we can keep
|
||||
// track, then delete it on completion
|
||||
AstBegin* const tempp = new AstBegin(nodep->fileline(), "[EditWrapper]", nodep);
|
||||
AstBegin* const tempp = new AstBegin{nodep->fileline(), "[EditWrapper]", nodep};
|
||||
{
|
||||
VL_DO_DANGLING(tempp->stmtsp()->accept(v),
|
||||
nodep); // nodep to null as may be replaced
|
||||
|
|
|
|||
303
src/V3Ast.h
303
src/V3Ast.h
|
|
@ -93,11 +93,11 @@ public:
|
|||
// const char* ascii() const {...};
|
||||
enum en m_e;
|
||||
// cppcheck-suppress uninitVar // responsibility of each subclass
|
||||
inline VNType() = default;
|
||||
VNType() = default;
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VNType(en _e)
|
||||
VNType(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VNType(int _e)
|
||||
explicit VNType(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
};
|
||||
|
|
@ -116,12 +116,12 @@ public:
|
|||
static const char* const names[] = {"NONE", "VAUTOM", "VSTATIC"};
|
||||
return names[m_e];
|
||||
}
|
||||
inline VLifetime()
|
||||
VLifetime()
|
||||
: m_e{NONE} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VLifetime(en _e)
|
||||
VLifetime(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VLifetime(int _e)
|
||||
explicit VLifetime(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
bool isNone() const { return m_e == NONE; }
|
||||
|
|
@ -157,16 +157,16 @@ public:
|
|||
static const char* const names[] = {"[RV] <-", "[LV] =>", "[LV] <=>", "--"};
|
||||
return names[m_e];
|
||||
}
|
||||
inline VAccess()
|
||||
VAccess()
|
||||
: m_e{READ} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VAccess(en _e)
|
||||
VAccess(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VAccess(int _e)
|
||||
explicit VAccess(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
VAccess invert() const {
|
||||
return (m_e == READWRITE) ? VAccess(m_e) : (m_e == WRITE ? VAccess(READ) : VAccess(WRITE));
|
||||
return (m_e == READWRITE) ? VAccess{m_e} : (m_e == WRITE ? VAccess{READ} : VAccess{WRITE});
|
||||
}
|
||||
bool isReadOnly() const { return m_e == READ; } // False with READWRITE
|
||||
bool isWriteOnly() const { return m_e == WRITE; } // False with READWRITE
|
||||
|
|
@ -194,19 +194,19 @@ public:
|
|||
static const char* const names[] = {"UNSIGNED", "SIGNED", "NOSIGN"};
|
||||
return names[m_e];
|
||||
}
|
||||
inline VSigning()
|
||||
VSigning()
|
||||
: m_e{UNSIGNED} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VSigning(en _e)
|
||||
VSigning(en _e)
|
||||
: m_e{_e} {}
|
||||
static inline VSigning fromBool(bool isSigned) { // Factory method
|
||||
return isSigned ? VSigning(SIGNED) : VSigning(UNSIGNED);
|
||||
static VSigning fromBool(bool isSigned) { // Factory method
|
||||
return isSigned ? VSigning{SIGNED} : VSigning{UNSIGNED};
|
||||
}
|
||||
explicit inline VSigning(int _e)
|
||||
explicit VSigning(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
inline bool isSigned() const { return m_e == SIGNED; }
|
||||
inline bool isNosign() const { return m_e == NOSIGN; }
|
||||
bool isSigned() const { return m_e == SIGNED; }
|
||||
bool isNosign() const { return m_e == NOSIGN; }
|
||||
// No isUnsigned() as it's ambiguous if NOSIGN should be included or not.
|
||||
};
|
||||
inline bool operator==(const VSigning& lhs, const VSigning& rhs) { return lhs.m_e == rhs.m_e; }
|
||||
|
|
@ -234,12 +234,12 @@ public:
|
|||
ENUM_SIZE
|
||||
};
|
||||
enum en m_e;
|
||||
inline VPragmaType()
|
||||
VPragmaType()
|
||||
: m_e{ILLEGAL} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VPragmaType(en _e)
|
||||
VPragmaType(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VPragmaType(int _e)
|
||||
explicit VPragmaType(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
};
|
||||
|
|
@ -330,12 +330,12 @@ public:
|
|||
}
|
||||
return false;
|
||||
}
|
||||
inline VEdgeType()
|
||||
VEdgeType()
|
||||
: m_e{ET_ILLEGAL} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VEdgeType(en _e)
|
||||
VEdgeType(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VEdgeType(int _e)
|
||||
explicit VEdgeType(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
};
|
||||
|
|
@ -411,12 +411,12 @@ public:
|
|||
// clang-format on
|
||||
return names[m_e];
|
||||
}
|
||||
inline VAttrType()
|
||||
VAttrType()
|
||||
: m_e{ILLEGAL} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VAttrType(en _e)
|
||||
VAttrType(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VAttrType(int _e)
|
||||
explicit VAttrType(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
};
|
||||
|
|
@ -515,17 +515,17 @@ public:
|
|||
return names[m_e];
|
||||
}
|
||||
static void selfTest() {
|
||||
UASSERT(0 == std::strcmp(VBasicDTypeKwd(_ENUM_MAX).ascii(), " MAX"),
|
||||
UASSERT(0 == std::strcmp(VBasicDTypeKwd{_ENUM_MAX}.ascii(), " MAX"),
|
||||
"SelfTest: Enum mismatch");
|
||||
UASSERT(0 == std::strcmp(VBasicDTypeKwd(_ENUM_MAX).dpiType(), " MAX"),
|
||||
UASSERT(0 == std::strcmp(VBasicDTypeKwd{_ENUM_MAX}.dpiType(), " MAX"),
|
||||
"SelfTest: Enum mismatch");
|
||||
}
|
||||
inline VBasicDTypeKwd()
|
||||
VBasicDTypeKwd()
|
||||
: m_e{UNKNOWN} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VBasicDTypeKwd(en _e)
|
||||
VBasicDTypeKwd(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VBasicDTypeKwd(int _e)
|
||||
explicit VBasicDTypeKwd(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
int width() const {
|
||||
|
|
@ -628,12 +628,12 @@ class VDirection final {
|
|||
public:
|
||||
enum en : uint8_t { NONE, INPUT, OUTPUT, INOUT, REF, CONSTREF };
|
||||
enum en m_e;
|
||||
inline VDirection()
|
||||
VDirection()
|
||||
: m_e{NONE} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VDirection(en _e)
|
||||
VDirection(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VDirection(int _e)
|
||||
explicit VDirection(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
const char* ascii() const {
|
||||
|
|
@ -674,12 +674,12 @@ public:
|
|||
enum en : uint8_t { BU_FALSE = 0, BU_TRUE = 1, BU_UNKNOWN = 2, _ENUM_END };
|
||||
enum en m_e;
|
||||
// CONSTRUCTOR - note defaults to *UNKNOWN*
|
||||
inline VBoolOrUnknown()
|
||||
VBoolOrUnknown()
|
||||
: m_e{BU_UNKNOWN} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VBoolOrUnknown(en _e)
|
||||
VBoolOrUnknown(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VBoolOrUnknown(int _e)
|
||||
explicit VBoolOrUnknown(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
const char* ascii() const {
|
||||
static const char* const names[] = {"FALSE", "TRUE", "UNK"};
|
||||
|
|
@ -713,12 +713,12 @@ public:
|
|||
enum en : uint8_t { JOIN = 0, JOIN_ANY = 1, JOIN_NONE = 2 };
|
||||
enum en m_e;
|
||||
// CONSTRUCTOR - note defaults to *UNKNOWN*
|
||||
inline VJoinType()
|
||||
VJoinType()
|
||||
: m_e{JOIN} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VJoinType(en _e)
|
||||
VJoinType(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VJoinType(int _e)
|
||||
explicit VJoinType(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
const char* ascii() const {
|
||||
static const char* const names[] = {"JOIN", "JOIN_ANY", "JOIN_NONE"};
|
||||
|
|
@ -766,12 +766,12 @@ public:
|
|||
MEMBER
|
||||
};
|
||||
enum en m_e;
|
||||
inline VVarType()
|
||||
VVarType()
|
||||
: m_e{UNKNOWN} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VVarType(en _e)
|
||||
VVarType(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VVarType(int _e)
|
||||
explicit VVarType(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
const char* ascii() const {
|
||||
|
|
@ -818,12 +818,12 @@ public:
|
|||
enum en : uint8_t { BP_UNKNOWN = 0, BP_LIKELY, BP_UNLIKELY, _ENUM_END };
|
||||
enum en m_e;
|
||||
// CONSTRUCTOR - note defaults to *UNKNOWN*
|
||||
inline VBranchPred()
|
||||
VBranchPred()
|
||||
: m_e{BP_UNKNOWN} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VBranchPred(en _e)
|
||||
VBranchPred(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VBranchPred(int _e)
|
||||
explicit VBranchPred(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
bool unknown() const { return m_e == BP_UNKNOWN; }
|
||||
|
|
@ -859,12 +859,12 @@ public:
|
|||
enum en : uint8_t { CLOCKER_UNKNOWN = 0, CLOCKER_YES, CLOCKER_NO, _ENUM_END };
|
||||
enum en m_e;
|
||||
// CONSTRUCTOR - note defaults to *UNKNOWN*
|
||||
inline VVarAttrClocker()
|
||||
VVarAttrClocker()
|
||||
: m_e{CLOCKER_UNKNOWN} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VVarAttrClocker(en _e)
|
||||
VVarAttrClocker(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VVarAttrClocker(int _e)
|
||||
explicit VVarAttrClocker(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
bool unknown() const { return m_e == CLOCKER_UNKNOWN; }
|
||||
|
|
@ -901,12 +901,12 @@ class VAlwaysKwd final {
|
|||
public:
|
||||
enum en : uint8_t { ALWAYS, ALWAYS_FF, ALWAYS_LATCH, ALWAYS_COMB };
|
||||
enum en m_e;
|
||||
inline VAlwaysKwd()
|
||||
VAlwaysKwd()
|
||||
: m_e{ALWAYS} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VAlwaysKwd(en _e)
|
||||
VAlwaysKwd(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VAlwaysKwd(int _e)
|
||||
explicit VAlwaysKwd(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
const char* ascii() const {
|
||||
|
|
@ -924,12 +924,12 @@ class VCaseType final {
|
|||
public:
|
||||
enum en : uint8_t { CT_CASE, CT_CASEX, CT_CASEZ, CT_CASEINSIDE };
|
||||
enum en m_e;
|
||||
inline VCaseType()
|
||||
VCaseType()
|
||||
: m_e{CT_CASE} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VCaseType(en _e)
|
||||
VCaseType(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VCaseType(int _e)
|
||||
explicit VCaseType(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
};
|
||||
|
|
@ -957,7 +957,7 @@ public:
|
|||
// cppcheck-suppress noExplicitConstructor
|
||||
VDisplayType(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VDisplayType(int _e)
|
||||
explicit VDisplayType(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
bool addNewline() const { return m_e != DT_WRITE; }
|
||||
|
|
@ -980,12 +980,12 @@ class VDumpCtlType final {
|
|||
public:
|
||||
enum en : uint8_t { FILE, VARS, ALL, FLUSH, LIMIT, OFF, ON };
|
||||
enum en m_e;
|
||||
inline VDumpCtlType()
|
||||
VDumpCtlType()
|
||||
: m_e{ON} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VDumpCtlType(en _e)
|
||||
VDumpCtlType(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VDumpCtlType(int _e)
|
||||
explicit VDumpCtlType(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
const char* ascii() const {
|
||||
|
|
@ -1010,12 +1010,12 @@ public:
|
|||
PX_TEXT // Unknown ID component
|
||||
};
|
||||
enum en m_e;
|
||||
inline VParseRefExp()
|
||||
VParseRefExp()
|
||||
: m_e{PX_NONE} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VParseRefExp(en _e)
|
||||
VParseRefExp(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VParseRefExp(int _e)
|
||||
explicit VParseRefExp(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
const char* ascii() const {
|
||||
|
|
@ -1039,9 +1039,10 @@ public:
|
|||
enum en : uint8_t { HIGHZ, SMALL, MEDIUM, WEAK, LARGE, PULL, STRONG, SUPPLY };
|
||||
enum en m_e;
|
||||
|
||||
inline VStrength(en strengthLevel)
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
VStrength(en strengthLevel)
|
||||
: m_e(strengthLevel) {}
|
||||
explicit inline VStrength(int _e)
|
||||
explicit VStrength(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
|
||||
operator en() const { return m_e; }
|
||||
|
|
@ -1133,12 +1134,12 @@ public:
|
|||
INT_FWD_CLASS, // Interface (.h) needs a forward class declaration
|
||||
};
|
||||
enum en m_e;
|
||||
inline VUseType()
|
||||
VUseType()
|
||||
: m_e{IMP_FWD_CLASS} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VUseType(en _e)
|
||||
VUseType(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VUseType(int _e)
|
||||
explicit VUseType(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
bool isInclude() const { return m_e == IMP_INCLUDE || m_e == INT_INCLUDE; }
|
||||
bool isFwdClass() const { return m_e == IMP_FWD_CLASS || m_e == INT_FWD_CLASS; }
|
||||
|
|
@ -1225,7 +1226,7 @@ public:
|
|||
AstNode* toNodep() const { return to<AstNode*>(); }
|
||||
V3GraphVertex* toGraphVertex() const { return to<V3GraphVertex*>(); }
|
||||
int toInt() const { return m_u.ui; }
|
||||
static VNUser fromInt(int i) { return VNUser(i); }
|
||||
static VNUser fromInt(int i) { return VNUser{i}; }
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
@ -1362,23 +1363,23 @@ class VNVisitor VL_NOT_FINAL : public VNDeleter {
|
|||
|
||||
public:
|
||||
/// Call visit()s on nodep
|
||||
void iterate(AstNode* nodep);
|
||||
inline void iterate(AstNode* nodep);
|
||||
/// Call visit()s on nodep
|
||||
void iterateNull(AstNode* nodep);
|
||||
inline void iterateNull(AstNode* nodep);
|
||||
/// Call visit()s on nodep's children
|
||||
void iterateChildren(AstNode* nodep);
|
||||
inline void iterateChildren(AstNode* nodep);
|
||||
/// Call visit()s on nodep's children in backp() order
|
||||
void iterateChildrenBackwards(AstNode* nodep);
|
||||
inline void iterateChildrenBackwards(AstNode* nodep);
|
||||
/// Call visit()s on const nodep's children
|
||||
void iterateChildrenConst(AstNode* nodep);
|
||||
inline void iterateChildrenConst(AstNode* nodep);
|
||||
/// Call visit()s on nodep (maybe nullptr) and nodep's nextp() list
|
||||
void iterateAndNextNull(AstNode* nodep);
|
||||
inline void iterateAndNextNull(AstNode* nodep);
|
||||
/// Call visit()s on const nodep (maybe nullptr) and nodep's nextp() list
|
||||
void iterateAndNextConstNull(AstNode* nodep);
|
||||
inline void iterateAndNextConstNull(AstNode* nodep);
|
||||
/// Call visit()s on const nodep (maybe nullptr) and nodep's nextp() list, in reverse order
|
||||
void iterateAndNextConstNullBackwards(AstNode* nodep);
|
||||
inline void iterateAndNextConstNullBackwards(AstNode* nodep);
|
||||
/// Return edited nodep; see comments in V3Ast.cpp
|
||||
AstNode* iterateSubtreeReturnEdits(AstNode* nodep);
|
||||
inline AstNode* iterateSubtreeReturnEdits(AstNode* nodep);
|
||||
|
||||
virtual void visit(AstNode* nodep) = 0;
|
||||
#include "V3Ast__gen_visitor_decls.h" // From ./astgen
|
||||
|
|
@ -1406,7 +1407,7 @@ protected:
|
|||
|
||||
public:
|
||||
VNRelinker() = default;
|
||||
void relink(AstNode* newp);
|
||||
inline void relink(AstNode* newp);
|
||||
AstNode* oldp() const { return m_oldp; }
|
||||
void dump(std::ostream& str = std::cout) const;
|
||||
};
|
||||
|
|
@ -1491,15 +1492,15 @@ class AstNode VL_NOT_FINAL {
|
|||
static int s_cloneCntGbl; // Count of which userp is set
|
||||
|
||||
// This member ordering both allows 64 bit alignment and puts associated data together
|
||||
VNUser m_user1u = VNUser{0}; // Contains any information the user iteration routine wants
|
||||
VNUser m_user1u{0}; // Contains any information the user iteration routine wants
|
||||
uint32_t m_user1Cnt = 0; // Mark of when userp was set
|
||||
uint32_t m_user2Cnt = 0; // Mark of when userp was set
|
||||
VNUser m_user2u = VNUser{0}; // Contains any information the user iteration routine wants
|
||||
VNUser m_user3u = VNUser{0}; // Contains any information the user iteration routine wants
|
||||
VNUser m_user2u{0}; // Contains any information the user iteration routine wants
|
||||
VNUser m_user3u{0}; // Contains any information the user iteration routine wants
|
||||
uint32_t m_user3Cnt = 0; // Mark of when userp was set
|
||||
uint32_t m_user4Cnt = 0; // Mark of when userp was set
|
||||
VNUser m_user4u = VNUser{0}; // Contains any information the user iteration routine wants
|
||||
VNUser m_user5u = VNUser{0}; // Contains any information the user iteration routine wants
|
||||
VNUser m_user4u{0}; // Contains any information the user iteration routine wants
|
||||
VNUser m_user5u{0}; // Contains any information the user iteration routine wants
|
||||
uint32_t m_user5Cnt = 0; // Mark of when userp was set
|
||||
|
||||
// METHODS
|
||||
|
|
@ -1578,7 +1579,7 @@ protected:
|
|||
|
||||
public:
|
||||
// ACCESSORS
|
||||
inline VNType type() const { return m_type; }
|
||||
VNType type() const { return m_type; }
|
||||
const char* typeName() const { return type().ascii(); } // See also prettyTypeName
|
||||
AstNode* nextp() const { return m_nextp; }
|
||||
AstNode* backp() const { return m_backp; }
|
||||
|
|
@ -1660,8 +1661,8 @@ public:
|
|||
virtual string prettyOperatorName() const { return "operator " + prettyTypeName(); }
|
||||
FileLine* fileline() const { return m_fileline; }
|
||||
void fileline(FileLine* fl) { m_fileline = fl; }
|
||||
bool width1() const;
|
||||
int widthInstrs() const;
|
||||
inline bool width1() const;
|
||||
inline int widthInstrs() const;
|
||||
void didWidth(bool flag) { m_flags.didWidth = flag; }
|
||||
bool didWidth() const { return m_flags.didWidth; }
|
||||
bool didWidthAndSet() {
|
||||
|
|
@ -1675,29 +1676,29 @@ public:
|
|||
void protect(bool flag) { m_flags.protect = flag; }
|
||||
|
||||
// TODO stomp these width functions out, and call via dtypep() instead
|
||||
int width() const;
|
||||
int widthMin() const;
|
||||
inline int width() const;
|
||||
inline int widthMin() const;
|
||||
int widthMinV() const {
|
||||
return v3Global.widthMinUsage() == VWidthMinUsage::VERILOG_WIDTH ? widthMin() : width();
|
||||
}
|
||||
int widthWords() const { return VL_WORDS_I(width()); }
|
||||
bool isQuad() const { return (width() > VL_IDATASIZE && width() <= VL_QUADSIZE); }
|
||||
bool isWide() const { return (width() > VL_QUADSIZE); }
|
||||
bool isDouble() const;
|
||||
bool isSigned() const;
|
||||
bool isString() const;
|
||||
inline bool isDouble() const;
|
||||
inline bool isSigned() const;
|
||||
inline bool isString() const;
|
||||
|
||||
// clang-format off
|
||||
VNUser user1u() const {
|
||||
// Slows things down measurably, so disabled by default
|
||||
//UASSERT_STATIC(VNUser1InUse::s_userBusy, "userp set w/o busy");
|
||||
return ((m_user1Cnt==VNUser1InUse::s_userCntGbl) ? m_user1u : VNUser(0));
|
||||
return ((m_user1Cnt==VNUser1InUse::s_userCntGbl) ? m_user1u : VNUser{0});
|
||||
}
|
||||
AstNode* user1p() const { return user1u().toNodep(); }
|
||||
void user1u(const VNUser& user) { m_user1u=user; m_user1Cnt=VNUser1InUse::s_userCntGbl; }
|
||||
void user1p(void* userp) { user1u(VNUser(userp)); }
|
||||
void user1p(void* userp) { user1u(VNUser{userp}); }
|
||||
int user1() const { return user1u().toInt(); }
|
||||
void user1(int val) { user1u(VNUser(val)); }
|
||||
void user1(int val) { user1u(VNUser{val}); }
|
||||
int user1Inc(int val=1) { int v=user1(); user1(v+val); return v; }
|
||||
int user1SetOnce() { int v=user1(); if (!v) user1(1); return v; } // Better for cache than user1Inc()
|
||||
static void user1ClearTree() { VNUser1InUse::clear(); } // Clear userp()'s across the entire tree
|
||||
|
|
@ -1705,13 +1706,13 @@ public:
|
|||
VNUser user2u() const {
|
||||
// Slows things down measurably, so disabled by default
|
||||
//UASSERT_STATIC(VNUser2InUse::s_userBusy, "userp set w/o busy");
|
||||
return ((m_user2Cnt==VNUser2InUse::s_userCntGbl) ? m_user2u : VNUser(0));
|
||||
return ((m_user2Cnt==VNUser2InUse::s_userCntGbl) ? m_user2u : VNUser{0});
|
||||
}
|
||||
AstNode* user2p() const { return user2u().toNodep(); }
|
||||
void user2u(const VNUser& user) { m_user2u=user; m_user2Cnt=VNUser2InUse::s_userCntGbl; }
|
||||
void user2p(void* userp) { user2u(VNUser(userp)); }
|
||||
void user2p(void* userp) { user2u(VNUser{userp}); }
|
||||
int user2() const { return user2u().toInt(); }
|
||||
void user2(int val) { user2u(VNUser(val)); }
|
||||
void user2(int val) { user2u(VNUser{val}); }
|
||||
int user2Inc(int val=1) { int v=user2(); user2(v+val); return v; }
|
||||
int user2SetOnce() { int v=user2(); if (!v) user2(1); return v; } // Better for cache than user2Inc()
|
||||
static void user2ClearTree() { VNUser2InUse::clear(); } // Clear userp()'s across the entire tree
|
||||
|
|
@ -1719,13 +1720,13 @@ public:
|
|||
VNUser user3u() const {
|
||||
// Slows things down measurably, so disabled by default
|
||||
//UASSERT_STATIC(VNUser3InUse::s_userBusy, "userp set w/o busy");
|
||||
return ((m_user3Cnt==VNUser3InUse::s_userCntGbl) ? m_user3u : VNUser(0));
|
||||
return ((m_user3Cnt==VNUser3InUse::s_userCntGbl) ? m_user3u : VNUser{0});
|
||||
}
|
||||
AstNode* user3p() const { return user3u().toNodep(); }
|
||||
void user3u(const VNUser& user) { m_user3u=user; m_user3Cnt=VNUser3InUse::s_userCntGbl; }
|
||||
void user3p(void* userp) { user3u(VNUser(userp)); }
|
||||
void user3p(void* userp) { user3u(VNUser{userp}); }
|
||||
int user3() const { return user3u().toInt(); }
|
||||
void user3(int val) { user3u(VNUser(val)); }
|
||||
void user3(int val) { user3u(VNUser{val}); }
|
||||
int user3Inc(int val=1) { int v=user3(); user3(v+val); return v; }
|
||||
int user3SetOnce() { int v=user3(); if (!v) user3(1); return v; } // Better for cache than user3Inc()
|
||||
static void user3ClearTree() { VNUser3InUse::clear(); } // Clear userp()'s across the entire tree
|
||||
|
|
@ -1733,13 +1734,13 @@ public:
|
|||
VNUser user4u() const {
|
||||
// Slows things down measurably, so disabled by default
|
||||
//UASSERT_STATIC(VNUser4InUse::s_userBusy, "userp set w/o busy");
|
||||
return ((m_user4Cnt==VNUser4InUse::s_userCntGbl) ? m_user4u : VNUser(0));
|
||||
return ((m_user4Cnt==VNUser4InUse::s_userCntGbl) ? m_user4u : VNUser{0});
|
||||
}
|
||||
AstNode* user4p() const { return user4u().toNodep(); }
|
||||
void user4u(const VNUser& user) { m_user4u=user; m_user4Cnt=VNUser4InUse::s_userCntGbl; }
|
||||
void user4p(void* userp) { user4u(VNUser(userp)); }
|
||||
void user4p(void* userp) { user4u(VNUser{userp}); }
|
||||
int user4() const { return user4u().toInt(); }
|
||||
void user4(int val) { user4u(VNUser(val)); }
|
||||
void user4(int val) { user4u(VNUser{val}); }
|
||||
int user4Inc(int val=1) { int v=user4(); user4(v+val); return v; }
|
||||
int user4SetOnce() { int v=user4(); if (!v) user4(1); return v; } // Better for cache than user4Inc()
|
||||
static void user4ClearTree() { VNUser4InUse::clear(); } // Clear userp()'s across the entire tree
|
||||
|
|
@ -1747,13 +1748,13 @@ public:
|
|||
VNUser user5u() const {
|
||||
// Slows things down measurably, so disabled by default
|
||||
//UASSERT_STATIC(VNUser5InUse::s_userBusy, "userp set w/o busy");
|
||||
return ((m_user5Cnt==VNUser5InUse::s_userCntGbl) ? m_user5u : VNUser(0));
|
||||
return ((m_user5Cnt==VNUser5InUse::s_userCntGbl) ? m_user5u : VNUser{0});
|
||||
}
|
||||
AstNode* user5p() const { return user5u().toNodep(); }
|
||||
void user5u(const VNUser& user) { m_user5u=user; m_user5Cnt=VNUser5InUse::s_userCntGbl; }
|
||||
void user5p(void* userp) { user5u(VNUser(userp)); }
|
||||
void user5p(void* userp) { user5u(VNUser{userp}); }
|
||||
int user5() const { return user5u().toInt(); }
|
||||
void user5(int val) { user5u(VNUser(val)); }
|
||||
void user5(int val) { user5u(VNUser{val}); }
|
||||
int user5Inc(int val=1) { int v=user5(); user5(v+val); return v; }
|
||||
int user5SetOnce() { int v=user5(); if (!v) user5(1); return v; } // Better for cache than user5Inc()
|
||||
static void user5ClearTree() { VNUser5InUse::clear(); } // Clear userp()'s across the entire tree
|
||||
|
|
@ -1769,11 +1770,11 @@ public:
|
|||
|
||||
// ACCESSORS for specific types
|
||||
// Alas these can't be virtual or they break when passed a nullptr
|
||||
bool isZero() const;
|
||||
bool isOne() const;
|
||||
bool isNeqZero() const;
|
||||
bool isAllOnes() const;
|
||||
bool isAllOnesV() const; // Verilog width rules apply
|
||||
inline bool isZero() const;
|
||||
inline bool isOne() const;
|
||||
inline bool isNeqZero() const;
|
||||
inline bool isAllOnes() const;
|
||||
inline bool isAllOnesV() const; // Verilog width rules apply
|
||||
|
||||
// METHODS - data type changes especially for initial creation
|
||||
void dtypep(AstNodeDType* nodep) {
|
||||
|
|
@ -1885,9 +1886,9 @@ public:
|
|||
}
|
||||
AstNode* cloneTree(bool cloneNextLink); // Not const, as sets clonep() on original nodep
|
||||
bool gateTree() { return gateTreeIter(); } // Is tree isGateOptimizable?
|
||||
bool sameTree(const AstNode* node2p) const; // Does tree of this == node2p?
|
||||
inline bool sameTree(const AstNode* node2p) const; // Does tree of this == node2p?
|
||||
// Does tree of this == node2p?, not allowing non-isGateOptimizable
|
||||
bool sameGateTree(const AstNode* node2p) const;
|
||||
inline bool sameGateTree(const AstNode* node2p) const;
|
||||
void deleteTree(); // Always deletes the next link
|
||||
void checkTree(); // User Interface version
|
||||
void checkIter() const;
|
||||
|
|
@ -1987,7 +1988,7 @@ private:
|
|||
public:
|
||||
// For use via the VN_IS macro only
|
||||
template <typename T, typename E>
|
||||
inline static bool privateIs(const AstNode* nodep) {
|
||||
static bool privateIs(const AstNode* nodep) {
|
||||
static_assert(!uselessCast<T, E>(), "Unnecessary VN_IS, node known to have target type.");
|
||||
static_assert(!impossibleCast<T, E>(), "Unnecessary VN_IS, node cannot be this type.");
|
||||
return nodep && privateTypeTest<T>(nodep);
|
||||
|
|
@ -1995,14 +1996,14 @@ public:
|
|||
|
||||
// For use via the VN_CAST macro only
|
||||
template <typename T, typename E>
|
||||
inline static T* privateCast(AstNode* nodep) {
|
||||
static T* privateCast(AstNode* nodep) {
|
||||
static_assert(!uselessCast<T, E>(),
|
||||
"Unnecessary VN_CAST, node known to have target type.");
|
||||
static_assert(!impossibleCast<T, E>(), "Unnecessary VN_CAST, node cannot be this type.");
|
||||
return nodep && privateTypeTest<T>(nodep) ? reinterpret_cast<T*>(nodep) : nullptr;
|
||||
}
|
||||
template <typename T, typename E>
|
||||
inline static const T* privateCast(const AstNode* nodep) {
|
||||
static const T* privateCast(const AstNode* nodep) {
|
||||
static_assert(!uselessCast<T, E>(),
|
||||
"Unnecessary VN_CAST, node known to have target type.");
|
||||
static_assert(!impossibleCast<T, E>(), "Unnecessary VN_CAST, node cannot be this type.");
|
||||
|
|
@ -2011,7 +2012,7 @@ public:
|
|||
|
||||
// For use via the VN_AS macro only
|
||||
template <typename T, typename E>
|
||||
inline static T* privateAs(AstNode* nodep) {
|
||||
static T* privateAs(AstNode* nodep) {
|
||||
static_assert(!uselessCast<T, E>(), "Unnecessary VN_AS, node known to have target type.");
|
||||
static_assert(!impossibleCast<T, E>(), "Unnecessary VN_AS, node cannot be this type.");
|
||||
UASSERT_OBJ(!nodep || privateTypeTest<T>(nodep), nodep,
|
||||
|
|
@ -2020,7 +2021,7 @@ public:
|
|||
return reinterpret_cast<T*>(nodep);
|
||||
}
|
||||
template <typename T, typename E>
|
||||
inline static const T* privateAs(const AstNode* nodep) {
|
||||
static const T* privateAs(const AstNode* nodep) {
|
||||
static_assert(!uselessCast<T, E>(), "Unnecessary VN_AS, node known to have target type.");
|
||||
static_assert(!impossibleCast<T, E>(), "Unnecessary VN_AS, node cannot be this type.");
|
||||
UASSERT_OBJ(!nodep || privateTypeTest<T>(nodep), nodep,
|
||||
|
|
@ -2239,7 +2240,7 @@ void AstNode::foreachImpl(ConstCorrectAstNode<T_Arg>* nodep, const std::function
|
|||
constexpr int prefetchDistance = 2;
|
||||
|
||||
// Grow stack to given size
|
||||
const auto grow = [&](size_t size) VL_ATTR_ALWINLINE {
|
||||
const auto grow = [&](size_t size) {
|
||||
const ptrdiff_t occupancy = topp - basep;
|
||||
stack.resize(size);
|
||||
basep = stack.data() + prefetchDistance;
|
||||
|
|
@ -2255,7 +2256,7 @@ void AstNode::foreachImpl(ConstCorrectAstNode<T_Arg>* nodep, const std::function
|
|||
for (int i = -prefetchDistance; i; ++i) basep[i] = nodep;
|
||||
|
||||
// Visit given node, enqueue children for traversal
|
||||
const auto visit = [&](Node* currp) VL_ATTR_ALWINLINE {
|
||||
const auto visit = [&](Node* currp) {
|
||||
// Type test this node
|
||||
if (AstNode::privateTypeTest<T_Arg_NonConst>(currp)) {
|
||||
// Call the client function
|
||||
|
|
@ -2320,7 +2321,7 @@ bool AstNode::predicateImpl(ConstCorrectAstNode<T_Arg>* nodep,
|
|||
constexpr int prefetchDistance = 2;
|
||||
|
||||
// Grow stack to given size
|
||||
const auto grow = [&](size_t size) VL_ATTR_ALWINLINE {
|
||||
const auto grow = [&](size_t size) {
|
||||
const ptrdiff_t occupancy = topp - basep;
|
||||
stack.resize(size);
|
||||
basep = stack.data() + prefetchDistance;
|
||||
|
|
@ -2336,7 +2337,7 @@ bool AstNode::predicateImpl(ConstCorrectAstNode<T_Arg>* nodep,
|
|||
for (int i = -prefetchDistance; i; ++i) basep[i] = nodep;
|
||||
|
||||
// Visit given node, enqueue children for traversal, return true if result determined.
|
||||
const auto visit = [&](Node* currp) VL_ATTR_ALWINLINE {
|
||||
const auto visit = [&](Node* currp) {
|
||||
// Type test this node
|
||||
if (AstNode::privateTypeTest<T_Arg_NonConst>(currp)) {
|
||||
// Call the client function
|
||||
|
|
@ -2389,7 +2390,7 @@ inline std::ostream& operator<<(std::ostream& os, const AstNode* rhs) {
|
|||
}
|
||||
return os;
|
||||
}
|
||||
inline void VNRelinker::relink(AstNode* newp) { newp->AstNode::relink(this); }
|
||||
void VNRelinker::relink(AstNode* newp) { newp->AstNode::relink(this); }
|
||||
|
||||
//######################################################################
|
||||
|
||||
|
|
@ -2436,58 +2437,36 @@ struct std::equal_to<VNRef<T_Node>> final {
|
|||
//######################################################################
|
||||
// Inline VNVisitor METHODS
|
||||
|
||||
inline void VNVisitor::iterate(AstNode* nodep) { nodep->accept(*this); }
|
||||
inline void VNVisitor::iterateNull(AstNode* nodep) {
|
||||
void VNVisitor::iterate(AstNode* nodep) { nodep->accept(*this); }
|
||||
void VNVisitor::iterateNull(AstNode* nodep) {
|
||||
if (VL_LIKELY(nodep)) nodep->accept(*this);
|
||||
}
|
||||
inline void VNVisitor::iterateChildren(AstNode* nodep) { nodep->iterateChildren(*this); }
|
||||
inline void VNVisitor::iterateChildrenBackwards(AstNode* nodep) {
|
||||
void VNVisitor::iterateChildren(AstNode* nodep) { nodep->iterateChildren(*this); }
|
||||
void VNVisitor::iterateChildrenBackwards(AstNode* nodep) {
|
||||
nodep->iterateChildrenBackwards(*this);
|
||||
}
|
||||
inline void VNVisitor::iterateChildrenConst(AstNode* nodep) { nodep->iterateChildrenConst(*this); }
|
||||
inline void VNVisitor::iterateAndNextNull(AstNode* nodep) {
|
||||
void VNVisitor::iterateChildrenConst(AstNode* nodep) { nodep->iterateChildrenConst(*this); }
|
||||
void VNVisitor::iterateAndNextNull(AstNode* nodep) {
|
||||
if (VL_LIKELY(nodep)) nodep->iterateAndNext(*this);
|
||||
}
|
||||
inline void VNVisitor::iterateAndNextConstNullBackwards(AstNode* nodep) {
|
||||
void VNVisitor::iterateAndNextConstNullBackwards(AstNode* nodep) {
|
||||
if (VL_LIKELY(nodep)) nodep->iterateListBackwards(*this);
|
||||
}
|
||||
inline void VNVisitor::iterateAndNextConstNull(AstNode* nodep) {
|
||||
void VNVisitor::iterateAndNextConstNull(AstNode* nodep) {
|
||||
if (VL_LIKELY(nodep)) nodep->iterateAndNextConst(*this);
|
||||
}
|
||||
inline AstNode* VNVisitor::iterateSubtreeReturnEdits(AstNode* nodep) {
|
||||
AstNode* VNVisitor::iterateSubtreeReturnEdits(AstNode* nodep) {
|
||||
return nodep->iterateSubtreeReturnEdits(*this);
|
||||
}
|
||||
|
||||
// ######################################################################
|
||||
// Standard defines for all AstNode subclasses
|
||||
|
||||
#define ASTNODE_BASE_FUNCS(name) \
|
||||
virtual ~Ast##name() override = default; \
|
||||
static Ast##name* cloneTreeNull(Ast##name* nodep, bool cloneNextLink) { \
|
||||
return nodep ? nodep->cloneTree(cloneNextLink) : nullptr; \
|
||||
} \
|
||||
Ast##name* cloneTree(bool cloneNext) { \
|
||||
return static_cast<Ast##name*>(AstNode::cloneTree(cloneNext)); \
|
||||
} \
|
||||
Ast##name* clonep() const { return static_cast<Ast##name*>(AstNode::clonep()); }
|
||||
|
||||
#define ASTNODE_NODE_FUNCS_NO_DTOR(name) \
|
||||
virtual void accept(VNVisitor& v) override { v.visit(this); } \
|
||||
virtual AstNode* clone() override { return new Ast##name(*this); } \
|
||||
static Ast##name* cloneTreeNull(Ast##name* nodep, bool cloneNextLink) { \
|
||||
return nodep ? nodep->cloneTree(cloneNextLink) : nullptr; \
|
||||
} \
|
||||
Ast##name* cloneTree(bool cloneNext) { \
|
||||
return static_cast<Ast##name*>(AstNode::cloneTree(cloneNext)); \
|
||||
} \
|
||||
Ast##name* clonep() const { return static_cast<Ast##name*>(AstNode::clonep()); }
|
||||
|
||||
#define ASTNODE_NODE_FUNCS(name) \
|
||||
virtual ~Ast##name() override = default; \
|
||||
ASTNODE_NODE_FUNCS_NO_DTOR(name)
|
||||
|
||||
// Macros generated by 'astgen'
|
||||
#include "V3AstNodes__gen_macros.h"
|
||||
// Include macros generated by 'astgen'. These include ASTGEN_MEMBERS_<Node>
|
||||
// for each AstNode sub-type, and ASTGEN_SUPER_<Node> for concrete final
|
||||
// AstNode sub-types. The generated members include boilerplate methods related
|
||||
// to cloning, visitor dispatch, and other functionality. ASTGEN_SUPER_<Node>
|
||||
// is the necessary constructor invocation for concrete AstNode sub-types
|
||||
// that passes the generated type-id numbers all the way back to AstNode.
|
||||
// For precise details please read the generated macros.
|
||||
#include "V3Ast__gen_macros.h"
|
||||
|
||||
// AstNode subclasses
|
||||
#include "V3AstNodeDType.h"
|
||||
|
|
|
|||
|
|
@ -25,71 +25,56 @@
|
|||
//######################################################################
|
||||
// Inline METHODS
|
||||
|
||||
inline AstNode* AstNode::addNext(AstNode* newp) { return addNext(this, newp); }
|
||||
inline AstNode* AstNode::addNextNull(AstNode* newp) { return addNextNull(this, newp); }
|
||||
inline void AstNode::addPrev(AstNode* newp) {
|
||||
AstNode* AstNode::addNext(AstNode* newp) { return addNext(this, newp); }
|
||||
AstNode* AstNode::addNextNull(AstNode* newp) { return addNextNull(this, newp); }
|
||||
void AstNode::addPrev(AstNode* newp) {
|
||||
replaceWith(newp);
|
||||
newp->addNext(this);
|
||||
}
|
||||
|
||||
inline int AstNode::width() const { return dtypep() ? dtypep()->width() : 0; }
|
||||
inline int AstNode::widthMin() const { return dtypep() ? dtypep()->widthMin() : 0; }
|
||||
inline bool AstNode::width1() const { // V3Const uses to know it can optimize
|
||||
int AstNode::width() const { return dtypep() ? dtypep()->width() : 0; }
|
||||
int AstNode::widthMin() const { return dtypep() ? dtypep()->widthMin() : 0; }
|
||||
bool AstNode::width1() const { // V3Const uses to know it can optimize
|
||||
return dtypep() && dtypep()->width() == 1;
|
||||
}
|
||||
inline int AstNode::widthInstrs() const {
|
||||
int AstNode::widthInstrs() const {
|
||||
return (!dtypep() ? 1 : (dtypep()->isWide() ? dtypep()->widthWords() : 1));
|
||||
}
|
||||
inline bool AstNode::isDouble() const {
|
||||
bool AstNode::isDouble() const {
|
||||
return dtypep() && VN_IS(dtypep(), BasicDType) && VN_AS(dtypep(), BasicDType)->isDouble();
|
||||
}
|
||||
inline bool AstNode::isString() const {
|
||||
bool AstNode::isString() const {
|
||||
return dtypep() && dtypep()->basicp() && dtypep()->basicp()->isString();
|
||||
}
|
||||
inline bool AstNode::isSigned() const { return dtypep() && dtypep()->isSigned(); }
|
||||
bool AstNode::isSigned() const { return dtypep() && dtypep()->isSigned(); }
|
||||
|
||||
inline bool AstNode::isZero() const {
|
||||
bool AstNode::isZero() const {
|
||||
return (VN_IS(this, Const) && VN_AS(this, Const)->num().isEqZero());
|
||||
}
|
||||
inline bool AstNode::isNeqZero() const {
|
||||
bool AstNode::isNeqZero() const {
|
||||
return (VN_IS(this, Const) && VN_AS(this, Const)->num().isNeqZero());
|
||||
}
|
||||
inline bool AstNode::isOne() const {
|
||||
return (VN_IS(this, Const) && VN_AS(this, Const)->num().isEqOne());
|
||||
}
|
||||
inline bool AstNode::isAllOnes() const {
|
||||
bool AstNode::isOne() const { return (VN_IS(this, Const) && VN_AS(this, Const)->num().isEqOne()); }
|
||||
bool AstNode::isAllOnes() const {
|
||||
return (VN_IS(this, Const) && VN_AS(this, Const)->isEqAllOnes());
|
||||
}
|
||||
inline bool AstNode::isAllOnesV() const {
|
||||
bool AstNode::isAllOnesV() const {
|
||||
return (VN_IS(this, Const) && VN_AS(this, Const)->isEqAllOnesV());
|
||||
}
|
||||
inline bool AstNode::sameTree(const AstNode* node2p) const {
|
||||
bool AstNode::sameTree(const AstNode* node2p) const {
|
||||
return sameTreeIter(this, node2p, true, false);
|
||||
}
|
||||
inline bool AstNode::sameGateTree(const AstNode* node2p) const {
|
||||
bool AstNode::sameGateTree(const AstNode* node2p) const {
|
||||
return sameTreeIter(this, node2p, true, true);
|
||||
}
|
||||
|
||||
inline void AstNodeVarRef::varp(AstVar* varp) {
|
||||
m_varp = varp;
|
||||
dtypeFrom(varp);
|
||||
}
|
||||
|
||||
inline bool AstNodeDType::isFourstate() const { return basicp()->isFourstate(); }
|
||||
|
||||
inline void AstNodeArrayDType::rangep(AstRange* nodep) { setOp2p(nodep); }
|
||||
inline int AstNodeArrayDType::left() const { return rangep()->leftConst(); }
|
||||
inline int AstNodeArrayDType::right() const { return rangep()->rightConst(); }
|
||||
inline int AstNodeArrayDType::hi() const { return rangep()->hiConst(); }
|
||||
inline int AstNodeArrayDType::lo() const { return rangep()->loConst(); }
|
||||
inline int AstNodeArrayDType::elementsConst() const { return rangep()->elementsConst(); }
|
||||
inline VNumRange AstNodeArrayDType::declRange() const { return VNumRange{left(), right()}; }
|
||||
|
||||
inline void AstIfaceRefDType::cloneRelink() {
|
||||
if (m_cellp && m_cellp->clonep()) m_cellp = m_cellp->clonep();
|
||||
if (m_ifacep && m_ifacep->clonep()) m_ifacep = m_ifacep->clonep();
|
||||
if (m_modportp && m_modportp->clonep()) m_modportp = m_modportp->clonep();
|
||||
}
|
||||
void AstNodeArrayDType::rangep(AstRange* nodep) { setOp2p(nodep); }
|
||||
int AstNodeArrayDType::left() const { return rangep()->leftConst(); }
|
||||
int AstNodeArrayDType::right() const { return rangep()->rightConst(); }
|
||||
int AstNodeArrayDType::hi() const { return rangep()->hiConst(); }
|
||||
int AstNodeArrayDType::lo() const { return rangep()->loConst(); }
|
||||
int AstNodeArrayDType::elementsConst() const { return rangep()->elementsConst(); }
|
||||
VNumRange AstNodeArrayDType::declRange() const { return VNumRange{left(), right()}; }
|
||||
|
||||
AstRange::AstRange(FileLine* fl, int left, int right)
|
||||
: ASTGEN_SUPER_Range(fl) {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
3506
src/V3AstNodeMath.h
3506
src/V3AstNodeMath.h
File diff suppressed because it is too large
Load Diff
1465
src/V3AstNodeOther.h
1465
src/V3AstNodeOther.h
File diff suppressed because it is too large
Load Diff
|
|
@ -26,7 +26,7 @@
|
|||
#include "V3PartitionGraph.h" // Just for mtask dumping
|
||||
#include "V3String.h"
|
||||
|
||||
#include "V3AstNodes__gen_macros.h" // Generated by 'astgen'
|
||||
#include "V3Ast__gen_macros.h" // Generated by 'astgen'
|
||||
|
||||
#include <iomanip>
|
||||
#include <iterator>
|
||||
|
|
@ -564,11 +564,11 @@ string AstVar::dpiArgType(bool named, bool forReturn) const {
|
|||
return dpiTypesToStringConverter{}.convert(this);
|
||||
} else {
|
||||
class converter final : public dpiTypesToStringConverter {
|
||||
virtual string bitLogicVector(const AstVar* varp, bool isBit) const override {
|
||||
string bitLogicVector(const AstVar* varp, bool isBit) const override {
|
||||
return string(varp->isReadOnly() ? "const " : "")
|
||||
+ dpiTypesToStringConverter::bitLogicVector(varp, isBit) + '*';
|
||||
}
|
||||
virtual string primitive(const AstVar* varp) const override {
|
||||
string primitive(const AstVar* varp) const override {
|
||||
string type = dpiTypesToStringConverter::primitive(varp);
|
||||
if (varp->isWritable() || VN_IS(varp->dtypep()->skipRefp(), UnpackArrayDType)) {
|
||||
if (!varp->isWritable() && varp->basicp()->keyword() != VBasicDTypeKwd::STRING)
|
||||
|
|
@ -600,16 +600,16 @@ string AstVar::dpiTmpVarType(const string& varName) const {
|
|||
return "";
|
||||
}
|
||||
}
|
||||
virtual string openArray(const AstVar* varp) const override {
|
||||
string openArray(const AstVar* varp) const override {
|
||||
return dpiTypesToStringConverter::openArray(varp) + ' ' + m_name
|
||||
+ arraySuffix(varp, 0);
|
||||
}
|
||||
virtual string bitLogicVector(const AstVar* varp, bool isBit) const override {
|
||||
string bitLogicVector(const AstVar* varp, bool isBit) const override {
|
||||
string type = dpiTypesToStringConverter::bitLogicVector(varp, isBit);
|
||||
type += ' ' + m_name + arraySuffix(varp, varp->widthWords());
|
||||
return type;
|
||||
}
|
||||
virtual string primitive(const AstVar* varp) const override {
|
||||
string primitive(const AstVar* varp) const override {
|
||||
string type = dpiTypesToStringConverter::primitive(varp);
|
||||
if (varp->isWritable() || VN_IS(varp->dtypep()->skipRefp(), UnpackArrayDType)) {
|
||||
if (!varp->isWritable() && varp->basicp()->keyword() == VBasicDTypeKwd::CHANDLE)
|
||||
|
|
@ -683,6 +683,8 @@ AstVar* AstVar::scVarRecurse(AstNode* nodep) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool AstNodeDType::isFourstate() const { return basicp()->isFourstate(); }
|
||||
|
||||
class AstNodeDType::CTypeRecursed final {
|
||||
public:
|
||||
string m_type; // The base type, e.g.: "Foo_t"s
|
||||
|
|
@ -1540,6 +1542,11 @@ void AstIfaceRefDType::dumpSmall(std::ostream& str) const {
|
|||
this->AstNodeDType::dumpSmall(str);
|
||||
str << "iface";
|
||||
}
|
||||
void AstIfaceRefDType::cloneRelink() {
|
||||
if (m_cellp && m_cellp->clonep()) m_cellp = m_cellp->clonep();
|
||||
if (m_ifacep && m_ifacep->clonep()) m_ifacep = m_ifacep->clonep();
|
||||
if (m_modportp && m_modportp->clonep()) m_modportp = m_modportp->clonep();
|
||||
}
|
||||
void AstInitArray::dump(std::ostream& str) const {
|
||||
this->AstNode::dump(str);
|
||||
int n = 0;
|
||||
|
|
@ -1923,7 +1930,7 @@ void AstTypeTable::dump(std::ostream& str) const {
|
|||
for (int i = 0; i < static_cast<int>(VBasicDTypeKwd::_ENUM_MAX); ++i) {
|
||||
if (AstBasicDType* const subnodep = m_basicps[i]) {
|
||||
str << '\n'; // Newline from caller, so newline first
|
||||
str << "\t\t" << std::setw(8) << VBasicDTypeKwd(i).ascii();
|
||||
str << "\t\t" << std::setw(8) << VBasicDTypeKwd{i}.ascii();
|
||||
str << " -> ";
|
||||
subnodep->dump(str);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ class AstUserAllocatorBase VL_NOT_FINAL {
|
|||
private:
|
||||
std::vector<T_Data*> m_allocated;
|
||||
|
||||
inline T_Data* getUserp(const T_Node* nodep) const {
|
||||
T_Data* getUserp(const T_Node* nodep) const {
|
||||
if VL_CONSTEXPR_CXX17 (T_UserN == 1) {
|
||||
const VNUser user = nodep->user1u();
|
||||
return user.to<T_Data*>();
|
||||
|
|
@ -54,17 +54,17 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
inline void setUserp(T_Node* nodep, T_Data* userp) const {
|
||||
void setUserp(T_Node* nodep, T_Data* userp) const {
|
||||
if VL_CONSTEXPR_CXX17 (T_UserN == 1) {
|
||||
nodep->user1u(VNUser(userp));
|
||||
nodep->user1u(VNUser{userp});
|
||||
} else if VL_CONSTEXPR_CXX17 (T_UserN == 2) {
|
||||
nodep->user2u(VNUser(userp));
|
||||
nodep->user2u(VNUser{userp});
|
||||
} else if VL_CONSTEXPR_CXX17 (T_UserN == 3) {
|
||||
nodep->user3u(VNUser(userp));
|
||||
nodep->user3u(VNUser{userp});
|
||||
} else if VL_CONSTEXPR_CXX17 (T_UserN == 4) {
|
||||
nodep->user4u(VNUser(userp));
|
||||
nodep->user4u(VNUser{userp});
|
||||
} else {
|
||||
nodep->user5u(VNUser(userp));
|
||||
nodep->user5u(VNUser{userp});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -121,20 +121,20 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstFork* nodep) override {
|
||||
void visit(AstFork* nodep) override {
|
||||
VL_RESTORER(m_underFork);
|
||||
m_underFork = true;
|
||||
dotNames(nodep, "__FORK__");
|
||||
nodep->name("");
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
VL_RESTORER(m_modp);
|
||||
{
|
||||
m_modp = nodep;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeFTask* nodep) override {
|
||||
void visit(AstNodeFTask* nodep) override {
|
||||
UINFO(8, " " << nodep << endl);
|
||||
// Rename it
|
||||
if (m_unnamedScope != "") {
|
||||
|
|
@ -169,7 +169,7 @@ private:
|
|||
m_ftaskp = nullptr;
|
||||
}
|
||||
}
|
||||
virtual void visit(AstBegin* nodep) override {
|
||||
void visit(AstBegin* nodep) override {
|
||||
// Begin blocks were only useful in variable creation, change names and delete
|
||||
UINFO(8, " " << nodep << endl);
|
||||
VL_RESTORER(m_displayScope);
|
||||
|
|
@ -206,7 +206,7 @@ private:
|
|||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
void visit(AstVar* nodep) override {
|
||||
if (m_unnamedScope != "") {
|
||||
// Rename it
|
||||
nodep->name(dot(m_unnamedScope, nodep->name()));
|
||||
|
|
@ -215,7 +215,7 @@ private:
|
|||
liftNode(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstTypedef* nodep) override {
|
||||
void visit(AstTypedef* nodep) override {
|
||||
if (m_unnamedScope != "") {
|
||||
// Rename it
|
||||
nodep->name(dot(m_unnamedScope, nodep->name()));
|
||||
|
|
@ -224,7 +224,7 @@ private:
|
|||
liftNode(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCell* nodep) override {
|
||||
void visit(AstCell* nodep) override {
|
||||
UINFO(8, " CELL " << nodep << endl);
|
||||
if (m_namedScope != "") {
|
||||
m_statep->userMarkChanged(nodep);
|
||||
|
|
@ -237,14 +237,14 @@ private:
|
|||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstVarXRef* nodep) override {
|
||||
void visit(AstVarXRef* nodep) override {
|
||||
UINFO(9, " VARXREF " << nodep << endl);
|
||||
if (m_namedScope != "" && nodep->inlinedDots() == "" && !m_ftaskp) {
|
||||
nodep->inlinedDots(m_namedScope);
|
||||
UINFO(9, " rescope to " << nodep << endl);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstScopeName* nodep) override {
|
||||
void visit(AstScopeName* nodep) override {
|
||||
// If there's a %m in the display text, we add a special node that will contain the name()
|
||||
// Similar code in V3Inline
|
||||
if (nodep->user1SetOnce()) return; // Don't double-add text's
|
||||
|
|
@ -259,13 +259,13 @@ private:
|
|||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstCoverDecl* nodep) override {
|
||||
void visit(AstCoverDecl* nodep) override {
|
||||
// Don't need to fix path in coverage statements, they're not under
|
||||
// any BEGINs, but V3Coverage adds them all under the module itself.
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
// VISITORS - LINT CHECK
|
||||
virtual void visit(AstIf* nodep) override { // not AstNodeIf; other types not covered
|
||||
void visit(AstIf* nodep) override { // not AstNodeIf; other types not covered
|
||||
VL_RESTORER(m_underFork);
|
||||
m_underFork = false;
|
||||
// Check IFDEPTH warning - could be in other transform files if desire
|
||||
|
|
@ -281,7 +281,7 @@ private:
|
|||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
VL_RESTORER(m_underFork);
|
||||
m_underFork = false;
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -293,7 +293,7 @@ public:
|
|||
: m_statep{statep} {
|
||||
iterate(nodep);
|
||||
}
|
||||
virtual ~BeginVisitor() override = default;
|
||||
~BeginVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
@ -306,21 +306,21 @@ private:
|
|||
// AstNodeFTask::user1p // Node replaced, rename it
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeFTaskRef* nodep) override {
|
||||
void visit(AstNodeFTaskRef* nodep) override {
|
||||
if (nodep->taskp()->user1()) { // It was converted
|
||||
UINFO(9, " relinkFTask " << nodep << endl);
|
||||
nodep->name(nodep->taskp()->name());
|
||||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
if (nodep->varp()->user1()) { // It was converted
|
||||
UINFO(9, " relinVarRef " << nodep << endl);
|
||||
nodep->name(nodep->varp()->name());
|
||||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstIfaceRefDType* nodep) override {
|
||||
void visit(AstIfaceRefDType* nodep) override {
|
||||
// May have changed cell names
|
||||
// TypeTable is always after all modules, so names are stable
|
||||
UINFO(8, " IFACEREFDTYPE " << nodep << endl);
|
||||
|
|
@ -329,12 +329,12 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
BeginRelinkVisitor(AstNetlist* nodep, BeginState*) { iterate(nodep); }
|
||||
virtual ~BeginRelinkVisitor() override = default;
|
||||
~BeginRelinkVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeIf* nodep) override {
|
||||
void visit(AstNodeIf* nodep) override {
|
||||
UINFO(4, " IF: " << nodep << endl);
|
||||
VL_RESTORER(m_likely);
|
||||
VL_RESTORER(m_unlikely);
|
||||
|
|
@ -87,17 +87,17 @@ private:
|
|||
} // else leave unknown
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeCCall* nodep) override {
|
||||
void visit(AstNodeCCall* nodep) override {
|
||||
checkUnlikely(nodep);
|
||||
nodep->funcp()->user1Inc();
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
checkUnlikely(nodep);
|
||||
m_cfuncsp.push_back(nodep);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
checkUnlikely(nodep);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
|
@ -116,7 +116,7 @@ public:
|
|||
iterateChildren(nodep);
|
||||
calc_tasks();
|
||||
}
|
||||
virtual ~BranchVisitor() override = default;
|
||||
~BranchVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -132,8 +132,8 @@ private:
|
|||
public:
|
||||
// METHODS
|
||||
void clear() { m_linkable.clear(); }
|
||||
inline void addLinkable(const AstNode* nodep) { m_linkable.emplace(nodep); }
|
||||
inline bool isLinkable(const AstNode* nodep) const { return m_linkable.count(nodep) != 0; }
|
||||
void addLinkable(const AstNode* nodep) { m_linkable.emplace(nodep); }
|
||||
bool isLinkable(const AstNode* nodep) const { return m_linkable.count(nodep) != 0; }
|
||||
} s_linkableTable;
|
||||
|
||||
bool V3Broken::isLinkable(const AstNode* nodep) { return s_linkableTable.isLinkable(nodep); }
|
||||
|
|
@ -214,27 +214,27 @@ private:
|
|||
}
|
||||
return false;
|
||||
}
|
||||
virtual void visit(AstNodeAssign* nodep) override {
|
||||
void visit(AstNodeAssign* nodep) override {
|
||||
processAndIterate(nodep);
|
||||
UASSERT_OBJ(!(v3Global.assertDTypesResolved() && nodep->brokeLhsMustBeLvalue()
|
||||
&& VN_IS(nodep->lhsp(), NodeVarRef)
|
||||
&& !VN_AS(nodep->lhsp(), NodeVarRef)->access().isWriteOrRW()),
|
||||
nodep, "Assignment LHS is not an lvalue");
|
||||
}
|
||||
virtual void visit(AstRelease* nodep) override {
|
||||
void visit(AstRelease* nodep) override {
|
||||
processAndIterate(nodep);
|
||||
UASSERT_OBJ(!(v3Global.assertDTypesResolved() && VN_IS(nodep->lhsp(), NodeVarRef)
|
||||
&& !VN_AS(nodep->lhsp(), NodeVarRef)->access().isWriteOrRW()),
|
||||
nodep, "Release LHS is not an lvalue");
|
||||
}
|
||||
virtual void visit(AstScope* nodep) override {
|
||||
void visit(AstScope* nodep) override {
|
||||
VL_RESTORER(m_inScope);
|
||||
{
|
||||
m_inScope = true;
|
||||
processAndIterate(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeVarRef* nodep) override {
|
||||
void visit(AstNodeVarRef* nodep) override {
|
||||
processAndIterate(nodep);
|
||||
// m_inScope because some Vars have initial variable references without scopes
|
||||
// This might false fire with some debug flags, as not certain we don't have temporary
|
||||
|
|
@ -252,7 +252,7 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
UASSERT_OBJ(!m_cfuncp, nodep, "Nested AstCFunc");
|
||||
m_cfuncp = nodep;
|
||||
m_localVars.clear();
|
||||
|
|
@ -270,7 +270,7 @@ private:
|
|||
|
||||
m_cfuncp = nullptr;
|
||||
}
|
||||
virtual void visit(AstNodeIf* nodep) override {
|
||||
void visit(AstNodeIf* nodep) override {
|
||||
// Each branch is a separate local variable scope
|
||||
pushLocalScope();
|
||||
processEnter(nodep);
|
||||
|
|
@ -288,21 +288,21 @@ private:
|
|||
processExit(nodep);
|
||||
popLocalScope();
|
||||
}
|
||||
virtual void visit(AstNodeStmt* nodep) override {
|
||||
void visit(AstNodeStmt* nodep) override {
|
||||
// For local variable checking act as if any statement introduces a new scope.
|
||||
// This is aggressive but conservatively correct.
|
||||
pushLocalScope();
|
||||
processAndIterate(nodep);
|
||||
popLocalScope();
|
||||
}
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
void visit(AstVar* nodep) override {
|
||||
processAndIterate(nodep);
|
||||
if (m_cfuncp) {
|
||||
m_localVars.insert(nodep);
|
||||
m_localsStack.back().insert(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
// Process not just iterate
|
||||
processAndIterate(nodep);
|
||||
}
|
||||
|
|
@ -310,7 +310,7 @@ private:
|
|||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit BrokenCheckVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
virtual ~BrokenCheckVisitor() override = default;
|
||||
~BrokenCheckVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ private:
|
|||
|
||||
public:
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VCtorType(en _e)
|
||||
VCtorType(en _e)
|
||||
: m_e{_e} {}
|
||||
bool isClass() const { return m_e == CLASS; }
|
||||
bool isCoverage() const { return m_e == COVERAGE; }
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ class CUseVisitor final : public VNVisitor {
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstClassRefDType* nodep) override {
|
||||
void visit(AstClassRefDType* nodep) override {
|
||||
if (nodep->user1SetOnce()) return; // Process once
|
||||
if (!m_impOnly) addNewUse(nodep, VUseType::INT_FWD_CLASS, nodep->classp()->name());
|
||||
// Need to include extends() when we implement, but no need for pointers to know
|
||||
|
|
@ -67,17 +67,17 @@ class CUseVisitor final : public VNVisitor {
|
|||
iterateChildren(nodep->classp()); // This also gets all extend classes
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeDType* nodep) override {
|
||||
void visit(AstNodeDType* nodep) override {
|
||||
if (nodep->user1SetOnce()) return; // Process once
|
||||
if (nodep->virtRefDTypep()) iterate(nodep->virtRefDTypep());
|
||||
if (nodep->virtRefDType2p()) iterate(nodep->virtRefDType2p());
|
||||
}
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
if (nodep->user1SetOnce()) return; // Process once
|
||||
if (nodep->dtypep() && !nodep->dtypep()->user1()) iterate(nodep->dtypep());
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstCell* nodep) override {
|
||||
void visit(AstCell* nodep) override {
|
||||
if (nodep->user1SetOnce()) return; // Process once
|
||||
// Currently no IMP_INCLUDE because we include __Syms which has them all
|
||||
addNewUse(nodep, VUseType::INT_FWD_CLASS, nodep->modp()->name());
|
||||
|
|
@ -90,7 +90,7 @@ public:
|
|||
: m_modp(modp) {
|
||||
iterate(modp);
|
||||
}
|
||||
virtual ~CUseVisitor() override = default;
|
||||
~CUseVisitor() override = default;
|
||||
VL_UNCOPYABLE(CUseVisitor);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ private:
|
|||
// METHODS
|
||||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
||||
virtual void visit(AstNodeCase* nodep) override {
|
||||
void visit(AstNodeCase* nodep) override {
|
||||
if (VN_IS(nodep, Case) && VN_AS(nodep, Case)->casex()) {
|
||||
nodep->v3warn(CASEX, "Suggest casez (with ?'s) in place of casex (with X's)");
|
||||
}
|
||||
|
|
@ -86,7 +86,7 @@ private:
|
|||
m_caseExprp = nullptr;
|
||||
}
|
||||
}
|
||||
virtual void visit(AstConst* nodep) override {
|
||||
void visit(AstConst* nodep) override {
|
||||
// See also neverItem
|
||||
if (m_caseExprp && nodep->num().isFourState()) {
|
||||
if (VN_IS(m_caseExprp, GenCase)) {
|
||||
|
|
@ -107,12 +107,12 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit CaseLintVisitor(AstNodeCase* nodep) { iterate(nodep); }
|
||||
virtual ~CaseLintVisitor() override = default;
|
||||
~CaseLintVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
@ -493,7 +493,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstCase* nodep) override {
|
||||
void visit(AstCase* nodep) override {
|
||||
V3Case::caseLint(nodep);
|
||||
iterateChildren(nodep);
|
||||
if (debug() >= 9) nodep->dumpTree(cout, " case_old: ");
|
||||
|
|
@ -510,7 +510,7 @@ private:
|
|||
}
|
||||
}
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
if (VN_IS(nodep, Always)) m_alwaysp = nodep;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
|
@ -521,7 +521,7 @@ public:
|
|||
for (auto& itr : m_valueItem) itr = nullptr;
|
||||
iterate(nodep);
|
||||
}
|
||||
virtual ~CaseVisitor() override {
|
||||
~CaseVisitor() override {
|
||||
V3Stats::addStat("Optimizations, Cases parallelized", m_statCaseFast);
|
||||
V3Stats::addStat("Optimizations, Cases complex", m_statCaseSlow);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,25 +111,25 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeUniop* nodep) override {
|
||||
void visit(AstNodeUniop* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
nodep->user1(nodep->lhsp()->user1());
|
||||
if (nodep->sizeMattersLhs()) ensureCast(nodep->lhsp());
|
||||
}
|
||||
virtual void visit(AstNodeBiop* nodep) override {
|
||||
void visit(AstNodeBiop* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
nodep->user1(nodep->lhsp()->user1() | nodep->rhsp()->user1());
|
||||
if (nodep->sizeMattersLhs()) ensureCast(nodep->lhsp());
|
||||
if (nodep->sizeMattersRhs()) ensureCast(nodep->rhsp());
|
||||
}
|
||||
virtual void visit(AstNodeTriop* nodep) override {
|
||||
void visit(AstNodeTriop* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
nodep->user1(nodep->lhsp()->user1() | nodep->rhsp()->user1() | nodep->thsp()->user1());
|
||||
if (nodep->sizeMattersLhs()) ensureCast(nodep->lhsp());
|
||||
if (nodep->sizeMattersRhs()) ensureCast(nodep->rhsp());
|
||||
if (nodep->sizeMattersThs()) ensureCast(nodep->thsp());
|
||||
}
|
||||
virtual void visit(AstNodeQuadop* nodep) override {
|
||||
void visit(AstNodeQuadop* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
nodep->user1(nodep->lhsp()->user1() | nodep->rhsp()->user1() | nodep->thsp()->user1()
|
||||
| nodep->fhsp()->user1());
|
||||
|
|
@ -138,12 +138,12 @@ private:
|
|||
if (nodep->sizeMattersThs()) ensureCast(nodep->thsp());
|
||||
if (nodep->sizeMattersFhs()) ensureCast(nodep->fhsp());
|
||||
}
|
||||
virtual void visit(AstCCast* nodep) override {
|
||||
void visit(AstCCast* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
ensureLower32Cast(nodep);
|
||||
nodep->user1(1);
|
||||
}
|
||||
virtual void visit(AstNegate* nodep) override {
|
||||
void visit(AstNegate* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
nodep->user1(nodep->lhsp()->user1());
|
||||
if (nodep->lhsp()->widthMin() == 1) {
|
||||
|
|
@ -155,7 +155,7 @@ private:
|
|||
ensureCast(nodep->lhsp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
const AstNode* const backp = nodep->backp();
|
||||
if (nodep->access().isReadOnly() && !VN_IS(backp, CCast) && VN_IS(backp, NodeMath)
|
||||
&& !VN_IS(backp, ArraySel) && !VN_IS(backp, RedXor)
|
||||
|
|
@ -168,7 +168,7 @@ private:
|
|||
}
|
||||
nodep->user1(1);
|
||||
}
|
||||
virtual void visit(AstConst* nodep) override {
|
||||
void visit(AstConst* nodep) override {
|
||||
// Constants are of unknown size if smaller than 33 bits, because
|
||||
// we're too lazy to wrap every constant in the universe in
|
||||
// ((IData)#).
|
||||
|
|
@ -176,29 +176,29 @@ private:
|
|||
}
|
||||
|
||||
// Null dereference protection
|
||||
virtual void visit(AstNullCheck* nodep) override {
|
||||
void visit(AstNullCheck* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
nodep->user1(nodep->lhsp()->user1());
|
||||
}
|
||||
virtual void visit(AstCMethodCall* nodep) override {
|
||||
void visit(AstCMethodCall* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
ensureNullChecked(nodep->fromp());
|
||||
}
|
||||
virtual void visit(AstMemberSel* nodep) override {
|
||||
void visit(AstMemberSel* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
ensureNullChecked(nodep->fromp());
|
||||
}
|
||||
|
||||
// NOPs
|
||||
virtual void visit(AstVar*) override {}
|
||||
void visit(AstVar*) override {}
|
||||
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit CastVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
virtual ~CastVisitor() override = default;
|
||||
~CastVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -67,9 +67,9 @@ public:
|
|||
, m_srcDomainSet{false}
|
||||
, m_dstDomainSet{false}
|
||||
, m_asyncPath{false} {}
|
||||
virtual ~CdcEitherVertex() override = default;
|
||||
~CdcEitherVertex() override = default;
|
||||
// ACCESSORS
|
||||
virtual FileLine* fileline() const override { return nodep()->fileline(); }
|
||||
FileLine* fileline() const override { return nodep()->fileline(); }
|
||||
AstScope* scopep() const { return m_scopep; }
|
||||
AstNode* nodep() const { return m_nodep; }
|
||||
AstSenTree* srcDomainp() const { return m_srcDomainp; }
|
||||
|
|
@ -93,11 +93,11 @@ public:
|
|||
CdcVarVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
|
||||
: CdcEitherVertex{graphp, scopep, varScp}
|
||||
, m_varScp{varScp} {}
|
||||
virtual ~CdcVarVertex() override = default;
|
||||
~CdcVarVertex() override = default;
|
||||
// ACCESSORS
|
||||
AstVarScope* varScp() const { return m_varScp; }
|
||||
virtual string name() const override { return (cvtToHex(m_varScp) + " " + varScp()->name()); }
|
||||
virtual string dotColor() const override {
|
||||
string name() const override { return (cvtToHex(m_varScp) + " " + varScp()->name()); }
|
||||
string dotColor() const override {
|
||||
return fromFlop() ? "green" : cntAsyncRst() ? "red" : "blue";
|
||||
}
|
||||
int cntAsyncRst() const { return m_cntAsyncRst; }
|
||||
|
|
@ -118,12 +118,10 @@ public:
|
|||
srcDomainp(sensenodep);
|
||||
dstDomainp(sensenodep);
|
||||
}
|
||||
virtual ~CdcLogicVertex() override = default;
|
||||
~CdcLogicVertex() override = default;
|
||||
// ACCESSORS
|
||||
virtual string name() const override {
|
||||
return (cvtToHex(nodep()) + "@" + scopep()->prettyName());
|
||||
}
|
||||
virtual string dotColor() const override { return hazard() ? "black" : "yellow"; }
|
||||
string name() const override { return (cvtToHex(nodep()) + "@" + scopep()->prettyName()); }
|
||||
string dotColor() const override { return hazard() ? "black" : "yellow"; }
|
||||
bool hazard() const { return m_hazard; }
|
||||
void setHazard(AstNode* nodep) {
|
||||
m_hazard = true;
|
||||
|
|
@ -144,7 +142,7 @@ private:
|
|||
std::ofstream* const m_ofp = nullptr; // Output file
|
||||
string m_prefix;
|
||||
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
*m_ofp << m_prefix;
|
||||
if (nodep->user3()) {
|
||||
*m_ofp << " %%";
|
||||
|
|
@ -171,7 +169,7 @@ public:
|
|||
, m_prefix{prefix} {
|
||||
iterate(nodep);
|
||||
}
|
||||
virtual ~CdcDumpVisitor() override = default;
|
||||
~CdcDumpVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
@ -181,7 +179,7 @@ private:
|
|||
int m_maxLineno = 0;
|
||||
size_t m_maxFilenameLen = 0;
|
||||
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
// Keeping line+filename lengths separate is much faster than calling ascii().length()
|
||||
if (nodep->fileline()->lineno() >= m_maxLineno) {
|
||||
|
|
@ -195,7 +193,7 @@ private:
|
|||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit CdcWidthVisitor(AstNode* nodep) { iterate(nodep); }
|
||||
virtual ~CdcWidthVisitor() override = default;
|
||||
~CdcWidthVisitor() override = default;
|
||||
// ACCESSORS
|
||||
int maxWidth() const {
|
||||
size_t width = 1;
|
||||
|
|
@ -628,21 +626,21 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
VL_RESTORER(m_modp);
|
||||
{
|
||||
m_modp = nodep;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstScope* nodep) override {
|
||||
void visit(AstScope* nodep) override {
|
||||
UINFO(4, " SCOPE " << nodep << endl);
|
||||
m_scopep = nodep;
|
||||
m_logicVertexp = nullptr;
|
||||
iterateChildren(nodep);
|
||||
m_scopep = nullptr;
|
||||
}
|
||||
virtual void visit(AstActive* nodep) override {
|
||||
void visit(AstActive* nodep) override {
|
||||
// Create required blocks and add to module
|
||||
UINFO(4, " BLOCK " << nodep << endl);
|
||||
AstNode::user2ClearTree();
|
||||
|
|
@ -654,7 +652,7 @@ private:
|
|||
m_domainp = nullptr;
|
||||
AstNode::user2ClearTree();
|
||||
}
|
||||
virtual void visit(AstNodeVarRef* nodep) override {
|
||||
void visit(AstNodeVarRef* nodep) override {
|
||||
if (m_scopep) {
|
||||
UASSERT_OBJ(m_logicVertexp, nodep, "Var ref not under a logic block");
|
||||
AstVarScope* const varscp = nodep->varScopep();
|
||||
|
|
@ -682,53 +680,53 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstAssignDly* nodep) override {
|
||||
void visit(AstAssignDly* nodep) override {
|
||||
m_inDly = true;
|
||||
iterateChildren(nodep);
|
||||
m_inDly = false;
|
||||
}
|
||||
virtual void visit(AstSenItem* nodep) override {
|
||||
void visit(AstSenItem* nodep) override {
|
||||
m_inSenItem = true;
|
||||
iterateChildren(nodep);
|
||||
m_inSenItem = false;
|
||||
}
|
||||
virtual void visit(AstAlways* nodep) override { iterateNewStmt(nodep); }
|
||||
virtual void visit(AstAlwaysPublic* nodep) override {
|
||||
void visit(AstAlways* nodep) override { iterateNewStmt(nodep); }
|
||||
void visit(AstAlwaysPublic* nodep) override {
|
||||
// CDC doesn't care about public variables
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) override { iterateNewStmt(nodep); }
|
||||
virtual void visit(AstAssignAlias* nodep) override { iterateNewStmt(nodep); }
|
||||
virtual void visit(AstAssignW* nodep) override { iterateNewStmt(nodep); }
|
||||
void visit(AstCFunc* nodep) override { iterateNewStmt(nodep); }
|
||||
void visit(AstAssignAlias* nodep) override { iterateNewStmt(nodep); }
|
||||
void visit(AstAssignW* nodep) override { iterateNewStmt(nodep); }
|
||||
|
||||
// Math that shouldn't cause us to clear hazard
|
||||
virtual void visit(AstConst*) override {}
|
||||
virtual void visit(AstReplicate* nodep) override { iterateChildren(nodep); }
|
||||
virtual void visit(AstConcat* nodep) override { iterateChildren(nodep); }
|
||||
virtual void visit(AstNot* nodep) override { iterateChildren(nodep); }
|
||||
virtual void visit(AstSel* nodep) override {
|
||||
void visit(AstConst*) override {}
|
||||
void visit(AstReplicate* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstConcat* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNot* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstSel* nodep) override {
|
||||
if (!VN_IS(nodep->lsbp(), Const)) setNodeHazard(nodep);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeSel* nodep) override {
|
||||
void visit(AstNodeSel* nodep) override {
|
||||
if (!VN_IS(nodep->bitp(), Const)) setNodeHazard(nodep);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
// Ignores
|
||||
virtual void visit(AstInitial*) override {}
|
||||
virtual void visit(AstInitialAutomatic*) override {}
|
||||
virtual void visit(AstInitialStatic*) override {}
|
||||
virtual void visit(AstTraceDecl*) override {}
|
||||
virtual void visit(AstCoverToggle*) override {}
|
||||
virtual void visit(AstNodeDType*) override {}
|
||||
void visit(AstInitial*) override {}
|
||||
void visit(AstInitialAutomatic*) override {}
|
||||
void visit(AstInitialStatic*) override {}
|
||||
void visit(AstTraceDecl*) override {}
|
||||
void visit(AstCoverToggle*) override {}
|
||||
void visit(AstNodeDType*) override {}
|
||||
|
||||
//--------------------
|
||||
// Default
|
||||
virtual void visit(AstNodeMath* nodep) override {
|
||||
void visit(AstNodeMath* nodep) override {
|
||||
setNodeHazard(nodep);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
@ -754,7 +752,7 @@ public:
|
|||
*m_ofp << '\n';
|
||||
}
|
||||
}
|
||||
virtual ~CdcVisitor() override {
|
||||
~CdcVisitor() override {
|
||||
if (m_ofp) VL_DO_CLEAR(delete m_ofp, m_ofp = nullptr);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -0,0 +1,256 @@
|
|||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Add temporaries, such as for changed nodes
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
||||
// can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
//
|
||||
//*************************************************************************
|
||||
// V3Changed's Transformations:
|
||||
//
|
||||
// Each module:
|
||||
// Each combo block
|
||||
// For each variable that comes from combo block and is generated AFTER a usage
|
||||
// Add __Vlast_{var} to local section, init to current value (just use array?)
|
||||
// Change = if any var != last.
|
||||
// If a signal is used as a clock in this module or any
|
||||
// module *below*, and it isn't a input to this module,
|
||||
// we need to indicate a new clock has been created.
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include "V3Changed.h"
|
||||
|
||||
#include "V3Ast.h"
|
||||
#include "V3Global.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
//######################################################################
|
||||
|
||||
class ChangedState final {
|
||||
public:
|
||||
// STATE
|
||||
AstNodeModule* m_topModp = nullptr; // Top module
|
||||
AstScope* m_scopetopp = nullptr; // Scope under TOPSCOPE
|
||||
AstCFunc* m_chgFuncp = nullptr; // Change function we're building
|
||||
AstCFunc* m_tlChgFuncp = nullptr; // Top level change function we're building
|
||||
int m_numStmts = 0; // Number of statements added to m_chgFuncp
|
||||
int m_funcNum = 0; // Number of change functions emitted
|
||||
bool m_madeTopChg = false;
|
||||
|
||||
ChangedState() = default;
|
||||
~ChangedState() = default;
|
||||
|
||||
void maybeCreateChgFuncp() {
|
||||
maybeCreateTopChg();
|
||||
maybeCreateMidChg();
|
||||
}
|
||||
void maybeCreateTopChg() {
|
||||
if (m_madeTopChg) return;
|
||||
m_madeTopChg = true;
|
||||
v3Global.rootp()->changeRequest(true);
|
||||
|
||||
// Create a wrapper change detection function that calls each change detection function
|
||||
m_tlChgFuncp
|
||||
= new AstCFunc{m_scopetopp->fileline(), "_change_request", m_scopetopp, "QData"};
|
||||
m_tlChgFuncp->isStatic(false);
|
||||
m_tlChgFuncp->isLoose(true);
|
||||
m_tlChgFuncp->declPrivate(true);
|
||||
m_scopetopp->addActivep(m_tlChgFuncp);
|
||||
// Each change detection function needs at least one AstChangeDet
|
||||
// to ensure that V3EmitC outputs the necessary code.
|
||||
maybeCreateMidChg();
|
||||
m_chgFuncp->addStmtsp(new AstChangeDet{m_scopetopp->fileline(), nullptr, nullptr});
|
||||
}
|
||||
void maybeCreateMidChg() {
|
||||
// Don't create an extra function call if splitting is disabled
|
||||
if (!v3Global.opt.outputSplitCFuncs()) {
|
||||
m_chgFuncp = m_tlChgFuncp;
|
||||
return;
|
||||
}
|
||||
if (!m_chgFuncp || v3Global.opt.outputSplitCFuncs() < m_numStmts) {
|
||||
m_chgFuncp
|
||||
= new AstCFunc{m_scopetopp->fileline(), "_change_request_" + cvtToStr(++m_funcNum),
|
||||
m_scopetopp, "QData"};
|
||||
m_chgFuncp->isStatic(false);
|
||||
m_chgFuncp->isLoose(true);
|
||||
m_chgFuncp->declPrivate(true);
|
||||
m_scopetopp->addActivep(m_chgFuncp);
|
||||
|
||||
// Add a top call to it
|
||||
AstCCall* const callp = new AstCCall{m_scopetopp->fileline(), m_chgFuncp};
|
||||
|
||||
if (!m_tlChgFuncp->stmtsp()) {
|
||||
m_tlChgFuncp->addStmtsp(new AstCReturn{m_scopetopp->fileline(), callp});
|
||||
} else {
|
||||
AstCReturn* const returnp = VN_AS(m_tlChgFuncp->stmtsp(), CReturn);
|
||||
UASSERT_OBJ(returnp, m_scopetopp, "Lost CReturn in top change function");
|
||||
// This is currently using AstLogOr which will shortcut the
|
||||
// evaluation if any function returns true. This is likely what
|
||||
// we want and is similar to the logic already in use inside
|
||||
// V3EmitC, however, it also means that verbose logging may
|
||||
// miss to print change detect variables.
|
||||
AstNode* const newp = new AstCReturn{
|
||||
m_scopetopp->fileline(),
|
||||
new AstLogOr{m_scopetopp->fileline(), callp, returnp->lhsp()->unlinkFrBack()}};
|
||||
returnp->replaceWith(newp);
|
||||
VL_DO_DANGLING(returnp->deleteTree(), returnp);
|
||||
}
|
||||
m_numStmts = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// Utility visitor to find elements to be compared
|
||||
|
||||
class ChangedInsertVisitor final : public VNVisitor {
|
||||
private:
|
||||
// STATE
|
||||
ChangedState& m_state; // Shared state across visitors
|
||||
AstVarScope* const m_vscp; // Original (non-change) variable we're change-detecting
|
||||
AstVarScope* m_newvscp = nullptr; // New (change detect) variable we're change-detecting
|
||||
AstNode* m_varEqnp = nullptr; // Original var's equation to get var value
|
||||
AstNode* m_newLvEqnp = nullptr; // New var's equation to read value
|
||||
AstNode* m_newRvEqnp = nullptr; // New var's equation to set value
|
||||
uint32_t m_detects = 0; // # detects created
|
||||
|
||||
// CONSTANTS
|
||||
// How many indexes before error. Ok to increase this, but may result in much slower model
|
||||
static constexpr uint32_t DETECTARRAY_MAX_INDEXES = 256;
|
||||
|
||||
void newChangeDet() {
|
||||
if (++m_detects > DETECTARRAY_MAX_INDEXES) {
|
||||
m_vscp->v3warn(E_DETECTARRAY,
|
||||
"Unsupported: Can't detect more than "
|
||||
<< DETECTARRAY_MAX_INDEXES
|
||||
<< " array indexes (probably with UNOPTFLAT warning suppressed): "
|
||||
<< m_vscp->prettyName() << '\n'
|
||||
<< m_vscp->warnMore()
|
||||
<< "... Could recompile with DETECTARRAY_MAX_INDEXES increased");
|
||||
return;
|
||||
}
|
||||
m_state.maybeCreateChgFuncp();
|
||||
|
||||
AstChangeDet* const changep = new AstChangeDet{
|
||||
m_vscp->fileline(), m_varEqnp->cloneTree(true), m_newRvEqnp->cloneTree(true)};
|
||||
m_state.m_chgFuncp->addStmtsp(changep);
|
||||
AstAssign* const initp = new AstAssign{m_vscp->fileline(), m_newLvEqnp->cloneTree(true),
|
||||
m_varEqnp->cloneTree(true)};
|
||||
m_state.m_chgFuncp->addFinalsp(initp);
|
||||
|
||||
// Later code will expand words which adds to GCC compile time,
|
||||
// so add penalty based on word width also
|
||||
m_state.m_numStmts += initp->nodeCount() + m_varEqnp->widthWords();
|
||||
}
|
||||
|
||||
void visit(AstBasicDType*) override { //
|
||||
newChangeDet();
|
||||
}
|
||||
void visit(AstPackArrayDType*) override { //
|
||||
newChangeDet();
|
||||
}
|
||||
void visit(AstUnpackArrayDType* nodep) override {
|
||||
for (int index = 0; index < nodep->elementsConst(); ++index) {
|
||||
VL_RESTORER(m_varEqnp);
|
||||
VL_RESTORER(m_newLvEqnp);
|
||||
VL_RESTORER(m_newRvEqnp);
|
||||
{
|
||||
m_varEqnp = new AstArraySel{nodep->fileline(), m_varEqnp->cloneTree(true), index};
|
||||
m_newLvEqnp
|
||||
= new AstArraySel{nodep->fileline(), m_newLvEqnp->cloneTree(true), index};
|
||||
m_newRvEqnp
|
||||
= new AstArraySel{nodep->fileline(), m_newRvEqnp->cloneTree(true), index};
|
||||
|
||||
iterate(nodep->subDTypep()->skipRefp());
|
||||
|
||||
m_varEqnp->deleteTree();
|
||||
m_newLvEqnp->deleteTree();
|
||||
m_newRvEqnp->deleteTree();
|
||||
}
|
||||
}
|
||||
}
|
||||
void visit(AstNodeUOrStructDType* nodep) override {
|
||||
if (nodep->packedUnsup()) {
|
||||
newChangeDet();
|
||||
} else {
|
||||
if (debug()) nodep->dumpTree(cout, "-DETECTARRAY-class-");
|
||||
m_vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable"
|
||||
" (probably with UNOPTFLAT warning suppressed): "
|
||||
<< m_vscp->varp()->prettyNameQ());
|
||||
}
|
||||
}
|
||||
void visit(AstNode* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (debug()) nodep->dumpTree(cout, "-DETECTARRAY-general-");
|
||||
m_vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable"
|
||||
" (probably with UNOPTFLAT warning suppressed): "
|
||||
<< m_vscp->varp()->prettyNameQ());
|
||||
}
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
ChangedInsertVisitor(AstVarScope* vscp, ChangedState& state)
|
||||
: m_state{state}
|
||||
, m_vscp{vscp} {
|
||||
// DPI export trigger should never need change detect. See similar assertions in V3Order
|
||||
// (OrderVisitor::nodeMarkCircular), and V3GenClk (GenClkRenameVisitor::genInpClk).
|
||||
UASSERT_OBJ(vscp != v3Global.rootp()->dpiExportTriggerp(), vscp,
|
||||
"DPI export trigger should not need change detect");
|
||||
{
|
||||
AstVar* const varp = m_vscp->varp();
|
||||
const string newvarname{"__Vchglast__" + m_vscp->scopep()->nameDotless() + "__"
|
||||
+ varp->shortName()};
|
||||
// Create: VARREF(_last)
|
||||
// ASSIGN(VARREF(_last), VARREF(var))
|
||||
// ...
|
||||
// CHANGEDET(VARREF(_last), VARREF(var))
|
||||
AstVar* const newvarp
|
||||
= new AstVar{varp->fileline(), VVarType::MODULETEMP, newvarname, varp};
|
||||
m_state.m_topModp->addStmtp(newvarp);
|
||||
m_newvscp = new AstVarScope{m_vscp->fileline(), m_state.m_scopetopp, newvarp};
|
||||
m_state.m_scopetopp->addVarp(m_newvscp);
|
||||
|
||||
m_varEqnp = new AstVarRef{m_vscp->fileline(), m_vscp, VAccess::READ};
|
||||
m_newLvEqnp = new AstVarRef{m_vscp->fileline(), m_newvscp, VAccess::WRITE};
|
||||
m_newRvEqnp = new AstVarRef{m_vscp->fileline(), m_newvscp, VAccess::READ};
|
||||
}
|
||||
iterate(vscp->dtypep()->skipRefp());
|
||||
m_varEqnp->deleteTree();
|
||||
m_newLvEqnp->deleteTree();
|
||||
m_newRvEqnp->deleteTree();
|
||||
}
|
||||
~ChangedInsertVisitor() override = default;
|
||||
VL_UNCOPYABLE(ChangedInsertVisitor);
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// Changed class functions
|
||||
|
||||
void V3Changed::changedAll(AstNetlist* nodep) {
|
||||
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||
|
||||
ChangedState state;
|
||||
state.m_scopetopp = nodep->topScopep()->scopep();
|
||||
state.m_topModp = nodep->topModulep();
|
||||
nodep->foreach<AstVarScope>([&state](AstVarScope* vscp) {
|
||||
if (vscp->isCircular()) {
|
||||
vscp->v3warn(IMPERFECTSCH,
|
||||
"Imperfect scheduling of variable: " << vscp->prettyNameQ());
|
||||
ChangedInsertVisitor{vscp, state};
|
||||
}
|
||||
});
|
||||
|
||||
V3Global::dumpCheckGlobalTree("changed", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
}
|
||||
|
|
@ -49,7 +49,7 @@ private:
|
|||
// METHODS
|
||||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
||||
virtual void visit(AstClass* nodep) override {
|
||||
void visit(AstClass* nodep) override {
|
||||
if (nodep->user1SetOnce()) return;
|
||||
// Move this class
|
||||
nodep->name(m_prefix + nodep->name());
|
||||
|
|
@ -100,7 +100,7 @@ private:
|
|||
}
|
||||
nodep->repairCache();
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
// Visit for NodeModules that are not AstClass (AstClass is-a AstNodeModule)
|
||||
VL_RESTORER(m_prefix);
|
||||
{
|
||||
|
|
@ -109,7 +109,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
void visit(AstVar* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (m_packageScopep) {
|
||||
if (m_ftaskp && m_ftaskp->lifetime().isStatic()) {
|
||||
|
|
@ -127,12 +127,12 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstVarScope* nodep) override {
|
||||
void visit(AstVarScope* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
nodep->varp()->user1p(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeFTask* nodep) override {
|
||||
void visit(AstNodeFTask* nodep) override {
|
||||
VL_RESTORER(m_ftaskp);
|
||||
{
|
||||
m_ftaskp = nodep;
|
||||
|
|
@ -142,7 +142,7 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
// Don't move now, or wouldn't keep interating the class
|
||||
// TODO move function statics only
|
||||
|
|
@ -150,14 +150,14 @@ private:
|
|||
// m_toScopeMoves.push_back(std::make_pair(nodep, m_classScopep));
|
||||
//}
|
||||
}
|
||||
virtual void visit(AstInitial* nodep) override {
|
||||
void visit(AstInitial* nodep) override {
|
||||
// But not AstInitialAutomatic, which remains under the class
|
||||
iterateChildren(nodep);
|
||||
if (m_packageScopep) {
|
||||
m_toScopeMoves.emplace_back(std::make_pair(nodep, m_packageScopep));
|
||||
}
|
||||
}
|
||||
virtual void visit(AstInitialStatic* nodep) override {
|
||||
void visit(AstInitialStatic* nodep) override {
|
||||
// But not AstInitialAutomatic, which remains under the class
|
||||
iterateChildren(nodep);
|
||||
if (m_packageScopep) {
|
||||
|
|
@ -165,14 +165,14 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeMath* nodep) override {} // Short circuit
|
||||
virtual void visit(AstNodeStmt* nodep) override {} // Short circuit
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNodeMath* nodep) override {} // Short circuit
|
||||
void visit(AstNodeStmt* nodep) override {} // Short circuit
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit ClassVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
virtual ~ClassVisitor() override {
|
||||
~ClassVisitor() override {
|
||||
for (auto moved : m_toScopeMoves) {
|
||||
AstNode* const nodep = moved.first;
|
||||
AstScope* const scopep = moved.second;
|
||||
|
|
|
|||
|
|
@ -173,64 +173,64 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
VL_RESTORER(m_modp);
|
||||
{
|
||||
m_modp = nodep;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeUniop* nodep) override {
|
||||
void visit(AstNodeUniop* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
computeCppWidth(nodep);
|
||||
if (nodep->cleanLhs()) ensureClean(nodep->lhsp());
|
||||
setClean(nodep, nodep->cleanOut());
|
||||
}
|
||||
virtual void visit(AstNodeBiop* nodep) override {
|
||||
void visit(AstNodeBiop* nodep) override {
|
||||
operandBiop(nodep);
|
||||
setClean(nodep, nodep->cleanOut());
|
||||
}
|
||||
virtual void visit(AstAnd* nodep) override {
|
||||
void visit(AstAnd* nodep) override {
|
||||
operandBiop(nodep);
|
||||
setClean(nodep, isClean(nodep->lhsp()) || isClean(nodep->rhsp()));
|
||||
}
|
||||
virtual void visit(AstXor* nodep) override {
|
||||
void visit(AstXor* nodep) override {
|
||||
operandBiop(nodep);
|
||||
setClean(nodep, isClean(nodep->lhsp()) && isClean(nodep->rhsp()));
|
||||
}
|
||||
virtual void visit(AstOr* nodep) override {
|
||||
void visit(AstOr* nodep) override {
|
||||
operandBiop(nodep);
|
||||
setClean(nodep, isClean(nodep->lhsp()) && isClean(nodep->rhsp()));
|
||||
}
|
||||
virtual void visit(AstNodeQuadop* nodep) override {
|
||||
void visit(AstNodeQuadop* nodep) override {
|
||||
operandQuadop(nodep);
|
||||
setClean(nodep, nodep->cleanOut());
|
||||
}
|
||||
virtual void visit(AstNodeMath* nodep) override {
|
||||
void visit(AstNodeMath* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
computeCppWidth(nodep);
|
||||
setClean(nodep, nodep->cleanOut());
|
||||
}
|
||||
virtual void visit(AstNodeAssign* nodep) override {
|
||||
void visit(AstNodeAssign* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
computeCppWidth(nodep);
|
||||
if (nodep->cleanRhs()) ensureClean(nodep->rhsp());
|
||||
}
|
||||
virtual void visit(AstText* nodep) override { //
|
||||
void visit(AstText* nodep) override { //
|
||||
setClean(nodep, true);
|
||||
}
|
||||
virtual void visit(AstScopeName* nodep) override { //
|
||||
void visit(AstScopeName* nodep) override { //
|
||||
setClean(nodep, true);
|
||||
}
|
||||
virtual void visit(AstCNew* nodep) override {
|
||||
void visit(AstCNew* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
setClean(nodep, true);
|
||||
}
|
||||
virtual void visit(AstSel* nodep) override {
|
||||
void visit(AstSel* nodep) override {
|
||||
operandTriop(nodep);
|
||||
setClean(nodep, nodep->cleanOut());
|
||||
}
|
||||
virtual void visit(AstUCFunc* nodep) override {
|
||||
void visit(AstUCFunc* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
computeCppWidth(nodep);
|
||||
setClean(nodep, false);
|
||||
|
|
@ -238,69 +238,69 @@ private:
|
|||
if (!VN_IS(nodep->backp(), And)) insertClean(nodep);
|
||||
ensureCleanAndNext(nodep->bodysp());
|
||||
}
|
||||
virtual void visit(AstTraceDecl* nodep) override {
|
||||
void visit(AstTraceDecl* nodep) override {
|
||||
// No cleaning, or would loose pointer to enum
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstTraceInc* nodep) override {
|
||||
void visit(AstTraceInc* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
ensureCleanAndNext(nodep->valuep());
|
||||
}
|
||||
virtual void visit(AstTypedef* nodep) override {
|
||||
void visit(AstTypedef* nodep) override {
|
||||
// No cleaning, or would loose pointer to enum
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstParamTypeDType* nodep) override {
|
||||
void visit(AstParamTypeDType* nodep) override {
|
||||
// No cleaning, or would loose pointer to enum
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
// Control flow operators
|
||||
virtual void visit(AstNodeCond* nodep) override {
|
||||
void visit(AstNodeCond* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
ensureClean(nodep->condp());
|
||||
setClean(nodep, isClean(nodep->expr1p()) && isClean(nodep->expr2p()));
|
||||
}
|
||||
virtual void visit(AstWhile* nodep) override {
|
||||
void visit(AstWhile* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
ensureClean(nodep->condp());
|
||||
}
|
||||
virtual void visit(AstNodeIf* nodep) override {
|
||||
void visit(AstNodeIf* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
ensureClean(nodep->condp());
|
||||
}
|
||||
virtual void visit(AstSFormatF* nodep) override {
|
||||
void visit(AstSFormatF* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
ensureCleanAndNext(nodep->exprsp());
|
||||
setClean(nodep, true); // generates a string, so not relevant
|
||||
}
|
||||
virtual void visit(AstUCStmt* nodep) override {
|
||||
void visit(AstUCStmt* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
ensureCleanAndNext(nodep->bodysp());
|
||||
}
|
||||
virtual void visit(AstNodeCCall* nodep) override {
|
||||
void visit(AstNodeCCall* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
ensureCleanAndNext(nodep->argsp());
|
||||
setClean(nodep, true);
|
||||
}
|
||||
virtual void visit(AstCMethodHard* nodep) override {
|
||||
void visit(AstCMethodHard* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
ensureCleanAndNext(nodep->pinsp());
|
||||
setClean(nodep, true);
|
||||
}
|
||||
virtual void visit(AstWith* nodep) override {
|
||||
void visit(AstWith* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
ensureCleanAndNext(nodep->exprp());
|
||||
setClean(nodep, true);
|
||||
}
|
||||
virtual void visit(AstIntfRef* nodep) override {
|
||||
void visit(AstIntfRef* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
setClean(nodep, true); // generates a string, so not relevant
|
||||
}
|
||||
|
||||
//--------------------
|
||||
// Default: Just iterate
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
computeCppWidth(nodep);
|
||||
}
|
||||
|
|
@ -308,7 +308,7 @@ private:
|
|||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit CleanVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
virtual ~CleanVisitor() override = default;
|
||||
~CleanVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ private:
|
|||
m_lastIfp = nullptr;
|
||||
}
|
||||
// VISITORS
|
||||
virtual void visit(AstCoverToggle* nodep) override {
|
||||
void visit(AstCoverToggle* nodep) override {
|
||||
// nodep->dumpTree(cout, "ct:");
|
||||
// COVERTOGGLE(INC, ORIG, CHANGE) ->
|
||||
// IF(ORIG ^ CHANGE) { INC; CHANGE = ORIG; }
|
||||
|
|
@ -137,11 +137,11 @@ private:
|
|||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
virtual void visit(AstSenTree* nodep) override {
|
||||
void visit(AstSenTree* nodep) override {
|
||||
nodep->unlinkFrBack();
|
||||
pushDeletep(nodep); // Delete it later, AstActives still pointing to it
|
||||
}
|
||||
virtual void visit(AstActive* nodep) override {
|
||||
void visit(AstActive* nodep) override {
|
||||
UASSERT_OBJ(nodep->hasClocked(), nodep, "Should have been converted by V3Sched");
|
||||
UASSERT_OBJ(nodep->stmtsp(), nodep, "Should not have been created if empty");
|
||||
|
||||
|
|
@ -164,7 +164,7 @@ private:
|
|||
// Dispose of the AstActive
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
virtual void visit(AstExecGraph* nodep) override {
|
||||
void visit(AstExecGraph* nodep) override {
|
||||
for (AstMTaskBody* mtaskBodyp = nodep->mTaskBodiesp(); mtaskBodyp;
|
||||
mtaskBodyp = VN_AS(mtaskBodyp->nextp(), MTaskBody)) {
|
||||
clearLastSen();
|
||||
|
|
@ -174,14 +174,14 @@ private:
|
|||
}
|
||||
|
||||
//========== Create sampled values
|
||||
virtual void visit(AstScope* nodep) override {
|
||||
void visit(AstScope* nodep) override {
|
||||
VL_RESTORER(m_scopep);
|
||||
{
|
||||
m_scopep = nodep;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSampled* nodep) override {
|
||||
void visit(AstSampled* nodep) override {
|
||||
VL_RESTORER(m_inSampled);
|
||||
{
|
||||
m_inSampled = true;
|
||||
|
|
@ -190,7 +190,7 @@ private:
|
|||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (m_inSampled && !nodep->user1SetOnce()) {
|
||||
UASSERT_OBJ(nodep->access().isReadOnly(), nodep, "Should have failed in V3Access");
|
||||
|
|
@ -204,7 +204,7 @@ private:
|
|||
}
|
||||
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
@ -212,7 +212,7 @@ public:
|
|||
m_evalp = netlistp->evalp();
|
||||
iterate(netlistp);
|
||||
}
|
||||
virtual ~ClockVisitor() override = default;
|
||||
~ClockVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -180,32 +180,32 @@ class CombineVisitor final : VNVisitor {
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep) override {
|
||||
void visit(AstNetlist* nodep) override {
|
||||
// Gather functions and references
|
||||
iterateChildrenConst(nodep);
|
||||
// Combine functions
|
||||
process(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
UASSERT_OBJ(!m_modp, nodep, "Should not nest");
|
||||
m_modp = nodep;
|
||||
iterateChildrenConst(nodep);
|
||||
m_modp = nullptr;
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
iterateChildrenConst(nodep);
|
||||
if (nodep->dontCombine()) return;
|
||||
auto& coll = nodep->slow() ? m_cfuncs(m_modp).m_slow : m_cfuncs(m_modp).m_fast;
|
||||
coll.emplace_back(nodep);
|
||||
}
|
||||
virtual void visit(AstCCall* nodep) override {
|
||||
void visit(AstCCall* nodep) override {
|
||||
iterateChildrenConst(nodep);
|
||||
AstCFunc* const funcp = nodep->funcp();
|
||||
if (funcp->dontCombine()) return;
|
||||
m_callSites(funcp).emplace_back(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstAddrOfCFunc* nodep) override {
|
||||
void visit(AstAddrOfCFunc* nodep) override {
|
||||
iterateChildrenConst(nodep);
|
||||
if (nodep->funcp()->dontCombine()) return;
|
||||
// LCOV_EXCL_START
|
||||
|
|
@ -217,7 +217,7 @@ class CombineVisitor final : VNVisitor {
|
|||
}
|
||||
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep) override { iterateChildrenConst(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildrenConst(nodep); }
|
||||
|
||||
// CONSTRUCTORS
|
||||
explicit CombineVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@ public:
|
|||
if (lineMatch(lineno, VPragmaType::FULL_CASE)) nodep->fullPragma(true);
|
||||
if (lineMatch(lineno, VPragmaType::PARALLEL_CASE)) nodep->parallelPragma(true);
|
||||
}
|
||||
inline void applyIgnores(FileLine* filelinep) {
|
||||
void applyIgnores(FileLine* filelinep) {
|
||||
// HOT routine, called each parsed token line of this filename
|
||||
if (m_lastIgnore.lineno != filelinep->lineno()) {
|
||||
// UINFO(9, " ApplyIgnores for " << filelinep->ascii() << endl);
|
||||
|
|
|
|||
|
|
@ -417,14 +417,12 @@ class ConstBitOpTreeVisitor final : public VNVisitor {
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
CONST_BITOP_SET_FAILED("Hit unexpected op", nodep);
|
||||
}
|
||||
virtual void visit(AstCCast* nodep) override {
|
||||
void visit(AstNode* nodep) override { CONST_BITOP_SET_FAILED("Hit unexpected op", nodep); }
|
||||
void visit(AstCCast* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (m_leafp) m_leafp->updateBitRange(nodep);
|
||||
}
|
||||
virtual void visit(AstShiftR* nodep) override {
|
||||
void visit(AstShiftR* nodep) override {
|
||||
CONST_BITOP_RETURN_IF(!m_leafp, nodep);
|
||||
AstConst* const constp = VN_CAST(nodep->rhsp(), Const);
|
||||
CONST_BITOP_RETURN_IF(!constp, nodep->rhsp());
|
||||
|
|
@ -434,7 +432,7 @@ class ConstBitOpTreeVisitor final : public VNVisitor {
|
|||
m_leafp->updateBitRange(nodep);
|
||||
m_lsb -= constp->toUInt();
|
||||
}
|
||||
virtual void visit(AstNot* nodep) override {
|
||||
void visit(AstNot* nodep) override {
|
||||
CONST_BITOP_RETURN_IF(nodep->widthMin() != 1, nodep);
|
||||
AstNode* lhsp = nodep->lhsp();
|
||||
AstCCast* const castp = VN_CAST(lhsp, CCast);
|
||||
|
|
@ -449,7 +447,7 @@ class ConstBitOpTreeVisitor final : public VNVisitor {
|
|||
if (!isXorTree()) m_polarity = !m_polarity;
|
||||
if (m_leafp && castp) m_leafp->updateBitRange(castp);
|
||||
}
|
||||
virtual void visit(AstWordSel* nodep) override {
|
||||
void visit(AstWordSel* nodep) override {
|
||||
CONST_BITOP_RETURN_IF(!m_leafp, nodep);
|
||||
AstConst* const constp = VN_CAST(nodep->bitp(), Const);
|
||||
CONST_BITOP_RETURN_IF(!constp, nodep->rhsp());
|
||||
|
|
@ -457,17 +455,17 @@ class ConstBitOpTreeVisitor final : public VNVisitor {
|
|||
m_leafp->wordIdx(constp->toSInt());
|
||||
iterate(nodep->fromp());
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
CONST_BITOP_RETURN_IF(!m_leafp, nodep);
|
||||
m_leafp->setLeaf(nodep);
|
||||
m_leafp->polarity(m_polarity);
|
||||
}
|
||||
virtual void visit(AstConst* nodep) override {
|
||||
void visit(AstConst* nodep) override {
|
||||
CONST_BITOP_RETURN_IF(!m_leafp, nodep);
|
||||
m_leafp->setLeaf(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstRedXor* nodep) override {
|
||||
void visit(AstRedXor* nodep) override {
|
||||
Restorer restorer{*this};
|
||||
CONST_BITOP_RETURN_IF(!VN_IS(m_rootp, Xor), nodep);
|
||||
AstNode* lhsp = nodep->lhsp();
|
||||
|
|
@ -514,7 +512,7 @@ class ConstBitOpTreeVisitor final : public VNVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeBiop* nodep) override {
|
||||
void visit(AstNodeBiop* nodep) override {
|
||||
if (VN_IS(nodep, And) && isConst(nodep->lhsp(), 1)) { // 1 & _
|
||||
// Always reach past a plain making AND
|
||||
Restorer restorer{*this};
|
||||
|
|
@ -2252,11 +2250,11 @@ private:
|
|||
//----------------------------------------
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep) override {
|
||||
void visit(AstNetlist* nodep) override {
|
||||
// Iterate modules backwards, in bottom-up order. That's faster
|
||||
iterateChildrenBackwards(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
VL_RESTORER(m_modp);
|
||||
{
|
||||
m_modp = nodep;
|
||||
|
|
@ -2264,7 +2262,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
// No ASSIGNW removals under funcs, we've long eliminated INITIALs
|
||||
// (We should perhaps rename the assignw's to just assigns)
|
||||
VL_RESTORER(m_wremove);
|
||||
|
|
@ -2273,7 +2271,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstScope* nodep) override {
|
||||
void visit(AstScope* nodep) override {
|
||||
// No ASSIGNW removals under scope, we've long eliminated INITIALs
|
||||
VL_RESTORER(m_wremove);
|
||||
VL_RESTORER(m_scopep);
|
||||
|
|
@ -2370,17 +2368,17 @@ private:
|
|||
}
|
||||
|
||||
// Special cases
|
||||
virtual void visit(AstConst*) override {} // Already constant
|
||||
void visit(AstConst*) override {} // Already constant
|
||||
|
||||
virtual void visit(AstCell* nodep) override {
|
||||
void visit(AstCell* nodep) override {
|
||||
if (m_params) {
|
||||
iterateAndNextNull(nodep->paramsp());
|
||||
} else {
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstClassOrPackageRef* nodep) override { iterateChildren(nodep); }
|
||||
virtual void visit(AstPin* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstClassOrPackageRef* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstPin* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
void replaceLogEq(AstLogEq* nodep) {
|
||||
// LOGEQ(a,b) => AstLogAnd{AstLogOr{AstLogNot{a},b},AstLogOr{AstLogNot{b},a}}
|
||||
|
|
@ -2562,7 +2560,7 @@ private:
|
|||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstAttrOf* nodep) override {
|
||||
void visit(AstAttrOf* nodep) override {
|
||||
VL_RESTORER(m_attrp);
|
||||
{
|
||||
m_attrp = nodep;
|
||||
|
|
@ -2570,7 +2568,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstArraySel* nodep) override {
|
||||
void visit(AstArraySel* nodep) override {
|
||||
iterateAndNextNull(nodep->bitp());
|
||||
if (VN_IS(nodep->bitp(), Const)
|
||||
&& VN_IS(nodep->fromp(), VarRef)
|
||||
|
|
@ -2596,7 +2594,7 @@ private:
|
|||
}
|
||||
m_selp = nullptr;
|
||||
}
|
||||
virtual void visit(AstNodeVarRef* nodep) override {
|
||||
void visit(AstNodeVarRef* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
UASSERT_OBJ(nodep->varp(), nodep, "Not linked");
|
||||
bool did = false;
|
||||
|
|
@ -2650,7 +2648,7 @@ private:
|
|||
<< nodep->varp()->prettyNameQ());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstEnumItemRef* nodep) override {
|
||||
void visit(AstEnumItemRef* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
UASSERT_OBJ(nodep->itemp(), nodep, "Not linked");
|
||||
bool did = false;
|
||||
|
|
@ -2675,7 +2673,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
// virtual void visit(AstCvtPackString* nodep) override {
|
||||
// void visit(AstCvtPackString* nodep) override {
|
||||
// Not constant propagated (for today) because AstNodeMath::isOpaque is set
|
||||
// Someday if lower is constant, convert to quoted "string".
|
||||
|
||||
|
|
@ -2683,7 +2681,7 @@ private:
|
|||
// Only one if it's not in a list
|
||||
return (!nodep->nextp() && nodep->backp()->nextp() != nodep);
|
||||
}
|
||||
virtual void visit(AstSenItem* nodep) override {
|
||||
void visit(AstSenItem* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (m_doNConst
|
||||
&& (VN_IS(nodep->sensp(), Const) || VN_IS(nodep->sensp(), EnumItemRef)
|
||||
|
|
@ -2772,7 +2770,7 @@ private:
|
|||
}
|
||||
};
|
||||
|
||||
virtual void visit(AstSenTree* nodep) override {
|
||||
void visit(AstSenTree* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (m_doExpensive) {
|
||||
// cout<<endl; nodep->dumpTree(cout, "ssin: ");
|
||||
|
|
@ -2852,18 +2850,18 @@ private:
|
|||
|
||||
//-----
|
||||
// Zero elimination
|
||||
virtual void visit(AstNodeAssign* nodep) override {
|
||||
void visit(AstNodeAssign* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (nodep->timingControlp()) m_hasJumpDelay = true;
|
||||
if (m_doNConst && replaceNodeAssign(nodep)) return;
|
||||
}
|
||||
virtual void visit(AstAssignAlias* nodep) override {
|
||||
void visit(AstAssignAlias* nodep) override {
|
||||
// Don't perform any optimizations, keep the alias around
|
||||
}
|
||||
virtual void visit(AstAssignVarScope* nodep) override {
|
||||
void visit(AstAssignVarScope* nodep) override {
|
||||
// Don't perform any optimizations, the node won't be linked yet
|
||||
}
|
||||
virtual void visit(AstAssignW* nodep) override {
|
||||
void visit(AstAssignW* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (m_doNConst && replaceNodeAssign(nodep)) return;
|
||||
AstNodeVarRef* const varrefp = VN_CAST(
|
||||
|
|
@ -2890,7 +2888,7 @@ private:
|
|||
varrefp->varp()->valuep(initvaluep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstRelease* nodep) override {
|
||||
void visit(AstRelease* nodep) override {
|
||||
if (AstConcat* const concatp = VN_CAST(nodep->lhsp(), Concat)) {
|
||||
FileLine* const flp = nodep->fileline();
|
||||
AstRelease* const newLp = new AstRelease{flp, concatp->lhsp()->unlinkFrBack()};
|
||||
|
|
@ -2903,7 +2901,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeIf* nodep) override {
|
||||
void visit(AstNodeIf* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (m_doNConst) {
|
||||
if (const AstConst* const constp = VN_CAST(nodep->condp(), Const)) {
|
||||
|
|
@ -2987,7 +2985,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstDisplay* nodep) override {
|
||||
void visit(AstDisplay* nodep) override {
|
||||
// DISPLAY(SFORMAT(text1)),DISPLAY(SFORMAT(text2)) -> DISPLAY(SFORMAT(text1+text2))
|
||||
iterateChildren(nodep);
|
||||
if (stmtDisplayDisplay(nodep)) return;
|
||||
|
|
@ -3041,7 +3039,7 @@ private:
|
|||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
return true;
|
||||
}
|
||||
virtual void visit(AstSFormatF* nodep) override {
|
||||
void visit(AstSFormatF* nodep) override {
|
||||
// Substitute constants into displays. The main point of this is to
|
||||
// simplify assertion methodologies which call functions with display's.
|
||||
// This eliminates a pile of wide temps, and makes the C a whole lot more readable.
|
||||
|
|
@ -3108,17 +3106,17 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstFuncRef* nodep) override {
|
||||
void visit(AstFuncRef* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (m_params) { // Only parameters force us to do constant function call propagation
|
||||
replaceWithSimulation(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstArg* nodep) override {
|
||||
void visit(AstArg* nodep) override {
|
||||
// replaceWithSimulation on the Arg's parent FuncRef replaces these
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstWhile* nodep) override {
|
||||
void visit(AstWhile* nodep) override {
|
||||
const bool oldHasJumpDelay = m_hasJumpDelay;
|
||||
m_hasJumpDelay = false;
|
||||
{ iterateChildren(nodep); }
|
||||
|
|
@ -3144,22 +3142,22 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstInitArray* nodep) override { iterateChildren(nodep); }
|
||||
virtual void visit(AstInitItem* nodep) override { iterateChildren(nodep); }
|
||||
virtual void visit(AstUnbounded* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstInitArray* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstInitItem* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstUnbounded* nodep) override { iterateChildren(nodep); }
|
||||
// These are converted by V3Param. Don't constify as we don't want the
|
||||
// from() VARREF to disappear, if any.
|
||||
// If output of a presel didn't get consted, chances are V3Param didn't visit properly
|
||||
virtual void visit(AstNodePreSel*) override {}
|
||||
void visit(AstNodePreSel*) override {}
|
||||
|
||||
// Ignored, can eliminate early
|
||||
virtual void visit(AstSysIgnore* nodep) override {
|
||||
void visit(AstSysIgnore* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (m_doNConst) VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
}
|
||||
|
||||
// Simplify
|
||||
virtual void visit(AstBasicDType* nodep) override {
|
||||
void visit(AstBasicDType* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
nodep->cvtRangeConst();
|
||||
}
|
||||
|
|
@ -3167,7 +3165,7 @@ private:
|
|||
//-----
|
||||
// Jump elimination
|
||||
|
||||
virtual void visit(AstJumpGo* nodep) override {
|
||||
void visit(AstJumpGo* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
// Jump to label where label immediately follows label is not useful
|
||||
if (nodep->labelp() == VN_CAST(nodep->nextp(), JumpLabel)) {
|
||||
|
|
@ -3198,7 +3196,7 @@ private:
|
|||
m_hasJumpDelay = true;
|
||||
}
|
||||
|
||||
virtual void visit(AstJumpBlock* nodep) override {
|
||||
void visit(AstJumpBlock* nodep) override {
|
||||
// Because JumpLabels disable many optimizations,
|
||||
// remove JumpLabels that are not pointed to by any AstJumpGos
|
||||
// Note this assumes all AstJumpGos are underneath the given label; V3Broken asserts this
|
||||
|
|
@ -3552,7 +3550,7 @@ private:
|
|||
// Note we can't convert EqCase/NeqCase to Eq/Neq here because that would break 3'b1x1==3'b101
|
||||
|
||||
//-----
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
// Default: Just iterate
|
||||
if (m_required) {
|
||||
if (VN_IS(nodep, NodeDType) || VN_IS(nodep, Range) || VN_IS(nodep, SliceSel)) {
|
||||
|
|
@ -3600,7 +3598,7 @@ public:
|
|||
}
|
||||
// clang-format on
|
||||
}
|
||||
virtual ~ConstVisitor() override {
|
||||
~ConstVisitor() override {
|
||||
if (m_doCpp) {
|
||||
if (m_globalPass) {
|
||||
V3Stats::addStat("Optimizations, Const bit op reduction", m_statBitOpReduction);
|
||||
|
|
|
|||
|
|
@ -209,7 +209,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS - BOTH
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
const AstNodeModule* const origModp = m_modp;
|
||||
VL_RESTORER(m_modp);
|
||||
VL_RESTORER(m_state);
|
||||
|
|
@ -227,9 +227,9 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeProcedure* nodep) override { iterateProcedure(nodep); }
|
||||
virtual void visit(AstWhile* nodep) override { iterateProcedure(nodep); }
|
||||
virtual void visit(AstNodeFTask* nodep) override {
|
||||
void visit(AstNodeProcedure* nodep) override { iterateProcedure(nodep); }
|
||||
void visit(AstWhile* nodep) override { iterateProcedure(nodep); }
|
||||
void visit(AstNodeFTask* nodep) override {
|
||||
if (!nodep->dpiImport()) iterateProcedure(nodep);
|
||||
}
|
||||
void iterateProcedure(AstNode* nodep) {
|
||||
|
|
@ -258,7 +258,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS - TOGGLE COVERAGE
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
void visit(AstVar* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (m_modp && !m_inToggleOff && !m_state.m_inModOff && nodep->fileline()->coverageOn()
|
||||
&& v3Global.opt.coverageToggle()) {
|
||||
|
|
@ -383,7 +383,7 @@ private:
|
|||
|
||||
// VISITORS - LINE COVERAGE
|
||||
// Note not AstNodeIf; other types don't get covered
|
||||
virtual void visit(AstIf* nodep) override {
|
||||
void visit(AstIf* nodep) override {
|
||||
UINFO(4, " IF: " << nodep << endl);
|
||||
if (m_state.m_on) {
|
||||
// An else-if. When we iterate the if, use "elsif" marking
|
||||
|
|
@ -460,7 +460,7 @@ private:
|
|||
}
|
||||
UINFO(9, " done HANDLE " << m_state.m_handle << " for " << nodep << endl);
|
||||
}
|
||||
virtual void visit(AstCaseItem* nodep) override {
|
||||
void visit(AstCaseItem* nodep) override {
|
||||
// We don't add an explicit "default" coverage if not provided,
|
||||
// as we already have a warning when there is no default.
|
||||
UINFO(4, " CASEI: " << nodep << endl);
|
||||
|
|
@ -479,7 +479,7 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCover* nodep) override {
|
||||
void visit(AstCover* nodep) override {
|
||||
UINFO(4, " COVER: " << nodep << endl);
|
||||
VL_RESTORER(m_state);
|
||||
{
|
||||
|
|
@ -495,11 +495,11 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstStop* nodep) override {
|
||||
void visit(AstStop* nodep) override {
|
||||
UINFO(4, " STOP: " << nodep << endl);
|
||||
m_state.m_on = false;
|
||||
}
|
||||
virtual void visit(AstPragma* nodep) override {
|
||||
void visit(AstPragma* nodep) override {
|
||||
if (nodep->pragType() == VPragmaType::COVERAGE_BLOCK_OFF) {
|
||||
// Skip all NEXT nodes under this block, and skip this if/case branch
|
||||
UINFO(4, " OFF: h" << m_state.m_handle << " " << nodep << endl);
|
||||
|
|
@ -510,7 +510,7 @@ private:
|
|||
lineTrack(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstBegin* nodep) override {
|
||||
void visit(AstBegin* nodep) override {
|
||||
// Record the hierarchy of any named begins, so we can apply to user
|
||||
// coverage points. This is because there may be cov points inside
|
||||
// generate blocks; each point should get separate consideration.
|
||||
|
|
@ -529,7 +529,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS - BOTH
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
lineTrack(nodep);
|
||||
}
|
||||
|
|
@ -537,7 +537,7 @@ private:
|
|||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit CoverageVisitor(AstNetlist* rootp) { iterateChildren(rootp); }
|
||||
virtual ~CoverageVisitor() override = default;
|
||||
~CoverageVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -88,24 +88,24 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep) override {
|
||||
void visit(AstNetlist* nodep) override {
|
||||
// Find all Coverage's
|
||||
iterateChildren(nodep);
|
||||
// Simplify
|
||||
detectDuplicates();
|
||||
}
|
||||
virtual void visit(AstCoverToggle* nodep) override {
|
||||
void visit(AstCoverToggle* nodep) override {
|
||||
m_toggleps.push_back(nodep);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
//--------------------
|
||||
virtual void visit(AstNodeMath*) override {} // Accelerate
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNodeMath*) override {} // Accelerate
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit CoverageJoinVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
virtual ~CoverageJoinVisitor() override {
|
||||
~CoverageJoinVisitor() override {
|
||||
V3Stats::addStat("Coverage, Toggle points joined", m_statToggleJoins);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
if (m_modp) m_modp->user1Inc(); // e.g. Class under Package
|
||||
VL_RESTORER(m_modp);
|
||||
{
|
||||
|
|
@ -120,12 +120,12 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
checkAll(nodep);
|
||||
if (nodep->scopep()) nodep->scopep()->user1Inc();
|
||||
}
|
||||
virtual void visit(AstScope* nodep) override {
|
||||
void visit(AstScope* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
checkAll(nodep);
|
||||
if (nodep->aboveScopep()) nodep->aboveScopep()->user1Inc();
|
||||
|
|
@ -136,14 +136,14 @@ private:
|
|||
m_scopesp.push_back(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCell* nodep) override {
|
||||
void visit(AstCell* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
checkAll(nodep);
|
||||
m_cellsp.push_back(nodep);
|
||||
nodep->modp()->user1Inc();
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeVarRef* nodep) override {
|
||||
void visit(AstNodeVarRef* nodep) override {
|
||||
// Note NodeAssign skips calling this in some cases
|
||||
iterateChildren(nodep);
|
||||
checkAll(nodep);
|
||||
|
|
@ -155,7 +155,7 @@ private:
|
|||
if (nodep->varp()) nodep->varp()->user1Inc();
|
||||
if (nodep->classOrPackagep()) nodep->classOrPackagep()->user1Inc();
|
||||
}
|
||||
virtual void visit(AstNodeFTaskRef* nodep) override {
|
||||
void visit(AstNodeFTaskRef* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
checkAll(nodep);
|
||||
if (nodep->classOrPackagep()) {
|
||||
|
|
@ -166,11 +166,11 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstMethodCall* nodep) override {
|
||||
void visit(AstMethodCall* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
checkAll(nodep);
|
||||
}
|
||||
virtual void visit(AstRefDType* nodep) override {
|
||||
void visit(AstRefDType* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
checkDType(nodep);
|
||||
checkAll(nodep);
|
||||
|
|
@ -184,7 +184,7 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstClassRefDType* nodep) override {
|
||||
void visit(AstClassRefDType* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
checkDType(nodep);
|
||||
checkAll(nodep);
|
||||
|
|
@ -197,12 +197,12 @@ private:
|
|||
}
|
||||
if (nodep->classp()) nodep->classp()->user1Inc();
|
||||
}
|
||||
virtual void visit(AstNodeDType* nodep) override {
|
||||
void visit(AstNodeDType* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
checkDType(nodep);
|
||||
checkAll(nodep);
|
||||
}
|
||||
virtual void visit(AstEnumItemRef* nodep) override {
|
||||
void visit(AstEnumItemRef* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
checkAll(nodep);
|
||||
if (nodep->classOrPackagep()) {
|
||||
|
|
@ -214,13 +214,13 @@ private:
|
|||
}
|
||||
checkAll(nodep);
|
||||
}
|
||||
virtual void visit(AstMemberSel* nodep) override {
|
||||
void visit(AstMemberSel* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (nodep->varp()) nodep->varp()->user1Inc();
|
||||
if (nodep->fromp()->dtypep()) nodep->fromp()->dtypep()->user1Inc(); // classref
|
||||
checkAll(nodep);
|
||||
}
|
||||
virtual void visit(AstModport* nodep) override {
|
||||
void visit(AstModport* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (m_elimCells) {
|
||||
if (!nodep->varsp()) {
|
||||
|
|
@ -230,14 +230,14 @@ private:
|
|||
}
|
||||
checkAll(nodep);
|
||||
}
|
||||
virtual void visit(AstSelLoopVars* nodep) override {
|
||||
void visit(AstSelLoopVars* nodep) override {
|
||||
// Var under a SelLoopVars means we haven't called V3Width to remove them yet
|
||||
VL_RESTORER(m_selloopvarsp);
|
||||
m_selloopvarsp = nodep;
|
||||
iterateChildren(nodep);
|
||||
checkAll(nodep);
|
||||
}
|
||||
virtual void visit(AstTypedef* nodep) override {
|
||||
void visit(AstTypedef* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (m_elimCells && !nodep->attrPublic()) {
|
||||
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
|
||||
|
|
@ -248,20 +248,20 @@ private:
|
|||
// Normal modules may disappear, e.g. if they are parameterized then removed
|
||||
if (nodep->attrPublic() && m_modp && VN_IS(m_modp, Package)) m_modp->user1Inc();
|
||||
}
|
||||
virtual void visit(AstVarScope* nodep) override {
|
||||
void visit(AstVarScope* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
checkAll(nodep);
|
||||
if (nodep->scopep()) nodep->scopep()->user1Inc();
|
||||
if (mightElimVar(nodep->varp())) m_vscsp.push_back(nodep);
|
||||
}
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
void visit(AstVar* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
checkAll(nodep);
|
||||
if (nodep->isSigPublic() && m_modp && VN_IS(m_modp, Package)) m_modp->user1Inc();
|
||||
if (m_selloopvarsp) nodep->user1Inc();
|
||||
if (mightElimVar(nodep)) m_varsp.push_back(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeAssign* nodep) override {
|
||||
void visit(AstNodeAssign* nodep) override {
|
||||
// See if simple assignments to variables may be eliminated because
|
||||
// that variable is never used.
|
||||
// Similar code in V3Life
|
||||
|
|
@ -285,7 +285,7 @@ private:
|
|||
}
|
||||
|
||||
//-----
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
if (nodep->isOutputter()) m_sideEffect = true;
|
||||
iterateChildren(nodep);
|
||||
checkAll(nodep);
|
||||
|
|
@ -452,7 +452,7 @@ public:
|
|||
// We may have removed some datatypes, cleanup
|
||||
nodep->typeTablep()->repairCache();
|
||||
}
|
||||
virtual ~DeadVisitor() override = default;
|
||||
~DeadVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -401,24 +401,24 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep) override {
|
||||
void visit(AstNetlist* nodep) override {
|
||||
// VV***** We reset all userp() on the netlist
|
||||
m_modVarMap.clear();
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstScope* nodep) override {
|
||||
void visit(AstScope* nodep) override {
|
||||
UINFO(4, " MOD " << nodep << endl);
|
||||
AstNode::user3ClearTree();
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
VL_RESTORER(m_cfuncp);
|
||||
{
|
||||
m_cfuncp = nodep;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstActive* nodep) override {
|
||||
void visit(AstActive* nodep) override {
|
||||
m_activep = nodep;
|
||||
VL_RESTORER(m_inInitial);
|
||||
{
|
||||
|
|
@ -429,7 +429,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeProcedure* nodep) override {
|
||||
void visit(AstNodeProcedure* nodep) override {
|
||||
m_procp = nodep;
|
||||
m_timingDomains.clear();
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -456,8 +456,8 @@ private:
|
|||
actp->sensesStorep(clockedDomain);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCAwait* nodep) override { m_timingDomains.insert(nodep->sensesp()); }
|
||||
virtual void visit(AstFireEvent* nodep) override {
|
||||
void visit(AstCAwait* nodep) override { m_timingDomains.insert(nodep->sensesp()); }
|
||||
void visit(AstFireEvent* nodep) override {
|
||||
UASSERT_OBJ(v3Global.hasEvents(), nodep, "Inconsistent");
|
||||
FileLine* const flp = nodep->fileline();
|
||||
if (nodep->isDelayed()) {
|
||||
|
|
@ -498,7 +498,7 @@ private:
|
|||
}
|
||||
nodep->deleteTree();
|
||||
}
|
||||
virtual void visit(AstAssignDly* nodep) override {
|
||||
void visit(AstAssignDly* nodep) override {
|
||||
m_inDly = true;
|
||||
m_nextDlyp
|
||||
= VN_CAST(nodep->nextp(), AssignDly); // Next assignment in same block, maybe nullptr.
|
||||
|
|
@ -535,7 +535,7 @@ private:
|
|||
m_nextDlyp = nullptr;
|
||||
}
|
||||
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
if (!nodep->user2Inc()) { // Not done yet
|
||||
if (m_inDly && nodep->access().isWriteOrRW()) {
|
||||
UINFO(4, "AssignDlyVar: " << nodep << endl);
|
||||
|
|
@ -587,18 +587,18 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeReadWriteMem* nodep) override {
|
||||
void visit(AstNodeReadWriteMem* nodep) override {
|
||||
VL_RESTORER(m_ignoreBlkAndNBlk);
|
||||
m_ignoreBlkAndNBlk = true; // $readmem/$writemem often used in mem models
|
||||
// so we will suppress BLKANDNBLK warnings
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeFor* nodep) override { // LCOV_EXCL_LINE
|
||||
void visit(AstNodeFor* nodep) override { // LCOV_EXCL_LINE
|
||||
nodep->v3fatalSrc(
|
||||
"For statements should have been converted to while statements in V3Begin");
|
||||
}
|
||||
virtual void visit(AstWhile* nodep) override {
|
||||
void visit(AstWhile* nodep) override {
|
||||
VL_RESTORER(m_inLoop);
|
||||
{
|
||||
m_inLoop = true;
|
||||
|
|
@ -607,12 +607,12 @@ private:
|
|||
}
|
||||
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit DelayedVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
virtual ~DelayedVisitor() override {
|
||||
~DelayedVisitor() override {
|
||||
V3Stats::addStat("Optimizations, Delayed shared-sets", m_statSharedSet);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
VL_RESTORER(m_cfuncp);
|
||||
VL_RESTORER(m_mtaskbodyp);
|
||||
{
|
||||
|
|
@ -85,7 +85,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstMTaskBody* nodep) override {
|
||||
void visit(AstMTaskBody* nodep) override {
|
||||
VL_RESTORER(m_cfuncp);
|
||||
VL_RESTORER(m_mtaskbodyp);
|
||||
{
|
||||
|
|
@ -106,7 +106,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeStmt* nodep) override {
|
||||
void visit(AstNodeStmt* nodep) override {
|
||||
if (!nodep->isStatement()) {
|
||||
iterateChildren(nodep);
|
||||
} else {
|
||||
|
|
@ -114,8 +114,8 @@ private:
|
|||
}
|
||||
}
|
||||
// Operators
|
||||
virtual void visit(AstNodeTermop* nodep) override {}
|
||||
virtual void visit(AstNodeMath* nodep) override {
|
||||
void visit(AstNodeTermop* nodep) override {}
|
||||
void visit(AstNodeMath* nodep) override {
|
||||
// We have some operator defines that use 2 parens, so += 2.
|
||||
{
|
||||
VL_RESTORER(m_depth);
|
||||
|
|
@ -142,19 +142,19 @@ private:
|
|||
m_cfuncp->isStatic(false);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstUCFunc* nodep) override {
|
||||
void visit(AstUCFunc* nodep) override {
|
||||
needNonStaticFunc(nodep);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstUCStmt* nodep) override {
|
||||
void visit(AstUCStmt* nodep) override {
|
||||
needNonStaticFunc(nodep);
|
||||
visitStmt(nodep);
|
||||
}
|
||||
|
||||
//--------------------
|
||||
// Default: Just iterate
|
||||
virtual void visit(AstVar*) override {} // Don't hit varrefs under vars
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstVar*) override {} // Don't hit varrefs under vars
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
@ -162,7 +162,7 @@ public:
|
|||
: m_tempNames{"__Vdeeptemp"} {
|
||||
iterate(nodep);
|
||||
}
|
||||
virtual ~DepthVisitor() override = default;
|
||||
~DepthVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
UINFO(4, " MOD " << nodep << endl);
|
||||
VL_RESTORER(m_modp);
|
||||
{
|
||||
|
|
@ -80,7 +80,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
// We recurse into this.
|
||||
VL_RESTORER(m_depth);
|
||||
VL_RESTORER(m_cfuncp);
|
||||
|
|
@ -106,7 +106,7 @@ private:
|
|||
}
|
||||
m_depth--;
|
||||
}
|
||||
virtual void visit(AstNodeStmt* nodep) override {
|
||||
void visit(AstNodeStmt* nodep) override {
|
||||
if (!nodep->isStatement()) {
|
||||
iterateChildren(nodep);
|
||||
} else {
|
||||
|
|
@ -114,15 +114,15 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeMath*) override {} // Accelerate
|
||||
void visit(AstNodeMath*) override {} // Accelerate
|
||||
//--------------------
|
||||
virtual void visit(AstVar*) override {} // Don't hit varrefs under vars
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstVar*) override {} // Don't hit varrefs under vars
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit DepthBlockVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
virtual ~DepthBlockVisitor() override = default;
|
||||
~DepthBlockVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
VL_RESTORER(m_modp);
|
||||
{
|
||||
m_modp = nodep;
|
||||
|
|
@ -195,17 +195,17 @@ private:
|
|||
makePublicFuncWrappers();
|
||||
}
|
||||
}
|
||||
virtual void visit(AstScope* nodep) override {
|
||||
void visit(AstScope* nodep) override {
|
||||
m_scopep = nodep;
|
||||
iterateChildren(nodep);
|
||||
m_scopep = nullptr;
|
||||
}
|
||||
virtual void visit(AstVarScope* nodep) override {
|
||||
void visit(AstVarScope* nodep) override {
|
||||
// Delete the varscope when we're finished
|
||||
nodep->unlinkFrBack();
|
||||
pushDeletep(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeVarRef* nodep) override {
|
||||
void visit(AstNodeVarRef* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (!nodep->varScopep()) {
|
||||
UASSERT_OBJ(nodep->varp()->isFuncLocal(), nodep,
|
||||
|
|
@ -229,7 +229,7 @@ private:
|
|||
nodep->varScopep(nullptr);
|
||||
UINFO(9, " refout " << nodep << " selfPtr=" << nodep->selfPointer() << endl);
|
||||
}
|
||||
virtual void visit(AstCCall* nodep) override {
|
||||
void visit(AstCCall* nodep) override {
|
||||
// UINFO(9, " " << nodep << endl);
|
||||
iterateChildren(nodep);
|
||||
// Convert the hierch name
|
||||
|
|
@ -239,9 +239,9 @@ private:
|
|||
// Can't do this, as we may have more calls later
|
||||
// nodep->funcp()->scopep(nullptr);
|
||||
}
|
||||
virtual void visit(AstCMethodCall* nodep) override { iterateChildren(nodep); }
|
||||
virtual void visit(AstCNew* nodep) override { iterateChildren(nodep); }
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCMethodCall* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstCNew* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstCFunc* nodep) override {
|
||||
VL_RESTORER(m_funcp);
|
||||
if (!nodep->user1()) {
|
||||
// Static functions should have been moved under the corresponding AstClassPackage
|
||||
|
|
@ -264,13 +264,13 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVar*) override {}
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstVar*) override {}
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit DescopeVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
virtual ~DescopeVisitor() override = default;
|
||||
~DescopeVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ public:
|
|||
|
||||
// CONSTRUCTORS
|
||||
EmitCBaseVisitor() = default;
|
||||
virtual ~EmitCBaseVisitor() override = default;
|
||||
~EmitCBaseVisitor() override = default;
|
||||
};
|
||||
|
||||
#endif // guard
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class EmitCConstInit VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
|
||||
protected:
|
||||
// VISITORS
|
||||
virtual void visit(AstInitArray* nodep) override {
|
||||
void visit(AstInitArray* nodep) override {
|
||||
VL_RESTORER(m_inUnpacked);
|
||||
VL_RESTORER(m_unpackedWord);
|
||||
m_inUnpacked = true;
|
||||
|
|
@ -94,11 +94,11 @@ protected:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstInitItem* nodep) override { // LCOV_EXCL_START
|
||||
void visit(AstInitItem* nodep) override { // LCOV_EXCL_START
|
||||
nodep->v3fatal("Handled by AstInitArray");
|
||||
} // LCOV_EXCL_STOP
|
||||
|
||||
virtual void visit(AstConst* nodep) override {
|
||||
void visit(AstConst* nodep) override {
|
||||
const V3Number& num = nodep->num();
|
||||
UASSERT_OBJ(!num.isFourState(), nodep, "4-state value in constant pool");
|
||||
const AstNodeDType* const dtypep = nodep->dtypep();
|
||||
|
|
@ -145,7 +145,7 @@ protected:
|
|||
}
|
||||
|
||||
// Default
|
||||
virtual void visit(AstNode* nodep) override { // LCOV_EXCL_START
|
||||
void visit(AstNode* nodep) override { // LCOV_EXCL_START
|
||||
nodep->v3fatalSrc("Unknown node type reached EmitCConstInit: " << nodep->prettyTypeName());
|
||||
} // LCOV_EXCL_STOP
|
||||
};
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ class EmitCConstPool final : public EmitCConstInit {
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstConst* nodep) override {
|
||||
void visit(AstConst* nodep) override {
|
||||
m_outFileSize += nodep->num().isString() ? 10 : nodep->isWide() ? nodep->widthWords() : 1;
|
||||
EmitCConstInit::visit(nodep);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,17 +70,17 @@ class EmitCLazyDecls final : public VNVisitor {
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeCCall* nodep) override {
|
||||
void visit(AstNodeCCall* nodep) override {
|
||||
lazyDeclare(nodep->funcp());
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstAddrOfCFunc* nodep) override {
|
||||
void visit(AstAddrOfCFunc* nodep) override {
|
||||
lazyDeclare(nodep->funcp());
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
AstVar* const varp = nodep->varp();
|
||||
// Only constant pool symbols are lazy declared for now ...
|
||||
if (EmitCBaseVisitor::isConstPoolMod(EmitCParentModule::get(varp))) {
|
||||
|
|
@ -88,7 +88,7 @@ class EmitCLazyDecls final : public VNVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep) override { iterateChildrenConst(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildrenConst(nodep); }
|
||||
|
||||
VL_DEBUG_FUNC;
|
||||
|
||||
|
|
@ -211,7 +211,7 @@ public:
|
|||
|
||||
// VISITORS
|
||||
using EmitCConstInit::visit;
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
VL_RESTORER(m_useSelfForThis);
|
||||
VL_RESTORER(m_cfuncp);
|
||||
m_cfuncp = nodep;
|
||||
|
|
@ -273,12 +273,12 @@ public:
|
|||
if (nodep->ifdef() != "") puts("#endif // " + nodep->ifdef() + "\n");
|
||||
}
|
||||
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
void visit(AstVar* nodep) override {
|
||||
UASSERT_OBJ(m_cfuncp, nodep, "Cannot emit non-local variable");
|
||||
emitVarDecl(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeAssign* nodep) override {
|
||||
void visit(AstNodeAssign* nodep) override {
|
||||
bool paren = true;
|
||||
bool decind = false;
|
||||
bool rhs = true;
|
||||
|
|
@ -360,8 +360,8 @@ public:
|
|||
if (decind) ofp()->blockDec();
|
||||
puts(";\n");
|
||||
}
|
||||
virtual void visit(AstAlwaysPublic*) override {}
|
||||
virtual void visit(AstAssocSel* nodep) override {
|
||||
void visit(AstAlwaysPublic*) override {}
|
||||
void visit(AstAssocSel* nodep) override {
|
||||
iterateAndNextNull(nodep->fromp());
|
||||
putbs(".at(");
|
||||
AstAssocArrayDType* const adtypep = VN_AS(nodep->fromp()->dtypep(), AssocArrayDType);
|
||||
|
|
@ -373,7 +373,7 @@ public:
|
|||
}
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstWildcardSel* nodep) override {
|
||||
void visit(AstWildcardSel* nodep) override {
|
||||
iterateAndNextNull(nodep->fromp());
|
||||
putbs(".at(");
|
||||
AstWildcardArrayDType* const adtypep = VN_AS(nodep->fromp()->dtypep(), WildcardArrayDType);
|
||||
|
|
@ -381,7 +381,7 @@ public:
|
|||
iterateAndNextNull(nodep->bitp());
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstCCall* nodep) override {
|
||||
void visit(AstCCall* nodep) override {
|
||||
const AstCFunc* const funcp = nodep->funcp();
|
||||
const AstNodeModule* const funcModp = EmitCParentModule::get(funcp);
|
||||
if (funcp->dpiImportPrototype()) {
|
||||
|
|
@ -407,7 +407,7 @@ public:
|
|||
}
|
||||
emitCCallArgs(nodep, nodep->selfPointerProtect(m_useSelfForThis));
|
||||
}
|
||||
virtual void visit(AstCMethodCall* nodep) override {
|
||||
void visit(AstCMethodCall* nodep) override {
|
||||
const AstCFunc* const funcp = nodep->funcp();
|
||||
UASSERT_OBJ(!funcp->isLoose(), nodep, "Loose method called via AstCMethodCall");
|
||||
iterate(nodep->fromp());
|
||||
|
|
@ -415,12 +415,12 @@ public:
|
|||
puts(funcp->nameProtect());
|
||||
emitCCallArgs(nodep, "");
|
||||
}
|
||||
virtual void visit(AstCAwait* nodep) override {
|
||||
void visit(AstCAwait* nodep) override {
|
||||
puts("co_await ");
|
||||
iterate(nodep->exprp());
|
||||
if (nodep->isStatement()) puts(";\n");
|
||||
}
|
||||
virtual void visit(AstCNew* nodep) override {
|
||||
void visit(AstCNew* nodep) override {
|
||||
bool comma = false;
|
||||
puts("std::make_shared<" + prefixNameProtect(nodep->dtypep()) + ">(");
|
||||
puts("vlSymsp"); // TODO make this part of argsp, and eliminate when unnecessary
|
||||
|
|
@ -432,7 +432,7 @@ public:
|
|||
}
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstCMethodHard* nodep) override {
|
||||
void visit(AstCMethodHard* nodep) override {
|
||||
iterate(nodep->fromp());
|
||||
puts(".");
|
||||
puts(nodep->name());
|
||||
|
|
@ -454,8 +454,8 @@ public:
|
|||
UASSERT_OBJ(!nodep->isStatement() || VN_IS(nodep->dtypep(), VoidDType), nodep,
|
||||
"Statement of non-void data type");
|
||||
}
|
||||
virtual void visit(AstLambdaArgRef* nodep) override { putbs(nodep->nameProtect()); }
|
||||
virtual void visit(AstWith* nodep) override {
|
||||
void visit(AstLambdaArgRef* nodep) override { putbs(nodep->nameProtect()); }
|
||||
void visit(AstWith* nodep) override {
|
||||
// With uses a C++11 lambda
|
||||
putbs("[=](");
|
||||
if (auto* const argrefp = nodep->indexArgRefp()) {
|
||||
|
|
@ -470,11 +470,11 @@ public:
|
|||
iterateAndNextNull(nodep->exprp());
|
||||
puts("; }\n");
|
||||
}
|
||||
virtual void visit(AstNodeCase* nodep) override { // LCOV_EXCL_LINE
|
||||
void visit(AstNodeCase* nodep) override { // LCOV_EXCL_LINE
|
||||
// In V3Case...
|
||||
nodep->v3fatalSrc("Case statements should have been reduced out");
|
||||
}
|
||||
virtual void visit(AstComment* nodep) override {
|
||||
void visit(AstComment* nodep) override {
|
||||
string at;
|
||||
if (nodep->showAt()) {
|
||||
at = " at " + nodep->fileline()->ascii();
|
||||
|
|
@ -486,7 +486,7 @@ public:
|
|||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstCoverDecl* nodep) override {
|
||||
void visit(AstCoverDecl* nodep) override {
|
||||
puts("vlSelf->__vlCoverInsert("); // As Declared in emitCoverageDecl
|
||||
puts("&(vlSymsp->__Vcoverage[");
|
||||
puts(cvtToStr(nodep->dataDeclThisp()->binNum()));
|
||||
|
|
@ -514,7 +514,7 @@ public:
|
|||
putsQuoted(nodep->linescov());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstCoverInc* nodep) override {
|
||||
void visit(AstCoverInc* nodep) override {
|
||||
if (v3Global.opt.threads()) {
|
||||
puts("vlSymsp->__Vcoverage[");
|
||||
puts(cvtToStr(nodep->declp()->dataDeclThisp()->binNum()));
|
||||
|
|
@ -525,17 +525,17 @@ public:
|
|||
puts("]);\n");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCReturn* nodep) override {
|
||||
void visit(AstCReturn* nodep) override {
|
||||
puts("return (");
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstDisplay* nodep) override {
|
||||
void visit(AstDisplay* nodep) override {
|
||||
string text = nodep->fmtp()->text();
|
||||
if (nodep->addNewline()) text += "\n";
|
||||
displayNode(nodep, nodep->fmtp()->scopeNamep(), text, nodep->fmtp()->exprsp(), false);
|
||||
}
|
||||
virtual void visit(AstDumpCtl* nodep) override {
|
||||
void visit(AstDumpCtl* nodep) override {
|
||||
switch (nodep->ctlType()) {
|
||||
case VDumpCtlType::FILE:
|
||||
puts("vlSymsp->_vm_contextp__->dumpfile(");
|
||||
|
|
@ -574,7 +574,7 @@ public:
|
|||
default: nodep->v3fatalSrc("Bad case, unexpected " << nodep->ctlType().ascii());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstScopeName* nodep) override {
|
||||
void visit(AstScopeName* nodep) override {
|
||||
// For use under AstCCalls for dpiImports. ScopeNames under
|
||||
// displays are handled in AstDisplay
|
||||
if (!nodep->dpiExport()) {
|
||||
|
|
@ -583,20 +583,20 @@ public:
|
|||
putbs("(&(vlSymsp->" + protect("__Vscope_" + scope) + "))");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSFormat* nodep) override {
|
||||
void visit(AstSFormat* nodep) override {
|
||||
displayNode(nodep, nodep->fmtp()->scopeNamep(), nodep->fmtp()->text(),
|
||||
nodep->fmtp()->exprsp(), false);
|
||||
}
|
||||
virtual void visit(AstSFormatF* nodep) override {
|
||||
void visit(AstSFormatF* nodep) override {
|
||||
displayNode(nodep, nodep->scopeNamep(), nodep->text(), nodep->exprsp(), false);
|
||||
}
|
||||
virtual void visit(AstFScanF* nodep) override {
|
||||
void visit(AstFScanF* nodep) override {
|
||||
displayNode(nodep, nullptr, nodep->text(), nodep->exprsp(), true);
|
||||
}
|
||||
virtual void visit(AstSScanF* nodep) override {
|
||||
void visit(AstSScanF* nodep) override {
|
||||
displayNode(nodep, nullptr, nodep->text(), nodep->exprsp(), true);
|
||||
}
|
||||
virtual void visit(AstValuePlusArgs* nodep) override {
|
||||
void visit(AstValuePlusArgs* nodep) override {
|
||||
puts("VL_VALUEPLUSARGS_IN");
|
||||
emitIQW(nodep->outp());
|
||||
puts("(");
|
||||
|
|
@ -608,19 +608,19 @@ public:
|
|||
iterateAndNextNull(nodep->outp());
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstTestPlusArgs* nodep) override {
|
||||
void visit(AstTestPlusArgs* nodep) override {
|
||||
puts("VL_TESTPLUSARGS_I(");
|
||||
emitCvtPackStr(nodep->searchp());
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstFError* nodep) override {
|
||||
void visit(AstFError* nodep) override {
|
||||
puts("VL_FERROR_IN(");
|
||||
iterateAndNextNull(nodep->filep());
|
||||
putbs(", ");
|
||||
iterateAndNextNull(nodep->strp());
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstFGetS* nodep) override {
|
||||
void visit(AstFGetS* nodep) override {
|
||||
checkMaxWords(nodep);
|
||||
emitOpName(nodep, nodep->emitC(), nodep->lhsp(), nodep->rhsp(), nullptr);
|
||||
}
|
||||
|
|
@ -633,7 +633,7 @@ public:
|
|||
<< " bits exceeds hardcoded limit VL_VALUE_STRING_MAX_WORDS in verilatedos.h");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstFOpen* nodep) override {
|
||||
void visit(AstFOpen* nodep) override {
|
||||
iterateAndNextNull(nodep->filep());
|
||||
puts(" = VL_FOPEN_NN(");
|
||||
emitCvtPackStr(nodep->filenamep());
|
||||
|
|
@ -643,13 +643,13 @@ public:
|
|||
emitCvtPackStr(nodep->modep());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstFOpenMcd* nodep) override {
|
||||
void visit(AstFOpenMcd* nodep) override {
|
||||
iterateAndNextNull(nodep->filep());
|
||||
puts(" = VL_FOPEN_MCD_N(");
|
||||
emitCvtPackStr(nodep->filenamep());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstNodeReadWriteMem* nodep) override {
|
||||
void visit(AstNodeReadWriteMem* nodep) override {
|
||||
puts(nodep->cFuncPrefixp());
|
||||
puts("N(");
|
||||
puts(nodep->isHex() ? "true" : "false");
|
||||
|
|
@ -698,14 +698,14 @@ public:
|
|||
}
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstFClose* nodep) override {
|
||||
void visit(AstFClose* nodep) override {
|
||||
puts("VL_FCLOSE_I(");
|
||||
iterateAndNextNull(nodep->filep());
|
||||
puts("); ");
|
||||
iterateAndNextNull(nodep->filep()); // For safety, so user doesn't later WRITE with it.
|
||||
puts(" = 0;\n");
|
||||
}
|
||||
virtual void visit(AstFFlush* nodep) override {
|
||||
void visit(AstFFlush* nodep) override {
|
||||
if (!nodep->filep()) {
|
||||
puts("Verilated::runFlushCallbacks();\n");
|
||||
} else {
|
||||
|
|
@ -716,7 +716,7 @@ public:
|
|||
puts("); }\n");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstFSeek* nodep) override {
|
||||
void visit(AstFSeek* nodep) override {
|
||||
puts("(VL_FSEEK_I(");
|
||||
iterateAndNextNull(nodep->filep());
|
||||
puts(",");
|
||||
|
|
@ -725,17 +725,17 @@ public:
|
|||
iterateAndNextNull(nodep->operation());
|
||||
puts(") == -1 ? -1 : 0)");
|
||||
}
|
||||
virtual void visit(AstFTell* nodep) override {
|
||||
void visit(AstFTell* nodep) override {
|
||||
puts("VL_FTELL_I(");
|
||||
iterateAndNextNull(nodep->filep());
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstFRewind* nodep) override {
|
||||
void visit(AstFRewind* nodep) override {
|
||||
puts("(VL_FSEEK_I(");
|
||||
iterateAndNextNull(nodep->filep());
|
||||
puts(", 0, 0) == -1 ? -1 : 0)");
|
||||
}
|
||||
virtual void visit(AstFRead* nodep) override {
|
||||
void visit(AstFRead* nodep) override {
|
||||
puts("VL_FREAD_I(");
|
||||
puts(cvtToStr(nodep->memp()->widthMin())); // Need real storage width
|
||||
putbs(",");
|
||||
|
|
@ -778,12 +778,12 @@ public:
|
|||
}
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstSysFuncAsTask* nodep) override {
|
||||
void visit(AstSysFuncAsTask* nodep) override {
|
||||
if (!nodep->lhsp()->isWide()) puts("(void)");
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
if (!nodep->lhsp()->isWide()) puts(";");
|
||||
}
|
||||
virtual void visit(AstSystemT* nodep) override {
|
||||
void visit(AstSystemT* nodep) override {
|
||||
puts("(void)VL_SYSTEM_I");
|
||||
emitIQW(nodep->lhsp());
|
||||
puts("(");
|
||||
|
|
@ -795,7 +795,7 @@ public:
|
|||
iterateAndNextNull(nodep->lhsp());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstSystemF* nodep) override {
|
||||
void visit(AstSystemF* nodep) override {
|
||||
puts("VL_SYSTEM_I");
|
||||
emitIQW(nodep->lhsp());
|
||||
puts("(");
|
||||
|
|
@ -807,20 +807,20 @@ public:
|
|||
iterateAndNextNull(nodep->lhsp());
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstJumpBlock* nodep) override {
|
||||
void visit(AstJumpBlock* nodep) override {
|
||||
nodep->labelNum(++m_labelNum);
|
||||
puts("{\n"); // Make it visually obvious label jumps outside these
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
iterateAndNextNull(nodep->endStmtsp());
|
||||
puts("}\n");
|
||||
}
|
||||
virtual void visit(AstJumpGo* nodep) override {
|
||||
void visit(AstJumpGo* nodep) override {
|
||||
puts("goto __Vlabel" + cvtToStr(nodep->labelp()->blockp()->labelNum()) + ";\n");
|
||||
}
|
||||
virtual void visit(AstJumpLabel* nodep) override {
|
||||
void visit(AstJumpLabel* nodep) override {
|
||||
puts("__Vlabel" + cvtToStr(nodep->blockp()->labelNum()) + ": ;\n");
|
||||
}
|
||||
virtual void visit(AstWhile* nodep) override {
|
||||
void visit(AstWhile* nodep) override {
|
||||
iterateAndNextNull(nodep->precondsp());
|
||||
puts("while (");
|
||||
iterateAndNextNull(nodep->condp());
|
||||
|
|
@ -830,7 +830,7 @@ public:
|
|||
iterateAndNextNull(nodep->precondsp()); // Need to recompute before next loop
|
||||
puts("}\n");
|
||||
}
|
||||
virtual void visit(AstNodeIf* nodep) override {
|
||||
void visit(AstNodeIf* nodep) override {
|
||||
puts("if (");
|
||||
if (!nodep->branchPred().unknown()) {
|
||||
puts(nodep->branchPred().ascii());
|
||||
|
|
@ -854,7 +854,7 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstExprStmt* nodep) override {
|
||||
void visit(AstExprStmt* nodep) override {
|
||||
// GCC allows compound statements in expressions, but this is not standard.
|
||||
// So we use an immediate-evaluation lambda and comma operator
|
||||
putbs("([&]() {\n");
|
||||
|
|
@ -863,7 +863,7 @@ public:
|
|||
iterateAndNextNull(nodep->resultp());
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstStop* nodep) override {
|
||||
void visit(AstStop* nodep) override {
|
||||
puts("VL_STOP_MT(");
|
||||
putsQuoted(protect(nodep->fileline()->filename()));
|
||||
puts(", ");
|
||||
|
|
@ -871,38 +871,38 @@ public:
|
|||
puts(", \"\"");
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstFinish* nodep) override {
|
||||
void visit(AstFinish* nodep) override {
|
||||
puts("VL_FINISH_MT(");
|
||||
putsQuoted(protect(nodep->fileline()->filename()));
|
||||
puts(", ");
|
||||
puts(cvtToStr(nodep->fileline()->lineno()));
|
||||
puts(", \"\");\n");
|
||||
}
|
||||
virtual void visit(AstPrintTimeScale* nodep) override {
|
||||
void visit(AstPrintTimeScale* nodep) override {
|
||||
puts("VL_PRINTTIMESCALE(");
|
||||
putsQuoted(protect(nodep->name()));
|
||||
puts(", ");
|
||||
putsQuoted(nodep->timeunit().ascii());
|
||||
puts(", vlSymsp->_vm_contextp__);\n");
|
||||
}
|
||||
virtual void visit(AstRand* nodep) override {
|
||||
void visit(AstRand* nodep) override {
|
||||
emitOpName(nodep, nodep->emitC(), nodep->seedp(), nullptr, nullptr);
|
||||
}
|
||||
virtual void visit(AstTime* nodep) override {
|
||||
void visit(AstTime* nodep) override {
|
||||
puts("VL_TIME_UNITED_Q(");
|
||||
if (nodep->timeunit().isNone()) nodep->v3fatalSrc("$time has no units");
|
||||
puts(cvtToStr(nodep->timeunit().multiplier()
|
||||
/ v3Global.rootp()->timeprecision().multiplier()));
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstTimeD* nodep) override {
|
||||
void visit(AstTimeD* nodep) override {
|
||||
puts("VL_TIME_UNITED_D(");
|
||||
if (nodep->timeunit().isNone()) nodep->v3fatalSrc("$realtime has no units");
|
||||
puts(cvtToStr(nodep->timeunit().multiplier()
|
||||
/ v3Global.rootp()->timeprecision().multiplier()));
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstTimeFormat* nodep) override {
|
||||
void visit(AstTimeFormat* nodep) override {
|
||||
puts("VL_TIMEFORMAT_IINI(");
|
||||
iterateAndNextNull(nodep->unitsp());
|
||||
puts(", ");
|
||||
|
|
@ -913,7 +913,7 @@ public:
|
|||
iterateAndNextNull(nodep->widthp());
|
||||
puts(", vlSymsp->_vm_contextp__);\n");
|
||||
}
|
||||
virtual void visit(AstNodeSimpleText* nodep) override {
|
||||
void visit(AstNodeSimpleText* nodep) override {
|
||||
const string text = m_inUC && m_useSelfForThis
|
||||
? VString::replaceWord(nodep->text(), "this", "vlSelf")
|
||||
: nodep->text();
|
||||
|
|
@ -923,29 +923,29 @@ public:
|
|||
ofp()->putsNoTracking(text);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstTextBlock* nodep) override {
|
||||
void visit(AstTextBlock* nodep) override {
|
||||
visit(static_cast<AstNodeSimpleText*>(nodep));
|
||||
for (AstNode* childp = nodep->nodesp(); childp; childp = childp->nextp()) {
|
||||
iterate(childp);
|
||||
if (nodep->commas() && childp->nextp()) puts(", ");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCStmt* nodep) override {
|
||||
void visit(AstCStmt* nodep) override {
|
||||
putbs("");
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
}
|
||||
virtual void visit(AstCMath* nodep) override {
|
||||
void visit(AstCMath* nodep) override {
|
||||
putbs("");
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
}
|
||||
virtual void visit(AstUCStmt* nodep) override {
|
||||
void visit(AstUCStmt* nodep) override {
|
||||
VL_RESTORER(m_inUC);
|
||||
m_inUC = true;
|
||||
putsDecoration(ifNoProtect("// $c statement at " + nodep->fileline()->ascii() + "\n"));
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
puts("\n");
|
||||
}
|
||||
virtual void visit(AstUCFunc* nodep) override {
|
||||
void visit(AstUCFunc* nodep) override {
|
||||
VL_RESTORER(m_inUC);
|
||||
m_inUC = true;
|
||||
puts("\n");
|
||||
|
|
@ -955,10 +955,10 @@ public:
|
|||
}
|
||||
|
||||
// Operators
|
||||
virtual void visit(AstNodeTermop* nodep) override {
|
||||
void visit(AstNodeTermop* nodep) override {
|
||||
emitOpName(nodep, nodep->emitC(), nullptr, nullptr, nullptr);
|
||||
}
|
||||
virtual void visit(AstNodeUniop* nodep) override {
|
||||
void visit(AstNodeUniop* nodep) override {
|
||||
if (nodep->emitCheckMaxWords()
|
||||
&& (nodep->widthWords() > VL_MULS_MAX_WORDS
|
||||
|| nodep->lhsp()->widthWords() > VL_MULS_MAX_WORDS)) {
|
||||
|
|
@ -978,7 +978,7 @@ public:
|
|||
emitOpName(nodep, nodep->emitC(), nodep->lhsp(), nullptr, nullptr);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeBiop* nodep) override {
|
||||
void visit(AstNodeBiop* nodep) override {
|
||||
if (nodep->emitCheckMaxWords() && nodep->widthWords() > VL_MULS_MAX_WORDS) {
|
||||
nodep->v3warn(
|
||||
E_UNSUPPORTED,
|
||||
|
|
@ -998,11 +998,11 @@ public:
|
|||
emitOpName(nodep, nodep->emitC(), nodep->lhsp(), nodep->rhsp(), nullptr);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeTriop* nodep) override {
|
||||
void visit(AstNodeTriop* nodep) override {
|
||||
UASSERT_OBJ(!emitSimpleOk(nodep), nodep, "Triop cannot be described in a simple way");
|
||||
emitOpName(nodep, nodep->emitC(), nodep->lhsp(), nodep->rhsp(), nodep->thsp());
|
||||
}
|
||||
virtual void visit(AstRedXor* nodep) override {
|
||||
void visit(AstRedXor* nodep) override {
|
||||
if (nodep->lhsp()->isWide()) {
|
||||
visit(static_cast<AstNodeUniop*>(nodep));
|
||||
} else {
|
||||
|
|
@ -1018,7 +1018,7 @@ public:
|
|||
puts(")");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCCast* nodep) override {
|
||||
void visit(AstCCast* nodep) override {
|
||||
// Extending a value of the same word width is just a NOP.
|
||||
if (nodep->size() <= VL_IDATASIZE) {
|
||||
puts("(IData)(");
|
||||
|
|
@ -1028,7 +1028,7 @@ public:
|
|||
iterateAndNextNull(nodep->lhsp());
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstNodeCond* nodep) override {
|
||||
void visit(AstNodeCond* nodep) override {
|
||||
// Widths match up already, so we'll just use C++'s operator w/o any temps.
|
||||
if (nodep->expr1p()->isWide()) {
|
||||
emitOpName(nodep, nodep->emitC(), nodep->condp(), nodep->expr1p(), nodep->expr2p());
|
||||
|
|
@ -1042,12 +1042,12 @@ public:
|
|||
puts(")");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstMemberSel* nodep) override {
|
||||
void visit(AstMemberSel* nodep) override {
|
||||
iterateAndNextNull(nodep->fromp());
|
||||
putbs("->");
|
||||
puts(nodep->varp()->nameProtect());
|
||||
}
|
||||
virtual void visit(AstNullCheck* nodep) override {
|
||||
void visit(AstNullCheck* nodep) override {
|
||||
puts("VL_NULL_CHECK(");
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
puts(", ");
|
||||
|
|
@ -1056,17 +1056,17 @@ public:
|
|||
puts(cvtToStr(nodep->fileline()->lineno()));
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstNewCopy* nodep) override {
|
||||
void visit(AstNewCopy* nodep) override {
|
||||
puts("std::make_shared<" + prefixNameProtect(nodep->dtypep()) + ">(");
|
||||
puts("*"); // i.e. make into a reference
|
||||
iterateAndNextNull(nodep->rhsp());
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstSel* nodep) override {
|
||||
void visit(AstSel* nodep) override {
|
||||
// Note ASSIGN checks for this on a LHS
|
||||
emitOpName(nodep, nodep->emitC(), nodep->fromp(), nodep->lsbp(), nodep->thsp());
|
||||
}
|
||||
virtual void visit(AstReplicate* nodep) override {
|
||||
void visit(AstReplicate* nodep) override {
|
||||
if (nodep->lhsp()->widthMin() == 1 && !nodep->isWide()) {
|
||||
UASSERT_OBJ((static_cast<int>(VN_AS(nodep->rhsp(), Const)->toUInt())
|
||||
* nodep->lhsp()->widthMin())
|
||||
|
|
@ -1085,7 +1085,7 @@ public:
|
|||
emitOpName(nodep, nodep->emitC(), nodep->lhsp(), nodep->rhsp(), nullptr);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstStreamL* nodep) override {
|
||||
void visit(AstStreamL* nodep) override {
|
||||
// Attempt to use a "fast" stream function for slice size = power of 2
|
||||
if (!nodep->isWide()) {
|
||||
const uint32_t isPow2 = VN_AS(nodep->rhsp(), Const)->num().countOnes() == 1;
|
||||
|
|
@ -1107,14 +1107,14 @@ public:
|
|||
emitOpName(nodep, "VL_STREAML_%nq%lq%rq(%lw, %P, %li, %ri)", nodep->lhsp(), nodep->rhsp(),
|
||||
nullptr);
|
||||
}
|
||||
virtual void visit(AstCastDynamic* nodep) override {
|
||||
void visit(AstCastDynamic* nodep) override {
|
||||
putbs("VL_CAST_DYNAMIC(");
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
puts(", ");
|
||||
iterateAndNextNull(nodep->rhsp());
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstCountBits* nodep) override {
|
||||
void visit(AstCountBits* nodep) override {
|
||||
putbs("VL_COUNTBITS_");
|
||||
emitIQW(nodep->lhsp());
|
||||
puts("(");
|
||||
|
|
@ -1134,9 +1134,9 @@ public:
|
|||
iterateAndNextNull(nodep->fhsp());
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstInitItem* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstInitItem* nodep) override { iterateChildren(nodep); }
|
||||
// Terminals
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
const AstVar* const varp = nodep->varp();
|
||||
const AstNodeModule* const varModp = EmitCParentModule::get(varp);
|
||||
if (isConstPoolMod(varModp)) {
|
||||
|
|
@ -1153,14 +1153,14 @@ public:
|
|||
}
|
||||
puts(nodep->varp()->nameProtect());
|
||||
}
|
||||
virtual void visit(AstAddrOfCFunc* nodep) override {
|
||||
void visit(AstAddrOfCFunc* nodep) override {
|
||||
// Note: Can be thought to handle more, but this is all that is needed right now
|
||||
const AstCFunc* const funcp = nodep->funcp();
|
||||
UASSERT_OBJ(funcp->isLoose(), nodep, "Cannot take address of non-loose method");
|
||||
puts("&");
|
||||
puts(funcNameProtect(funcp));
|
||||
}
|
||||
virtual void visit(AstConst* nodep) override {
|
||||
void visit(AstConst* nodep) override {
|
||||
if (m_emitConstInit) {
|
||||
EmitCConstInit::visit(nodep);
|
||||
} else if (nodep->isWide()) {
|
||||
|
|
@ -1173,12 +1173,12 @@ public:
|
|||
}
|
||||
|
||||
//
|
||||
virtual void visit(AstMTaskBody* nodep) override {
|
||||
void visit(AstMTaskBody* nodep) override {
|
||||
VL_RESTORER(m_useSelfForThis);
|
||||
m_useSelfForThis = true;
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstConsAssoc* nodep) override {
|
||||
void visit(AstConsAssoc* nodep) override {
|
||||
putbs(nodep->dtypep()->cType("", false, false));
|
||||
puts("()");
|
||||
if (nodep->defaultp()) {
|
||||
|
|
@ -1187,7 +1187,7 @@ public:
|
|||
puts(")");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSetAssoc* nodep) override {
|
||||
void visit(AstSetAssoc* nodep) override {
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
putbs(".set(");
|
||||
iterateAndNextNull(nodep->keyp());
|
||||
|
|
@ -1196,7 +1196,7 @@ public:
|
|||
iterateAndNextNull(nodep->valuep());
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstConsWildcard* nodep) override {
|
||||
void visit(AstConsWildcard* nodep) override {
|
||||
putbs(nodep->dtypep()->cType("", false, false));
|
||||
puts("()");
|
||||
if (nodep->defaultp()) {
|
||||
|
|
@ -1205,7 +1205,7 @@ public:
|
|||
puts(")");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSetWildcard* nodep) override {
|
||||
void visit(AstSetWildcard* nodep) override {
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
putbs(".set(");
|
||||
iterateAndNextNull(nodep->keyp());
|
||||
|
|
@ -1214,7 +1214,7 @@ public:
|
|||
iterateAndNextNull(nodep->valuep());
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstConsDynArray* nodep) override {
|
||||
void visit(AstConsDynArray* nodep) override {
|
||||
putbs(nodep->dtypep()->cType("", false, false));
|
||||
if (!nodep->lhsp()) {
|
||||
puts("()");
|
||||
|
|
@ -1229,7 +1229,7 @@ public:
|
|||
puts(")");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstConsQueue* nodep) override {
|
||||
void visit(AstConsQueue* nodep) override {
|
||||
putbs(nodep->dtypep()->cType("", false, false));
|
||||
if (!nodep->lhsp()) {
|
||||
puts("()");
|
||||
|
|
@ -1244,11 +1244,11 @@ public:
|
|||
puts(")");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCReset* nodep) override {
|
||||
void visit(AstCReset* nodep) override {
|
||||
AstVar* const varp = nodep->varrefp()->varp();
|
||||
emitVarReset(varp);
|
||||
}
|
||||
virtual void visit(AstExecGraph* nodep) override {
|
||||
void visit(AstExecGraph* nodep) override {
|
||||
// The location of the AstExecGraph within the containing AstCFunc is where we want to
|
||||
// invoke the graph and wait for it to complete. Emitting the children does just that.
|
||||
UASSERT_OBJ(!nodep->mTaskBodiesp(), nodep, "These should have been lowered");
|
||||
|
|
@ -1256,7 +1256,7 @@ public:
|
|||
}
|
||||
|
||||
// Default
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
puts(string("\n???? // ") + nodep->prettyTypeName() + "\n");
|
||||
iterateChildren(nodep);
|
||||
// LCOV_EXCL_START
|
||||
|
|
@ -1274,7 +1274,7 @@ public:
|
|||
m_trackText = trackText;
|
||||
iterate(nodep);
|
||||
}
|
||||
virtual ~EmitCFunc() override = default;
|
||||
~EmitCFunc() override = default;
|
||||
};
|
||||
|
||||
#endif // guard
|
||||
|
|
|
|||
|
|
@ -327,7 +327,7 @@ class EmitCHeader final : public EmitCConstInit {
|
|||
// Close output file
|
||||
VL_DO_CLEAR(delete m_ofp, m_ofp = nullptr);
|
||||
}
|
||||
virtual ~EmitCHeader() override = default;
|
||||
~EmitCHeader() override = default;
|
||||
|
||||
public:
|
||||
static void main(const AstNodeModule* modp) { EmitCHeader emitCHeader(modp); }
|
||||
|
|
|
|||
|
|
@ -68,59 +68,59 @@ class EmitCGatherDependencies final : VNVisitor {
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstCCall* nodep) override {
|
||||
void visit(AstCCall* nodep) override {
|
||||
addSelfDependency(nodep->selfPointer(), nodep->funcp());
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstCNew* nodep) override {
|
||||
void visit(AstCNew* nodep) override {
|
||||
addDTypeDependency(nodep->dtypep());
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstCMethodCall* nodep) override {
|
||||
void visit(AstCMethodCall* nodep) override {
|
||||
addDTypeDependency(nodep->fromp()->dtypep());
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstNewCopy* nodep) override {
|
||||
void visit(AstNewCopy* nodep) override {
|
||||
addDTypeDependency(nodep->dtypep());
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstMemberSel* nodep) override {
|
||||
void visit(AstMemberSel* nodep) override {
|
||||
addDTypeDependency(nodep->fromp()->dtypep());
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeVarRef* nodep) override {
|
||||
void visit(AstNodeVarRef* nodep) override {
|
||||
addSelfDependency(nodep->selfPointer(), nodep->varp());
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstCoverDecl* nodep) override {
|
||||
void visit(AstCoverDecl* nodep) override {
|
||||
addSymsDependency();
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstCoverInc* nodep) override {
|
||||
void visit(AstCoverInc* nodep) override {
|
||||
addSymsDependency();
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstDumpCtl* nodep) override {
|
||||
void visit(AstDumpCtl* nodep) override {
|
||||
addSymsDependency();
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstScopeName* nodep) override {
|
||||
void visit(AstScopeName* nodep) override {
|
||||
addSymsDependency();
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstPrintTimeScale* nodep) override {
|
||||
void visit(AstPrintTimeScale* nodep) override {
|
||||
addSymsDependency();
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstTimeFormat* nodep) override {
|
||||
void visit(AstTimeFormat* nodep) override {
|
||||
addSymsDependency();
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeSimpleText* nodep) override {
|
||||
void visit(AstNodeSimpleText* nodep) override {
|
||||
if (nodep->text().find("vlSymsp") != string::npos) addSymsDependency();
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstNode* nodep) override { iterateChildrenConst(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildrenConst(nodep); }
|
||||
|
||||
// CONSTRUCTOR
|
||||
explicit EmitCGatherDependencies(AstCFunc* cfuncp) {
|
||||
|
|
@ -517,7 +517,7 @@ class EmitCImp final : EmitCFunc {
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
if (splitNeeded()) {
|
||||
// Splitting file, so using parallel build.
|
||||
v3Global.useParallelBuild(true);
|
||||
|
|
@ -549,7 +549,7 @@ class EmitCImp final : EmitCFunc {
|
|||
// Emit implementations of all AstCFunc
|
||||
emitCFuncImp(modp);
|
||||
}
|
||||
virtual ~EmitCImp() override = default;
|
||||
~EmitCImp() override = default;
|
||||
|
||||
public:
|
||||
static void main(const AstNodeModule* modp, bool slow, std::deque<AstCFile*>& cfilesr) {
|
||||
|
|
@ -828,7 +828,7 @@ class EmitCTrace final : EmitCFunc {
|
|||
|
||||
// VISITORS
|
||||
using EmitCFunc::visit; // Suppress hidden overloaded virtual function warning
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
if (!nodep->isTrace()) return;
|
||||
if (nodep->slow() != m_slow) return;
|
||||
|
||||
|
|
@ -843,17 +843,17 @@ class EmitCTrace final : EmitCFunc {
|
|||
|
||||
EmitCFunc::visit(nodep);
|
||||
}
|
||||
virtual void visit(AstTracePushNamePrefix* nodep) override {
|
||||
void visit(AstTracePushNamePrefix* nodep) override {
|
||||
puts("tracep->pushNamePrefix(");
|
||||
putsQuoted(VIdProtect::protectWordsIf(nodep->prefix(), nodep->protect()));
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstTracePopNamePrefix* nodep) override { //
|
||||
void visit(AstTracePopNamePrefix* nodep) override { //
|
||||
puts("tracep->popNamePrefix(");
|
||||
puts(cvtToStr(nodep->count()));
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstTraceDecl* nodep) override {
|
||||
void visit(AstTraceDecl* nodep) override {
|
||||
const int enumNum = emitTraceDeclDType(nodep->dtypep());
|
||||
if (nodep->arrayRange().ranged()) {
|
||||
puts("for (int i = 0; i < " + cvtToStr(nodep->arrayRange().elements()) + "; ++i) {\n");
|
||||
|
|
@ -864,7 +864,7 @@ class EmitCTrace final : EmitCFunc {
|
|||
puts("\n");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstTraceInc* nodep) override {
|
||||
void visit(AstTraceInc* nodep) override {
|
||||
if (nodep->declp()->arrayRange().ranged()) {
|
||||
// It traces faster if we unroll the loop
|
||||
for (int i = 0; i < nodep->declp()->arrayRange().elements(); i++) {
|
||||
|
|
@ -888,7 +888,7 @@ class EmitCTrace final : EmitCFunc {
|
|||
// Close output file
|
||||
VL_DO_CLEAR(delete m_ofp, m_ofp = nullptr);
|
||||
}
|
||||
virtual ~EmitCTrace() override = default;
|
||||
~EmitCTrace() override = default;
|
||||
|
||||
public:
|
||||
static void main(AstNodeModule* modp, bool slow, std::deque<AstCFile*>& cfilesr) {
|
||||
|
|
|
|||
|
|
@ -32,18 +32,18 @@ class EmitCInlines final : EmitCBaseVisitor {
|
|||
// METHODS
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstCNew* nodep) override {
|
||||
void visit(AstCNew* nodep) override {
|
||||
if (v3Global.opt.savable())
|
||||
v3warn(E_UNSUPPORTED, "Unsupported: --savable with dynamic new");
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstDumpCtl* nodep) override {
|
||||
void visit(AstDumpCtl* nodep) override {
|
||||
if (v3Global.opt.trace()) v3Global.needTraceDumper(true);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
//---------------------------------------
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
explicit EmitCInlines(AstNetlist* nodep) { iterate(nodep); }
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class EmitCMain final : EmitCBaseVisitor {
|
|||
|
||||
// VISITORS
|
||||
// This visitor doesn't really iterate, but exist to appease base class
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); } // LCOV_EXCL_LINE
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); } // LCOV_EXCL_LINE
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ class EmitCModel final : public EmitCFunc {
|
|||
+ "C* tfp, int levels, int options = 0);\n");
|
||||
if (optSystemC()) {
|
||||
puts("/// SC tracing; avoid overloaded virtual function lint warning\n");
|
||||
puts("virtual void trace(sc_trace_file* tfp) const override { "
|
||||
puts("void trace(sc_trace_file* tfp) const override { "
|
||||
"::sc_core::sc_module::trace(tfp); }\n");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -258,7 +258,7 @@ class EmitCSyms final : EmitCBaseVisitor {
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep) override {
|
||||
void visit(AstNetlist* nodep) override {
|
||||
// Collect list of scopes
|
||||
iterateChildren(nodep);
|
||||
varsExpand();
|
||||
|
|
@ -280,8 +280,8 @@ class EmitCSyms final : EmitCBaseVisitor {
|
|||
if (!m_dpiHdrOnly) emitDpiImp();
|
||||
}
|
||||
}
|
||||
virtual void visit(AstConstPool* nodep) override {} // Ignore
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstConstPool* nodep) override {} // Ignore
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
nameCheck(nodep);
|
||||
VL_RESTORER(m_modp);
|
||||
{
|
||||
|
|
@ -289,7 +289,7 @@ class EmitCSyms final : EmitCBaseVisitor {
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCellInline* nodep) override {
|
||||
void visit(AstCellInline* nodep) override {
|
||||
if (v3Global.opt.vpi()) {
|
||||
const string type
|
||||
= (nodep->origModName() == "__BEGIN__") ? "SCOPE_OTHER" : "SCOPE_MODULE";
|
||||
|
|
@ -300,7 +300,7 @@ class EmitCSyms final : EmitCBaseVisitor {
|
|||
std::make_pair(name, ScopeData(scopeSymString(name), name_dedot, timeunit, type)));
|
||||
}
|
||||
}
|
||||
virtual void visit(AstScope* nodep) override {
|
||||
void visit(AstScope* nodep) override {
|
||||
if (VN_IS(m_modp, Class)) return; // The ClassPackage is what is visible
|
||||
nameCheck(nodep);
|
||||
|
||||
|
|
@ -315,7 +315,7 @@ class EmitCSyms final : EmitCBaseVisitor {
|
|||
timeunit, type)));
|
||||
}
|
||||
}
|
||||
virtual void visit(AstScopeName* nodep) override {
|
||||
void visit(AstScopeName* nodep) override {
|
||||
const string name = nodep->scopeSymName();
|
||||
// UINFO(9,"scnameins sp "<<nodep->name()<<" sp "<<nodep->scopePrettySymName()
|
||||
// <<" ss"<<name<<endl);
|
||||
|
|
@ -337,19 +337,19 @@ class EmitCSyms final : EmitCBaseVisitor {
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
void visit(AstVar* nodep) override {
|
||||
nameCheck(nodep);
|
||||
iterateChildren(nodep);
|
||||
if (nodep->isSigUserRdPublic() && !m_cfuncp)
|
||||
m_modVars.emplace_back(std::make_pair(m_modp, nodep));
|
||||
}
|
||||
virtual void visit(AstCoverDecl* nodep) override {
|
||||
void visit(AstCoverDecl* nodep) override {
|
||||
// Assign numbers to all bins, so we know how big of an array to use
|
||||
if (!nodep->dataDeclNullp()) { // else duplicate we don't need code for
|
||||
nodep->binNum(m_coverBins++);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
nameCheck(nodep);
|
||||
if (nodep->dpiImportPrototype() || nodep->dpiExportDispatcher()) m_dpis.push_back(nodep);
|
||||
VL_RESTORER(m_cfuncp);
|
||||
|
|
@ -360,8 +360,8 @@ class EmitCSyms final : EmitCBaseVisitor {
|
|||
}
|
||||
|
||||
//---------------------------------------
|
||||
virtual void visit(AstConst*) override {}
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstConst*) override {}
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
explicit EmitCSyms(AstNetlist* nodep, bool dpiHdrOnly)
|
||||
|
|
|
|||
238
src/V3EmitV.cpp
238
src/V3EmitV.cpp
|
|
@ -53,14 +53,14 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep) override { iterateAndNextConstNull(nodep->modulesp()); }
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNetlist* nodep) override { iterateAndNextConstNull(nodep->modulesp()); }
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
putfs(nodep, nodep->verilogKwd() + " " + prefixNameProtect(nodep) + ";\n");
|
||||
iterateChildrenConst(nodep);
|
||||
putqs(nodep, "end" + nodep->verilogKwd() + "\n");
|
||||
}
|
||||
virtual void visit(AstPort* nodep) override {}
|
||||
virtual void visit(AstNodeFTask* nodep) override {
|
||||
void visit(AstPort* nodep) override {}
|
||||
void visit(AstNodeFTask* nodep) override {
|
||||
putfs(nodep, nodep->isFunction() ? "function" : "task");
|
||||
puts(" ");
|
||||
puts(nodep->prettyName());
|
||||
|
|
@ -70,7 +70,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
putfs(nodep, nodep->isFunction() ? "endfunction\n" : "endtask\n");
|
||||
}
|
||||
|
||||
virtual void visit(AstBegin* nodep) override {
|
||||
void visit(AstBegin* nodep) override {
|
||||
if (nodep->name() == "") {
|
||||
putbs("begin\n");
|
||||
} else {
|
||||
|
|
@ -79,7 +79,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
iterateChildrenConst(nodep);
|
||||
puts("end\n");
|
||||
}
|
||||
virtual void visit(AstFork* nodep) override {
|
||||
void visit(AstFork* nodep) override {
|
||||
if (nodep->name() == "") {
|
||||
putbs("fork\n");
|
||||
} else {
|
||||
|
|
@ -89,19 +89,19 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
puts(nodep->joinType().verilogKwd());
|
||||
puts("\n");
|
||||
}
|
||||
virtual void visit(AstFinal* nodep) override {
|
||||
void visit(AstFinal* nodep) override {
|
||||
putfs(nodep, "final begin\n");
|
||||
iterateChildrenConst(nodep);
|
||||
putqs(nodep, "end\n");
|
||||
}
|
||||
virtual void visit(AstInitial* nodep) override {
|
||||
void visit(AstInitial* nodep) override {
|
||||
putfs(nodep, "initial begin\n");
|
||||
iterateChildrenConst(nodep);
|
||||
putqs(nodep, "end\n");
|
||||
}
|
||||
virtual void visit(AstInitialAutomatic* nodep) override { iterateChildrenConst(nodep); }
|
||||
virtual void visit(AstInitialStatic* nodep) override { iterateChildrenConst(nodep); }
|
||||
virtual void visit(AstAlways* nodep) override {
|
||||
void visit(AstInitialAutomatic* nodep) override { iterateChildrenConst(nodep); }
|
||||
void visit(AstInitialStatic* nodep) override { iterateChildrenConst(nodep); }
|
||||
void visit(AstAlways* nodep) override {
|
||||
putfs(nodep, "always ");
|
||||
if (m_sensesp) {
|
||||
iterateAndNextConstNull(m_sensesp);
|
||||
|
|
@ -113,7 +113,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
iterateAndNextConstNull(nodep->bodysp());
|
||||
putqs(nodep, "end\n");
|
||||
}
|
||||
virtual void visit(AstAlwaysPublic* nodep) override {
|
||||
void visit(AstAlwaysPublic* nodep) override {
|
||||
putfs(nodep, "/*verilator public_flat_rw ");
|
||||
if (m_sensesp) {
|
||||
iterateAndNextConstNull(m_sensesp);
|
||||
|
|
@ -125,43 +125,43 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
iterateAndNextConstNull(nodep->bodysp());
|
||||
putqs(nodep, "*/\n");
|
||||
}
|
||||
virtual void visit(AstNodeAssign* nodep) override {
|
||||
void visit(AstNodeAssign* nodep) override {
|
||||
if (VN_IS(nodep, AssignForce)) puts("force ");
|
||||
iterateAndNextConstNull(nodep->lhsp());
|
||||
putfs(nodep, " " + nodep->verilogKwd() + " ");
|
||||
iterateAndNextConstNull(nodep->rhsp());
|
||||
if (!m_suppressSemi) puts(";\n");
|
||||
}
|
||||
virtual void visit(AstAssignDly* nodep) override {
|
||||
void visit(AstAssignDly* nodep) override {
|
||||
iterateAndNextConstNull(nodep->lhsp());
|
||||
putfs(nodep, " <= ");
|
||||
iterateAndNextConstNull(nodep->rhsp());
|
||||
puts(";\n");
|
||||
}
|
||||
virtual void visit(AstAssignAlias* nodep) override {
|
||||
void visit(AstAssignAlias* nodep) override {
|
||||
putbs("alias ");
|
||||
iterateAndNextConstNull(nodep->lhsp());
|
||||
putfs(nodep, " = ");
|
||||
iterateAndNextConstNull(nodep->rhsp());
|
||||
if (!m_suppressSemi) puts(";\n");
|
||||
}
|
||||
virtual void visit(AstAssignW* nodep) override {
|
||||
void visit(AstAssignW* nodep) override {
|
||||
putfs(nodep, "assign ");
|
||||
iterateAndNextConstNull(nodep->lhsp());
|
||||
putbs(" = ");
|
||||
iterateAndNextConstNull(nodep->rhsp());
|
||||
if (!m_suppressSemi) puts(";\n");
|
||||
}
|
||||
virtual void visit(AstRelease* nodep) override {
|
||||
void visit(AstRelease* nodep) override {
|
||||
puts("release ");
|
||||
iterateAndNextConstNull(nodep->lhsp());
|
||||
if (!m_suppressSemi) puts(";\n");
|
||||
}
|
||||
virtual void visit(AstBreak*) override {
|
||||
void visit(AstBreak*) override {
|
||||
putbs("break");
|
||||
if (!m_suppressSemi) puts(";\n");
|
||||
}
|
||||
virtual void visit(AstSenTree* nodep) override {
|
||||
void visit(AstSenTree* nodep) override {
|
||||
// AstSenItem is called for dumping in isolation by V3Order
|
||||
putfs(nodep, "@(");
|
||||
for (AstNode* expp = nodep->sensesp(); expp; expp = expp->nextp()) {
|
||||
|
|
@ -170,13 +170,13 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
}
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstSenItem* nodep) override {
|
||||
void visit(AstSenItem* nodep) override {
|
||||
putfs(nodep, "");
|
||||
puts(nodep->edgeType().verilogKwd());
|
||||
if (nodep->sensp()) puts(" ");
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeCase* nodep) override {
|
||||
void visit(AstNodeCase* nodep) override {
|
||||
putfs(nodep, "");
|
||||
if (const AstCase* const casep = VN_CAST(nodep, Case)) {
|
||||
if (casep->priorityPragma()) puts("priority ");
|
||||
|
|
@ -197,7 +197,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
iterateAndNextConstNull(nodep->itemsp());
|
||||
putqs(nodep, "endcase\n");
|
||||
}
|
||||
virtual void visit(AstCaseItem* nodep) override {
|
||||
void visit(AstCaseItem* nodep) override {
|
||||
if (nodep->condsp()) {
|
||||
iterateAndNextConstNull(nodep->condsp());
|
||||
} else {
|
||||
|
|
@ -207,17 +207,17 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
iterateAndNextConstNull(nodep->bodysp());
|
||||
putqs(nodep, "end\n");
|
||||
}
|
||||
virtual void visit(AstComment* nodep) override {
|
||||
void visit(AstComment* nodep) override {
|
||||
puts(std::string{"// "} + nodep->name() + "\n");
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
virtual void visit(AstContinue*) override {
|
||||
void visit(AstContinue*) override {
|
||||
putbs("continue");
|
||||
if (!m_suppressSemi) puts(";\n");
|
||||
}
|
||||
virtual void visit(AstCoverDecl*) override {} // N/A
|
||||
virtual void visit(AstCoverInc*) override {} // N/A
|
||||
virtual void visit(AstCoverToggle*) override {} // N/A
|
||||
void visit(AstCoverDecl*) override {} // N/A
|
||||
void visit(AstCoverInc*) override {} // N/A
|
||||
void visit(AstCoverToggle*) override {} // N/A
|
||||
|
||||
void visitNodeDisplay(AstNode* nodep, AstNode* fileOrStrgp, const string& text,
|
||||
AstNode* exprsp) {
|
||||
|
|
@ -234,26 +234,26 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
}
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstDisable* nodep) override { putbs("disable " + nodep->name() + ";\n"); }
|
||||
virtual void visit(AstDisplay* nodep) override {
|
||||
void visit(AstDisable* nodep) override { putbs("disable " + nodep->name() + ";\n"); }
|
||||
void visit(AstDisplay* nodep) override {
|
||||
visitNodeDisplay(nodep, nodep->filep(), nodep->fmtp()->text(), nodep->fmtp()->exprsp());
|
||||
}
|
||||
virtual void visit(AstElabDisplay* nodep) override {
|
||||
void visit(AstElabDisplay* nodep) override {
|
||||
visitNodeDisplay(nodep, nullptr, nodep->fmtp()->text(), nodep->fmtp()->exprsp());
|
||||
}
|
||||
virtual void visit(AstFScanF* nodep) override {
|
||||
void visit(AstFScanF* nodep) override {
|
||||
visitNodeDisplay(nodep, nodep->filep(), nodep->text(), nodep->exprsp());
|
||||
}
|
||||
virtual void visit(AstSScanF* nodep) override {
|
||||
void visit(AstSScanF* nodep) override {
|
||||
visitNodeDisplay(nodep, nodep->fromp(), nodep->text(), nodep->exprsp());
|
||||
}
|
||||
virtual void visit(AstSFormat* nodep) override {
|
||||
void visit(AstSFormat* nodep) override {
|
||||
visitNodeDisplay(nodep, nodep->lhsp(), nodep->fmtp()->text(), nodep->fmtp()->exprsp());
|
||||
}
|
||||
virtual void visit(AstSFormatF* nodep) override {
|
||||
void visit(AstSFormatF* nodep) override {
|
||||
visitNodeDisplay(nodep, nullptr, nodep->text(), nodep->exprsp());
|
||||
}
|
||||
virtual void visit(AstFOpen* nodep) override {
|
||||
void visit(AstFOpen* nodep) override {
|
||||
putfs(nodep, nodep->verilogKwd());
|
||||
putbs("(");
|
||||
iterateAndNextConstNull(nodep->filenamep());
|
||||
|
|
@ -261,36 +261,34 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
iterateAndNextConstNull(nodep->modep());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstFOpenMcd* nodep) override {
|
||||
void visit(AstFOpenMcd* nodep) override {
|
||||
putfs(nodep, nodep->verilogKwd());
|
||||
putbs("(");
|
||||
iterateAndNextConstNull(nodep->filenamep());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstFClose* nodep) override {
|
||||
void visit(AstFClose* nodep) override {
|
||||
putfs(nodep, nodep->verilogKwd());
|
||||
putbs("(");
|
||||
if (nodep->filep()) iterateAndNextConstNull(nodep->filep());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstFFlush* nodep) override {
|
||||
void visit(AstFFlush* nodep) override {
|
||||
putfs(nodep, nodep->verilogKwd());
|
||||
putbs("(");
|
||||
if (nodep->filep()) iterateAndNextConstNull(nodep->filep());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstJumpBlock* nodep) override {
|
||||
void visit(AstJumpBlock* nodep) override {
|
||||
putbs("begin : label" + cvtToStr(nodep->labelNum()) + "\n");
|
||||
if (nodep->stmtsp()) iterateAndNextConstNull(nodep->stmtsp());
|
||||
puts("end\n");
|
||||
}
|
||||
virtual void visit(AstJumpGo* nodep) override {
|
||||
void visit(AstJumpGo* nodep) override {
|
||||
putbs("disable label" + cvtToStr(nodep->labelp()->blockp()->labelNum()) + ";\n");
|
||||
}
|
||||
virtual void visit(AstJumpLabel* nodep) override {
|
||||
putbs("// " + cvtToStr(nodep->blockp()) + ":\n");
|
||||
}
|
||||
virtual void visit(AstNodeReadWriteMem* nodep) override {
|
||||
void visit(AstJumpLabel* nodep) override { putbs("// " + cvtToStr(nodep->blockp()) + ":\n"); }
|
||||
void visit(AstNodeReadWriteMem* nodep) override {
|
||||
putfs(nodep, nodep->verilogKwd());
|
||||
putbs("(");
|
||||
if (nodep->filenamep()) iterateAndNextConstNull(nodep->filenamep());
|
||||
|
|
@ -306,17 +304,17 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
}
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstSysFuncAsTask* nodep) override {
|
||||
void visit(AstSysFuncAsTask* nodep) override {
|
||||
iterateAndNextConstNull(nodep->lhsp());
|
||||
puts(";\n");
|
||||
}
|
||||
virtual void visit(AstSysIgnore* nodep) override {
|
||||
void visit(AstSysIgnore* nodep) override {
|
||||
putfs(nodep, nodep->verilogKwd());
|
||||
putbs("(");
|
||||
iterateAndNextConstNull(nodep->exprsp());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstNodeFor* nodep) override {
|
||||
void visit(AstNodeFor* nodep) override {
|
||||
putfs(nodep, "for (");
|
||||
{
|
||||
VL_RESTORER(m_suppressSemi);
|
||||
|
|
@ -331,14 +329,14 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
iterateAndNextConstNull(nodep->bodysp());
|
||||
putqs(nodep, "end\n");
|
||||
}
|
||||
virtual void visit(AstRepeat* nodep) override {
|
||||
void visit(AstRepeat* nodep) override {
|
||||
putfs(nodep, "repeat (");
|
||||
iterateAndNextConstNull(nodep->countp());
|
||||
puts(") begin\n");
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
putfs(nodep, "end\n");
|
||||
}
|
||||
virtual void visit(AstWhile* nodep) override {
|
||||
void visit(AstWhile* nodep) override {
|
||||
iterateAndNextConstNull(nodep->precondsp());
|
||||
putfs(nodep, "while (");
|
||||
iterateAndNextConstNull(nodep->condp());
|
||||
|
|
@ -348,7 +346,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
iterateAndNextConstNull(nodep->precondsp()); // Need to recompute before next loop
|
||||
putfs(nodep, "end\n");
|
||||
}
|
||||
virtual void visit(AstNodeIf* nodep) override {
|
||||
void visit(AstNodeIf* nodep) override {
|
||||
putfs(nodep, "");
|
||||
if (const AstIf* const ifp = VN_CAST(nodep, If)) {
|
||||
if (ifp->priorityPragma()) puts("priority ");
|
||||
|
|
@ -366,7 +364,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
}
|
||||
putqs(nodep, "end\n");
|
||||
}
|
||||
virtual void visit(AstPast* nodep) override {
|
||||
void visit(AstPast* nodep) override {
|
||||
putfs(nodep, "$past(");
|
||||
iterateAndNextConstNull(nodep->exprp());
|
||||
if (nodep->ticksp()) {
|
||||
|
|
@ -375,21 +373,21 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
}
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstReturn* nodep) override {
|
||||
void visit(AstReturn* nodep) override {
|
||||
putfs(nodep, "return ");
|
||||
iterateAndNextConstNull(nodep->lhsp());
|
||||
puts(";\n");
|
||||
}
|
||||
virtual void visit(AstStop* nodep) override { putfs(nodep, "$stop;\n"); }
|
||||
virtual void visit(AstFinish* nodep) override { putfs(nodep, "$finish;\n"); }
|
||||
virtual void visit(AstNodeSimpleText* nodep) override {
|
||||
void visit(AstStop* nodep) override { putfs(nodep, "$stop;\n"); }
|
||||
void visit(AstFinish* nodep) override { putfs(nodep, "$finish;\n"); }
|
||||
void visit(AstNodeSimpleText* nodep) override {
|
||||
if (nodep->tracking() || m_trackText) {
|
||||
puts(nodep->text());
|
||||
} else {
|
||||
putsNoTracking(nodep->text());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstTextBlock* nodep) override {
|
||||
void visit(AstTextBlock* nodep) override {
|
||||
visit(static_cast<AstNodeSimpleText*>(nodep));
|
||||
{
|
||||
VL_RESTORER(m_suppressSemi);
|
||||
|
|
@ -400,29 +398,29 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstScopeName* nodep) override {}
|
||||
virtual void visit(AstCStmt* nodep) override {
|
||||
void visit(AstScopeName* nodep) override {}
|
||||
void visit(AstCStmt* nodep) override {
|
||||
putfs(nodep, "$_CSTMT(");
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstCMath* nodep) override {
|
||||
void visit(AstCMath* nodep) override {
|
||||
putfs(nodep, "$_CMATH(");
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstUCStmt* nodep) override {
|
||||
void visit(AstUCStmt* nodep) override {
|
||||
putfs(nodep, "$c(");
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstUCFunc* nodep) override {
|
||||
void visit(AstUCFunc* nodep) override {
|
||||
putfs(nodep, "$c(");
|
||||
iterateAndNextConstNull(nodep->bodysp());
|
||||
puts(")");
|
||||
}
|
||||
|
||||
virtual void visit(AstCMethodHard* nodep) override {
|
||||
void visit(AstCMethodHard* nodep) override {
|
||||
iterate(nodep->fromp());
|
||||
puts("." + nodep->name() + "(");
|
||||
for (AstNode* pinp = nodep->pinsp(); pinp; pinp = pinp->nextp()) {
|
||||
|
|
@ -491,25 +489,23 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeTermop* nodep) override {
|
||||
emitVerilogFormat(nodep, nodep->emitVerilog());
|
||||
}
|
||||
virtual void visit(AstNodeUniop* nodep) override {
|
||||
void visit(AstNodeTermop* nodep) override { emitVerilogFormat(nodep, nodep->emitVerilog()); }
|
||||
void visit(AstNodeUniop* nodep) override {
|
||||
emitVerilogFormat(nodep, nodep->emitVerilog(), nodep->lhsp());
|
||||
}
|
||||
virtual void visit(AstNodeBiop* nodep) override {
|
||||
void visit(AstNodeBiop* nodep) override {
|
||||
emitVerilogFormat(nodep, nodep->emitVerilog(), nodep->lhsp(), nodep->rhsp());
|
||||
}
|
||||
virtual void visit(AstNodeTriop* nodep) override {
|
||||
void visit(AstNodeTriop* nodep) override {
|
||||
emitVerilogFormat(nodep, nodep->emitVerilog(), nodep->lhsp(), nodep->rhsp(),
|
||||
nodep->thsp());
|
||||
}
|
||||
virtual void visit(AstMemberSel* nodep) override {
|
||||
void visit(AstMemberSel* nodep) override {
|
||||
iterate(nodep->fromp());
|
||||
puts(".");
|
||||
puts(nodep->prettyName());
|
||||
}
|
||||
virtual void visit(AstAttrOf* nodep) override {
|
||||
void visit(AstAttrOf* nodep) override {
|
||||
putfs(nodep, "$_ATTROF(");
|
||||
iterateAndNextConstNull(nodep->fromp());
|
||||
if (nodep->dimp()) {
|
||||
|
|
@ -518,7 +514,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
}
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstInitArray* nodep) override {
|
||||
void visit(AstInitArray* nodep) override {
|
||||
putfs(nodep, "'{");
|
||||
int comma = 0;
|
||||
const auto& mapr = nodep->map();
|
||||
|
|
@ -531,7 +527,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
}
|
||||
puts("}");
|
||||
}
|
||||
virtual void visit(AstNodeCond* nodep) override {
|
||||
void visit(AstNodeCond* nodep) override {
|
||||
putbs("(");
|
||||
iterateAndNextConstNull(nodep->condp());
|
||||
putfs(nodep, " ? ");
|
||||
|
|
@ -540,7 +536,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
iterateAndNextConstNull(nodep->expr2p());
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstRange* nodep) override {
|
||||
void visit(AstRange* nodep) override {
|
||||
puts("[");
|
||||
if (VN_IS(nodep->leftp(), Const) && VN_IS(nodep->rightp(), Const)) {
|
||||
// Looks nicer if we print [1:0] rather than [32'sh1:32sh0]
|
||||
|
|
@ -555,7 +551,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
puts("]");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSel* nodep) override {
|
||||
void visit(AstSel* nodep) override {
|
||||
iterateAndNextConstNull(nodep->fromp());
|
||||
puts("[");
|
||||
if (VN_IS(nodep->lsbp(), Const)) {
|
||||
|
|
@ -579,18 +575,18 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
}
|
||||
puts("]");
|
||||
}
|
||||
virtual void visit(AstSliceSel* nodep) override {
|
||||
void visit(AstSliceSel* nodep) override {
|
||||
iterateAndNextConstNull(nodep->fromp());
|
||||
puts(cvtToStr(nodep->declRange()));
|
||||
}
|
||||
virtual void visit(AstTypedef* nodep) override {
|
||||
void visit(AstTypedef* nodep) override {
|
||||
putfs(nodep, "typedef ");
|
||||
iterateAndNextConstNull(nodep->dtypep());
|
||||
puts(" ");
|
||||
puts(nodep->prettyName());
|
||||
puts(";\n");
|
||||
}
|
||||
virtual void visit(AstBasicDType* nodep) override {
|
||||
void visit(AstBasicDType* nodep) override {
|
||||
if (nodep->isSigned()) putfs(nodep, "signed ");
|
||||
putfs(nodep, nodep->prettyName());
|
||||
if (nodep->rangep()) {
|
||||
|
|
@ -603,15 +599,15 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
puts(":0] ");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstConstDType* nodep) override {
|
||||
void visit(AstConstDType* nodep) override {
|
||||
putfs(nodep, "const ");
|
||||
iterate(nodep->subDTypep());
|
||||
}
|
||||
virtual void visit(AstNodeArrayDType* nodep) override {
|
||||
void visit(AstNodeArrayDType* nodep) override {
|
||||
iterate(nodep->subDTypep());
|
||||
iterateAndNextConstNull(nodep->rangep());
|
||||
}
|
||||
virtual void visit(AstNodeUOrStructDType* nodep) override {
|
||||
void visit(AstNodeUOrStructDType* nodep) override {
|
||||
puts(nodep->verilogKwd() + " ");
|
||||
if (nodep->packed()) puts("packed ");
|
||||
puts("\n");
|
||||
|
|
@ -619,12 +615,12 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
iterateAndNextConstNull(nodep->membersp());
|
||||
puts("}");
|
||||
}
|
||||
virtual void visit(AstMemberDType* nodep) override {
|
||||
void visit(AstMemberDType* nodep) override {
|
||||
iterate(nodep->subDTypep());
|
||||
puts(" ");
|
||||
puts(nodep->name());
|
||||
}
|
||||
virtual void visit(AstNodeFTaskRef* nodep) override {
|
||||
void visit(AstNodeFTaskRef* nodep) override {
|
||||
if (nodep->dotted() != "") {
|
||||
putfs(nodep, nodep->dotted());
|
||||
puts(".");
|
||||
|
|
@ -636,14 +632,14 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
iterateAndNextConstNull(nodep->pinsp());
|
||||
puts(")");
|
||||
}
|
||||
virtual void visit(AstArg* nodep) override { iterateAndNextConstNull(nodep->exprp()); }
|
||||
virtual void visit(AstPrintTimeScale* nodep) override {
|
||||
void visit(AstArg* nodep) override { iterateAndNextConstNull(nodep->exprp()); }
|
||||
void visit(AstPrintTimeScale* nodep) override {
|
||||
puts(nodep->verilogKwd());
|
||||
puts(";\n");
|
||||
}
|
||||
|
||||
// Terminals
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
if (nodep->varScopep()) {
|
||||
putfs(nodep, nodep->varScopep()->prettyName());
|
||||
} else {
|
||||
|
|
@ -659,7 +655,7 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVarXRef* nodep) override {
|
||||
void visit(AstVarXRef* nodep) override {
|
||||
putfs(nodep, nodep->dotted());
|
||||
puts(".");
|
||||
if (nodep->varp()) {
|
||||
|
|
@ -668,12 +664,12 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
puts(nodep->prettyName());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstConst* nodep) override { putfs(nodep, nodep->num().ascii(true, true)); }
|
||||
void visit(AstConst* nodep) override { putfs(nodep, nodep->num().ascii(true, true)); }
|
||||
|
||||
// Just iterate
|
||||
virtual void visit(AstTopScope* nodep) override { iterateChildrenConst(nodep); }
|
||||
virtual void visit(AstScope* nodep) override { iterateChildrenConst(nodep); }
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
void visit(AstTopScope* nodep) override { iterateChildrenConst(nodep); }
|
||||
void visit(AstScope* nodep) override { iterateChildrenConst(nodep); }
|
||||
void visit(AstVar* nodep) override {
|
||||
if (nodep->isIO()) {
|
||||
putfs(nodep, nodep->verilogKwd());
|
||||
puts(" ");
|
||||
|
|
@ -701,21 +697,21 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor {
|
|||
}
|
||||
puts(m_suppressVarSemi ? "\n" : ";\n");
|
||||
}
|
||||
virtual void visit(AstActive* nodep) override {
|
||||
void visit(AstActive* nodep) override {
|
||||
m_sensesp = nodep->sensesp();
|
||||
iterateAndNextConstNull(nodep->stmtsp());
|
||||
m_sensesp = nullptr;
|
||||
}
|
||||
virtual void visit(AstParseRef* nodep) override { puts(nodep->prettyName()); }
|
||||
virtual void visit(AstVarScope*) override {}
|
||||
virtual void visit(AstNodeText*) override {}
|
||||
virtual void visit(AstTraceDecl*) override {}
|
||||
virtual void visit(AstTraceInc*) override {}
|
||||
void visit(AstParseRef* nodep) override { puts(nodep->prettyName()); }
|
||||
void visit(AstVarScope*) override {}
|
||||
void visit(AstNodeText*) override {}
|
||||
void visit(AstTraceDecl*) override {}
|
||||
void visit(AstTraceInc*) override {}
|
||||
// NOPs
|
||||
virtual void visit(AstPragma*) override {}
|
||||
virtual void visit(AstCell*) override {} // Handled outside the Visit class
|
||||
void visit(AstPragma*) override {}
|
||||
void visit(AstCell*) override {} // Handled outside the Visit class
|
||||
// Default
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
puts(std::string{"\n???? // "} + nodep->prettyTypeName() + "\n");
|
||||
iterateChildrenConst(nodep);
|
||||
// Not v3fatalSrc so we keep processing
|
||||
|
|
@ -730,7 +726,7 @@ public:
|
|||
explicit EmitVBaseVisitor(bool suppressUnknown, AstSenTree* domainp)
|
||||
: m_suppressUnknown{suppressUnknown}
|
||||
, m_sensesp{domainp} {}
|
||||
virtual ~EmitVBaseVisitor() override = default;
|
||||
~EmitVBaseVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
@ -741,11 +737,11 @@ class EmitVFileVisitor final : public EmitVBaseVisitor {
|
|||
V3OutFile* m_ofp;
|
||||
// METHODS
|
||||
V3OutFile* ofp() const { return m_ofp; }
|
||||
virtual void puts(const string& str) override { ofp()->puts(str); }
|
||||
virtual void putbs(const string& str) override { ofp()->putbs(str); }
|
||||
virtual void putfs(AstNode*, const string& str) override { putbs(str); }
|
||||
virtual void putqs(AstNode*, const string& str) override { putbs(str); }
|
||||
virtual void putsNoTracking(const string& str) override { ofp()->putsNoTracking(str); }
|
||||
void puts(const string& str) override { ofp()->puts(str); }
|
||||
void putbs(const string& str) override { ofp()->putbs(str); }
|
||||
void putfs(AstNode*, const string& str) override { putbs(str); }
|
||||
void putqs(AstNode*, const string& str) override { putbs(str); }
|
||||
void putsNoTracking(const string& str) override { ofp()->putsNoTracking(str); }
|
||||
|
||||
public:
|
||||
EmitVFileVisitor(AstNode* nodep, V3OutFile* ofp, bool trackText, bool suppressUnknown)
|
||||
|
|
@ -754,7 +750,7 @@ public:
|
|||
m_trackText = trackText;
|
||||
iterate(nodep);
|
||||
}
|
||||
virtual ~EmitVFileVisitor() override = default;
|
||||
~EmitVFileVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
@ -764,11 +760,11 @@ class EmitVStreamVisitor final : public EmitVBaseVisitor {
|
|||
// MEMBERS
|
||||
std::ostream& m_os;
|
||||
// METHODS
|
||||
virtual void putsNoTracking(const string& str) override { m_os << str; }
|
||||
virtual void puts(const string& str) override { putsNoTracking(str); }
|
||||
virtual void putbs(const string& str) override { puts(str); }
|
||||
virtual void putfs(AstNode*, const string& str) override { putbs(str); }
|
||||
virtual void putqs(AstNode*, const string& str) override { putbs(str); }
|
||||
void putsNoTracking(const string& str) override { m_os << str; }
|
||||
void puts(const string& str) override { putsNoTracking(str); }
|
||||
void putbs(const string& str) override { puts(str); }
|
||||
void putfs(AstNode*, const string& str) override { putbs(str); }
|
||||
void putqs(AstNode*, const string& str) override { putbs(str); }
|
||||
|
||||
public:
|
||||
EmitVStreamVisitor(const AstNode* nodep, std::ostream& os)
|
||||
|
|
@ -776,7 +772,7 @@ public:
|
|||
, m_os(os) { // Need () or GCC 4.8 false warning
|
||||
iterate(const_cast<AstNode*>(nodep));
|
||||
}
|
||||
virtual ~EmitVStreamVisitor() override = default;
|
||||
~EmitVStreamVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
@ -789,7 +785,7 @@ class EmitVPrefixedFormatter final : public V3OutFormatter {
|
|||
int m_column = 0; // Rough location; need just zero or non-zero
|
||||
FileLine* m_prefixFl;
|
||||
// METHODS
|
||||
virtual void putcOutput(char chr) override {
|
||||
void putcOutput(char chr) override {
|
||||
if (chr == '\n') {
|
||||
m_column = 0;
|
||||
m_os << chr;
|
||||
|
|
@ -806,7 +802,7 @@ class EmitVPrefixedFormatter final : public V3OutFormatter {
|
|||
}
|
||||
}
|
||||
|
||||
virtual void putsOutput(const char* strg) override {
|
||||
void putsOutput(const char* strg) override {
|
||||
for (const char* cp = strg; *cp; cp++) putcOutput(*cp);
|
||||
}
|
||||
|
||||
|
|
@ -822,7 +818,7 @@ public:
|
|||
m_prefixFl = v3Global.rootp()->fileline(); // NETLIST's fileline instead of nullptr to
|
||||
// avoid nullptr checks
|
||||
}
|
||||
virtual ~EmitVPrefixedFormatter() override {
|
||||
~EmitVPrefixedFormatter() override {
|
||||
if (m_column) puts("\n");
|
||||
}
|
||||
};
|
||||
|
|
@ -832,13 +828,13 @@ class EmitVPrefixedVisitor final : public EmitVBaseVisitor {
|
|||
EmitVPrefixedFormatter m_formatter; // Special verilog formatter (Way down the
|
||||
// inheritance is another unused V3OutFormatter)
|
||||
// METHODS
|
||||
virtual void putsNoTracking(const string& str) override { m_formatter.putsNoTracking(str); }
|
||||
virtual void puts(const string& str) override { m_formatter.puts(str); }
|
||||
void putsNoTracking(const string& str) override { m_formatter.putsNoTracking(str); }
|
||||
void puts(const string& str) override { m_formatter.puts(str); }
|
||||
// We don't use m_formatter's putbs because the tokens will change filelines
|
||||
// and insert returns at the proper locations
|
||||
virtual void putbs(const string& str) override { m_formatter.puts(str); }
|
||||
virtual void putfs(AstNode* nodep, const string& str) override { putfsqs(nodep, str, false); }
|
||||
virtual void putqs(AstNode* nodep, const string& str) override { putfsqs(nodep, str, true); }
|
||||
void putbs(const string& str) override { m_formatter.puts(str); }
|
||||
void putfs(AstNode* nodep, const string& str) override { putfsqs(nodep, str, false); }
|
||||
void putqs(AstNode* nodep, const string& str) override { putfsqs(nodep, str, true); }
|
||||
void putfsqs(AstNode* nodep, const string& str, bool quiet) {
|
||||
if (m_formatter.prefixFl() != nodep->fileline()) {
|
||||
m_formatter.prefixFl(nodep->fileline());
|
||||
|
|
@ -856,7 +852,7 @@ public:
|
|||
if (user3mark) VNUser3InUse::check();
|
||||
iterate(const_cast<AstNode*>(nodep));
|
||||
}
|
||||
virtual ~EmitVPrefixedVisitor() override = default;
|
||||
~EmitVPrefixedVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -101,11 +101,11 @@ class EmitXmlFileVisitor final : public VNVisitor {
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstAssignW* nodep) override {
|
||||
void visit(AstAssignW* nodep) override {
|
||||
outputTag(nodep, "contassign"); // IEEE: vpiContAssign
|
||||
outputChildrenEnd(nodep, "contassign");
|
||||
}
|
||||
virtual void visit(AstCell* nodep) override {
|
||||
void visit(AstCell* nodep) override {
|
||||
outputTag(nodep, "instance"); // IEEE: vpiInstance
|
||||
puts(" defName=");
|
||||
putsQuoted(nodep->modName()); // IEEE vpiDefName
|
||||
|
|
@ -113,7 +113,7 @@ class EmitXmlFileVisitor final : public VNVisitor {
|
|||
putsQuoted(nodep->origName());
|
||||
outputChildrenEnd(nodep, "instance");
|
||||
}
|
||||
virtual void visit(AstNodeIf* nodep) override {
|
||||
void visit(AstNodeIf* nodep) override {
|
||||
outputTag(nodep, "if");
|
||||
puts(">\n");
|
||||
iterateAndNextNull(nodep->op1p());
|
||||
|
|
@ -127,7 +127,7 @@ class EmitXmlFileVisitor final : public VNVisitor {
|
|||
}
|
||||
puts("</if>\n");
|
||||
}
|
||||
virtual void visit(AstWhile* nodep) override {
|
||||
void visit(AstWhile* nodep) override {
|
||||
outputTag(nodep, "while");
|
||||
puts(">\n");
|
||||
puts("<begin>\n");
|
||||
|
|
@ -150,19 +150,19 @@ class EmitXmlFileVisitor final : public VNVisitor {
|
|||
}
|
||||
puts("</while>\n");
|
||||
}
|
||||
virtual void visit(AstNetlist* nodep) override {
|
||||
void visit(AstNetlist* nodep) override {
|
||||
puts("<netlist>\n");
|
||||
iterateChildren(nodep);
|
||||
puts("</netlist>\n");
|
||||
}
|
||||
virtual void visit(AstConstPool* nodep) override {
|
||||
void visit(AstConstPool* nodep) override {
|
||||
if (!v3Global.opt.xmlOnly()) {
|
||||
puts("<constpool>\n");
|
||||
iterateChildren(nodep);
|
||||
puts("</constpool>\n");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstInitArray* nodep) override {
|
||||
void visit(AstInitArray* nodep) override {
|
||||
puts("<initarray>\n");
|
||||
const auto& mapr = nodep->map();
|
||||
for (const auto& itr : mapr) {
|
||||
|
|
@ -174,7 +174,7 @@ class EmitXmlFileVisitor final : public VNVisitor {
|
|||
}
|
||||
puts("</initarray>\n");
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
outputTag(nodep, "");
|
||||
puts(" origName=");
|
||||
putsQuoted(nodep->origName());
|
||||
|
|
@ -184,7 +184,7 @@ class EmitXmlFileVisitor final : public VNVisitor {
|
|||
if (nodep->modPublic()) puts(" public=\"true\"");
|
||||
outputChildrenEnd(nodep, "");
|
||||
}
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
void visit(AstVar* nodep) override {
|
||||
const VVarType typ = nodep->varType();
|
||||
const string kw = nodep->verilogKwd();
|
||||
const string vt = nodep->dtypep()->name();
|
||||
|
|
@ -221,7 +221,7 @@ class EmitXmlFileVisitor final : public VNVisitor {
|
|||
if (nodep->attrSFormat()) puts(" sformat=\"true\"");
|
||||
outputChildrenEnd(nodep, "");
|
||||
}
|
||||
virtual void visit(AstPin* nodep) override {
|
||||
void visit(AstPin* nodep) override {
|
||||
// What we call a pin in verilator is a port in the IEEE spec.
|
||||
outputTag(nodep, "port"); // IEEE: vpiPort
|
||||
if (nodep->modVarp()->isIO()) {
|
||||
|
|
@ -231,12 +231,12 @@ class EmitXmlFileVisitor final : public VNVisitor {
|
|||
// Children includes vpiHighConn and vpiLowConn; we don't support port bits (yet?)
|
||||
outputChildrenEnd(nodep, "port");
|
||||
}
|
||||
virtual void visit(AstSenItem* nodep) override {
|
||||
void visit(AstSenItem* nodep) override {
|
||||
outputTag(nodep, "");
|
||||
puts(" edgeType=\"" + cvtToStr(nodep->edgeType().ascii()) + "\""); // IEEE vpiTopModule
|
||||
outputChildrenEnd(nodep, "");
|
||||
}
|
||||
virtual void visit(AstModportVarRef* nodep) override {
|
||||
void visit(AstModportVarRef* nodep) override {
|
||||
// Dump direction for Modport references
|
||||
const string kw = nodep->direction().xmlKwd();
|
||||
outputTag(nodep, "");
|
||||
|
|
@ -244,13 +244,13 @@ class EmitXmlFileVisitor final : public VNVisitor {
|
|||
putsQuoted(kw);
|
||||
outputChildrenEnd(nodep, "");
|
||||
}
|
||||
virtual void visit(AstVarXRef* nodep) override {
|
||||
void visit(AstVarXRef* nodep) override {
|
||||
outputTag(nodep, "");
|
||||
puts(" dotted=");
|
||||
putsQuoted(nodep->dotted());
|
||||
outputChildrenEnd(nodep, "");
|
||||
}
|
||||
virtual void visit(AstNodeCCall* nodep) override {
|
||||
void visit(AstNodeCCall* nodep) override {
|
||||
outputTag(nodep, "");
|
||||
puts(" func=");
|
||||
putsQuoted(nodep->funcp()->name());
|
||||
|
|
@ -258,7 +258,7 @@ class EmitXmlFileVisitor final : public VNVisitor {
|
|||
}
|
||||
|
||||
// Data types
|
||||
virtual void visit(AstBasicDType* nodep) override {
|
||||
void visit(AstBasicDType* nodep) override {
|
||||
outputTag(nodep, "basicdtype");
|
||||
if (nodep->isRanged()) {
|
||||
puts(" left=\"" + cvtToStr(nodep->left()) + "\"");
|
||||
|
|
@ -267,7 +267,7 @@ class EmitXmlFileVisitor final : public VNVisitor {
|
|||
if (nodep->isSigned()) { puts(" signed=\"true\""); }
|
||||
puts("/>\n");
|
||||
}
|
||||
virtual void visit(AstIfaceRefDType* nodep) override {
|
||||
void visit(AstIfaceRefDType* nodep) override {
|
||||
string mpn;
|
||||
outputTag(nodep, "");
|
||||
if (nodep->isModport()) mpn = nodep->modportName();
|
||||
|
|
@ -275,19 +275,19 @@ class EmitXmlFileVisitor final : public VNVisitor {
|
|||
putsQuoted(mpn);
|
||||
outputChildrenEnd(nodep, "");
|
||||
}
|
||||
virtual void visit(AstDisplay* nodep) override {
|
||||
void visit(AstDisplay* nodep) override {
|
||||
outputTag(nodep, "");
|
||||
puts(" displaytype=");
|
||||
putsQuoted(nodep->verilogKwd());
|
||||
outputChildrenEnd(nodep, "");
|
||||
}
|
||||
virtual void visit(AstElabDisplay* nodep) override {
|
||||
void visit(AstElabDisplay* nodep) override {
|
||||
outputTag(nodep, "");
|
||||
puts(" displaytype=");
|
||||
putsQuoted(nodep->verilogKwd());
|
||||
outputChildrenEnd(nodep, "");
|
||||
}
|
||||
virtual void visit(AstExtend* nodep) override {
|
||||
void visit(AstExtend* nodep) override {
|
||||
outputTag(nodep, "");
|
||||
puts(" width=");
|
||||
putsQuoted(cvtToStr(nodep->width()));
|
||||
|
|
@ -295,7 +295,7 @@ class EmitXmlFileVisitor final : public VNVisitor {
|
|||
putsQuoted(cvtToStr(nodep->lhsp()->widthMinV()));
|
||||
outputChildrenEnd(nodep, "");
|
||||
}
|
||||
virtual void visit(AstExtendS* nodep) override {
|
||||
void visit(AstExtendS* nodep) override {
|
||||
outputTag(nodep, "");
|
||||
puts(" width=");
|
||||
putsQuoted(cvtToStr(nodep->width()));
|
||||
|
|
@ -305,7 +305,7 @@ class EmitXmlFileVisitor final : public VNVisitor {
|
|||
}
|
||||
|
||||
// Default
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
outputTag(nodep, "");
|
||||
outputChildrenEnd(nodep, "");
|
||||
}
|
||||
|
|
@ -315,7 +315,7 @@ public:
|
|||
: m_ofp{ofp} {
|
||||
iterate(nodep);
|
||||
}
|
||||
virtual ~EmitXmlFileVisitor() override = default;
|
||||
~EmitXmlFileVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
@ -332,11 +332,11 @@ private:
|
|||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep) override {
|
||||
void visit(AstNetlist* nodep) override {
|
||||
// Children are iterated backwards to ensure correct compilation order
|
||||
iterateChildrenBackwards(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
// Only list modules and interfaces
|
||||
// Assumes modules and interfaces list is already sorted level wise
|
||||
if (!nodep->dead() && (VN_IS(nodep, Module) || VN_IS(nodep, Iface))
|
||||
|
|
@ -345,7 +345,7 @@ private:
|
|||
}
|
||||
}
|
||||
//-----
|
||||
virtual void visit(AstNode*) override {
|
||||
void visit(AstNode*) override {
|
||||
// All modules are present at root so no need to iterate on children
|
||||
}
|
||||
|
||||
|
|
@ -363,7 +363,7 @@ public:
|
|||
}
|
||||
m_os << "</module_files>\n";
|
||||
}
|
||||
virtual ~ModuleFilesXmlVisitor() override = default;
|
||||
~ModuleFilesXmlVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
@ -380,9 +380,9 @@ private:
|
|||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstConstPool*) override {}
|
||||
void visit(AstConstPool*) override {}
|
||||
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
if (nodep->level() >= 0
|
||||
&& nodep->level() <= 2) { // ==2 because we don't add wrapper when in XML mode
|
||||
m_os << "<cells>\n";
|
||||
|
|
@ -401,7 +401,7 @@ private:
|
|||
m_os << "</cells>\n";
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCell* nodep) override {
|
||||
void visit(AstCell* nodep) override {
|
||||
if (nodep->modp()->dead()) return;
|
||||
if (!m_hasChildren) m_os << ">\n";
|
||||
m_os << "<cell " << nodep->fileline()->xmlDetailedLocation() << " name=\"" << nodep->name()
|
||||
|
|
@ -421,7 +421,7 @@ private:
|
|||
m_hasChildren = true;
|
||||
}
|
||||
//-----
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
@ -430,7 +430,7 @@ public:
|
|||
// Operate on whole netlist
|
||||
nodep->accept(*this);
|
||||
}
|
||||
virtual ~HierCellsXmlVisitor() override = default;
|
||||
~HierCellsXmlVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ v3errorIniter v3errorInit;
|
|||
V3ErrorCode::V3ErrorCode(const char* msgp) {
|
||||
// Return error encoding for given string, or ERROR, which is a bad code
|
||||
for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) {
|
||||
const V3ErrorCode code = V3ErrorCode(codei);
|
||||
const V3ErrorCode code{codei};
|
||||
if (0 == VL_STRCASECMP(msgp, code.ascii())) {
|
||||
m_e = code;
|
||||
return;
|
||||
|
|
@ -69,9 +69,9 @@ V3ErrorCode::V3ErrorCode(const char* msgp) {
|
|||
void V3Error::init() {
|
||||
for (int i = 0; i < V3ErrorCode::_ENUM_MAX; i++) {
|
||||
s_describedEachWarn[i] = false;
|
||||
s_pretendError[i] = V3ErrorCode(i).pretendError();
|
||||
s_pretendError[i] = V3ErrorCode{i}.pretendError();
|
||||
}
|
||||
if (VL_UNCOVERABLE(string(V3ErrorCode(V3ErrorCode::_ENUM_MAX).ascii()) != " MAX")) {
|
||||
if (VL_UNCOVERABLE(string(V3ErrorCode{V3ErrorCode::_ENUM_MAX}.ascii()) != " MAX")) {
|
||||
v3fatalSrc("Enum table in V3ErrorCode::EC_ascii() is munged");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -149,13 +149,13 @@ public:
|
|||
};
|
||||
// clang-format on
|
||||
enum en m_e;
|
||||
inline V3ErrorCode()
|
||||
V3ErrorCode()
|
||||
: m_e{EC_MIN} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline V3ErrorCode(en _e)
|
||||
V3ErrorCode(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit V3ErrorCode(const char* msgp); // Matching code or ERROR
|
||||
explicit inline V3ErrorCode(int _e)
|
||||
explicit V3ErrorCode(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
const char* ascii() const {
|
||||
|
|
|
|||
|
|
@ -313,7 +313,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstExtend* nodep) override {
|
||||
void visit(AstExtend* nodep) override {
|
||||
if (nodep->user1SetOnce()) return; // Process once
|
||||
iterateChildren(nodep);
|
||||
if (nodep->isWide()) {
|
||||
|
|
@ -339,7 +339,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstSel* nodep) override {
|
||||
void visit(AstSel* nodep) override {
|
||||
if (nodep->user1SetOnce()) return; // Process once
|
||||
iterateChildren(nodep);
|
||||
// Remember, Sel's may have non-integer rhs, so need to optimize for that!
|
||||
|
|
@ -628,7 +628,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstConcat* nodep) override {
|
||||
void visit(AstConcat* nodep) override {
|
||||
if (nodep->user1SetOnce()) return; // Process once
|
||||
iterateChildren(nodep);
|
||||
if (nodep->isWide()) {
|
||||
|
|
@ -665,7 +665,7 @@ private:
|
|||
return true;
|
||||
}
|
||||
|
||||
virtual void visit(AstReplicate* nodep) override {
|
||||
void visit(AstReplicate* nodep) override {
|
||||
if (nodep->user1SetOnce()) return; // Process once
|
||||
iterateChildren(nodep);
|
||||
if (nodep->isWide()) {
|
||||
|
|
@ -750,10 +750,10 @@ private:
|
|||
VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstEq* nodep) override { visitEqNeq(nodep); }
|
||||
virtual void visit(AstNeq* nodep) override { visitEqNeq(nodep); }
|
||||
void visit(AstEq* nodep) override { visitEqNeq(nodep); }
|
||||
void visit(AstNeq* nodep) override { visitEqNeq(nodep); }
|
||||
|
||||
virtual void visit(AstRedOr* nodep) override {
|
||||
void visit(AstRedOr* nodep) override {
|
||||
if (nodep->user1SetOnce()) return; // Process once
|
||||
iterateChildren(nodep);
|
||||
FileLine* const fl = nodep->fileline();
|
||||
|
|
@ -775,7 +775,7 @@ private:
|
|||
VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstRedAnd* nodep) override {
|
||||
void visit(AstRedAnd* nodep) override {
|
||||
if (nodep->user1SetOnce()) return; // Process once
|
||||
iterateChildren(nodep);
|
||||
FileLine* const fl = nodep->fileline();
|
||||
|
|
@ -805,7 +805,7 @@ private:
|
|||
VL_DO_DANGLING(replaceWithDelete(nodep, newp), nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstRedXor* nodep) override {
|
||||
void visit(AstRedXor* nodep) override {
|
||||
if (nodep->user1SetOnce()) return; // Process once
|
||||
iterateChildren(nodep);
|
||||
if (nodep->lhsp()->isWide()) {
|
||||
|
|
@ -825,7 +825,7 @@ private:
|
|||
// which the inlined function does nicely.
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeStmt* nodep) override {
|
||||
void visit(AstNodeStmt* nodep) override {
|
||||
if (nodep->user1SetOnce()) return; // Process once
|
||||
if (!nodep->isStatement()) {
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -835,7 +835,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
m_stmtp = nullptr;
|
||||
}
|
||||
virtual void visit(AstNodeAssign* nodep) override {
|
||||
void visit(AstNodeAssign* nodep) override {
|
||||
if (nodep->user1SetOnce()) return; // Process once
|
||||
m_stmtp = nodep;
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -876,13 +876,13 @@ private:
|
|||
}
|
||||
|
||||
//--------------------
|
||||
virtual void visit(AstVar*) override {} // Don't hit varrefs under vars
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstVar*) override {} // Don't hit varrefs under vars
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit ExpandVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
virtual ~ExpandVisitor() override {
|
||||
~ExpandVisitor() override {
|
||||
V3Stats::addStat("Optimizations, expand wides", m_statWides);
|
||||
V3Stats::addStat("Optimizations, expand wide words", m_statWideWords);
|
||||
V3Stats::addStat("Optimizations, expand limited", m_statWideLimited);
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ V3FileDependImp dependImp; // Depend implementation class
|
|||
//######################################################################
|
||||
// V3FileDependImp
|
||||
|
||||
inline void V3FileDependImp::writeDepend(const string& filename) {
|
||||
void V3FileDependImp::writeDepend(const string& filename) {
|
||||
const std::unique_ptr<std::ofstream> ofp{V3File::new_ofstream(filename)};
|
||||
if (ofp->fail()) v3fatal("Can't write " << filename);
|
||||
|
||||
|
|
@ -171,7 +171,7 @@ inline void V3FileDependImp::writeDepend(const string& filename) {
|
|||
}
|
||||
}
|
||||
|
||||
inline std::vector<string> V3FileDependImp::getAllDeps() const {
|
||||
std::vector<string> V3FileDependImp::getAllDeps() const {
|
||||
std::vector<string> r;
|
||||
for (const auto& itr : m_filenameList) {
|
||||
if (!itr.target() && itr.exists()) r.push_back(itr.filename());
|
||||
|
|
@ -179,7 +179,7 @@ inline std::vector<string> V3FileDependImp::getAllDeps() const {
|
|||
return r;
|
||||
}
|
||||
|
||||
inline void V3FileDependImp::writeTimes(const string& filename, const string& cmdlineIn) {
|
||||
void V3FileDependImp::writeTimes(const string& filename, const string& cmdlineIn) {
|
||||
const std::unique_ptr<std::ofstream> ofp{V3File::new_ofstream(filename)};
|
||||
if (ofp->fail()) v3fatal("Can't write " << filename);
|
||||
|
||||
|
|
@ -214,7 +214,7 @@ inline void V3FileDependImp::writeTimes(const string& filename, const string& cm
|
|||
}
|
||||
}
|
||||
|
||||
inline bool V3FileDependImp::checkTimes(const string& filename, const string& cmdlineIn) {
|
||||
bool V3FileDependImp::checkTimes(const string& filename, const string& cmdlineIn) {
|
||||
const std::unique_ptr<std::ifstream> ifp{V3File::new_ifstream_nodepend(filename)};
|
||||
if (ifp->fail()) {
|
||||
UINFO(2, " --check-times failed: no input " << filename << endl);
|
||||
|
|
|
|||
20
src/V3File.h
20
src/V3File.h
|
|
@ -206,7 +206,7 @@ public:
|
|||
V3OutFile(V3OutFile&&) = delete;
|
||||
V3OutFile& operator=(V3OutFile&&) = delete;
|
||||
|
||||
virtual ~V3OutFile() override;
|
||||
~V3OutFile() override;
|
||||
void putsForceIncs();
|
||||
|
||||
private:
|
||||
|
|
@ -216,11 +216,11 @@ private:
|
|||
}
|
||||
|
||||
// CALLBACKS
|
||||
virtual void putcOutput(char chr) override {
|
||||
void putcOutput(char chr) override {
|
||||
m_bufferp->at(m_usedBytes++) = chr;
|
||||
if (VL_UNLIKELY(m_usedBytes >= WRITE_BUFFER_SIZE_BYTES)) writeBlock();
|
||||
}
|
||||
virtual void putsOutput(const char* str) override {
|
||||
void putsOutput(const char* str) override {
|
||||
std::size_t len = strlen(str);
|
||||
std::size_t availableBytes = WRITE_BUFFER_SIZE_BYTES - m_usedBytes;
|
||||
while (VL_UNLIKELY(len >= availableBytes)) {
|
||||
|
|
@ -246,7 +246,7 @@ public:
|
|||
: V3OutFile{filename, V3OutFormatter::LA_C} {
|
||||
resetPrivate();
|
||||
}
|
||||
virtual ~V3OutCFile() override = default;
|
||||
~V3OutCFile() override = default;
|
||||
virtual void putsHeader() { puts("// Verilated -*- C++ -*-\n"); }
|
||||
virtual void putsIntTopInclude() { putsForceIncs(); }
|
||||
virtual void putsGuard();
|
||||
|
|
@ -270,9 +270,9 @@ class V3OutScFile final : public V3OutCFile {
|
|||
public:
|
||||
explicit V3OutScFile(const string& filename)
|
||||
: V3OutCFile{filename} {}
|
||||
virtual ~V3OutScFile() override = default;
|
||||
virtual void putsHeader() override { puts("// Verilated -*- SystemC -*-\n"); }
|
||||
virtual void putsIntTopInclude() override {
|
||||
~V3OutScFile() override = default;
|
||||
void putsHeader() override { puts("// Verilated -*- SystemC -*-\n"); }
|
||||
void putsIntTopInclude() override {
|
||||
putsForceIncs();
|
||||
puts("#include \"systemc.h\"\n");
|
||||
puts("#include \"verilated_sc.h\"\n");
|
||||
|
|
@ -283,7 +283,7 @@ class V3OutVFile final : public V3OutFile {
|
|||
public:
|
||||
explicit V3OutVFile(const string& filename)
|
||||
: V3OutFile{filename, V3OutFormatter::LA_VERILOG} {}
|
||||
virtual ~V3OutVFile() override = default;
|
||||
~V3OutVFile() override = default;
|
||||
virtual void putsHeader() { puts("// Verilated -*- Verilog -*-\n"); }
|
||||
};
|
||||
|
||||
|
|
@ -293,7 +293,7 @@ public:
|
|||
: V3OutFile{filename, V3OutFormatter::LA_XML} {
|
||||
blockIndent(2);
|
||||
}
|
||||
virtual ~V3OutXmlFile() override = default;
|
||||
~V3OutXmlFile() override = default;
|
||||
virtual void putsHeader() { puts("<?xml version=\"1.0\" ?>\n"); }
|
||||
};
|
||||
|
||||
|
|
@ -301,7 +301,7 @@ class V3OutMkFile final : public V3OutFile {
|
|||
public:
|
||||
explicit V3OutMkFile(const string& filename)
|
||||
: V3OutFile{filename, V3OutFormatter::LA_MK} {}
|
||||
virtual ~V3OutMkFile() override = default;
|
||||
~V3OutMkFile() override = default;
|
||||
virtual void putsHeader() { puts("# Verilated -*- Makefile -*-\n"); }
|
||||
// No automatic indentation yet.
|
||||
void puts(const char* strg) { putsNoTracking(strg); }
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ FileLine::FileLine(FileLine::EmptySecret) {
|
|||
|
||||
m_warnOn = 0;
|
||||
for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) {
|
||||
const V3ErrorCode code = V3ErrorCode(codei);
|
||||
const V3ErrorCode code{codei};
|
||||
warnOff(code, code.defaultsOff());
|
||||
}
|
||||
}
|
||||
|
|
@ -309,14 +309,14 @@ bool FileLine::warnOff(const string& msg, bool flag) {
|
|||
|
||||
void FileLine::warnLintOff(bool flag) {
|
||||
for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) {
|
||||
const V3ErrorCode code = V3ErrorCode(codei);
|
||||
const V3ErrorCode code{codei};
|
||||
if (code.lintError()) warnOff(code, flag);
|
||||
}
|
||||
}
|
||||
|
||||
void FileLine::warnStyleOff(bool flag) {
|
||||
for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) {
|
||||
const V3ErrorCode code = V3ErrorCode(codei);
|
||||
const V3ErrorCode code{codei};
|
||||
if (code.styleError()) warnOff(code, flag);
|
||||
}
|
||||
}
|
||||
|
|
@ -333,7 +333,7 @@ bool FileLine::warnIsOff(V3ErrorCode code) const {
|
|||
void FileLine::modifyStateInherit(const FileLine* fromp) {
|
||||
// Any warnings that are off in "from", become off in "this".
|
||||
for (int codei = V3ErrorCode::EC_MIN; codei < V3ErrorCode::_ENUM_MAX; codei++) {
|
||||
const V3ErrorCode code = V3ErrorCode(codei);
|
||||
const V3ErrorCode code{codei};
|
||||
if (fromp->warnIsOff(code)) warnOff(code, true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -249,7 +249,11 @@ public:
|
|||
|
||||
// OPERATORS
|
||||
void v3errorEnd(std::ostringstream& str, const string& extra = "");
|
||||
void v3errorEndFatal(std::ostringstream& str) VL_ATTR_NORETURN;
|
||||
void v3errorEndFatal(std::ostringstream& str) VL_ATTR_NORETURN {
|
||||
v3errorEnd(str);
|
||||
assert(0); // LCOV_EXCL_LINE
|
||||
VL_UNREACHABLE
|
||||
}
|
||||
/// When building an error, prefix for printing continuation lines
|
||||
/// e.g. information referring to the same FileLine as before
|
||||
string warnMore() const;
|
||||
|
|
@ -288,10 +292,4 @@ private:
|
|||
};
|
||||
std::ostream& operator<<(std::ostream& os, FileLine* fileline);
|
||||
|
||||
inline void FileLine::v3errorEndFatal(std::ostringstream& str) {
|
||||
v3errorEnd(str);
|
||||
assert(0); // LCOV_EXCL_LINE
|
||||
VL_UNREACHABLE
|
||||
}
|
||||
|
||||
#endif // Guard
|
||||
|
|
|
|||
158
src/V3Gate.cpp
158
src/V3Gate.cpp
|
|
@ -62,8 +62,8 @@ public:
|
|||
explicit GateGraphBaseVisitor(V3Graph* graphp)
|
||||
: m_graphp{graphp} {}
|
||||
virtual ~GateGraphBaseVisitor() = default;
|
||||
virtual VNUser visit(GateLogicVertex* vertexp, VNUser vu = VNUser(0)) = 0;
|
||||
virtual VNUser visit(GateVarVertex* vertexp, VNUser vu = VNUser(0)) = 0;
|
||||
virtual VNUser visit(GateLogicVertex* vertexp, VNUser vu = VNUser{0}) = 0;
|
||||
virtual VNUser visit(GateVarVertex* vertexp, VNUser vu = VNUser{0}) = 0;
|
||||
VL_DEBUG_FUNC; // Declare debug()
|
||||
};
|
||||
|
||||
|
|
@ -79,9 +79,9 @@ public:
|
|||
GateEitherVertex(V3Graph* graphp, AstScope* scopep)
|
||||
: V3GraphVertex{graphp}
|
||||
, m_scopep{scopep} {}
|
||||
virtual ~GateEitherVertex() override = default;
|
||||
~GateEitherVertex() override = default;
|
||||
// ACCESSORS
|
||||
virtual string dotStyle() const override { return m_consumed ? "" : "dotted"; }
|
||||
string dotStyle() const override { return m_consumed ? "" : "dotted"; }
|
||||
AstScope* scopep() const { return m_scopep; }
|
||||
bool reducible() const { return m_reducible; }
|
||||
bool dedupable() const { return m_dedupable; }
|
||||
|
|
@ -102,10 +102,10 @@ public:
|
|||
clearReducible(nonReducibleReason);
|
||||
clearDedupable(nonReducibleReason);
|
||||
}
|
||||
virtual VNUser accept(GateGraphBaseVisitor& v, VNUser vu = VNUser(0)) = 0;
|
||||
virtual VNUser accept(GateGraphBaseVisitor& v, VNUser vu = VNUser{0}) = 0;
|
||||
// Returns only the result from the LAST vertex iterated over
|
||||
VNUser iterateInEdges(GateGraphBaseVisitor& v, VNUser vu = VNUser(0)) {
|
||||
VNUser ret = VNUser(0);
|
||||
VNUser iterateInEdges(GateGraphBaseVisitor& v, VNUser vu = VNUser{0}) {
|
||||
VNUser ret{0};
|
||||
for (V3GraphEdge* edgep = inBeginp(); edgep; edgep = edgep->inNextp()) {
|
||||
ret = static_cast<GateEitherVertex*>(edgep->fromp())->accept(v, vu);
|
||||
}
|
||||
|
|
@ -115,8 +115,8 @@ public:
|
|||
// Note: This behaves differently than iterateInEdges() in that it will traverse
|
||||
// all edges that exist when it is initially called, whereas
|
||||
// iterateInEdges() will stop traversing edges if one is deleted
|
||||
VNUser iterateCurrentOutEdges(GateGraphBaseVisitor& v, VNUser vu = VNUser(0)) {
|
||||
VNUser ret = VNUser(0);
|
||||
VNUser iterateCurrentOutEdges(GateGraphBaseVisitor& v, VNUser vu = VNUser{0}) {
|
||||
VNUser ret{0};
|
||||
V3GraphEdge* next_edgep = nullptr;
|
||||
for (V3GraphEdge* edgep = outBeginp(); edgep; edgep = next_edgep) {
|
||||
// Need to find the next edge before visiting in case the edge is deleted
|
||||
|
|
@ -137,11 +137,11 @@ public:
|
|||
GateVarVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
|
||||
: GateEitherVertex{graphp, scopep}
|
||||
, m_varScp{varScp} {}
|
||||
virtual ~GateVarVertex() override = default;
|
||||
~GateVarVertex() override = default;
|
||||
// ACCESSORS
|
||||
AstVarScope* varScp() const { return m_varScp; }
|
||||
virtual string name() const override { return (cvtToHex(m_varScp) + " " + varScp()->name()); }
|
||||
virtual string dotColor() const override { return "blue"; }
|
||||
string name() const override { return (cvtToHex(m_varScp) + " " + varScp()->name()); }
|
||||
string dotColor() const override { return "blue"; }
|
||||
bool isTop() const { return m_isTop; }
|
||||
void setIsTop() { m_isTop = true; }
|
||||
bool isClock() const { return m_isClock; }
|
||||
|
|
@ -162,7 +162,7 @@ public:
|
|||
setIsClock();
|
||||
}
|
||||
}
|
||||
virtual VNUser accept(GateGraphBaseVisitor& v, VNUser vu = VNUser(0)) override {
|
||||
VNUser accept(GateGraphBaseVisitor& v, VNUser vu = VNUser{0}) override {
|
||||
return v.visit(this, vu);
|
||||
}
|
||||
};
|
||||
|
|
@ -178,17 +178,15 @@ public:
|
|||
, m_nodep{nodep}
|
||||
, m_activep{activep}
|
||||
, m_slow{slow} {}
|
||||
virtual ~GateLogicVertex() override = default;
|
||||
~GateLogicVertex() override = default;
|
||||
// ACCESSORS
|
||||
virtual string name() const override {
|
||||
return (cvtToHex(m_nodep) + "@" + scopep()->prettyName());
|
||||
}
|
||||
virtual string dotColor() const override { return "purple"; }
|
||||
virtual FileLine* fileline() const override { return nodep()->fileline(); }
|
||||
string name() const override { return (cvtToHex(m_nodep) + "@" + scopep()->prettyName()); }
|
||||
string dotColor() const override { return "purple"; }
|
||||
FileLine* fileline() const override { return nodep()->fileline(); }
|
||||
AstNode* nodep() const { return m_nodep; }
|
||||
AstActive* activep() const { return m_activep; }
|
||||
bool slow() const { return m_slow; }
|
||||
virtual VNUser accept(GateGraphBaseVisitor& v, VNUser vu = VNUser(0)) override {
|
||||
VNUser accept(GateGraphBaseVisitor& v, VNUser vu = VNUser{0}) override {
|
||||
return v.visit(this, vu);
|
||||
}
|
||||
};
|
||||
|
|
@ -217,7 +215,7 @@ private:
|
|||
}
|
||||
}
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeVarRef* nodep) override {
|
||||
void visit(AstNodeVarRef* nodep) override {
|
||||
++m_ops;
|
||||
iterateChildren(nodep);
|
||||
// We only allow a LHS ref for the var being set, and a RHS ref for
|
||||
|
|
@ -243,7 +241,7 @@ private:
|
|||
m_rhsVarRefs.push_back(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeAssign* nodep) override {
|
||||
void visit(AstNodeAssign* nodep) override {
|
||||
m_substTreep = nodep->rhsp();
|
||||
if (!VN_IS(nodep->lhsp(), NodeVarRef)) {
|
||||
clearSimple("ASSIGN(non-VARREF)");
|
||||
|
|
@ -266,7 +264,7 @@ private:
|
|||
}
|
||||
}
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
// *** Special iterator
|
||||
if (!m_isSimple) return; // Fastpath
|
||||
if (++m_ops > v3Global.opt.gateStmts()) clearSimple("--gate-stmts exceeded");
|
||||
|
|
@ -296,7 +294,7 @@ public:
|
|||
}
|
||||
if (debug() >= 9 && !m_isSimple) nodep->dumpTree(cout, " gate!Ok: ");
|
||||
}
|
||||
virtual ~GateOkVisitor() override = default;
|
||||
~GateOkVisitor() override = default;
|
||||
// PUBLIC METHODS
|
||||
bool isSimple() const { return m_isSimple; }
|
||||
AstNode* substTree() const { return m_substTreep; }
|
||||
|
|
@ -423,7 +421,7 @@ private:
|
|||
void decomposeClkVectors();
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep) override {
|
||||
void visit(AstNetlist* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
// if (debug() > 6) m_graph.dump();
|
||||
if (debug() > 6) m_graph.dumpDotFilePrefixed("gate_pre");
|
||||
|
|
@ -455,7 +453,7 @@ private:
|
|||
// Rewrite assignments
|
||||
consumedMove();
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
VL_RESTORER(m_modp);
|
||||
{
|
||||
m_modp = nodep;
|
||||
|
|
@ -463,14 +461,14 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstScope* nodep) override {
|
||||
void visit(AstScope* nodep) override {
|
||||
UINFO(4, " SCOPE " << nodep << endl);
|
||||
m_scopep = nodep;
|
||||
m_logicVertexp = nullptr;
|
||||
iterateChildren(nodep);
|
||||
m_scopep = nullptr;
|
||||
}
|
||||
virtual void visit(AstActive* nodep) override {
|
||||
void visit(AstActive* nodep) override {
|
||||
// Create required blocks and add to module
|
||||
UINFO(4, " BLOCK " << nodep << endl);
|
||||
m_activeReducible = !(nodep->hasClocked()); // Seq logic outputs aren't reducible
|
||||
|
|
@ -481,7 +479,7 @@ private:
|
|||
m_activep = nullptr;
|
||||
m_activeReducible = true;
|
||||
}
|
||||
virtual void visit(AstNodeVarRef* nodep) override {
|
||||
void visit(AstNodeVarRef* nodep) override {
|
||||
if (m_scopep) {
|
||||
UASSERT_OBJ(m_logicVertexp, nodep, "Var ref not under a logic block");
|
||||
AstVarScope* const varscp = nodep->varScopep();
|
||||
|
|
@ -509,17 +507,17 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstAlwaysPublic* nodep) override {
|
||||
void visit(AstAlwaysPublic* nodep) override {
|
||||
VL_RESTORER(m_inSlow);
|
||||
{
|
||||
m_inSlow = true;
|
||||
iterateNewStmt(nodep, "AlwaysPublic", nullptr);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
iterateNewStmt(nodep, "User C Function", "User C Function");
|
||||
}
|
||||
virtual void visit(AstSenItem* nodep) override {
|
||||
void visit(AstSenItem* nodep) override {
|
||||
m_inSenItem = true;
|
||||
if (m_logicVertexp) { // Already under logic; presumably a SenGate
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -528,7 +526,7 @@ private:
|
|||
}
|
||||
m_inSenItem = false;
|
||||
}
|
||||
virtual void visit(AstNodeProcedure* nodep) override {
|
||||
void visit(AstNodeProcedure* nodep) override {
|
||||
VL_RESTORER(m_inSlow);
|
||||
{
|
||||
m_inSlow = VN_IS(nodep, Initial) || VN_IS(nodep, Final);
|
||||
|
|
@ -536,23 +534,23 @@ private:
|
|||
nullptr);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstAssignAlias* nodep) override { //
|
||||
void visit(AstAssignAlias* nodep) override { //
|
||||
iterateNewStmt(nodep, nullptr, nullptr);
|
||||
}
|
||||
virtual void visit(AstAssignW* nodep) override { //
|
||||
void visit(AstAssignW* nodep) override { //
|
||||
iterateNewStmt(nodep, nullptr, nullptr);
|
||||
}
|
||||
virtual void visit(AstCoverToggle* nodep) override {
|
||||
void visit(AstCoverToggle* nodep) override {
|
||||
iterateNewStmt(nodep, "CoverToggle", "CoverToggle");
|
||||
}
|
||||
virtual void visit(AstTraceDecl* nodep) override {
|
||||
void visit(AstTraceDecl* nodep) override {
|
||||
VL_RESTORER(m_inSlow);
|
||||
{
|
||||
m_inSlow = true;
|
||||
iterateNewStmt(nodep, "Tracing", "Tracing");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstConcat* nodep) override {
|
||||
void visit(AstConcat* nodep) override {
|
||||
UASSERT_OBJ(!(VN_IS(nodep->backp(), NodeAssign)
|
||||
&& VN_AS(nodep->backp(), NodeAssign)->lhsp() == nodep),
|
||||
nodep, "Concat on LHS of assignment; V3Const should have deleted it");
|
||||
|
|
@ -560,7 +558,7 @@ private:
|
|||
}
|
||||
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (nodep->isOutputter() && m_logicVertexp) m_logicVertexp->setConsumed("outputter");
|
||||
checkTimingControl(nodep);
|
||||
|
|
@ -569,7 +567,7 @@ private:
|
|||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit GateVisitor(AstNode* nodep) { iterate(nodep); }
|
||||
virtual ~GateVisitor() override {
|
||||
~GateVisitor() override {
|
||||
V3Stats::addStat("Optimizations, Gate sigs deleted", m_statSigs);
|
||||
V3Stats::addStat("Optimizations, Gate inputs replaced", m_statRefs);
|
||||
V3Stats::addStat("Optimizations, Gate sigs deduped", m_statDedupLogic);
|
||||
|
|
@ -821,7 +819,7 @@ private:
|
|||
|
||||
public:
|
||||
GateDedupeHash() = default;
|
||||
virtual ~GateDedupeHash() override {
|
||||
~GateDedupeHash() override {
|
||||
if (v3Global.opt.debugCheck()) check();
|
||||
}
|
||||
|
||||
|
|
@ -847,7 +845,7 @@ public:
|
|||
}
|
||||
|
||||
// Callback from V3DupFinder::findDuplicate
|
||||
virtual bool isSame(AstNode* node1p, AstNode* node2p) override {
|
||||
bool isSame(AstNode* node1p, AstNode* node2p) override {
|
||||
// Assignment may have been hashReplaced, if so consider non-match (effectively removed)
|
||||
if (isReplaced(node1p) || isReplaced(node2p)) {
|
||||
// UINFO(9, "isSame hit on replaced "<<(void*)node1p<<" "<<(void*)node2p<<endl);
|
||||
|
|
@ -919,7 +917,7 @@ private:
|
|||
bool m_dedupable = true; // Determined the assign to be dedupable
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeAssign* assignp) override {
|
||||
void visit(AstNodeAssign* assignp) override {
|
||||
if (m_dedupable) {
|
||||
// I think we could safely dedupe an always block with multiple
|
||||
// non-blocking statements, but erring on side of caution here
|
||||
|
|
@ -930,7 +928,7 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstAlways* alwaysp) override {
|
||||
void visit(AstAlways* alwaysp) override {
|
||||
if (m_dedupable) {
|
||||
if (!m_always) {
|
||||
m_always = true;
|
||||
|
|
@ -944,7 +942,7 @@ private:
|
|||
// always @(...)
|
||||
// if (...)
|
||||
// foo = ...; // or foo <= ...;
|
||||
virtual void visit(AstNodeIf* ifp) override {
|
||||
void visit(AstNodeIf* ifp) override {
|
||||
if (m_dedupable) {
|
||||
if (m_always && !m_ifCondp && !ifp->elsesp()) {
|
||||
// we're under an always, this is the first IF, and there's no else
|
||||
|
|
@ -956,16 +954,16 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstComment*) override {} // NOP
|
||||
void visit(AstComment*) override {} // NOP
|
||||
//--------------------
|
||||
virtual void visit(AstNode*) override { //
|
||||
void visit(AstNode*) override { //
|
||||
m_dedupable = false;
|
||||
}
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
GateDedupeVarVisitor() = default;
|
||||
virtual ~GateDedupeVarVisitor() override = default;
|
||||
~GateDedupeVarVisitor() override = default;
|
||||
// PUBLIC METHODS
|
||||
AstNodeVarRef* findDupe(AstNode* nodep, AstVarScope* consumerVarScopep, AstActive* activep) {
|
||||
m_assignp = nullptr;
|
||||
|
|
@ -1054,17 +1052,17 @@ private:
|
|||
GateDedupeVarVisitor m_varVisitor; // Looks for a dupe of the logic
|
||||
int m_depth = 0; // Iteration depth
|
||||
|
||||
virtual VNUser visit(GateVarVertex* vvertexp, VNUser) override {
|
||||
VNUser visit(GateVarVertex* vvertexp, VNUser) override {
|
||||
// Check that we haven't been here before
|
||||
if (m_depth > GATE_DEDUP_MAX_DEPTH)
|
||||
return VNUser(0); // Break loops; before user2 set so hit this vertex later
|
||||
if (vvertexp->varScp()->user2()) return VNUser(0);
|
||||
return VNUser{0}; // Break loops; before user2 set so hit this vertex later
|
||||
if (vvertexp->varScp()->user2()) return VNUser{0};
|
||||
vvertexp->varScp()->user2(true);
|
||||
|
||||
m_depth++;
|
||||
if (vvertexp->inSize1()) {
|
||||
AstNodeVarRef* const dupVarRefp = static_cast<AstNodeVarRef*>(
|
||||
vvertexp->iterateInEdges(*this, VNUser(vvertexp)).toNodep());
|
||||
vvertexp->iterateInEdges(*this, VNUser{vvertexp}).toNodep());
|
||||
if (dupVarRefp) { // visit(GateLogicVertex*...) returned match
|
||||
const V3GraphEdge* edgep = vvertexp->inBeginp();
|
||||
GateLogicVertex* const lvertexp = static_cast<GateLogicVertex*>(edgep->fromp());
|
||||
|
|
@ -1111,12 +1109,12 @@ private:
|
|||
}
|
||||
}
|
||||
m_depth--;
|
||||
return VNUser(0);
|
||||
return VNUser{0};
|
||||
}
|
||||
|
||||
// Given iterated logic, starting at vu which was consumer's GateVarVertex
|
||||
// Returns a varref that has the same logic input; or nullptr if none
|
||||
virtual VNUser visit(GateLogicVertex* lvertexp, VNUser vu) override {
|
||||
VNUser visit(GateLogicVertex* lvertexp, VNUser vu) override {
|
||||
lvertexp->iterateInEdges(*this);
|
||||
|
||||
const GateVarVertex* const consumerVvertexpp
|
||||
|
|
@ -1129,9 +1127,9 @@ private:
|
|||
// different generated clocks will never compare as equal, even if the
|
||||
// generated clocks are deduped into one clock.
|
||||
AstActive* const activep = lvertexp->activep();
|
||||
return VNUser(m_varVisitor.findDupe(nodep, consumerVarScopep, activep));
|
||||
return VNUser{m_varVisitor.findDupe(nodep, consumerVarScopep, activep)};
|
||||
}
|
||||
return VNUser(0);
|
||||
return VNUser{0};
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
@ -1196,7 +1194,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual VNUser visit(GateVarVertex* vvertexp, VNUser) override {
|
||||
VNUser visit(GateVarVertex* vvertexp, VNUser) override {
|
||||
for (V3GraphEdge* edgep = vvertexp->inBeginp(); edgep;) {
|
||||
V3GraphEdge* oldedgep = edgep;
|
||||
edgep = edgep->inNextp(); // for recursive since the edge could be deleted
|
||||
|
|
@ -1268,10 +1266,10 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
return VNUser(0);
|
||||
return VNUser{0};
|
||||
}
|
||||
virtual VNUser visit(GateLogicVertex*, VNUser) override { //
|
||||
return VNUser(0);
|
||||
VNUser visit(GateLogicVertex*, VNUser) override { //
|
||||
return VNUser{0};
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
@ -1308,7 +1306,7 @@ private:
|
|||
bool m_found = false; // Offset found
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeVarRef* nodep) override {
|
||||
void visit(AstNodeVarRef* nodep) override {
|
||||
UINFO(9, "CLK DECOMP Concat search var (off = " << m_offset << ") - " << nodep << endl);
|
||||
if (nodep->varScopep() == m_vscp && !nodep->user2() && !m_found) {
|
||||
// A concatenation may use the same var multiple times
|
||||
|
|
@ -1320,18 +1318,18 @@ private:
|
|||
}
|
||||
m_offset += nodep->dtypep()->width();
|
||||
}
|
||||
virtual void visit(AstConcat* nodep) override {
|
||||
void visit(AstConcat* nodep) override {
|
||||
UINFO(9, "CLK DECOMP Concat search (off = " << m_offset << ") - " << nodep << endl);
|
||||
iterate(nodep->rhsp());
|
||||
iterate(nodep->lhsp());
|
||||
}
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
GateConcatVisitor() = default;
|
||||
virtual ~GateConcatVisitor() override = default;
|
||||
~GateConcatVisitor() override = default;
|
||||
// PUBLIC METHODS
|
||||
bool concatOffset(AstConcat* concatp, AstVarScope* vscp, int& offsetr) {
|
||||
m_vscp = vscp;
|
||||
|
|
@ -1371,10 +1369,10 @@ private:
|
|||
int m_total_seen_clk_vectors = 0;
|
||||
int m_total_decomposed_clk_vectors = 0;
|
||||
|
||||
virtual VNUser visit(GateVarVertex* vvertexp, VNUser vu) override {
|
||||
VNUser visit(GateVarVertex* vvertexp, VNUser vu) override {
|
||||
// Check that we haven't been here before
|
||||
AstVarScope* const vsp = vvertexp->varScp();
|
||||
if (vsp->user2SetOnce()) return VNUser(0);
|
||||
if (vsp->user2SetOnce()) return VNUser{0};
|
||||
UINFO(9, "CLK DECOMP Var - " << vvertexp << " : " << vsp << endl);
|
||||
if (vsp->varp()->width() > 1) {
|
||||
m_seen_clk_vectors++;
|
||||
|
|
@ -1382,13 +1380,13 @@ private:
|
|||
}
|
||||
const GateClkDecompState* const currState = reinterpret_cast<GateClkDecompState*>(vu.c());
|
||||
GateClkDecompState nextState(currState->m_offset, vsp);
|
||||
vvertexp->iterateCurrentOutEdges(*this, VNUser(&nextState));
|
||||
vvertexp->iterateCurrentOutEdges(*this, VNUser{&nextState});
|
||||
if (vsp->varp()->width() > 1) --m_seen_clk_vectors;
|
||||
vsp->user2(false);
|
||||
return VNUser(0); // Unused
|
||||
return VNUser{0}; // Unused
|
||||
}
|
||||
|
||||
virtual VNUser visit(GateLogicVertex* lvertexp, VNUser vu) override {
|
||||
VNUser visit(GateLogicVertex* lvertexp, VNUser vu) override {
|
||||
const GateClkDecompState* const currState = reinterpret_cast<GateClkDecompState*>(vu.c());
|
||||
int clk_offset = currState->m_offset;
|
||||
if (const AstAssignW* const assignp = VN_CAST(lvertexp->nodep(), AssignW)) {
|
||||
|
|
@ -1401,37 +1399,37 @@ private:
|
|||
UINFO(9, "CLK DECOMP Sel [ " << rselp->msbConst() << " : "
|
||||
<< rselp->lsbConst() << " ] dropped clock ("
|
||||
<< clk_offset << ")" << endl);
|
||||
return VNUser(0);
|
||||
return VNUser{0};
|
||||
}
|
||||
clk_offset -= rselp->lsbConst();
|
||||
} else {
|
||||
return VNUser(0);
|
||||
return VNUser{0};
|
||||
}
|
||||
} else if (AstConcat* const catp = VN_CAST(assignp->rhsp(), Concat)) {
|
||||
UINFO(9, "CLK DECOMP Concat searching - " << assignp->lhsp() << endl);
|
||||
int concat_offset;
|
||||
if (!m_concat_visitor.concatOffset(catp, currState->m_last_vsp,
|
||||
concat_offset /*ref*/)) {
|
||||
return VNUser(0);
|
||||
return VNUser{0};
|
||||
}
|
||||
clk_offset += concat_offset;
|
||||
} else if (VN_IS(assignp->rhsp(), VarRef)) {
|
||||
UINFO(9, "CLK DECOMP VarRef searching - " << assignp->lhsp() << endl);
|
||||
} else {
|
||||
return VNUser(0);
|
||||
return VNUser{0};
|
||||
}
|
||||
// LHS
|
||||
if (const AstSel* const lselp = VN_CAST(assignp->lhsp(), Sel)) {
|
||||
if (VN_IS(lselp->lsbp(), Const) && VN_IS(lselp->widthp(), Const)) {
|
||||
clk_offset += lselp->lsbConst();
|
||||
} else {
|
||||
return VNUser(0);
|
||||
return VNUser{0};
|
||||
}
|
||||
} else if (const AstVarRef* const vrp = VN_CAST(assignp->lhsp(), VarRef)) {
|
||||
if (vrp->dtypep()->width() == 1 && m_seen_clk_vectors) {
|
||||
if (clk_offset != 0) {
|
||||
UINFO(9, "Should only make it here with clk_offset = 0" << endl);
|
||||
return VNUser(0);
|
||||
return VNUser{0};
|
||||
}
|
||||
UINFO(9, "CLK DECOMP Connecting - " << assignp->lhsp() << endl);
|
||||
UINFO(9, " to - " << m_clk_vsp << endl);
|
||||
|
|
@ -1444,18 +1442,18 @@ private:
|
|||
m_total_decomposed_clk_vectors++;
|
||||
}
|
||||
} else {
|
||||
return VNUser(0);
|
||||
return VNUser{0};
|
||||
}
|
||||
GateClkDecompState nextState(clk_offset, currState->m_last_vsp);
|
||||
return lvertexp->iterateCurrentOutEdges(*this, VNUser(&nextState));
|
||||
return lvertexp->iterateCurrentOutEdges(*this, VNUser{&nextState});
|
||||
}
|
||||
return VNUser(0);
|
||||
return VNUser{0};
|
||||
}
|
||||
|
||||
public:
|
||||
explicit GateClkDecompGraphVisitor(V3Graph* graphp)
|
||||
: GateGraphBaseVisitor{graphp} {}
|
||||
virtual ~GateClkDecompGraphVisitor() override {
|
||||
~GateClkDecompGraphVisitor() override {
|
||||
V3Stats::addStat("Optimizations, Clocker seen vectors", m_total_seen_clk_vectors);
|
||||
V3Stats::addStat("Optimizations, Clocker decomposed vectors",
|
||||
m_total_decomposed_clk_vectors);
|
||||
|
|
@ -1466,7 +1464,7 @@ public:
|
|||
m_clk_vsp = vvertexp->varScp();
|
||||
m_clk_vvertexp = vvertexp;
|
||||
GateClkDecompState nextState(0, m_clk_vsp);
|
||||
vvertexp->accept(*this, VNUser(&nextState));
|
||||
vvertexp->accept(*this, VNUser{&nextState});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,225 @@
|
|||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Generated Clock repairs
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
||||
// can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
//
|
||||
//*************************************************************************
|
||||
// GENCLK TRANSFORMATIONS:
|
||||
// Follow control-flow graph with assignments and var usages
|
||||
// ASSIGNDLY to variable later used as clock requires change detect
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include "V3GenClk.h"
|
||||
|
||||
#include "V3Ast.h"
|
||||
#include "V3Global.h"
|
||||
|
||||
//######################################################################
|
||||
// GenClk state, as a visitor of each AstNode
|
||||
|
||||
class GenClkBaseVisitor VL_NOT_FINAL : public VNVisitor {
|
||||
protected:
|
||||
VL_DEBUG_FUNC; // Declare debug()
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// GenClk Read
|
||||
|
||||
class GenClkRenameVisitor final : public GenClkBaseVisitor {
|
||||
private:
|
||||
// NODE STATE
|
||||
// Cleared on top scope
|
||||
// AstVarScope::user2() -> AstVarScope*. Signal replacing activation with
|
||||
// AstVarRef::user3() -> bool. Signal is replaced activation (already done)
|
||||
const VNUser2InUse m_inuser2;
|
||||
const VNUser3InUse m_inuser3;
|
||||
|
||||
// STATE
|
||||
const AstActive* m_activep = nullptr; // Inside activate statement
|
||||
AstNodeModule* const m_topModp; // Top module
|
||||
AstScope* const m_scopetopp = v3Global.rootp()->topScopep()->scopep(); // The top AstScope
|
||||
|
||||
// METHODS
|
||||
AstVarScope* genInpClk(AstVarScope* vscp) {
|
||||
if (!vscp->user2p()) {
|
||||
// In order to create a __VinpClk* for a signal, it needs to be marked circular.
|
||||
// The DPI export trigger is never marked circular by V3Order (see comments in
|
||||
// OrderVisitor::nodeMarkCircular). The only other place where one might mark
|
||||
// a node circular is in this pass (V3GenClk), if the signal is assigned but was
|
||||
// previously used as a clock. The DPI export trigger is only ever assigned in
|
||||
// a DPI export called from outside eval, or from a DPI import, which are not
|
||||
// discovered by GenClkReadVisitor (note that impure tasks - i.e.: those setting
|
||||
// non-local variables - cannot be no-inline, see V3Task), hence the DPI export
|
||||
// trigger should never be marked circular. Note that ordering should still be
|
||||
// correct as there will be a change detect on any signals set from a DPI export
|
||||
// that might have dependents scheduled earlier.
|
||||
UASSERT_OBJ(vscp != v3Global.rootp()->dpiExportTriggerp(), vscp,
|
||||
"DPI export trigger should not need __VinpClk");
|
||||
AstVar* const varp = vscp->varp();
|
||||
const string newvarname
|
||||
= "__VinpClk__" + vscp->scopep()->nameDotless() + "__" + varp->name();
|
||||
// Create: VARREF(inpclk)
|
||||
// ...
|
||||
// ASSIGN(VARREF(inpclk), VARREF(var))
|
||||
AstVar* const newvarp
|
||||
= new AstVar(varp->fileline(), VVarType::MODULETEMP, newvarname, varp);
|
||||
m_topModp->addStmtp(newvarp);
|
||||
AstVarScope* const newvscp = new AstVarScope(vscp->fileline(), m_scopetopp, newvarp);
|
||||
m_scopetopp->addVarp(newvscp);
|
||||
AstAssign* const asninitp = new AstAssign(
|
||||
vscp->fileline(), new AstVarRef(vscp->fileline(), newvscp, VAccess::WRITE),
|
||||
new AstVarRef(vscp->fileline(), vscp, VAccess::READ));
|
||||
m_scopetopp->addFinalClkp(asninitp);
|
||||
//
|
||||
vscp->user2p(newvscp);
|
||||
}
|
||||
return VN_AS(vscp->user2p(), VarScope);
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
void visit(AstVarRef* nodep) override {
|
||||
// Consumption/generation of a variable,
|
||||
if (m_activep && !nodep->user3SetOnce()) {
|
||||
AstVarScope* const vscp = nodep->varScopep();
|
||||
if (vscp->isCircular()) {
|
||||
UINFO(8, " VarActReplace " << nodep << endl);
|
||||
// Replace with the new variable
|
||||
AstVarScope* const newvscp = genInpClk(vscp);
|
||||
AstVarRef* const newrefp
|
||||
= new AstVarRef(nodep->fileline(), newvscp, nodep->access());
|
||||
nodep->replaceWith(newrefp);
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
}
|
||||
}
|
||||
void visit(AstActive* nodep) override {
|
||||
m_activep = nodep;
|
||||
iterate(nodep->sensesp());
|
||||
m_activep = nullptr;
|
||||
}
|
||||
|
||||
//-----
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
GenClkRenameVisitor(AstTopScope* nodep, AstNodeModule* topModp)
|
||||
: m_topModp{topModp} {
|
||||
iterate(nodep);
|
||||
}
|
||||
~GenClkRenameVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// GenClk Read
|
||||
|
||||
class GenClkReadVisitor final : public GenClkBaseVisitor {
|
||||
private:
|
||||
// NODE STATE
|
||||
// Cleared on top scope
|
||||
// AstVarScope::user() -> bool. Set when the var has been used as clock
|
||||
|
||||
// STATE
|
||||
bool m_tracingCall = false; // Iterating into a call to a cfunc
|
||||
const AstActive* m_activep = nullptr; // Inside activate statement
|
||||
const AstNodeAssign* m_assignp = nullptr; // Inside assigndly statement
|
||||
AstNodeModule* m_topModp = nullptr; // Top module
|
||||
|
||||
// VISITORS
|
||||
void visit(AstTopScope* nodep) override {
|
||||
{
|
||||
const VNUser1InUse user1InUse;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
// Make the new clock signals and replace any activate references
|
||||
// See rename, it does some AstNode::userClearTree()'s
|
||||
GenClkRenameVisitor{nodep, m_topModp};
|
||||
}
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
// Only track the top scopes, not lower level functions
|
||||
if (nodep->isTop()) {
|
||||
m_topModp = nodep;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
void visit(AstNodeCCall* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (!nodep->funcp()->entryPoint()) {
|
||||
// Enter the function and trace it
|
||||
m_tracingCall = true;
|
||||
iterate(nodep->funcp());
|
||||
}
|
||||
}
|
||||
void visit(AstCFunc* nodep) override {
|
||||
if (!m_tracingCall && !nodep->entryPoint()) {
|
||||
// Only consider logic within a CFunc when looking
|
||||
// at the call to it, and not when scanning whatever
|
||||
// scope it happens to live beneath.
|
||||
return;
|
||||
}
|
||||
m_tracingCall = false;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
//----
|
||||
|
||||
void visit(AstVarRef* nodep) override {
|
||||
// Consumption/generation of a variable,
|
||||
AstVarScope* const vscp = nodep->varScopep();
|
||||
UASSERT_OBJ(vscp, nodep, "Scope not assigned");
|
||||
if (m_activep) {
|
||||
UINFO(8, " VarAct " << nodep << endl);
|
||||
vscp->user1(true);
|
||||
}
|
||||
if (m_assignp && nodep->access().isWriteOrRW() && vscp->user1()) {
|
||||
// Variable was previously used as a clock, and is now being set
|
||||
// Thus a unordered generated clock...
|
||||
UINFO(8, " VarSetAct " << nodep << endl);
|
||||
vscp->circular(true);
|
||||
}
|
||||
}
|
||||
void visit(AstNodeAssign* nodep) override {
|
||||
// UINFO(8, "ASS " << nodep << endl);
|
||||
m_assignp = nodep;
|
||||
iterateChildren(nodep);
|
||||
m_assignp = nullptr;
|
||||
}
|
||||
void visit(AstActive* nodep) override {
|
||||
UINFO(8, "ACTIVE " << nodep << endl);
|
||||
m_activep = nodep;
|
||||
UASSERT_OBJ(nodep->sensesp(), nodep, "Unlinked");
|
||||
iterate(nodep->sensesp());
|
||||
m_activep = nullptr;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
//-----
|
||||
void visit(AstVar*) override {} // Don't want varrefs under it
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit GenClkReadVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
~GenClkReadVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// GenClk class functions
|
||||
|
||||
void V3GenClk::genClkAll(AstNetlist* nodep) {
|
||||
UINFO(2, __FUNCTION__ << ": " << endl);
|
||||
{ GenClkReadVisitor{nodep}; } // Destruct before checking
|
||||
V3Global::dumpCheckGlobalTree("genclk", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||
}
|
||||
|
|
@ -54,12 +54,12 @@ public:
|
|||
// // an array dimension or loop bound.
|
||||
};
|
||||
enum en m_e;
|
||||
inline GraphWay()
|
||||
GraphWay()
|
||||
: m_e{FORWARD} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline constexpr GraphWay(en _e)
|
||||
constexpr GraphWay(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline constexpr GraphWay(int _e)
|
||||
explicit constexpr GraphWay(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
const char* ascii() const {
|
||||
|
|
|
|||
|
|
@ -42,13 +42,13 @@ public:
|
|||
GraphAcycVertex(V3Graph* graphp, V3GraphVertex* origVertexp)
|
||||
: V3GraphVertex{graphp}
|
||||
, m_origVertexp{origVertexp} {}
|
||||
virtual ~GraphAcycVertex() override = default;
|
||||
~GraphAcycVertex() override = default;
|
||||
V3GraphVertex* origVertexp() const { return m_origVertexp; }
|
||||
void setDelete() { m_deleted = true; }
|
||||
bool isDelete() const { return m_deleted; }
|
||||
virtual string name() const override { return m_origVertexp->name(); }
|
||||
virtual string dotColor() const override { return m_origVertexp->dotColor(); }
|
||||
virtual FileLine* fileline() const override { return m_origVertexp->fileline(); }
|
||||
string name() const override { return m_origVertexp->name(); }
|
||||
string dotColor() const override { return m_origVertexp->dotColor(); }
|
||||
FileLine* fileline() const override { return m_origVertexp->fileline(); }
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -67,11 +67,9 @@ public:
|
|||
GraphAcycEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight,
|
||||
bool cutable = false)
|
||||
: V3GraphEdge{graphp, fromp, top, weight, cutable} {}
|
||||
virtual ~GraphAcycEdge() override = default;
|
||||
~GraphAcycEdge() override = default;
|
||||
// yellow=we might still cut it, else oldEdge: yellowGreen=made uncutable, red=uncutable
|
||||
virtual string dotColor() const override {
|
||||
return (cutable() ? "yellow" : origEdgep()->dotColor());
|
||||
}
|
||||
string dotColor() const override { return (cutable() ? "yellow" : origEdgep()->dotColor()); }
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
|
@ -123,7 +121,7 @@ private:
|
|||
void placeTryEdge(V3GraphEdge* edgep);
|
||||
bool placeIterate(GraphAcycVertex* vertexp, uint32_t currentRank);
|
||||
|
||||
inline bool origFollowEdge(V3GraphEdge* edgep) {
|
||||
bool origFollowEdge(V3GraphEdge* edgep) {
|
||||
return (edgep->weight() && (m_origEdgeFuncp)(edgep));
|
||||
}
|
||||
V3GraphEdge* edgeFromEdge(V3GraphEdge* oldedgep, V3GraphVertex* fromp, V3GraphVertex* top) {
|
||||
|
|
|
|||
|
|
@ -38,9 +38,7 @@ protected:
|
|||
, m_edgeFuncp{edgeFuncp} {}
|
||||
~GraphAlg() = default;
|
||||
// METHODS
|
||||
inline bool followEdge(V3GraphEdge* edgep) {
|
||||
return (edgep->weight() && (m_edgeFuncp)(edgep));
|
||||
}
|
||||
bool followEdge(V3GraphEdge* edgep) { return (edgep->weight() && (m_edgeFuncp)(edgep)); }
|
||||
};
|
||||
|
||||
//============================================================================
|
||||
|
|
|
|||
|
|
@ -56,18 +56,18 @@ public:
|
|||
V3GraphTestVertex(V3Graph* graphp, const string& name)
|
||||
: V3GraphVertex{graphp}
|
||||
, m_name{name} {}
|
||||
virtual ~V3GraphTestVertex() override = default;
|
||||
~V3GraphTestVertex() override = default;
|
||||
// ACCESSORS
|
||||
virtual string name() const override { return m_name; }
|
||||
string name() const override { return m_name; }
|
||||
};
|
||||
|
||||
class V3GraphTestVarVertex final : public V3GraphTestVertex {
|
||||
public:
|
||||
V3GraphTestVarVertex(V3Graph* graphp, const string& name)
|
||||
: V3GraphTestVertex{graphp, name} {}
|
||||
virtual ~V3GraphTestVarVertex() override = default;
|
||||
~V3GraphTestVarVertex() override = default;
|
||||
// ACCESSORS
|
||||
virtual string dotColor() const override { return "blue"; }
|
||||
string dotColor() const override { return "blue"; }
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
@ -76,8 +76,8 @@ public:
|
|||
|
||||
class V3GraphTestStrong final : public V3GraphTest {
|
||||
public:
|
||||
virtual string name() override { return "strong"; }
|
||||
virtual void runTest() override {
|
||||
string name() override { return "strong"; }
|
||||
void runTest() override {
|
||||
V3Graph* gp = &m_graph;
|
||||
// Verify we break edges at a good point
|
||||
// A simple alg would make 3 breaks, below only requires b->i to break
|
||||
|
|
@ -114,8 +114,8 @@ public:
|
|||
|
||||
class V3GraphTestAcyc final : public V3GraphTest {
|
||||
public:
|
||||
virtual string name() override { return "acyc"; }
|
||||
virtual void runTest() override {
|
||||
string name() override { return "acyc"; }
|
||||
void runTest() override {
|
||||
V3Graph* gp = &m_graph;
|
||||
// Verify we break edges at a good point
|
||||
// A simple alg would make 3 breaks, below only requires b->i to break
|
||||
|
|
@ -142,8 +142,8 @@ public:
|
|||
|
||||
class V3GraphTestVars final : public V3GraphTest {
|
||||
public:
|
||||
virtual string name() override { return "vars"; }
|
||||
virtual void runTest() override {
|
||||
string name() override { return "vars"; }
|
||||
void runTest() override {
|
||||
V3Graph* gp = &m_graph;
|
||||
|
||||
V3GraphTestVertex* clk = new V3GraphTestVarVertex(gp, "$clk");
|
||||
|
|
@ -268,8 +268,8 @@ class V3GraphTestImport final : public V3GraphTest {
|
|||
#endif
|
||||
|
||||
public:
|
||||
virtual string name() override { return "import"; }
|
||||
virtual void runTest() override {
|
||||
string name() override { return "import"; }
|
||||
void runTest() override {
|
||||
V3Graph* const gp = &m_graph;
|
||||
dotImport();
|
||||
dump();
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
class V3Hash final {
|
||||
uint32_t m_value; // The 32-bit hash value.
|
||||
|
||||
inline static uint32_t combine(uint32_t a, uint32_t b) {
|
||||
static uint32_t combine(uint32_t a, uint32_t b) {
|
||||
return a ^ (b + 0x9e3779b9 + (a << 6) + (a >> 2));
|
||||
}
|
||||
|
||||
|
|
|
|||
154
src/V3Hasher.cpp
154
src/V3Hasher.cpp
|
|
@ -80,7 +80,7 @@ private:
|
|||
//------------------------------------------------------------
|
||||
// AstNode - Warns to help find missing cases
|
||||
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
#if VL_DEBUG
|
||||
UINFO(0, "%Warning: Hashing node as AstNode: " << nodep << endl);
|
||||
#endif
|
||||
|
|
@ -89,93 +89,93 @@ private:
|
|||
|
||||
//------------------------------------------------------------
|
||||
// AstNodeDType
|
||||
virtual void visit(AstNodeArrayDType* nodep) override {
|
||||
void visit(AstNodeArrayDType* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() {
|
||||
iterateNull(nodep->virtRefDTypep());
|
||||
m_hash += nodep->left();
|
||||
m_hash += nodep->right();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstNodeUOrStructDType* nodep) override {
|
||||
void visit(AstNodeUOrStructDType* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, false, [=]() { //
|
||||
m_hash += nodep->uniqueNum();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstParamTypeDType* nodep) override {
|
||||
void visit(AstParamTypeDType* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {
|
||||
m_hash += nodep->name();
|
||||
m_hash += nodep->varType();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstMemberDType* nodep) override {
|
||||
void visit(AstMemberDType* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->name();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstDefImplicitDType* nodep) override {
|
||||
void visit(AstDefImplicitDType* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->uniqueNum();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstAssocArrayDType* nodep) override {
|
||||
void visit(AstAssocArrayDType* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() {
|
||||
iterateNull(nodep->virtRefDTypep());
|
||||
iterateNull(nodep->virtRefDType2p());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstDynArrayDType* nodep) override {
|
||||
void visit(AstDynArrayDType* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { //
|
||||
iterateNull(nodep->virtRefDTypep());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstUnsizedArrayDType* nodep) override {
|
||||
void visit(AstUnsizedArrayDType* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { //
|
||||
iterateNull(nodep->virtRefDTypep());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstWildcardArrayDType* nodep) override {
|
||||
void visit(AstWildcardArrayDType* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { //
|
||||
iterateNull(nodep->virtRefDTypep());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstBasicDType* nodep) override {
|
||||
void visit(AstBasicDType* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() {
|
||||
m_hash += nodep->keyword();
|
||||
m_hash += nodep->nrange().left();
|
||||
m_hash += nodep->nrange().right();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstConstDType* nodep) override {
|
||||
void visit(AstConstDType* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
iterateNull(nodep->virtRefDTypep());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstClassRefDType* nodep) override {
|
||||
void visit(AstClassRefDType* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { //
|
||||
iterateNull(nodep->classp());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstIfaceRefDType* nodep) override {
|
||||
void visit(AstIfaceRefDType* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { //
|
||||
iterateNull(nodep->cellp());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstQueueDType* nodep) override {
|
||||
void visit(AstQueueDType* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { //
|
||||
iterateNull(nodep->virtRefDTypep());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstRefDType* nodep) override {
|
||||
void visit(AstRefDType* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() {
|
||||
m_hash += nodep->name();
|
||||
iterateNull(nodep->typedefp());
|
||||
iterateNull(nodep->refDTypep());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstVoidDType* nodep) override {
|
||||
void visit(AstVoidDType* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() {});
|
||||
}
|
||||
virtual void visit(AstEnumDType* nodep) override {
|
||||
void visit(AstEnumDType* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, false, [=]() { //
|
||||
m_hash += nodep->uniqueNum();
|
||||
});
|
||||
|
|
@ -183,23 +183,23 @@ private:
|
|||
|
||||
//------------------------------------------------------------
|
||||
// AstNodeMath
|
||||
virtual void visit(AstNodeMath* nodep) override {
|
||||
void visit(AstNodeMath* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {});
|
||||
}
|
||||
virtual void visit(AstConst* nodep) override {
|
||||
void visit(AstConst* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->num().toHash();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstNullCheck* nodep) override {
|
||||
void visit(AstNullCheck* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {});
|
||||
}
|
||||
virtual void visit(AstCCast* nodep) override {
|
||||
void visit(AstCCast* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->size();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {
|
||||
if (nodep->varScopep()) {
|
||||
iterateNull(nodep->varScopep());
|
||||
|
|
@ -209,28 +209,28 @@ private:
|
|||
}
|
||||
});
|
||||
}
|
||||
virtual void visit(AstVarXRef* nodep) override {
|
||||
void visit(AstVarXRef* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {
|
||||
iterateNull(nodep->varp());
|
||||
m_hash += nodep->dotted();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstMemberSel* nodep) override {
|
||||
void visit(AstMemberSel* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->name();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstFScanF* nodep) override {
|
||||
void visit(AstFScanF* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->text();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstSScanF* nodep) override {
|
||||
void visit(AstSScanF* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->text();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstAddrOfCFunc* nodep) override {
|
||||
void visit(AstAddrOfCFunc* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
iterateNull(nodep->funcp());
|
||||
});
|
||||
|
|
@ -238,61 +238,61 @@ private:
|
|||
|
||||
//------------------------------------------------------------
|
||||
// AstNodeStmt
|
||||
virtual void visit(AstNodeStmt* nodep) override {
|
||||
void visit(AstNodeStmt* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() {});
|
||||
}
|
||||
virtual void visit(AstNodeText* nodep) override {
|
||||
void visit(AstNodeText* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->text();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstNodeCCall* nodep) override {
|
||||
void visit(AstNodeCCall* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { //
|
||||
iterateNull(nodep->funcp());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstNodeFTaskRef* nodep) override {
|
||||
void visit(AstNodeFTaskRef* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() {
|
||||
iterateNull(nodep->taskp());
|
||||
iterateNull(nodep->classOrPackagep());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstCMethodHard* nodep) override {
|
||||
void visit(AstCMethodHard* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->name();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstCAwait* nodep) override {
|
||||
void visit(AstCAwait* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
iterateNull(nodep->sensesp());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstCoverInc* nodep) override {
|
||||
void visit(AstCoverInc* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { //
|
||||
iterateNull(nodep->declp());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstDisplay* nodep) override {
|
||||
void visit(AstDisplay* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->displayType();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstMonitorOff* nodep) override {
|
||||
void visit(AstMonitorOff* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->off();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstJumpGo* nodep) override {
|
||||
void visit(AstJumpGo* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { //
|
||||
iterateNull(nodep->labelp());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstTraceInc* nodep) override {
|
||||
void visit(AstTraceInc* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { //
|
||||
iterateNull(nodep->declp());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstNodeCoverOrAssert* nodep) override {
|
||||
void visit(AstNodeCoverOrAssert* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, false, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->name();
|
||||
});
|
||||
|
|
@ -300,62 +300,62 @@ private:
|
|||
|
||||
//------------------------------------------------------------
|
||||
// AstNode direct descendents
|
||||
virtual void visit(AstNodeRange* nodep) override {
|
||||
void visit(AstNodeRange* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {});
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, false, [=]() { //
|
||||
m_hash += nodep->origName();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstNodePreSel* nodep) override {
|
||||
void visit(AstNodePreSel* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {});
|
||||
}
|
||||
virtual void visit(AstClassExtends* nodep) override {
|
||||
void visit(AstClassExtends* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {});
|
||||
}
|
||||
virtual void visit(AstSelLoopVars* nodep) override {
|
||||
void visit(AstSelLoopVars* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {});
|
||||
}
|
||||
virtual void visit(AstDefParam* nodep) override {
|
||||
void visit(AstDefParam* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {});
|
||||
}
|
||||
virtual void visit(AstArg* nodep) override {
|
||||
void visit(AstArg* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {});
|
||||
}
|
||||
virtual void visit(AstParseRef* nodep) override {
|
||||
void visit(AstParseRef* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {
|
||||
m_hash += nodep->expect();
|
||||
m_hash += nodep->name();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstClassOrPackageRef* nodep) override {
|
||||
void visit(AstClassOrPackageRef* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
iterateNull(nodep->classOrPackageNodep());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstSenItem* nodep) override {
|
||||
void visit(AstSenItem* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->edgeType();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstSenTree* nodep) override {
|
||||
void visit(AstSenTree* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {});
|
||||
}
|
||||
virtual void visit(AstSFormatF* nodep) override {
|
||||
void visit(AstSFormatF* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->text();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstElabDisplay* nodep) override {
|
||||
void visit(AstElabDisplay* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->displayType();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstInitItem* nodep) override {
|
||||
void visit(AstInitItem* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {});
|
||||
}
|
||||
virtual void visit(AstInitArray* nodep) override {
|
||||
void visit(AstInitArray* nodep) override {
|
||||
if (const AstAssocArrayDType* const dtypep = VN_CAST(nodep->dtypep(), AssocArrayDType)) {
|
||||
if (nodep->defaultp()) {
|
||||
m_hash
|
||||
|
|
@ -381,22 +381,22 @@ private:
|
|||
});
|
||||
}
|
||||
}
|
||||
virtual void visit(AstPragma* nodep) override {
|
||||
void visit(AstPragma* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->pragType();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstAttrOf* nodep) override {
|
||||
void visit(AstAttrOf* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->attrType();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstNodeFile* nodep) override {
|
||||
void visit(AstNodeFile* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->name();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
// We might be in a recursive function, if so on *second* call
|
||||
// here we need to break what would be an infinite loop.
|
||||
|
|
@ -407,90 +407,90 @@ private:
|
|||
m_hash += nodep->isLoose();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
void visit(AstVar* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {
|
||||
m_hash += nodep->name();
|
||||
m_hash += nodep->varType();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstScope* nodep) override {
|
||||
void visit(AstScope* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, false, [=]() {
|
||||
m_hash += nodep->name();
|
||||
iterateNull(nodep->aboveScopep());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstVarScope* nodep) override {
|
||||
void visit(AstVarScope* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {
|
||||
iterateNull(nodep->varp());
|
||||
iterateNull(nodep->scopep());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstEnumItem* nodep) override {
|
||||
void visit(AstEnumItem* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->name();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstTypedef* nodep) override {
|
||||
void visit(AstTypedef* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->name();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstTypedefFwd* nodep) override {
|
||||
void visit(AstTypedefFwd* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->name();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstActive* nodep) override {
|
||||
void visit(AstActive* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
iterateNull(nodep->sensesp());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstCell* nodep) override {
|
||||
void visit(AstCell* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {
|
||||
m_hash += nodep->name();
|
||||
iterateNull(nodep->modp());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstCellInline* nodep) override {
|
||||
void visit(AstCellInline* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {
|
||||
m_hash += nodep->name();
|
||||
iterateNull(nodep->scopep());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstNodeFTask* nodep) override {
|
||||
void visit(AstNodeFTask* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->name();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstModport* nodep) override {
|
||||
void visit(AstModport* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->name();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstModportVarRef* nodep) override {
|
||||
void visit(AstModportVarRef* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {
|
||||
m_hash += nodep->name();
|
||||
iterateNull(nodep->varp());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstModportFTaskRef* nodep) override {
|
||||
void visit(AstModportFTaskRef* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {
|
||||
m_hash += nodep->name();
|
||||
iterateNull(nodep->ftaskp());
|
||||
});
|
||||
}
|
||||
virtual void visit(AstMTaskBody* nodep) override {
|
||||
void visit(AstMTaskBody* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {});
|
||||
}
|
||||
virtual void visit(AstNodeProcedure* nodep) override {
|
||||
void visit(AstNodeProcedure* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {});
|
||||
}
|
||||
virtual void visit(AstNodeBlock* nodep) override {
|
||||
void visit(AstNodeBlock* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() { //
|
||||
m_hash += nodep->name();
|
||||
});
|
||||
}
|
||||
virtual void visit(AstPin* nodep) override {
|
||||
void visit(AstPin* nodep) override {
|
||||
m_hash += hashNodeAndIterate(nodep, HASH_DTYPE, HASH_CHILDREN, [=]() {
|
||||
m_hash += nodep->name();
|
||||
m_hash += nodep->pinNum();
|
||||
|
|
@ -509,7 +509,7 @@ public:
|
|||
iterate(const_cast<AstNode*>(nodep));
|
||||
}
|
||||
V3Hash finalHash() const { return m_hash; }
|
||||
virtual ~HasherVisitor() override = default;
|
||||
~HasherVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -250,7 +250,7 @@ class HierBlockUsageCollectVisitor final : public VNVisitor {
|
|||
ModuleSet m_referred; // Modules that have hier_block pragma
|
||||
V3HierBlock::GParams m_gparams; // list of variables that is VVarType::GPARAM
|
||||
|
||||
virtual void visit(AstModule* nodep) override {
|
||||
void visit(AstModule* nodep) override {
|
||||
// Don't visit twice
|
||||
if (nodep->user1SetOnce()) return;
|
||||
UINFO(5, "Checking " << nodep->prettyNameQ() << " from "
|
||||
|
|
@ -277,7 +277,7 @@ class HierBlockUsageCollectVisitor final : public VNVisitor {
|
|||
}
|
||||
m_gparams = prevGParams;
|
||||
}
|
||||
virtual void visit(AstCell* nodep) override {
|
||||
void visit(AstCell* nodep) override {
|
||||
// Visit used module here to know that the module is hier_block or not.
|
||||
// This visitor behaves almost depth first search
|
||||
if (AstModule* const modp = VN_CAST(nodep->modp(), Module)) {
|
||||
|
|
@ -287,15 +287,15 @@ class HierBlockUsageCollectVisitor final : public VNVisitor {
|
|||
// Nothing to do for interface because hierarchical block does not exist
|
||||
// beyond interface.
|
||||
}
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
void visit(AstVar* nodep) override {
|
||||
if (m_modp && m_modp->hierBlock() && nodep->isIfaceRef() && !nodep->isIfaceParent()) {
|
||||
nodep->v3error("Modport cannot be used at the hierarchical block boundary");
|
||||
}
|
||||
if (nodep->isGParam() && nodep->overriddenParam()) m_gparams.push_back(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeMath*) override {} // Accelerate
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNodeMath*) override {} // Accelerate
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
HierBlockUsageCollectVisitor(V3HierBlockPlan* planp, AstNetlist* netlist)
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
UASSERT_OBJ(!m_modp, nodep, "Unsupported: Nested modules");
|
||||
m_modp = nodep;
|
||||
m_allMods.push_back(nodep);
|
||||
|
|
@ -130,19 +130,19 @@ private:
|
|||
iterateChildren(nodep);
|
||||
m_modp = nullptr;
|
||||
}
|
||||
virtual void visit(AstClass* nodep) override {
|
||||
void visit(AstClass* nodep) override {
|
||||
// TODO allow inlining of modules that have classes
|
||||
// (Probably wait for new inliner scheme)
|
||||
cantInline("class", true);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstCell* nodep) override {
|
||||
void visit(AstCell* nodep) override {
|
||||
m_moduleState(nodep->modp()).m_cellRefs++;
|
||||
m_moduleState(m_modp).m_childCells.push_back(nodep);
|
||||
m_instances[m_modp][nodep->modp()]++;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstPragma* nodep) override {
|
||||
void visit(AstPragma* nodep) override {
|
||||
if (nodep->pragType() == VPragmaType::INLINE_MODULE) {
|
||||
if (!m_modp) {
|
||||
nodep->v3error("Inline pragma not under a module"); // LCOV_EXCL_LINE
|
||||
|
|
@ -162,28 +162,28 @@ private:
|
|||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVarXRef* nodep) override {
|
||||
void visit(AstVarXRef* nodep) override {
|
||||
// Remove link. V3LinkDot will reestablish it after inlining.
|
||||
nodep->varp(nullptr);
|
||||
}
|
||||
virtual void visit(AstNodeFTaskRef* nodep) override {
|
||||
void visit(AstNodeFTaskRef* nodep) override {
|
||||
// Remove link. V3LinkDot will reestablish it after inlining.
|
||||
// MethodCalls not currently supported by inliner, so keep linked
|
||||
if (!nodep->classOrPackagep() && !VN_IS(nodep, MethodCall)) nodep->taskp(nullptr);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstAlways* nodep) override {
|
||||
void visit(AstAlways* nodep) override {
|
||||
m_modp->user4Inc(); // statement count
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeAssign* nodep) override {
|
||||
void visit(AstNodeAssign* nodep) override {
|
||||
// Don't count assignments, as they'll likely flatten out
|
||||
// Still need to iterate though to nullify VarXRefs
|
||||
const int oldcnt = m_modp->user4();
|
||||
iterateChildren(nodep);
|
||||
m_modp->user4(oldcnt);
|
||||
}
|
||||
virtual void visit(AstNetlist* nodep) override {
|
||||
void visit(AstNetlist* nodep) override {
|
||||
// Build ModuleState, user2, and user4 for all modules.
|
||||
// Also build m_allMods and m_instances.
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -226,7 +226,7 @@ private:
|
|||
}
|
||||
}
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
if (m_modp) m_modp->user4Inc(); // Inc statement count
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
|
@ -237,7 +237,7 @@ public:
|
|||
: m_moduleState{moduleState} {
|
||||
iterate(nodep);
|
||||
}
|
||||
virtual ~InlineMarkVisitor() override {
|
||||
~InlineMarkVisitor() override {
|
||||
V3Stats::addStat("Optimizations, Inline unsupported", m_statUnsup);
|
||||
}
|
||||
};
|
||||
|
|
@ -260,7 +260,7 @@ private:
|
|||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstCellInline* nodep) override {
|
||||
void visit(AstCellInline* nodep) override {
|
||||
// Inlined cell under the inline cell, need to move to avoid conflicts
|
||||
nodep->unlinkFrBack();
|
||||
m_modp->addInlinesp(nodep);
|
||||
|
|
@ -270,20 +270,20 @@ private:
|
|||
// Do CellInlines under this, but don't move them
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstCell* nodep) override {
|
||||
void visit(AstCell* nodep) override {
|
||||
// Cell under the inline cell, need to rename to avoid conflicts
|
||||
nodep->name(m_cellp->name() + "__DOT__" + nodep->name());
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstClass* nodep) override {
|
||||
void visit(AstClass* nodep) override {
|
||||
nodep->name(m_cellp->name() + "__DOT__" + nodep->name());
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstModule* nodep) override {
|
||||
void visit(AstModule* nodep) override {
|
||||
m_renamedInterfaces.clear();
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
void visit(AstVar* nodep) override {
|
||||
if (nodep->user2p()) {
|
||||
// Make an assignment, so we'll trace it properly
|
||||
// user2p is either a const or a var.
|
||||
|
|
@ -360,17 +360,17 @@ private:
|
|||
if (debug() >= 9) nodep->dumpTree(cout, "varchanged:");
|
||||
if (debug() >= 9 && nodep->valuep()) nodep->valuep()->dumpTree(cout, "varchangei:");
|
||||
}
|
||||
virtual void visit(AstNodeFTask* nodep) override {
|
||||
void visit(AstNodeFTask* nodep) override {
|
||||
// Function under the inline cell, need to rename to avoid conflicts
|
||||
nodep->name(m_cellp->name() + "__DOT__" + nodep->name());
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstTypedef* nodep) override {
|
||||
void visit(AstTypedef* nodep) override {
|
||||
// Typedef under the inline cell, need to rename to avoid conflicts
|
||||
nodep->name(m_cellp->name() + "__DOT__" + nodep->name());
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
if (nodep->varp()->user2p() // It's being converted to an alias.
|
||||
&& !nodep->varp()->user3()
|
||||
// Don't constant propagate aliases (we just made)
|
||||
|
|
@ -388,7 +388,7 @@ private:
|
|||
}
|
||||
nodep->name(nodep->varp()->name());
|
||||
}
|
||||
virtual void visit(AstVarXRef* nodep) override {
|
||||
void visit(AstVarXRef* nodep) override {
|
||||
// Track what scope it was originally under so V3LinkDot can resolve it
|
||||
nodep->inlinedDots(VString::dot(m_cellp->name(), ".", nodep->inlinedDots()));
|
||||
for (string tryname = nodep->dotted(); true;) {
|
||||
|
|
@ -406,7 +406,7 @@ private:
|
|||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeFTaskRef* nodep) override {
|
||||
void visit(AstNodeFTaskRef* nodep) override {
|
||||
// Track what scope it was originally under so V3LinkDot can resolve it
|
||||
nodep->inlinedDots(VString::dot(m_cellp->name(), ".", nodep->inlinedDots()));
|
||||
if (m_renamedInterfaces.count(nodep->dotted())) {
|
||||
|
|
@ -417,9 +417,9 @@ private:
|
|||
}
|
||||
|
||||
// Not needed, as V3LinkDot doesn't care about typedefs
|
||||
// virtual void visit(AstRefDType* nodep) override {}
|
||||
// void visit(AstRefDType* nodep) override {}
|
||||
|
||||
virtual void visit(AstScopeName* nodep) override {
|
||||
void visit(AstScopeName* nodep) override {
|
||||
// If there's a %m in the display text, we add a special node that will contain the name()
|
||||
// Similar code in V3Begin
|
||||
// To keep correct visual order, must add before other Text's
|
||||
|
|
@ -435,12 +435,12 @@ private:
|
|||
if (afterp) nodep->scopeEntrp(afterp);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstCoverDecl* nodep) override {
|
||||
void visit(AstCoverDecl* nodep) override {
|
||||
// Fix path in coverage statements
|
||||
nodep->hier(VString::dot(m_cellp->prettyName(), ".", nodep->hier()));
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
@ -449,7 +449,7 @@ public:
|
|||
, m_cellp{cellp} {
|
||||
iterate(cloneModp);
|
||||
}
|
||||
virtual ~InlineRelinkVisitor() override = default;
|
||||
~InlineRelinkVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
@ -576,13 +576,13 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep) override {
|
||||
void visit(AstNetlist* nodep) override {
|
||||
// Iterate modules backwards, in bottom-up order. Required!
|
||||
iterateAndNextConstNullBackwards(nodep->modulesp());
|
||||
// Clean up AstIfaceRefDType references
|
||||
iterateChildren(nodep->typeTablep());
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
UASSERT_OBJ(!m_modp, nodep, "Unsupported: Nested modules");
|
||||
m_modp = nodep;
|
||||
// Iterate the stored cells directly to reduce traversal
|
||||
|
|
@ -592,7 +592,7 @@ private:
|
|||
m_moduleState(nodep).m_childCells.clear();
|
||||
m_modp = nullptr;
|
||||
}
|
||||
virtual void visit(AstIfaceRefDType* nodep) override {
|
||||
void visit(AstIfaceRefDType* nodep) override {
|
||||
if (nodep->user5()) {
|
||||
// The cell has been removed so let's make sure we don't leave a reference to it
|
||||
// This dtype may still be in use by the AstAssignVarScope created earlier
|
||||
|
|
@ -602,15 +602,15 @@ private:
|
|||
}
|
||||
|
||||
//--------------------
|
||||
virtual void visit(AstCell* nodep) override { // LCOV_EXCL_START
|
||||
void visit(AstCell* nodep) override { // LCOV_EXCL_START
|
||||
nodep->v3fatal("Traversal should have been short circuited");
|
||||
}
|
||||
virtual void visit(AstNodeStmt* nodep) override {
|
||||
void visit(AstNodeStmt* nodep) override {
|
||||
nodep->v3fatal("Traversal should have been short circuited");
|
||||
} // LCOV_EXCL_STOP
|
||||
virtual void visit(AstNodeFile*) override {} // Accelerate
|
||||
virtual void visit(AstNodeDType*) override {} // Accelerate
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNodeFile*) override {} // Accelerate
|
||||
void visit(AstNodeDType*) override {} // Accelerate
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
@ -618,7 +618,7 @@ public:
|
|||
: m_moduleState{moduleState} {
|
||||
iterate(nodep);
|
||||
}
|
||||
virtual ~InlineVisitor() override {
|
||||
~InlineVisitor() override {
|
||||
V3Stats::addStat("Optimizations, Inlined instances", m_statCells);
|
||||
}
|
||||
};
|
||||
|
|
@ -639,8 +639,8 @@ private:
|
|||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep) override { iterateChildren(nodep->topModulep()); }
|
||||
virtual void visit(AstCell* nodep) override {
|
||||
void visit(AstNetlist* nodep) override { iterateChildren(nodep->topModulep()); }
|
||||
void visit(AstCell* nodep) override {
|
||||
VL_RESTORER(m_scope);
|
||||
if (m_scope.empty()) {
|
||||
m_scope = nodep->name();
|
||||
|
|
@ -673,7 +673,7 @@ private:
|
|||
iterateChildren(modp);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstAssignVarScope* nodep) override {
|
||||
void visit(AstAssignVarScope* nodep) override {
|
||||
// Reference
|
||||
const AstVarRef* const reflp = VN_CAST(nodep->lhsp(), VarRef);
|
||||
// What the reference refers to
|
||||
|
|
@ -698,14 +698,14 @@ private:
|
|||
cellp->addIntfRefp(new AstIntfRef(varlp->fileline(), alias));
|
||||
}
|
||||
//--------------------
|
||||
virtual void visit(AstNodeMath*) override {} // Accelerate
|
||||
virtual void visit(AstNodeStmt*) override {} // Accelerate
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNodeMath*) override {} // Accelerate
|
||||
void visit(AstNodeStmt*) override {} // Accelerate
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit InlineIntfRefVisitor(AstNode* nodep) { iterate(nodep); }
|
||||
virtual ~InlineIntfRefVisitor() override = default;
|
||||
~InlineIntfRefVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ private:
|
|||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstCell* nodep) override {
|
||||
void visit(AstCell* nodep) override {
|
||||
UINFO(4, " CELL " << nodep << endl);
|
||||
m_cellp = nodep;
|
||||
// VV***** We reset user1p() on each cell!!!
|
||||
|
|
@ -57,7 +57,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
m_cellp = nullptr;
|
||||
}
|
||||
virtual void visit(AstPin* nodep) override {
|
||||
void visit(AstPin* nodep) override {
|
||||
// PIN(p,expr) -> ASSIGNW(VARXREF(p),expr) (if sub's input)
|
||||
// or ASSIGNW(expr,VARXREF(p)) (if sub's output)
|
||||
UINFO(4, " PIN " << nodep << endl);
|
||||
|
|
@ -116,7 +116,7 @@ private:
|
|||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstUdpTable* nodep) override {
|
||||
void visit(AstUdpTable* nodep) override {
|
||||
if (!v3Global.opt.bboxUnsup()) {
|
||||
// If we support primitives, update V3Undriven to remove special case
|
||||
nodep->v3warn(E_UNSUPPORTED, "Unsupported: Verilog 1995 UDP Tables. "
|
||||
|
|
@ -125,17 +125,17 @@ private:
|
|||
}
|
||||
|
||||
// Save some time
|
||||
virtual void visit(AstNodeMath*) override {}
|
||||
virtual void visit(AstNodeAssign*) override {}
|
||||
virtual void visit(AstAlways*) override {}
|
||||
void visit(AstNodeMath*) override {}
|
||||
void visit(AstNodeAssign*) override {}
|
||||
void visit(AstAlways*) override {}
|
||||
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit InstVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
virtual ~InstVisitor() override = default;
|
||||
~InstVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
@ -149,15 +149,15 @@ private:
|
|||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
void visit(AstVar* nodep) override {
|
||||
if (VN_IS(nodep->dtypep(), IfaceRefDType)) {
|
||||
UINFO(8, " dm-1-VAR " << nodep << endl);
|
||||
insert(nodep);
|
||||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeMath*) override {} // Accelerate
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNodeMath*) override {} // Accelerate
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// METHODS
|
||||
|
|
@ -181,7 +181,7 @@ public:
|
|||
|
||||
// CONSTRUCTORS
|
||||
InstDeModVarVisitor() = default;
|
||||
virtual ~InstDeModVarVisitor() override = default;
|
||||
~InstDeModVarVisitor() override = default;
|
||||
void main(AstNodeModule* nodep) {
|
||||
UINFO(8, " dmMODULE " << nodep << endl);
|
||||
m_modVarNameMap.clear();
|
||||
|
|
@ -203,7 +203,7 @@ private:
|
|||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
void visit(AstVar* nodep) override {
|
||||
if (VN_IS(nodep->dtypep(), UnpackArrayDType)
|
||||
&& VN_IS(VN_AS(nodep->dtypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType)) {
|
||||
UINFO(8, " dv-vec-VAR " << nodep << endl);
|
||||
|
|
@ -239,7 +239,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstCell* nodep) override {
|
||||
void visit(AstCell* nodep) override {
|
||||
UINFO(4, " CELL " << nodep << endl);
|
||||
// Find submodule vars
|
||||
UASSERT_OBJ(nodep->modp(), nodep, "Unlinked");
|
||||
|
|
@ -316,7 +316,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstPin* nodep) override {
|
||||
void visit(AstPin* nodep) override {
|
||||
// Any non-direct pins need reconnection with a part-select
|
||||
if (!nodep->exprp()) return; // No-connect
|
||||
if (m_cellRangep) {
|
||||
|
|
@ -478,13 +478,13 @@ private:
|
|||
}
|
||||
|
||||
//--------------------
|
||||
virtual void visit(AstNodeMath*) override {} // Accelerate
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNodeMath*) override {} // Accelerate
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit InstDeVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
virtual ~InstDeVisitor() override = default;
|
||||
~InstDeVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ public:
|
|||
, m_osp{osp} {
|
||||
if (nodep) iterate(nodep);
|
||||
}
|
||||
virtual ~InstrCountVisitor() override = default;
|
||||
~InstrCountVisitor() override = default;
|
||||
|
||||
// METHODS
|
||||
uint32_t instrCount() const { return m_instrCount; }
|
||||
|
|
@ -123,7 +123,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeSel* nodep) override {
|
||||
void visit(AstNodeSel* nodep) override {
|
||||
if (m_ignoreRemaining) return;
|
||||
// This covers both AstArraySel and AstWordSel
|
||||
//
|
||||
|
|
@ -135,7 +135,7 @@ private:
|
|||
const VisitBase vb{this, nodep};
|
||||
iterateAndNextNull(nodep->bitp());
|
||||
}
|
||||
virtual void visit(AstSel* nodep) override {
|
||||
void visit(AstSel* nodep) override {
|
||||
if (m_ignoreRemaining) return;
|
||||
// Similar to AstNodeSel above, a small select into a large vector
|
||||
// is not expensive. Count the cost of the AstSel itself (scales with
|
||||
|
|
@ -145,13 +145,13 @@ private:
|
|||
iterateAndNextNull(nodep->lsbp());
|
||||
iterateAndNextNull(nodep->widthp());
|
||||
}
|
||||
virtual void visit(AstSliceSel* nodep) override { // LCOV_EXCL_LINE
|
||||
void visit(AstSliceSel* nodep) override { // LCOV_EXCL_LINE
|
||||
nodep->v3fatalSrc("AstSliceSel unhandled");
|
||||
}
|
||||
virtual void visit(AstMemberSel* nodep) override { // LCOV_EXCL_LINE
|
||||
void visit(AstMemberSel* nodep) override { // LCOV_EXCL_LINE
|
||||
nodep->v3fatalSrc("AstMemberSel unhandled");
|
||||
}
|
||||
virtual void visit(AstConcat* nodep) override {
|
||||
void visit(AstConcat* nodep) override {
|
||||
if (m_ignoreRemaining) return;
|
||||
// Nop.
|
||||
//
|
||||
|
|
@ -172,7 +172,7 @@ private:
|
|||
// the widths of the operands (ignored here).
|
||||
markCost(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeIf* nodep) override {
|
||||
void visit(AstNodeIf* nodep) override {
|
||||
if (m_ignoreRemaining) return;
|
||||
const VisitBase vb{this, nodep};
|
||||
iterateAndNextNull(nodep->condp());
|
||||
|
|
@ -199,7 +199,7 @@ private:
|
|||
if (nodep->ifsp()) nodep->ifsp()->user4(0); // Don't dump it
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeCond* nodep) override {
|
||||
void visit(AstNodeCond* nodep) override {
|
||||
if (m_ignoreRemaining) return;
|
||||
// Just like if/else above, the ternary operator only evaluates
|
||||
// one of the two expressions, so only count the max.
|
||||
|
|
@ -226,13 +226,13 @@ private:
|
|||
if (nodep->expr2p()) nodep->expr2p()->user4(0); // Don't dump it
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCAwait* nodep) override {
|
||||
void visit(AstCAwait* nodep) override {
|
||||
if (m_ignoreRemaining) return;
|
||||
iterateChildren(nodep);
|
||||
// Anything past a co_await is irrelevant
|
||||
m_ignoreRemaining = true;
|
||||
}
|
||||
virtual void visit(AstFork* nodep) override {
|
||||
void visit(AstFork* nodep) override {
|
||||
if (m_ignoreRemaining) return;
|
||||
const VisitBase vb{this, nodep};
|
||||
uint32_t totalCount = m_instrCount;
|
||||
|
|
@ -245,7 +245,7 @@ private:
|
|||
m_instrCount = totalCount;
|
||||
m_ignoreRemaining = false;
|
||||
}
|
||||
virtual void visit(AstActive* nodep) override {
|
||||
void visit(AstActive* nodep) override {
|
||||
// You'd think that the OrderLogicVertex's would be disjoint trees
|
||||
// of stuff in the AST, but it isn't so: V3Order makes an
|
||||
// OrderLogicVertex for each ACTIVE, and then also makes an
|
||||
|
|
@ -261,7 +261,7 @@ private:
|
|||
markCost(nodep);
|
||||
UASSERT_OBJ(nodep == m_startNodep, nodep, "Multiple actives, or not start node");
|
||||
}
|
||||
virtual void visit(AstNodeCCall* nodep) override {
|
||||
void visit(AstNodeCCall* nodep) override {
|
||||
if (m_ignoreRemaining) return;
|
||||
const VisitBase vb{this, nodep};
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -269,7 +269,7 @@ private:
|
|||
iterate(nodep->funcp());
|
||||
UASSERT_OBJ(!m_tracingCall, nodep, "visit(AstCFunc) should have cleared m_tracingCall.");
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
// Don't count a CFunc other than by tracing a call or counting it
|
||||
// from the root
|
||||
UASSERT_OBJ(m_tracingCall || nodep == m_startNodep, nodep,
|
||||
|
|
@ -284,7 +284,7 @@ private:
|
|||
}
|
||||
m_ignoreRemaining = false;
|
||||
}
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
if (m_ignoreRemaining) return;
|
||||
const VisitBase vb{this, nodep};
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -312,12 +312,12 @@ public:
|
|||
UASSERT_OBJ(osp, nodep, "Don't call if not dumping");
|
||||
if (nodep) iterate(nodep);
|
||||
}
|
||||
virtual ~InstrCountDumpVisitor() override = default;
|
||||
~InstrCountDumpVisitor() override = default;
|
||||
|
||||
private:
|
||||
// METHODS
|
||||
string indent() const { return string(m_depth, ':') + " "; }
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
++m_depth;
|
||||
if (unsigned costPlus1 = nodep->user4()) {
|
||||
*m_osp << " " << indent() << "cost " << std::setw(6) << std::left << (costPlus1 - 1)
|
||||
|
|
|
|||
|
|
@ -48,20 +48,20 @@ public:
|
|||
"1800-2005", "1800-2009", "1800-2012", "1800-2017"};
|
||||
return names[m_e];
|
||||
}
|
||||
static V3LangCode mostRecent() { return V3LangCode(L1800_2017); }
|
||||
static V3LangCode mostRecent() { return V3LangCode{L1800_2017}; }
|
||||
bool systemVerilog() const {
|
||||
return m_e == L1800_2005 || m_e == L1800_2009 || m_e == L1800_2012 || m_e == L1800_2017;
|
||||
}
|
||||
bool legal() const { return m_e != L_ERROR; }
|
||||
//
|
||||
enum en m_e;
|
||||
inline V3LangCode()
|
||||
V3LangCode()
|
||||
: m_e{L_ERROR} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline V3LangCode(en _e)
|
||||
V3LangCode(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit V3LangCode(const char* textp);
|
||||
explicit inline V3LangCode(int _e)
|
||||
explicit V3LangCode(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -94,18 +94,18 @@ public:
|
|||
consumed();
|
||||
}
|
||||
~LifeVarEntry() = default;
|
||||
inline void simpleAssign(AstNodeAssign* assp) { // New simple A=.... assignment
|
||||
void simpleAssign(AstNodeAssign* assp) { // New simple A=.... assignment
|
||||
m_assignp = assp;
|
||||
m_constp = nullptr;
|
||||
m_everSet = true;
|
||||
if (VN_IS(assp->rhsp(), Const)) m_constp = VN_AS(assp->rhsp(), Const);
|
||||
}
|
||||
inline void complexAssign() { // A[x]=... or some complicated assignment
|
||||
void complexAssign() { // A[x]=... or some complicated assignment
|
||||
m_assignp = nullptr;
|
||||
m_constp = nullptr;
|
||||
m_everSet = true;
|
||||
}
|
||||
inline void consumed() { // Rvalue read of A
|
||||
void consumed() { // Rvalue read of A
|
||||
m_assignp = nullptr;
|
||||
}
|
||||
AstNodeAssign* assignp() const { return m_assignp; }
|
||||
|
|
@ -165,7 +165,7 @@ public:
|
|||
checkRemoveAssign(it);
|
||||
it->second.simpleAssign(assp);
|
||||
} else {
|
||||
m_map.emplace(nodep, LifeVarEntry(LifeVarEntry::SIMPLEASSIGN(), assp));
|
||||
m_map.emplace(nodep, LifeVarEntry{LifeVarEntry::SIMPLEASSIGN{}, assp});
|
||||
}
|
||||
// lifeDump();
|
||||
}
|
||||
|
|
@ -175,7 +175,7 @@ public:
|
|||
if (it != m_map.end()) {
|
||||
it->second.complexAssign();
|
||||
} else {
|
||||
m_map.emplace(nodep, LifeVarEntry(LifeVarEntry::COMPLEXASSIGN()));
|
||||
m_map.emplace(nodep, LifeVarEntry{LifeVarEntry::COMPLEXASSIGN{}});
|
||||
}
|
||||
}
|
||||
void varUsageReplace(AstVarScope* nodep, AstVarRef* varrefp) {
|
||||
|
|
@ -196,7 +196,7 @@ public:
|
|||
UINFO(4, " usage: " << nodep << endl);
|
||||
it->second.consumed();
|
||||
} else {
|
||||
m_map.emplace(nodep, LifeVarEntry(LifeVarEntry::CONSUMED()));
|
||||
m_map.emplace(nodep, LifeVarEntry{LifeVarEntry::CONSUMED{}});
|
||||
}
|
||||
}
|
||||
void complexAssignFind(AstVarScope* nodep) {
|
||||
|
|
@ -205,7 +205,7 @@ public:
|
|||
UINFO(4, " casfind: " << it->first << endl);
|
||||
it->second.complexAssign();
|
||||
} else {
|
||||
m_map.emplace(nodep, LifeVarEntry(LifeVarEntry::COMPLEXASSIGN()));
|
||||
m_map.emplace(nodep, LifeVarEntry{LifeVarEntry::COMPLEXASSIGN{}});
|
||||
}
|
||||
}
|
||||
void consumedFind(AstVarScope* nodep) {
|
||||
|
|
@ -213,7 +213,7 @@ public:
|
|||
if (it != m_map.end()) {
|
||||
it->second.consumed();
|
||||
} else {
|
||||
m_map.emplace(nodep, LifeVarEntry(LifeVarEntry::CONSUMED()));
|
||||
m_map.emplace(nodep, LifeVarEntry{LifeVarEntry::CONSUMED{}});
|
||||
}
|
||||
}
|
||||
void lifeToAbove() {
|
||||
|
|
@ -291,7 +291,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
// Consumption/generation of a variable,
|
||||
// it's used so can't elim assignment before this use.
|
||||
UASSERT_OBJ(nodep->varScopep(), nodep, "nullptr");
|
||||
|
|
@ -305,7 +305,7 @@ private:
|
|||
VL_DO_DANGLING(m_lifep->varUsageReplace(vscp, nodep), nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeAssign* nodep) override {
|
||||
void visit(AstNodeAssign* nodep) override {
|
||||
if (nodep->isTimingControl()) {
|
||||
// V3Life doesn't understand time sense - don't optimize
|
||||
setNoopt();
|
||||
|
|
@ -331,7 +331,7 @@ private:
|
|||
iterateAndNextNull(nodep->lhsp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstAssignDly* nodep) override {
|
||||
void visit(AstAssignDly* nodep) override {
|
||||
// V3Life doesn't understand time sense
|
||||
if (nodep->isTimingControl()) {
|
||||
// Don't optimize
|
||||
|
|
@ -342,7 +342,7 @@ private:
|
|||
}
|
||||
|
||||
//---- Track control flow changes
|
||||
virtual void visit(AstNodeIf* nodep) override {
|
||||
void visit(AstNodeIf* nodep) override {
|
||||
UINFO(4, " IF " << nodep << endl);
|
||||
// Condition is part of PREVIOUS block
|
||||
iterateAndNextNull(nodep->condp());
|
||||
|
|
@ -368,7 +368,7 @@ private:
|
|||
VL_DO_DANGLING(delete elseLifep, elseLifep);
|
||||
}
|
||||
|
||||
virtual void visit(AstWhile* nodep) override {
|
||||
void visit(AstWhile* nodep) override {
|
||||
// While's are a problem, as we don't allow loops in the graph. We
|
||||
// may go around the cond/body multiple times. Thus a
|
||||
// lifelication just in the body is ok, but we can't delete an
|
||||
|
|
@ -397,7 +397,7 @@ private:
|
|||
VL_DO_DANGLING(delete condLifep, condLifep);
|
||||
VL_DO_DANGLING(delete bodyLifep, bodyLifep);
|
||||
}
|
||||
virtual void visit(AstJumpBlock* nodep) override {
|
||||
void visit(AstJumpBlock* nodep) override {
|
||||
// As with While's we can't predict if a JumpGo will kill us or not
|
||||
// It's worse though as an IF(..., JUMPGO) may change the control flow.
|
||||
// Just don't optimize blocks with labels; they're rare - so far.
|
||||
|
|
@ -415,7 +415,7 @@ private:
|
|||
bodyLifep->lifeToAbove();
|
||||
VL_DO_DANGLING(delete bodyLifep, bodyLifep);
|
||||
}
|
||||
virtual void visit(AstNodeCCall* nodep) override {
|
||||
void visit(AstNodeCCall* nodep) override {
|
||||
// UINFO(4, " CCALL " << nodep << endl);
|
||||
iterateChildren(nodep);
|
||||
// Enter the function and trace it
|
||||
|
|
@ -425,7 +425,7 @@ private:
|
|||
iterate(nodep->funcp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
// UINFO(4, " CFUNC " << nodep << endl);
|
||||
if (!m_tracingCall && !nodep->entryPoint()) return;
|
||||
m_tracingCall = false;
|
||||
|
|
@ -434,17 +434,17 @@ private:
|
|||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstUCFunc* nodep) override {
|
||||
void visit(AstUCFunc* nodep) override {
|
||||
m_sideEffect = true; // If appears on assign RHS, don't ever delete the assignment
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstCMath* nodep) override {
|
||||
void visit(AstCMath* nodep) override {
|
||||
m_sideEffect = true; // If appears on assign RHS, don't ever delete the assignment
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstVar*) override {} // Don't want varrefs under it
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstVar*) override {} // Don't want varrefs under it
|
||||
void visit(AstNode* nodep) override {
|
||||
if (nodep->isTimingControl()) {
|
||||
// V3Life doesn't understand time sense - don't optimize
|
||||
setNoopt();
|
||||
|
|
@ -463,7 +463,7 @@ public:
|
|||
if (m_lifep) VL_DO_CLEAR(delete m_lifep, m_lifep = nullptr);
|
||||
}
|
||||
}
|
||||
virtual ~LifeVisitor() override {
|
||||
~LifeVisitor() override {
|
||||
if (m_lifep) VL_DO_CLEAR(delete m_lifep, m_lifep = nullptr);
|
||||
}
|
||||
VL_UNCOPYABLE(LifeVisitor);
|
||||
|
|
@ -479,20 +479,20 @@ private:
|
|||
LifeState* const m_statep; // Current state
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
if (nodep->entryPoint()) {
|
||||
// Usage model 1: Simulate all C code, doing lifetime analysis
|
||||
LifeVisitor{nodep, m_statep};
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeProcedure* nodep) override {
|
||||
void visit(AstNodeProcedure* nodep) override {
|
||||
// Usage model 2: Cleanup basic blocks
|
||||
LifeVisitor{nodep, m_statep};
|
||||
}
|
||||
virtual void visit(AstVar*) override {} // Accelerate
|
||||
virtual void visit(AstNodeStmt*) override {} // Accelerate
|
||||
virtual void visit(AstNodeMath*) override {} // Accelerate
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstVar*) override {} // Accelerate
|
||||
void visit(AstNodeStmt*) override {} // Accelerate
|
||||
void visit(AstNodeMath*) override {} // Accelerate
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
@ -500,7 +500,7 @@ public:
|
|||
: m_statep{statep} {
|
||||
iterate(nodep);
|
||||
}
|
||||
virtual ~LifeTopVisitor() override = default;
|
||||
~LifeTopVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -54,21 +54,21 @@ private:
|
|||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
const AstVarScope* const vscp = nodep->varScopep();
|
||||
UASSERT_OBJ(vscp, nodep, "Scope not assigned");
|
||||
if (AstVarScope* const newvscp = reinterpret_cast<AstVarScope*>(vscp->user4p())) {
|
||||
UINFO(9, " Replace " << nodep << " to " << newvscp << endl);
|
||||
AstVarRef* const newrefp = new AstVarRef(nodep->fileline(), newvscp, nodep->access());
|
||||
AstVarRef* const newrefp = new AstVarRef{nodep->fileline(), newvscp, nodep->access()};
|
||||
nodep->replaceWith(newrefp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
// Only track the top scopes, not lower level functions
|
||||
if (nodep->isTop()) iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeCCall* nodep) override {
|
||||
void visit(AstNodeCCall* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (!nodep->funcp()->entryPoint()) {
|
||||
// Enter the function and trace it
|
||||
|
|
@ -76,23 +76,23 @@ private:
|
|||
iterate(nodep->funcp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstExecGraph* nodep) override {
|
||||
void visit(AstExecGraph* nodep) override {
|
||||
// Can just iterate across the MTask bodies in any order. Order
|
||||
// isn't important for LifePostElimVisitor's simple substitution.
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
if (!m_tracingCall && !nodep->entryPoint()) return;
|
||||
m_tracingCall = false;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstVar*) override {} // Don't want varrefs under it
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstVar*) override {} // Don't want varrefs under it
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit LifePostElimVisitor(AstTopScope* nodep) { iterate(nodep); }
|
||||
virtual ~LifePostElimVisitor() override = default;
|
||||
~LifePostElimVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
@ -256,7 +256,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstTopScope* nodep) override {
|
||||
void visit(AstTopScope* nodep) override {
|
||||
AstNode::user4ClearTree(); // user4p() used on entire tree
|
||||
|
||||
// First, build maps of every location (mtask and sequence
|
||||
|
|
@ -280,7 +280,7 @@ private:
|
|||
// Replace any node4p varscopes with the new scope
|
||||
LifePostElimVisitor{nodep};
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
// Mark variables referenced outside _eval__nba
|
||||
if (!m_inEvalNba) {
|
||||
nodep->varScopep()->user1(true);
|
||||
|
|
@ -295,7 +295,7 @@ private:
|
|||
if (nodep->access().isWriteOrRW()) m_writes[vscp].insert(loc);
|
||||
if (nodep->access().isReadOrRW()) m_reads[vscp].insert(loc);
|
||||
}
|
||||
virtual void visit(AstAssignPre* nodep) override {
|
||||
void visit(AstAssignPre* nodep) override {
|
||||
// Do not record varrefs within assign pre.
|
||||
//
|
||||
// The pre-assignment into the dly var should not count as its
|
||||
|
|
@ -303,7 +303,7 @@ private:
|
|||
// would still happen if the dly var were eliminated.
|
||||
if (!m_inEvalNba) iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstAssignPost* nodep) override {
|
||||
void visit(AstAssignPost* nodep) override {
|
||||
// Don't record ASSIGNPOST in the read/write maps, record them in a
|
||||
// separate map
|
||||
if (const AstVarRef* const rhsp = VN_CAST(nodep->rhsp(), VarRef)) {
|
||||
|
|
@ -315,11 +315,11 @@ private:
|
|||
m_assignposts[dlyVarp] = LifePostLocation(loc, nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
// Only track the top scopes, not lower level functions
|
||||
if (nodep->isTop()) iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeCCall* nodep) override {
|
||||
void visit(AstNodeCCall* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (!nodep->funcp()->entryPoint()) {
|
||||
// Enter the function and trace it
|
||||
|
|
@ -327,7 +327,7 @@ private:
|
|||
iterate(nodep->funcp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstExecGraph* nodep) override {
|
||||
void visit(AstExecGraph* nodep) override {
|
||||
// Treat the ExecGraph like a call to each mtask body
|
||||
if (m_inEvalNba) {
|
||||
UASSERT_OBJ(!m_mtasksGraphp, nodep, "Cannot handle more than one AstExecGraph");
|
||||
|
|
@ -342,7 +342,7 @@ private:
|
|||
}
|
||||
m_execMTaskp = nullptr;
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
if (!m_tracingCall && !nodep->entryPoint()) return;
|
||||
VL_RESTORER(m_inEvalNba);
|
||||
if (nodep == m_evalNbap) m_inEvalNba = true;
|
||||
|
|
@ -350,8 +350,8 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
//-----
|
||||
virtual void visit(AstVar*) override {} // Don't want varrefs under it
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstVar*) override {} // Don't want varrefs under it
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
@ -359,7 +359,7 @@ public:
|
|||
: m_evalNbap{netlistp->evalNbap()} {
|
||||
iterate(netlistp);
|
||||
}
|
||||
virtual ~LifePostDlyVisitor() override {
|
||||
~LifePostDlyVisitor() override {
|
||||
V3Stats::addStat("Optimizations, Lifetime postassign deletions", m_statAssnDel);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@
|
|||
class LinkCellsGraph final : public V3Graph {
|
||||
public:
|
||||
LinkCellsGraph() = default;
|
||||
virtual ~LinkCellsGraph() override = default;
|
||||
virtual void loopsMessageCb(V3GraphVertex* vertexp) override;
|
||||
~LinkCellsGraph() override = default;
|
||||
void loopsMessageCb(V3GraphVertex* vertexp) override;
|
||||
};
|
||||
|
||||
class LinkCellsVertex final : public V3GraphVertex {
|
||||
|
|
@ -56,12 +56,12 @@ public:
|
|||
LinkCellsVertex(V3Graph* graphp, AstNodeModule* modp)
|
||||
: V3GraphVertex{graphp}
|
||||
, m_modp{modp} {}
|
||||
virtual ~LinkCellsVertex() override = default;
|
||||
~LinkCellsVertex() override = default;
|
||||
AstNodeModule* modp() const { return m_modp; }
|
||||
virtual string name() const override { return modp()->name(); }
|
||||
virtual FileLine* fileline() const override { return modp()->fileline(); }
|
||||
string name() const override { return modp()->name(); }
|
||||
FileLine* fileline() const override { return modp()->fileline(); }
|
||||
// Recursive modules get space for maximum recursion
|
||||
virtual uint32_t rankAdder() const override {
|
||||
uint32_t rankAdder() const override {
|
||||
return m_modp->recursiveClone() ? (1 + v3Global.opt.moduleRecursionDepth()) : 1;
|
||||
}
|
||||
};
|
||||
|
|
@ -70,8 +70,8 @@ class LibraryVertex final : public V3GraphVertex {
|
|||
public:
|
||||
explicit LibraryVertex(V3Graph* graphp)
|
||||
: V3GraphVertex{graphp} {}
|
||||
virtual ~LibraryVertex() override = default;
|
||||
virtual string name() const override { return "*LIBRARY*"; }
|
||||
~LibraryVertex() override = default;
|
||||
string name() const override { return "*LIBRARY*"; }
|
||||
};
|
||||
|
||||
void LinkCellsGraph::loopsMessageCb(V3GraphVertex* vertexp) {
|
||||
|
|
@ -161,7 +161,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITs
|
||||
virtual void visit(AstNetlist* nodep) override {
|
||||
void visit(AstNetlist* nodep) override {
|
||||
AstNode::user1ClearTree();
|
||||
readModNames();
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -181,8 +181,8 @@ private:
|
|||
<< "' was not found in design.");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstConstPool* nodep) override {}
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstConstPool* nodep) override {}
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
// Module: Pick up modnames, so we can resolve cells later
|
||||
VL_RESTORER(m_modp);
|
||||
{
|
||||
|
|
@ -227,7 +227,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstIfaceRefDType* nodep) override {
|
||||
void visit(AstIfaceRefDType* nodep) override {
|
||||
// Cell: Resolve its filename. If necessary, parse it.
|
||||
UINFO(4, "Link IfaceRef: " << nodep << endl);
|
||||
// Use findIdUpward instead of findIdFlat; it doesn't matter for now
|
||||
|
|
@ -246,14 +246,14 @@ private:
|
|||
// Note cannot do modport resolution here; modports are allowed underneath generates
|
||||
}
|
||||
|
||||
virtual void visit(AstPackageImport* nodep) override {
|
||||
void visit(AstPackageImport* nodep) override {
|
||||
// Package Import: We need to do the package before the use of a package
|
||||
iterateChildren(nodep);
|
||||
UASSERT_OBJ(nodep->packagep(), nodep, "Unlinked package"); // Parser should set packagep
|
||||
new V3GraphEdge(&m_graph, vertex(m_modp), vertex(nodep->packagep()), 1, false);
|
||||
}
|
||||
|
||||
virtual void visit(AstBind* nodep) override {
|
||||
void visit(AstBind* nodep) override {
|
||||
// Bind: Has cells underneath that need to be put into the new
|
||||
// module, and cells which need resolution
|
||||
// TODO this doesn't allow bind to dotted hier names, that would require
|
||||
|
|
@ -275,7 +275,7 @@ private:
|
|||
pushDeletep(nodep->unlinkFrBack());
|
||||
}
|
||||
|
||||
virtual void visit(AstCell* nodep) override {
|
||||
void visit(AstCell* nodep) override {
|
||||
// Cell: Resolve its filename. If necessary, parse it.
|
||||
// Execute only once. Complication is that cloning may result in
|
||||
// user1 being set (for pre-clone) so check if user1() matches the
|
||||
|
|
@ -452,14 +452,14 @@ private:
|
|||
UINFO(4, " Link Cell done: " << nodep << endl);
|
||||
}
|
||||
|
||||
virtual void visit(AstRefDType* nodep) override {
|
||||
void visit(AstRefDType* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
for (AstPin* pinp = nodep->paramsp(); pinp; pinp = VN_AS(pinp->nextp(), Pin)) {
|
||||
pinp->param(true);
|
||||
if (pinp->name() == "") pinp->name("__paramNumber" + cvtToStr(pinp->pinNum()));
|
||||
}
|
||||
}
|
||||
virtual void visit(AstClassOrPackageRef* nodep) override {
|
||||
void visit(AstClassOrPackageRef* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
// Inside a class, an extends or reference to another class
|
||||
// Note we don't add a V3GraphEdge{vertex(m_modp), vertex(nodep->classOrPackagep()}
|
||||
|
|
@ -471,7 +471,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
// METHODS
|
||||
void readModNames() {
|
||||
|
|
@ -528,7 +528,7 @@ public:
|
|||
}
|
||||
iterate(nodep);
|
||||
}
|
||||
virtual ~LinkCellsVisitor() override = default;
|
||||
~LinkCellsVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -81,25 +81,25 @@
|
|||
|
||||
class LinkNodeMatcherClass final : public VNodeMatcher {
|
||||
public:
|
||||
virtual bool nodeMatch(const AstNode* nodep) const override { return VN_IS(nodep, Class); }
|
||||
bool nodeMatch(const AstNode* nodep) const override { return VN_IS(nodep, Class); }
|
||||
};
|
||||
class LinkNodeMatcherFTask final : public VNodeMatcher {
|
||||
public:
|
||||
virtual bool nodeMatch(const AstNode* nodep) const override { return VN_IS(nodep, NodeFTask); }
|
||||
bool nodeMatch(const AstNode* nodep) const override { return VN_IS(nodep, NodeFTask); }
|
||||
};
|
||||
class LinkNodeMatcherModport final : public VNodeMatcher {
|
||||
public:
|
||||
virtual bool nodeMatch(const AstNode* nodep) const override { return VN_IS(nodep, Modport); }
|
||||
bool nodeMatch(const AstNode* nodep) const override { return VN_IS(nodep, Modport); }
|
||||
};
|
||||
class LinkNodeMatcherVar final : public VNodeMatcher {
|
||||
public:
|
||||
virtual bool nodeMatch(const AstNode* nodep) const override {
|
||||
bool nodeMatch(const AstNode* nodep) const override {
|
||||
return VN_IS(nodep, Var) || VN_IS(nodep, LambdaArgRef);
|
||||
}
|
||||
};
|
||||
class LinkNodeMatcherVarIO final : public VNodeMatcher {
|
||||
public:
|
||||
virtual bool nodeMatch(const AstNode* nodep) const override {
|
||||
bool nodeMatch(const AstNode* nodep) const override {
|
||||
const AstVar* const varp = VN_CAST(nodep, Var);
|
||||
if (!varp) return false;
|
||||
return varp->isIO();
|
||||
|
|
@ -107,7 +107,7 @@ public:
|
|||
};
|
||||
class LinkNodeMatcherVarParam final : public VNodeMatcher {
|
||||
public:
|
||||
virtual bool nodeMatch(const AstNode* nodep) const override {
|
||||
bool nodeMatch(const AstNode* nodep) const override {
|
||||
const AstVar* const varp = VN_CAST(nodep, Var);
|
||||
if (!varp) return false;
|
||||
return varp->isParam();
|
||||
|
|
@ -742,7 +742,7 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
}
|
||||
|
||||
// VISITs
|
||||
virtual void visit(AstNetlist* nodep) override {
|
||||
void visit(AstNetlist* nodep) override {
|
||||
// Process $unit or other packages
|
||||
// Not needed - dotted references not allowed from inside packages
|
||||
// for (AstNodeModule* nodep = v3Global.rootp()->modulesp();
|
||||
|
|
@ -770,9 +770,9 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
m_curSymp = m_modSymp = nullptr;
|
||||
}
|
||||
}
|
||||
virtual void visit(AstTypeTable*) override {}
|
||||
virtual void visit(AstConstPool*) override {}
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstTypeTable*) override {}
|
||||
void visit(AstConstPool*) override {}
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
// Called on top module from Netlist, other modules from the cell creating them,
|
||||
// and packages
|
||||
UINFO(8, " " << nodep << endl);
|
||||
|
|
@ -839,7 +839,7 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
UINFO(5, "Module not under any CELL or top - dead module: " << nodep << endl);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstClass* nodep) override {
|
||||
void visit(AstClass* nodep) override {
|
||||
UASSERT_OBJ(m_curSymp, nodep, "Class not under module/package/$unit");
|
||||
UINFO(8, " " << nodep << endl);
|
||||
VL_RESTORER(m_scope);
|
||||
|
|
@ -871,12 +871,12 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
if (!m_explicitNew && m_statep->forPrimary()) makeImplicitNew(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstScope* nodep) override {
|
||||
void visit(AstScope* nodep) override {
|
||||
UASSERT_OBJ(m_statep->forScopeCreation(), nodep,
|
||||
"Scopes should only exist right after V3Scope");
|
||||
// Ignored. Processed in next step
|
||||
}
|
||||
virtual void visit(AstCell* nodep) override {
|
||||
void visit(AstCell* nodep) override {
|
||||
UINFO(5, " CELL under " << m_scope << " is " << nodep << endl);
|
||||
// Process XREFs/etc inside pins
|
||||
if (nodep->recursive() && m_inRecursion) return;
|
||||
|
|
@ -911,7 +911,7 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
if (nodep->modp()) iterate(nodep->modp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCellInline* nodep) override {
|
||||
void visit(AstCellInline* nodep) override {
|
||||
UINFO(5, " CELLINLINE under " << m_scope << " is " << nodep << endl);
|
||||
VSymEnt* aboveSymp = m_curSymp;
|
||||
// If baz__DOT__foo__DOT__bar, we need to find baz__DOT__foo and add bar to it.
|
||||
|
|
@ -931,11 +931,11 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
m_statep->insertInline(aboveSymp, m_modSymp, nodep, nodep->name());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstDefParam* nodep) override {
|
||||
void visit(AstDefParam* nodep) override {
|
||||
nodep->user1p(m_curSymp);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeBlock* nodep) override {
|
||||
void visit(AstNodeBlock* nodep) override {
|
||||
UINFO(5, " " << nodep << endl);
|
||||
if (nodep->name() == "" && nodep->unnamed()) {
|
||||
// Unnamed blocks are only important when they contain var
|
||||
|
|
@ -967,7 +967,7 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeFTask* nodep) override {
|
||||
void visit(AstNodeFTask* nodep) override {
|
||||
// NodeTask: Remember its name for later resolution
|
||||
UINFO(5, " " << nodep << endl);
|
||||
UASSERT_OBJ(m_curSymp && m_modSymp, nodep, "Function/Task not under module?");
|
||||
|
|
@ -1024,7 +1024,7 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
}
|
||||
AstVar* const newvarp
|
||||
= new AstVar(nodep->fileline(), VVarType::VAR, nodep->name(),
|
||||
VFlagChildDType(), dtypep); // Not dtype resolved yet
|
||||
VFlagChildDType{}, dtypep); // Not dtype resolved yet
|
||||
newvarp->direction(VDirection::OUTPUT);
|
||||
newvarp->lifetime(VLifetime::AUTOMATIC);
|
||||
newvarp->funcReturn(true);
|
||||
|
|
@ -1040,7 +1040,7 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
m_ftaskp = nullptr;
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
void visit(AstVar* nodep) override {
|
||||
// Var: Remember its name for later resolution
|
||||
UASSERT_OBJ(m_curSymp && m_modSymp, nodep, "Var not under module?");
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -1139,8 +1139,8 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
// We first search if the parameter is overwritten and then replace it with a
|
||||
// new value. It will keep the same FileLine information.
|
||||
if (v3Global.opt.hasParameter(nodep->name())) {
|
||||
AstVar* const newp = new AstVar(
|
||||
nodep->fileline(), VVarType(VVarType::GPARAM), nodep->name(), nodep);
|
||||
AstVar* const newp = new AstVar{
|
||||
nodep->fileline(), VVarType{VVarType::GPARAM}, nodep->name(), nodep};
|
||||
newp->combineType(nodep);
|
||||
const string svalue = v3Global.opt.parameter(nodep->name());
|
||||
if (AstNode* const valuep
|
||||
|
|
@ -1173,18 +1173,18 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstTypedef* nodep) override {
|
||||
void visit(AstTypedef* nodep) override {
|
||||
UASSERT_OBJ(m_curSymp, nodep, "Typedef not under module/package/$unit");
|
||||
iterateChildren(nodep);
|
||||
m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_classOrPackagep);
|
||||
}
|
||||
virtual void visit(AstTypedefFwd* nodep) override {
|
||||
void visit(AstTypedefFwd* nodep) override {
|
||||
UASSERT_OBJ(m_curSymp, nodep, "Typedef not under module/package/$unit");
|
||||
iterateChildren(nodep);
|
||||
// No need to insert, only the real typedef matters, but need to track for errors
|
||||
nodep->user1p(m_curSymp);
|
||||
}
|
||||
virtual void visit(AstParamTypeDType* nodep) override {
|
||||
void visit(AstParamTypeDType* nodep) override {
|
||||
UASSERT_OBJ(m_curSymp, nodep, "Parameter type not under module/package/$unit");
|
||||
iterateChildren(nodep);
|
||||
m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_classOrPackagep);
|
||||
|
|
@ -1195,11 +1195,11 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
symp->exported(false);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
// For dotted resolution, ignore all AstVars under functions, otherwise shouldn't exist
|
||||
UASSERT_OBJ(!m_statep->forScopeCreation(), nodep, "No CFuncs expected in tree yet");
|
||||
}
|
||||
virtual void visit(AstEnumItem* nodep) override {
|
||||
void visit(AstEnumItem* nodep) override {
|
||||
// EnumItem: Remember its name for later resolution
|
||||
iterateChildren(nodep);
|
||||
// Find under either a task or the module's vars
|
||||
|
|
@ -1238,7 +1238,7 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
}
|
||||
if (ins) m_statep->insertSym(m_curSymp, nodep->name(), nodep, m_classOrPackagep);
|
||||
}
|
||||
virtual void visit(AstPackageImport* nodep) override {
|
||||
void visit(AstPackageImport* nodep) override {
|
||||
UINFO(4, " Link: " << nodep << endl);
|
||||
VSymEnt* const srcp = m_statep->getNodeSym(nodep->packagep());
|
||||
if (nodep->name() == "*") {
|
||||
|
|
@ -1256,7 +1256,7 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
UINFO(9, " Link Done: " << nodep << endl);
|
||||
// No longer needed, but can't delete until any multi-instantiated modules are expanded
|
||||
}
|
||||
virtual void visit(AstPackageExport* nodep) override {
|
||||
void visit(AstPackageExport* nodep) override {
|
||||
UINFO(9, " Link: " << nodep << endl);
|
||||
VSymEnt* const srcp = m_statep->getNodeSym(nodep->packagep());
|
||||
if (nodep->name() != "*") {
|
||||
|
|
@ -1270,13 +1270,13 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
UINFO(9, " Link Done: " << nodep << endl);
|
||||
// No longer needed, but can't delete until any multi-instantiated modules are expanded
|
||||
}
|
||||
virtual void visit(AstPackageExportStarStar* nodep) override {
|
||||
void visit(AstPackageExportStarStar* nodep) override {
|
||||
UINFO(4, " Link: " << nodep << endl);
|
||||
m_curSymp->exportStarStar(m_statep->symsp());
|
||||
// No longer needed, but can't delete until any multi-instantiated modules are expanded
|
||||
}
|
||||
|
||||
virtual void visit(AstForeach* nodep) override {
|
||||
void visit(AstForeach* nodep) override {
|
||||
// Symbol table needs nodep->name() as the index variable's name
|
||||
VL_RESTORER(m_curSymp);
|
||||
VSymEnt* const oldCurSymp = m_curSymp;
|
||||
|
|
@ -1327,7 +1327,7 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstWithParse* nodep) override {
|
||||
void visit(AstWithParse* nodep) override {
|
||||
// Change WITHPARSE(FUNCREF, equation) to FUNCREF(WITH(equation))
|
||||
const auto funcrefp = VN_AS(nodep->funcrefp(), NodeFTaskRef);
|
||||
UASSERT_OBJ(funcrefp, nodep, "'with' only can operate on a function/task");
|
||||
|
|
@ -1355,7 +1355,7 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
nodep->replaceWith(funcrefp->unlinkFrBack());
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
virtual void visit(AstWith* nodep) override {
|
||||
void visit(AstWith* nodep) override {
|
||||
// Symbol table needs nodep->name() as the index variable's name
|
||||
// Iteration will pickup the AstVar we made under AstWith
|
||||
VL_RESTORER(m_curSymp);
|
||||
|
|
@ -1373,7 +1373,7 @@ class LinkDotFindVisitor final : public VNVisitor {
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
@ -1383,7 +1383,7 @@ public:
|
|||
|
||||
iterate(rootp);
|
||||
}
|
||||
virtual ~LinkDotFindVisitor() override = default;
|
||||
~LinkDotFindVisitor() override = default;
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
|
|
@ -1425,9 +1425,9 @@ private:
|
|||
}
|
||||
|
||||
// VISITs
|
||||
virtual void visit(AstTypeTable*) override {}
|
||||
virtual void visit(AstConstPool*) override {}
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstTypeTable*) override {}
|
||||
void visit(AstConstPool*) override {}
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
UINFO(5, " " << nodep << endl);
|
||||
if (nodep->dead() || !nodep->user4()) {
|
||||
UINFO(4, "Mark dead module " << nodep << endl);
|
||||
|
|
@ -1444,7 +1444,7 @@ private:
|
|||
m_modp = nullptr;
|
||||
}
|
||||
}
|
||||
virtual void visit(AstPin* nodep) override {
|
||||
void visit(AstPin* nodep) override {
|
||||
// Pin: Link to submodule's port
|
||||
// Deal with implicit definitions - do before Resolve visitor as may
|
||||
// be referenced above declaration
|
||||
|
|
@ -1453,7 +1453,7 @@ private:
|
|||
pinImplicitExprRecurse(nodep->exprp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstDefParam* nodep) override {
|
||||
void visit(AstDefParam* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
nodep->v3warn(DEFPARAM, "defparam is deprecated (IEEE 1800-2017 C.4.1)\n"
|
||||
<< nodep->warnMore()
|
||||
|
|
@ -1475,7 +1475,7 @@ private:
|
|||
}
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
}
|
||||
virtual void visit(AstPort* nodep) override {
|
||||
void visit(AstPort* nodep) override {
|
||||
// Port: Stash the pin number
|
||||
// Need to set pin numbers after varnames are created
|
||||
// But before we do the final resolution based on names
|
||||
|
|
@ -1508,14 +1508,14 @@ private:
|
|||
// Ports not needed any more
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
}
|
||||
virtual void visit(AstAssignW* nodep) override {
|
||||
void visit(AstAssignW* nodep) override {
|
||||
// Deal with implicit definitions
|
||||
// We used to nodep->allowImplicit() here, but it turns out
|
||||
// normal "assigns" can also make implicit wires. Yuk.
|
||||
pinImplicitExprRecurse(nodep->lhsp());
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstAssignAlias* nodep) override {
|
||||
void visit(AstAssignAlias* nodep) override {
|
||||
// tran gates need implicit creation
|
||||
// As VarRefs don't exist in forPrimary, sanity check
|
||||
UASSERT_OBJ(!m_statep->forPrimary(), nodep, "Assign aliases unexpected pre-dot");
|
||||
|
|
@ -1527,13 +1527,13 @@ private:
|
|||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstImplicit* nodep) override {
|
||||
void visit(AstImplicit* nodep) override {
|
||||
// Unsupported gates need implicit creation
|
||||
pinImplicitExprRecurse(nodep);
|
||||
// We're done with implicit gates
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
}
|
||||
virtual void visit(AstClassOrPackageRef* nodep) override {
|
||||
void visit(AstClassOrPackageRef* nodep) override {
|
||||
if (auto* const fwdp = VN_CAST(nodep->classOrPackageNodep(), TypedefFwd)) {
|
||||
// Relink forward definitions to the "real" definition
|
||||
VSymEnt* const foundp = m_statep->getNodeSym(fwdp)->findIdFallback(fwdp->name());
|
||||
|
|
@ -1555,7 +1555,7 @@ private:
|
|||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstTypedefFwd* nodep) override {
|
||||
void visit(AstTypedefFwd* nodep) override {
|
||||
VSymEnt* const foundp = m_statep->getNodeSym(nodep)->findIdFallback(nodep->name());
|
||||
if (!foundp && v3Global.opt.pedantic()) {
|
||||
// We only check it was ever really defined in pedantic mode, as it
|
||||
|
|
@ -1570,7 +1570,7 @@ private:
|
|||
VL_DO_DANGLING(pushDeletep(nodep->unlinkFrBack()), nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
@ -1579,7 +1579,7 @@ public:
|
|||
UINFO(4, __FUNCTION__ << ": " << endl);
|
||||
iterate(rootp);
|
||||
}
|
||||
virtual ~LinkDotParamVisitor() override = default;
|
||||
~LinkDotParamVisitor() override = default;
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
|
|
@ -1594,12 +1594,12 @@ class LinkDotScopeVisitor final : public VNVisitor {
|
|||
static int debug() { return LinkDotState::debug(); }
|
||||
|
||||
// VISITs
|
||||
virtual void visit(AstNetlist* nodep) override {
|
||||
void visit(AstNetlist* nodep) override {
|
||||
// Recurse..., backward as must do packages before using packages
|
||||
iterateChildrenBackwards(nodep);
|
||||
}
|
||||
virtual void visit(AstConstPool*) override {}
|
||||
virtual void visit(AstScope* nodep) override {
|
||||
void visit(AstConstPool*) override {}
|
||||
void visit(AstScope* nodep) override {
|
||||
UINFO(8, " SCOPE " << nodep << endl);
|
||||
UASSERT_OBJ(m_statep->forScopeCreation(), nodep,
|
||||
"Scopes should only exist right after V3Scope");
|
||||
|
|
@ -1611,7 +1611,7 @@ class LinkDotScopeVisitor final : public VNVisitor {
|
|||
m_modSymp = nullptr;
|
||||
m_scopep = nullptr;
|
||||
}
|
||||
virtual void visit(AstVarScope* nodep) override {
|
||||
void visit(AstVarScope* nodep) override {
|
||||
if (!nodep->varp()->isFuncLocal() && !nodep->varp()->isClassMember()) {
|
||||
VSymEnt* const varSymp
|
||||
= m_statep->insertSym(m_modSymp, nodep->varp()->name(), nodep, nullptr);
|
||||
|
|
@ -1649,22 +1649,22 @@ class LinkDotScopeVisitor final : public VNVisitor {
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeFTask* nodep) override {
|
||||
void visit(AstNodeFTask* nodep) override {
|
||||
VSymEnt* const symp = m_statep->insertBlock(m_modSymp, nodep->name(), nodep, nullptr);
|
||||
symp->fallbackp(m_modSymp);
|
||||
// No recursion, we don't want to pick up variables
|
||||
}
|
||||
virtual void visit(AstForeach* nodep) override {
|
||||
void visit(AstForeach* nodep) override {
|
||||
VSymEnt* const symp = m_statep->insertBlock(m_modSymp, nodep->name(), nodep, nullptr);
|
||||
symp->fallbackp(m_modSymp);
|
||||
// No recursion, we don't want to pick up variables
|
||||
}
|
||||
virtual void visit(AstWith* nodep) override {
|
||||
void visit(AstWith* nodep) override {
|
||||
VSymEnt* const symp = m_statep->insertBlock(m_modSymp, nodep->name(), nodep, nullptr);
|
||||
symp->fallbackp(m_modSymp);
|
||||
// No recursion, we don't want to pick up variables
|
||||
}
|
||||
virtual void visit(AstAssignAlias* nodep) override {
|
||||
void visit(AstAssignAlias* nodep) override {
|
||||
// Track aliases created by V3Inline; if we get a VARXREF(aliased_from)
|
||||
// we'll need to replace it with a VARXREF(aliased_to)
|
||||
if (debug() >= 9) nodep->dumpTree(cout, "- alias: ");
|
||||
|
|
@ -1674,7 +1674,7 @@ class LinkDotScopeVisitor final : public VNVisitor {
|
|||
fromVscp->user2p(toVscp);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstAssignVarScope* nodep) override {
|
||||
void visit(AstAssignVarScope* nodep) override {
|
||||
UINFO(5, "ASSIGNVARSCOPE " << nodep << endl);
|
||||
if (debug() >= 9) nodep->dumpTree(cout, "- avs: ");
|
||||
VSymEnt* rhsSymp;
|
||||
|
|
@ -1734,9 +1734,9 @@ class LinkDotScopeVisitor final : public VNVisitor {
|
|||
}
|
||||
// For speed, don't recurse things that can't have scope
|
||||
// Note we allow AstNodeStmt's as generates may be under them
|
||||
virtual void visit(AstCell*) override {}
|
||||
virtual void visit(AstVar*) override {}
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstCell*) override {}
|
||||
void visit(AstVar*) override {}
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
@ -1745,7 +1745,7 @@ public:
|
|||
UINFO(4, __FUNCTION__ << ": " << endl);
|
||||
iterate(rootp);
|
||||
}
|
||||
virtual ~LinkDotScopeVisitor() override = default;
|
||||
~LinkDotScopeVisitor() override = default;
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
|
|
@ -1760,7 +1760,7 @@ class LinkDotIfaceVisitor final : public VNVisitor {
|
|||
static int debug() { return LinkDotState::debug(); }
|
||||
|
||||
// VISITs
|
||||
virtual void visit(AstModport* nodep) override {
|
||||
void visit(AstModport* nodep) override {
|
||||
// Modport: Remember its name for later resolution
|
||||
UINFO(5, " fiv: " << nodep << endl);
|
||||
VL_RESTORER(m_curSymp);
|
||||
|
|
@ -1772,7 +1772,7 @@ class LinkDotIfaceVisitor final : public VNVisitor {
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstModportFTaskRef* nodep) override {
|
||||
void visit(AstModportFTaskRef* nodep) override {
|
||||
UINFO(5, " fif: " << nodep << endl);
|
||||
iterateChildren(nodep);
|
||||
if (nodep->isExport()) nodep->v3warn(E_UNSUPPORTED, "Unsupported: modport export");
|
||||
|
|
@ -1795,7 +1795,7 @@ class LinkDotIfaceVisitor final : public VNVisitor {
|
|||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstModportVarRef* nodep) override {
|
||||
void visit(AstModportVarRef* nodep) override {
|
||||
UINFO(5, " fiv: " << nodep << endl);
|
||||
iterateChildren(nodep);
|
||||
VSymEnt* const symp = m_curSymp->findIdFallback(nodep->name());
|
||||
|
|
@ -1820,7 +1820,7 @@ class LinkDotIfaceVisitor final : public VNVisitor {
|
|||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
@ -1830,7 +1830,7 @@ public:
|
|||
UINFO(4, __FUNCTION__ << ": " << endl);
|
||||
iterate(nodep);
|
||||
}
|
||||
virtual ~LinkDotIfaceVisitor() override = default;
|
||||
~LinkDotIfaceVisitor() override = default;
|
||||
};
|
||||
|
||||
void LinkDotState::computeIfaceModSyms() {
|
||||
|
|
@ -1935,7 +1935,7 @@ private:
|
|||
}
|
||||
}
|
||||
AstVar* const newp = new AstVar(nodep->fileline(), VVarType::WIRE, nodep->name(),
|
||||
VFlagLogicPacked(), 1);
|
||||
VFlagLogicPacked{}, 1);
|
||||
newp->trace(modp->modTrace());
|
||||
nodep->varp(newp);
|
||||
modp->addStmtp(newp);
|
||||
|
|
@ -1966,7 +1966,7 @@ private:
|
|||
nodep->v3error("Illegal call of a task as a function: " << nodep->prettyNameQ());
|
||||
}
|
||||
}
|
||||
inline void checkNoDot(AstNode* nodep) {
|
||||
void checkNoDot(AstNode* nodep) {
|
||||
if (VL_UNLIKELY(m_ds.m_dotPos != DP_NONE)) {
|
||||
// UINFO(9, "ds=" << m_ds.ascii() << endl);
|
||||
nodep->v3error("Syntax Error: Not expecting " << nodep->type() << " under a "
|
||||
|
|
@ -2005,13 +2005,13 @@ private:
|
|||
}
|
||||
|
||||
// VISITs
|
||||
virtual void visit(AstNetlist* nodep) override {
|
||||
void visit(AstNetlist* nodep) override {
|
||||
// Recurse..., backward as must do packages before using packages
|
||||
iterateChildrenBackwards(nodep);
|
||||
}
|
||||
virtual void visit(AstTypeTable*) override {}
|
||||
virtual void visit(AstConstPool*) override {}
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstTypeTable*) override {}
|
||||
void visit(AstConstPool*) override {}
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
if (nodep->dead()) return;
|
||||
checkNoDot(nodep);
|
||||
UINFO(8, " " << nodep << endl);
|
||||
|
|
@ -2025,7 +2025,7 @@ private:
|
|||
m_modp = nullptr;
|
||||
m_ds.m_dotSymp = m_curSymp = m_modSymp = nullptr;
|
||||
}
|
||||
virtual void visit(AstScope* nodep) override {
|
||||
void visit(AstScope* nodep) override {
|
||||
UINFO(8, " " << nodep << endl);
|
||||
VL_RESTORER(m_modSymp);
|
||||
VL_RESTORER(m_curSymp);
|
||||
|
|
@ -2036,14 +2036,14 @@ private:
|
|||
m_ds.m_dotSymp = m_curSymp = m_modSymp = nullptr;
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCellInline* nodep) override {
|
||||
void visit(AstCellInline* nodep) override {
|
||||
checkNoDot(nodep);
|
||||
if (m_statep->forScopeCreation() && !v3Global.opt.vpi()) {
|
||||
nodep->unlinkFrBack();
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCell* nodep) override {
|
||||
void visit(AstCell* nodep) override {
|
||||
// Cell: Recurse inside or cleanup not founds
|
||||
checkNoDot(nodep);
|
||||
AstNode::user5ClearTree();
|
||||
|
|
@ -2072,7 +2072,7 @@ private:
|
|||
// Parent module inherits child's publicity
|
||||
// This is done bottom up in the LinkBotupVisitor stage
|
||||
}
|
||||
virtual void visit(AstClassRefDType* nodep) override {
|
||||
void visit(AstClassRefDType* nodep) override {
|
||||
// Cell: Recurse inside or cleanup not founds
|
||||
checkNoDot(nodep);
|
||||
AstNode::user5ClearTree();
|
||||
|
|
@ -2089,7 +2089,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstPin* nodep) override {
|
||||
void visit(AstPin* nodep) override {
|
||||
// Pin: Link to submodule's port
|
||||
checkNoDot(nodep);
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -2130,7 +2130,7 @@ private:
|
|||
}
|
||||
// Early return() above when deleted
|
||||
}
|
||||
virtual void visit(AstDot* nodep) override {
|
||||
void visit(AstDot* nodep) override {
|
||||
// Legal under a DOT: AstDot, AstParseRef, AstPackageRef, AstNodeSel
|
||||
// also a DOT can be part of an expression, but only above plus
|
||||
// AstFTaskRef are legal children
|
||||
|
|
@ -2239,7 +2239,7 @@ private:
|
|||
m_ds.m_dotp = lastStates.m_dotp;
|
||||
}
|
||||
}
|
||||
virtual void visit(AstParseRef* nodep) override {
|
||||
void visit(AstParseRef* nodep) override {
|
||||
if (nodep->user3SetOnce()) return;
|
||||
UINFO(9, " linkPARSEREF " << m_ds.ascii() << " n=" << nodep << endl);
|
||||
// m_curSymp is symbol table of outer expression
|
||||
|
|
@ -2509,7 +2509,7 @@ private:
|
|||
UINFO(7, " ErrParseRef curSymp=se" << cvtToHex(m_curSymp)
|
||||
<< " ds=" << m_ds.ascii() << endl);
|
||||
const string suggest = m_statep->suggestSymFallback(
|
||||
m_ds.m_dotSymp, nodep->name(), VNodeMatcher());
|
||||
m_ds.m_dotSymp, nodep->name(), VNodeMatcher{});
|
||||
nodep->v3error("Can't find definition of "
|
||||
<< expectWhat << ": " << nodep->prettyNameQ() << '\n'
|
||||
<< (suggest.empty() ? "" : nodep->warnMore() + suggest));
|
||||
|
|
@ -2538,7 +2538,7 @@ private:
|
|||
}
|
||||
if (start) m_ds = lastStates;
|
||||
}
|
||||
virtual void visit(AstClassOrPackageRef* nodep) override {
|
||||
void visit(AstClassOrPackageRef* nodep) override {
|
||||
// Class: Recurse inside or cleanup not founds
|
||||
// checkNoDot not appropriate, can be under a dot
|
||||
AstNode::user5ClearTree();
|
||||
|
|
@ -2559,7 +2559,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
// VarRef: Resolve its reference
|
||||
// ParseRefs are used the first pass (forPrimary) so we shouldn't get can't find
|
||||
// errors here now that we have a VarRef.
|
||||
|
|
@ -2581,7 +2581,7 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVarXRef* nodep) override {
|
||||
void visit(AstVarXRef* nodep) override {
|
||||
// VarRef: Resolve its reference
|
||||
// We always link even if varp() is set, because the module we choose may change
|
||||
// due to creating new modules, flattening, etc.
|
||||
|
|
@ -2661,18 +2661,18 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstEnumDType* nodep) override {
|
||||
void visit(AstEnumDType* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
AstRefDType* const refdtypep = VN_CAST(nodep->subDTypep(), RefDType);
|
||||
if (refdtypep && (nodep == refdtypep->subDTypep())) {
|
||||
refdtypep->v3error("Self-referential enumerated type definition");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstEnumItemRef* nodep) override {
|
||||
void visit(AstEnumItemRef* nodep) override {
|
||||
// EnumItemRef may be under a dot. Should already be resolved.
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstMethodCall* nodep) override {
|
||||
void visit(AstMethodCall* nodep) override {
|
||||
// Created here so should already be resolved.
|
||||
VL_RESTORER(m_ds);
|
||||
{
|
||||
|
|
@ -2680,7 +2680,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
void visit(AstVar* nodep) override {
|
||||
checkNoDot(nodep);
|
||||
iterateChildren(nodep);
|
||||
if (m_statep->forPrimary() && nodep->isIO() && !m_ftaskp && !nodep->user4()) {
|
||||
|
|
@ -2688,7 +2688,7 @@ private:
|
|||
"Input/output/inout does not appear in port list: " << nodep->prettyNameQ());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeFTaskRef* nodep) override {
|
||||
void visit(AstNodeFTaskRef* nodep) override {
|
||||
if (nodep->user3SetOnce()) return;
|
||||
UINFO(8, " " << nodep << endl);
|
||||
UINFO(8, " " << m_ds.ascii() << endl);
|
||||
|
|
@ -2854,7 +2854,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSelBit* nodep) override {
|
||||
void visit(AstSelBit* nodep) override {
|
||||
if (nodep->user3SetOnce()) return;
|
||||
iterateAndNextNull(nodep->fromp());
|
||||
if (m_ds.m_dotPos
|
||||
|
|
@ -2882,7 +2882,7 @@ private:
|
|||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodePreSel* nodep) override {
|
||||
void visit(AstNodePreSel* nodep) override {
|
||||
// Excludes simple AstSelBit, see above
|
||||
if (nodep->user3SetOnce()) return;
|
||||
if (m_ds.m_dotPos
|
||||
|
|
@ -2901,11 +2901,11 @@ private:
|
|||
iterateAndNextNull(nodep->attrp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstMemberSel* nodep) override {
|
||||
void visit(AstMemberSel* nodep) override {
|
||||
// checkNoDot not appropriate, can be under a dot
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeBlock* nodep) override {
|
||||
void visit(AstNodeBlock* nodep) override {
|
||||
UINFO(5, " " << nodep << endl);
|
||||
checkNoDot(nodep);
|
||||
VSymEnt* const oldCurSymp = m_curSymp;
|
||||
|
|
@ -2919,7 +2919,7 @@ private:
|
|||
m_ds.m_dotSymp = m_curSymp = oldCurSymp;
|
||||
UINFO(5, " cur=se" << cvtToHex(m_curSymp) << endl);
|
||||
}
|
||||
virtual void visit(AstNodeFTask* nodep) override {
|
||||
void visit(AstNodeFTask* nodep) override {
|
||||
UINFO(5, " " << nodep << endl);
|
||||
checkNoDot(nodep);
|
||||
if (nodep->isExternDef()) {
|
||||
|
|
@ -2941,7 +2941,7 @@ private:
|
|||
m_ds.m_dotSymp = m_curSymp = oldCurSymp;
|
||||
m_ftaskp = nullptr;
|
||||
}
|
||||
virtual void visit(AstForeach* nodep) override {
|
||||
void visit(AstForeach* nodep) override {
|
||||
UINFO(5, " " << nodep << endl);
|
||||
checkNoDot(nodep);
|
||||
VSymEnt* const oldCurSymp = m_curSymp;
|
||||
|
|
@ -2951,7 +2951,7 @@ private:
|
|||
}
|
||||
m_ds.m_dotSymp = m_curSymp = oldCurSymp;
|
||||
}
|
||||
virtual void visit(AstWith* nodep) override {
|
||||
void visit(AstWith* nodep) override {
|
||||
UINFO(5, " " << nodep << endl);
|
||||
checkNoDot(nodep);
|
||||
VSymEnt* const oldCurSymp = m_curSymp;
|
||||
|
|
@ -2961,12 +2961,12 @@ private:
|
|||
}
|
||||
m_ds.m_dotSymp = m_curSymp = oldCurSymp;
|
||||
}
|
||||
virtual void visit(AstLambdaArgRef* nodep) override {
|
||||
void visit(AstLambdaArgRef* nodep) override {
|
||||
UINFO(5, " " << nodep << endl);
|
||||
// No checknodot(nodep), visit(AstScope) will check for LambdaArgRef
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstClass* nodep) override {
|
||||
void visit(AstClass* nodep) override {
|
||||
UINFO(5, " " << nodep << endl);
|
||||
checkNoDot(nodep);
|
||||
VL_RESTORER(m_curSymp);
|
||||
|
|
@ -3041,7 +3041,7 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstRefDType* nodep) override {
|
||||
void visit(AstRefDType* nodep) override {
|
||||
// Resolve its reference
|
||||
if (nodep->user3SetOnce()) return;
|
||||
if (AstNode* const cpackagep = nodep->classOrPackageOpp()) {
|
||||
|
|
@ -3112,7 +3112,7 @@ private:
|
|||
}
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstDpiExport* nodep) override {
|
||||
void visit(AstDpiExport* nodep) override {
|
||||
// AstDpiExport: Make sure the function referenced exists, then dump it
|
||||
iterateChildren(nodep);
|
||||
checkNoDot(nodep);
|
||||
|
|
@ -3130,35 +3130,35 @@ private:
|
|||
}
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
}
|
||||
virtual void visit(AstPackageImport* nodep) override {
|
||||
void visit(AstPackageImport* nodep) override {
|
||||
// No longer needed
|
||||
checkNoDot(nodep);
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
}
|
||||
virtual void visit(AstPackageExport* nodep) override {
|
||||
void visit(AstPackageExport* nodep) override {
|
||||
// No longer needed
|
||||
checkNoDot(nodep);
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
}
|
||||
virtual void visit(AstPackageExportStarStar* nodep) override {
|
||||
void visit(AstPackageExportStarStar* nodep) override {
|
||||
// No longer needed
|
||||
checkNoDot(nodep);
|
||||
VL_DO_DANGLING(nodep->unlinkFrBack()->deleteTree(), nodep);
|
||||
}
|
||||
virtual void visit(AstCellRef* nodep) override {
|
||||
void visit(AstCellRef* nodep) override {
|
||||
UINFO(5, " AstCellRef: " << nodep << " " << m_ds.ascii() << endl);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstCellArrayRef* nodep) override {
|
||||
void visit(AstCellArrayRef* nodep) override {
|
||||
UINFO(5, " AstCellArrayRef: " << nodep << " " << m_ds.ascii() << endl);
|
||||
// Expression already iterated
|
||||
}
|
||||
virtual void visit(AstUnlinkedRef* nodep) override {
|
||||
void visit(AstUnlinkedRef* nodep) override {
|
||||
UINFO(5, " AstCellArrayRef: " << nodep << " " << m_ds.ascii() << endl);
|
||||
// No need to iterate, if we have a UnlinkedVarXRef, we're already done
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
checkNoDot(nodep);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
|
@ -3170,7 +3170,7 @@ public:
|
|||
UINFO(4, __FUNCTION__ << ": " << endl);
|
||||
iterate(rootp);
|
||||
}
|
||||
virtual ~LinkDotResolveVisitor() override = default;
|
||||
~LinkDotResolveVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -89,12 +89,12 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
VL_RESTORER(m_modIncrementsNum);
|
||||
m_modIncrementsNum = 0;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstWhile* nodep) override {
|
||||
void visit(AstWhile* nodep) override {
|
||||
// Special, as statements need to be put in different places
|
||||
// Preconditions insert first just before themselves (the normal
|
||||
// rule for other statement types)
|
||||
|
|
@ -111,7 +111,7 @@ private:
|
|||
// Done the loop
|
||||
m_insStmtp = nullptr; // Next thing should be new statement
|
||||
}
|
||||
virtual void visit(AstForeach* nodep) override {
|
||||
void visit(AstForeach* nodep) override {
|
||||
// Special, as statements need to be put in different places
|
||||
// Body insert just before themselves
|
||||
m_insStmtp = nullptr; // First thing should be new statement
|
||||
|
|
@ -119,7 +119,7 @@ private:
|
|||
// Done the loop
|
||||
m_insStmtp = nullptr; // Next thing should be new statement
|
||||
}
|
||||
virtual void visit(AstJumpBlock* nodep) override {
|
||||
void visit(AstJumpBlock* nodep) override {
|
||||
// Special, as statements need to be put in different places
|
||||
// Body insert just before themselves
|
||||
m_insStmtp = nullptr; // First thing should be new statement
|
||||
|
|
@ -127,7 +127,7 @@ private:
|
|||
// Done the loop
|
||||
m_insStmtp = nullptr; // Next thing should be new statement
|
||||
}
|
||||
virtual void visit(AstNodeIf* nodep) override {
|
||||
void visit(AstNodeIf* nodep) override {
|
||||
m_insStmtp = nodep;
|
||||
iterateAndNextNull(nodep->condp());
|
||||
m_insStmtp = nullptr;
|
||||
|
|
@ -135,7 +135,7 @@ private:
|
|||
iterateAndNextNull(nodep->elsesp());
|
||||
m_insStmtp = nullptr;
|
||||
}
|
||||
virtual void visit(AstCaseItem* nodep) override {
|
||||
void visit(AstCaseItem* nodep) override {
|
||||
m_insMode = IM_BEFORE;
|
||||
{
|
||||
VL_RESTORER(m_unsupportedHere);
|
||||
|
|
@ -145,30 +145,30 @@ private:
|
|||
m_insStmtp = nullptr; // Next thing should be new statement
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
}
|
||||
virtual void visit(AstNodeFor* nodep) override { // LCOV_EXCL_LINE
|
||||
void visit(AstNodeFor* nodep) override { // LCOV_EXCL_LINE
|
||||
nodep->v3fatalSrc(
|
||||
"For statements should have been converted to while statements in V3Begin.cpp");
|
||||
}
|
||||
virtual void visit(AstDelay* nodep) override {
|
||||
void visit(AstDelay* nodep) override {
|
||||
m_insStmtp = nodep;
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
m_insStmtp = nullptr;
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
m_insStmtp = nullptr;
|
||||
}
|
||||
virtual void visit(AstEventControl* nodep) override {
|
||||
void visit(AstEventControl* nodep) override {
|
||||
m_insStmtp = nullptr;
|
||||
iterateAndNextNull(nodep->stmtsp());
|
||||
m_insStmtp = nullptr;
|
||||
}
|
||||
virtual void visit(AstWait* nodep) override {
|
||||
void visit(AstWait* nodep) override {
|
||||
m_insStmtp = nodep;
|
||||
iterateAndNextNull(nodep->condp());
|
||||
m_insStmtp = nullptr;
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
m_insStmtp = nullptr;
|
||||
}
|
||||
virtual void visit(AstNodeStmt* nodep) override {
|
||||
void visit(AstNodeStmt* nodep) override {
|
||||
if (!nodep->isStatement()) {
|
||||
iterateChildren(nodep);
|
||||
return;
|
||||
|
|
@ -184,11 +184,11 @@ private:
|
|||
UINFO(9, "Marking unsupported " << nodep << endl);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstLogAnd* nodep) override { unsupported_visit(nodep); }
|
||||
virtual void visit(AstLogOr* nodep) override { unsupported_visit(nodep); }
|
||||
virtual void visit(AstLogEq* nodep) override { unsupported_visit(nodep); }
|
||||
virtual void visit(AstLogIf* nodep) override { unsupported_visit(nodep); }
|
||||
virtual void visit(AstNodeCond* nodep) override { unsupported_visit(nodep); }
|
||||
void visit(AstLogAnd* nodep) override { unsupported_visit(nodep); }
|
||||
void visit(AstLogOr* nodep) override { unsupported_visit(nodep); }
|
||||
void visit(AstLogEq* nodep) override { unsupported_visit(nodep); }
|
||||
void visit(AstLogIf* nodep) override { unsupported_visit(nodep); }
|
||||
void visit(AstNodeCond* nodep) override { unsupported_visit(nodep); }
|
||||
void prepost_visit(AstNodeTriop* nodep) {
|
||||
// Check if we are underneath a statement
|
||||
if (!m_insStmtp) {
|
||||
|
|
@ -276,17 +276,17 @@ private:
|
|||
nodep->replaceWith(new AstVarRef(varrefp->fileline(), varp, VAccess::WRITE));
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
virtual void visit(AstPreAdd* nodep) override { prepost_visit(nodep); }
|
||||
virtual void visit(AstPostAdd* nodep) override { prepost_visit(nodep); }
|
||||
virtual void visit(AstPreSub* nodep) override { prepost_visit(nodep); }
|
||||
virtual void visit(AstPostSub* nodep) override { prepost_visit(nodep); }
|
||||
virtual void visit(AstGenFor* nodep) override { iterateChildren(nodep); }
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstPreAdd* nodep) override { prepost_visit(nodep); }
|
||||
void visit(AstPostAdd* nodep) override { prepost_visit(nodep); }
|
||||
void visit(AstPreSub* nodep) override { prepost_visit(nodep); }
|
||||
void visit(AstPostSub* nodep) override { prepost_visit(nodep); }
|
||||
void visit(AstGenFor* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit LinkIncVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
virtual ~LinkIncVisitor() override = default;
|
||||
~LinkIncVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -122,7 +122,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
if (nodep->dead()) return;
|
||||
VL_RESTORER(m_modp);
|
||||
VL_RESTORER(m_modRepeatNum);
|
||||
|
|
@ -132,12 +132,12 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeFTask* nodep) override {
|
||||
void visit(AstNodeFTask* nodep) override {
|
||||
m_ftaskp = nodep;
|
||||
iterateChildren(nodep);
|
||||
m_ftaskp = nullptr;
|
||||
}
|
||||
virtual void visit(AstNodeBlock* nodep) override {
|
||||
void visit(AstNodeBlock* nodep) override {
|
||||
UINFO(8, " " << nodep << endl);
|
||||
VL_RESTORER(m_inFork);
|
||||
m_blockStack.push_back(nodep);
|
||||
|
|
@ -147,7 +147,7 @@ private:
|
|||
}
|
||||
m_blockStack.pop_back();
|
||||
}
|
||||
virtual void visit(AstRepeat* nodep) override {
|
||||
void visit(AstRepeat* nodep) override {
|
||||
// So later optimizations don't need to deal with them,
|
||||
// REPEAT(count,body) -> loop=count,WHILE(loop>0) { body, loop-- }
|
||||
// Note var can be signed or unsigned based on original number.
|
||||
|
|
@ -175,7 +175,7 @@ private:
|
|||
nodep->replaceWith(newp);
|
||||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
virtual void visit(AstWhile* nodep) override {
|
||||
void visit(AstWhile* nodep) override {
|
||||
// Don't need to track AstRepeat/AstFor as they have already been converted
|
||||
VL_RESTORER(m_loopp);
|
||||
VL_RESTORER(m_loopInc);
|
||||
|
|
@ -189,14 +189,14 @@ private:
|
|||
iterateAndNextNull(nodep->incsp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstForeach* nodep) override {
|
||||
void visit(AstForeach* nodep) override {
|
||||
VL_RESTORER(m_loopp);
|
||||
{
|
||||
m_loopp = nodep;
|
||||
iterateAndNextNull(nodep->bodysp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstReturn* nodep) override {
|
||||
void visit(AstReturn* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
const AstFunc* const funcp = VN_CAST(m_ftaskp, Func);
|
||||
if (m_inFork) {
|
||||
|
|
@ -224,7 +224,7 @@ private:
|
|||
nodep->unlinkFrBack();
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
virtual void visit(AstBreak* nodep) override {
|
||||
void visit(AstBreak* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (!m_loopp) {
|
||||
nodep->v3error("break isn't underneath a loop");
|
||||
|
|
@ -236,7 +236,7 @@ private:
|
|||
nodep->unlinkFrBack();
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
virtual void visit(AstContinue* nodep) override {
|
||||
void visit(AstContinue* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (!m_loopp) {
|
||||
nodep->v3error("continue isn't underneath a loop");
|
||||
|
|
@ -249,7 +249,7 @@ private:
|
|||
nodep->unlinkFrBack();
|
||||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
}
|
||||
virtual void visit(AstDisable* nodep) override {
|
||||
void visit(AstDisable* nodep) override {
|
||||
UINFO(8, " DISABLE " << nodep << endl);
|
||||
iterateChildren(nodep);
|
||||
AstNodeBlock* blockp = nullptr;
|
||||
|
|
@ -274,16 +274,16 @@ private:
|
|||
VL_DO_DANGLING(pushDeletep(nodep), nodep);
|
||||
// if (debug() >= 9) { UINFO(0, "\n"); beginp->dumpTree(cout, " labelo: "); }
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
if (m_loopInc && nodep->varp()) nodep->varp()->usedLoopIdx(true);
|
||||
}
|
||||
virtual void visit(AstConst*) override {}
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstConst*) override {}
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit LinkJumpVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
virtual ~LinkJumpVisitor() override = default;
|
||||
~LinkJumpVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ private:
|
|||
|
||||
// VISITs
|
||||
// Result handing
|
||||
virtual void visit(AstNodeVarRef* nodep) override {
|
||||
void visit(AstNodeVarRef* nodep) override {
|
||||
// VarRef: LValue its reference
|
||||
if (m_setRefLvalue != VAccess::NOCHANGE) nodep->access(m_setRefLvalue);
|
||||
if (nodep->varp()) {
|
||||
|
|
@ -65,7 +65,7 @@ private:
|
|||
}
|
||||
|
||||
// Nodes that start propagating down lvalues
|
||||
virtual void visit(AstPin* nodep) override {
|
||||
void visit(AstPin* nodep) override {
|
||||
if (nodep->modVarp() && nodep->modVarp()->isWritable()) {
|
||||
// When the varref's were created, we didn't know the I/O state
|
||||
// Now that we do, and it's from a output, we know it's a lvalue
|
||||
|
|
@ -76,7 +76,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeAssign* nodep) override {
|
||||
void visit(AstNodeAssign* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
VL_RESTORER(m_setContinuously);
|
||||
{
|
||||
|
|
@ -92,7 +92,7 @@ private:
|
|||
iterateAndNextNull(nodep->rhsp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstRelease* nodep) override {
|
||||
void visit(AstRelease* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
VL_RESTORER(m_setContinuously);
|
||||
{
|
||||
|
|
@ -101,14 +101,14 @@ private:
|
|||
iterateAndNextNull(nodep->lhsp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstFireEvent* nodep) override {
|
||||
void visit(AstFireEvent* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
m_setRefLvalue = VAccess::WRITE;
|
||||
iterateAndNextNull(nodep->operandp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCastDynamic* nodep) override {
|
||||
void visit(AstCastDynamic* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
m_setRefLvalue = VAccess::NOCHANGE;
|
||||
|
|
@ -117,7 +117,7 @@ private:
|
|||
iterateAndNextNull(nodep->top());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstFOpen* nodep) override {
|
||||
void visit(AstFOpen* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
m_setRefLvalue = VAccess::WRITE;
|
||||
|
|
@ -127,7 +127,7 @@ private:
|
|||
iterateAndNextNull(nodep->modep());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstFOpenMcd* nodep) override {
|
||||
void visit(AstFOpenMcd* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
m_setRefLvalue = VAccess::WRITE;
|
||||
|
|
@ -136,14 +136,14 @@ private:
|
|||
iterateAndNextNull(nodep->filenamep());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstFClose* nodep) override {
|
||||
void visit(AstFClose* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
m_setRefLvalue = VAccess::WRITE;
|
||||
iterateAndNextNull(nodep->filep());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstFError* nodep) override {
|
||||
void visit(AstFError* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
m_setRefLvalue = VAccess::WRITE;
|
||||
|
|
@ -151,21 +151,21 @@ private:
|
|||
iterateAndNextNull(nodep->strp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstFFlush* nodep) override {
|
||||
void visit(AstFFlush* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
m_setRefLvalue = VAccess::WRITE;
|
||||
iterateAndNextNull(nodep->filep());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstFGetC* nodep) override {
|
||||
void visit(AstFGetC* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
m_setRefLvalue = VAccess::WRITE;
|
||||
iterateAndNextNull(nodep->filep());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstFGetS* nodep) override {
|
||||
void visit(AstFGetS* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
m_setRefLvalue = VAccess::WRITE;
|
||||
|
|
@ -173,7 +173,7 @@ private:
|
|||
iterateAndNextNull(nodep->strgp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstFRead* nodep) override {
|
||||
void visit(AstFRead* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
m_setRefLvalue = VAccess::WRITE;
|
||||
|
|
@ -181,7 +181,7 @@ private:
|
|||
iterateAndNextNull(nodep->filep());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstFScanF* nodep) override {
|
||||
void visit(AstFScanF* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
m_setRefLvalue = VAccess::WRITE;
|
||||
|
|
@ -189,33 +189,33 @@ private:
|
|||
iterateAndNextNull(nodep->exprsp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstFUngetC* nodep) override {
|
||||
void visit(AstFUngetC* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
m_setRefLvalue = VAccess::WRITE;
|
||||
iterateAndNextNull(nodep->filep());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSScanF* nodep) override {
|
||||
void visit(AstSScanF* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
m_setRefLvalue = VAccess::WRITE;
|
||||
iterateAndNextNull(nodep->exprsp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSysIgnore* nodep) override {
|
||||
void visit(AstSysIgnore* nodep) override {
|
||||
// Can't know if lvalue or not; presume so as stricter
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstRand* nodep) override {
|
||||
void visit(AstRand* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
if (!nodep->urandom()) m_setRefLvalue = VAccess::WRITE;
|
||||
iterateAndNextNull(nodep->seedp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstReadMem* nodep) override {
|
||||
void visit(AstReadMem* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
m_setRefLvalue = VAccess::WRITE;
|
||||
|
|
@ -226,14 +226,14 @@ private:
|
|||
iterateAndNextNull(nodep->msbp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstTestPlusArgs* nodep) override {
|
||||
void visit(AstTestPlusArgs* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
m_setRefLvalue = VAccess::NOCHANGE;
|
||||
iterateAndNextNull(nodep->searchp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstValuePlusArgs* nodep) override {
|
||||
void visit(AstValuePlusArgs* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
m_setRefLvalue = VAccess::NOCHANGE;
|
||||
|
|
@ -242,7 +242,7 @@ private:
|
|||
iterateAndNextNull(nodep->outp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSFormat* nodep) override {
|
||||
void visit(AstSFormat* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
m_setRefLvalue = VAccess::WRITE;
|
||||
|
|
@ -261,13 +261,13 @@ private:
|
|||
iterateAndNextNull(nodep->thsp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstPreAdd* nodep) override { prepost_visit(nodep); }
|
||||
virtual void visit(AstPostAdd* nodep) override { prepost_visit(nodep); }
|
||||
virtual void visit(AstPreSub* nodep) override { prepost_visit(nodep); }
|
||||
virtual void visit(AstPostSub* nodep) override { prepost_visit(nodep); }
|
||||
void visit(AstPreAdd* nodep) override { prepost_visit(nodep); }
|
||||
void visit(AstPostAdd* nodep) override { prepost_visit(nodep); }
|
||||
void visit(AstPreSub* nodep) override { prepost_visit(nodep); }
|
||||
void visit(AstPostSub* nodep) override { prepost_visit(nodep); }
|
||||
|
||||
// Nodes that change LValue state
|
||||
virtual void visit(AstSel* nodep) override {
|
||||
void visit(AstSel* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
|
|
@ -277,7 +277,7 @@ private:
|
|||
iterateAndNextNull(nodep->thsp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeSel* nodep) override {
|
||||
void visit(AstNodeSel* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{ // Only set lvalues on the from
|
||||
iterateAndNextNull(nodep->lhsp());
|
||||
|
|
@ -285,14 +285,14 @@ private:
|
|||
iterateAndNextNull(nodep->rhsp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCellArrayRef* nodep) override {
|
||||
void visit(AstCellArrayRef* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{ // selp is not an lvalue
|
||||
m_setRefLvalue = VAccess::NOCHANGE;
|
||||
iterateAndNextNull(nodep->selp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodePreSel* nodep) override {
|
||||
void visit(AstNodePreSel* nodep) override {
|
||||
VL_RESTORER(m_setRefLvalue);
|
||||
{ // Only set lvalues on the from
|
||||
iterateAndNextNull(nodep->fromp());
|
||||
|
|
@ -301,12 +301,12 @@ private:
|
|||
iterateAndNextNull(nodep->thsp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeFTask* nodep) override {
|
||||
void visit(AstNodeFTask* nodep) override {
|
||||
m_ftaskp = nodep;
|
||||
iterateChildren(nodep);
|
||||
m_ftaskp = nullptr;
|
||||
}
|
||||
virtual void visit(AstNodeFTaskRef* nodep) override {
|
||||
void visit(AstNodeFTaskRef* nodep) override {
|
||||
AstNode* pinp = nodep->pinsp();
|
||||
const AstNodeFTask* const taskp = nodep->taskp();
|
||||
// We'll deal with mismatching pins later
|
||||
|
|
@ -328,7 +328,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
|
@ -336,7 +336,7 @@ public:
|
|||
: m_setRefLvalue{start} {
|
||||
iterate(nodep);
|
||||
}
|
||||
virtual ~LinkLValueVisitor() override = default;
|
||||
~LinkLValueVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ void V3LinkLevel::timescaling(const ModVec& mods) {
|
|||
}
|
||||
}
|
||||
unit = v3Global.opt.timeComputeUnit(unit); // Apply override
|
||||
if (unit.isNone()) unit = VTimescale(VTimescale::TS_DEFAULT);
|
||||
if (unit.isNone()) unit = VTimescale{VTimescale::TS_DEFAULT};
|
||||
v3Global.rootp()->timeunit(unit);
|
||||
|
||||
bool dunitTimed = false; // $unit had a timeunit
|
||||
|
|
@ -127,7 +127,7 @@ void V3LinkLevel::timescaling(const ModVec& mods) {
|
|||
|
||||
if (v3Global.rootp()->timeprecision().isNone()) {
|
||||
v3Global.rootp()->timeprecisionMerge(v3Global.rootp()->fileline(),
|
||||
VTimescale(VTimescale::TS_DEFAULT));
|
||||
VTimescale{VTimescale::TS_DEFAULT});
|
||||
}
|
||||
|
||||
// Classes under package have timescale propaged in V3LinkParse
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ private:
|
|||
// We could have verilog.l create a new one on every token,
|
||||
// but that's a lot more structures than only doing AST nodes.
|
||||
if (m_filelines.find(nodep->fileline()) != m_filelines.end()) {
|
||||
nodep->fileline(new FileLine(nodep->fileline()));
|
||||
nodep->fileline(new FileLine{nodep->fileline()});
|
||||
}
|
||||
m_filelines.insert(nodep->fileline());
|
||||
}
|
||||
|
|
@ -122,7 +122,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITs
|
||||
virtual void visit(AstNodeFTask* nodep) override {
|
||||
void visit(AstNodeFTask* nodep) override {
|
||||
if (!nodep->user1SetOnce()) { // Process only once.
|
||||
V3Config::applyFTask(m_modp, nodep);
|
||||
cleanFileline(nodep);
|
||||
|
|
@ -139,7 +139,7 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeFTaskRef* nodep) override {
|
||||
void visit(AstNodeFTaskRef* nodep) override {
|
||||
if (!nodep->user1SetOnce()) { // Process only once.
|
||||
cleanFileline(nodep);
|
||||
UINFO(5, " " << nodep << endl);
|
||||
|
|
@ -150,20 +150,20 @@ private:
|
|||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeDType* nodep) override { visitIterateNodeDType(nodep); }
|
||||
virtual void visit(AstEnumDType* nodep) override {
|
||||
void visit(AstNodeDType* nodep) override { visitIterateNodeDType(nodep); }
|
||||
void visit(AstEnumDType* nodep) override {
|
||||
if (nodep->name() == "") {
|
||||
nodep->name(nameFromTypedef(nodep)); // Might still remain ""
|
||||
}
|
||||
visitIterateNodeDType(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeUOrStructDType* nodep) override {
|
||||
void visit(AstNodeUOrStructDType* nodep) override {
|
||||
if (nodep->name() == "") {
|
||||
nodep->name(nameFromTypedef(nodep)); // Might still remain ""
|
||||
}
|
||||
visitIterateNodeDType(nodep);
|
||||
}
|
||||
virtual void visit(AstEnumItem* nodep) override {
|
||||
void visit(AstEnumItem* nodep) override {
|
||||
// Expand ranges
|
||||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -198,7 +198,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
void visit(AstVar* nodep) override {
|
||||
cleanFileline(nodep);
|
||||
if (nodep->lifetime().isNone()) {
|
||||
if (m_ftaskp) {
|
||||
|
|
@ -296,7 +296,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstAttrOf* nodep) override {
|
||||
void visit(AstAttrOf* nodep) override {
|
||||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
if (nodep->attrType() == VAttrType::DT_PUBLIC) {
|
||||
|
|
@ -365,7 +365,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstAlwaysPublic* nodep) override {
|
||||
void visit(AstAlwaysPublic* nodep) override {
|
||||
// AlwaysPublic was attached under a var, but it's a statement that should be
|
||||
// at the same level as the var
|
||||
cleanFileline(nodep);
|
||||
|
|
@ -381,7 +381,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstDefImplicitDType* nodep) override {
|
||||
void visit(AstDefImplicitDType* nodep) override {
|
||||
cleanFileline(nodep);
|
||||
UINFO(8, " DEFIMPLICIT " << nodep << endl);
|
||||
// Must remember what names we've already created, and combine duplicates
|
||||
|
|
@ -422,7 +422,7 @@ private:
|
|||
VL_DO_DANGLING(nodep->deleteTree(), nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstForeach* nodep) override {
|
||||
void visit(AstForeach* nodep) override {
|
||||
// FOREACH(array, loopvars, body)
|
||||
UINFO(9, "FOREACH " << nodep << endl);
|
||||
// Separate iteration vars from base from variable
|
||||
|
|
@ -457,7 +457,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
V3Config::applyModule(nodep);
|
||||
|
||||
VL_RESTORER(m_modp);
|
||||
|
|
@ -490,16 +490,16 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeProcedure* nodep) override { visitIterateNoValueMod(nodep); }
|
||||
virtual void visit(AstAlways* nodep) override {
|
||||
void visit(AstNodeProcedure* nodep) override { visitIterateNoValueMod(nodep); }
|
||||
void visit(AstAlways* nodep) override {
|
||||
VL_RESTORER(m_inAlways);
|
||||
m_inAlways = true;
|
||||
visitIterateNoValueMod(nodep);
|
||||
}
|
||||
virtual void visit(AstCover* nodep) override { visitIterateNoValueMod(nodep); }
|
||||
virtual void visit(AstRestrict* nodep) override { visitIterateNoValueMod(nodep); }
|
||||
void visit(AstCover* nodep) override { visitIterateNoValueMod(nodep); }
|
||||
void visit(AstRestrict* nodep) override { visitIterateNoValueMod(nodep); }
|
||||
|
||||
virtual void visit(AstBegin* nodep) override {
|
||||
void visit(AstBegin* nodep) override {
|
||||
V3Config::applyCoverageBlock(m_modp, nodep);
|
||||
cleanFileline(nodep);
|
||||
const AstNode* const backp = nodep->backp();
|
||||
|
|
@ -525,7 +525,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstGenCase* nodep) override {
|
||||
void visit(AstGenCase* nodep) override {
|
||||
++m_genblkNum;
|
||||
cleanFileline(nodep);
|
||||
{
|
||||
|
|
@ -536,7 +536,7 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstGenIf* nodep) override {
|
||||
void visit(AstGenIf* nodep) override {
|
||||
cleanFileline(nodep);
|
||||
const bool nestedIf
|
||||
= (VN_IS(nodep->backp(), Begin) && nestedIfBegin(VN_CAST(nodep->backp(), Begin)));
|
||||
|
|
@ -551,39 +551,39 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCase* nodep) override {
|
||||
void visit(AstCase* nodep) override {
|
||||
V3Config::applyCase(nodep);
|
||||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstPrintTimeScale* nodep) override {
|
||||
void visit(AstPrintTimeScale* nodep) override {
|
||||
// Inlining may change hierarchy, so just save timescale where needed
|
||||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
nodep->name(m_modp->name());
|
||||
nodep->timeunit(m_modp->timeunit());
|
||||
}
|
||||
virtual void visit(AstSFormatF* nodep) override {
|
||||
void visit(AstSFormatF* nodep) override {
|
||||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
nodep->timeunit(m_modp->timeunit());
|
||||
}
|
||||
virtual void visit(AstTime* nodep) override {
|
||||
void visit(AstTime* nodep) override {
|
||||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
nodep->timeunit(m_modp->timeunit());
|
||||
}
|
||||
virtual void visit(AstTimeD* nodep) override {
|
||||
void visit(AstTimeD* nodep) override {
|
||||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
nodep->timeunit(m_modp->timeunit());
|
||||
}
|
||||
virtual void visit(AstTimeImport* nodep) override {
|
||||
void visit(AstTimeImport* nodep) override {
|
||||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
nodep->timeunit(m_modp->timeunit());
|
||||
}
|
||||
virtual void visit(AstEventControl* nodep) override {
|
||||
void visit(AstEventControl* nodep) override {
|
||||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
AstAlways* const alwaysp = VN_CAST(nodep->backp(), Always);
|
||||
|
|
@ -603,7 +603,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
// Default: Just iterate
|
||||
cleanFileline(nodep);
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -612,7 +612,7 @@ private:
|
|||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit LinkParseVisitor(AstNetlist* rootp) { iterate(rootp); }
|
||||
virtual ~LinkParseVisitor() override = default;
|
||||
~LinkParseVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ private:
|
|||
// TODO: Most of these visitors are here for historical reasons.
|
||||
// TODO: ExpectDecriptor can move to data type resolution, and the rest
|
||||
// TODO: could move to V3LinkParse to get them out of the way of elaboration
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
// Module: Create sim table for entire module and iterate
|
||||
UINFO(8, "MODULE " << nodep << endl);
|
||||
if (nodep->dead()) return;
|
||||
|
|
@ -74,14 +74,14 @@ private:
|
|||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstClass* nodep) override {
|
||||
void visit(AstClass* nodep) override {
|
||||
VL_RESTORER(m_classp);
|
||||
{
|
||||
m_classp = nodep;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstInitialAutomatic* nodep) override {
|
||||
void visit(AstInitialAutomatic* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
// Initial assignments under function/tasks can just be simple
|
||||
// assignments without the initial
|
||||
|
|
@ -89,13 +89,13 @@ private:
|
|||
VL_DO_DANGLING(nodep->replaceWith(nodep->bodysp()->unlinkFrBackWithNext()), nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeCoverOrAssert* nodep) override {
|
||||
void visit(AstNodeCoverOrAssert* nodep) override {
|
||||
if (m_assertp) nodep->v3error("Assert not allowed under another assert");
|
||||
m_assertp = nodep;
|
||||
iterateChildren(nodep);
|
||||
m_assertp = nullptr;
|
||||
}
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
void visit(AstVar* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (m_classp && !nodep->isParam()) nodep->varType(VVarType::MEMBER);
|
||||
if (m_ftaskp) nodep->funcLocal(true);
|
||||
|
|
@ -105,13 +105,13 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeVarRef* nodep) override {
|
||||
void visit(AstNodeVarRef* nodep) override {
|
||||
// VarRef: Resolve its reference
|
||||
if (nodep->varp()) nodep->varp()->usedParam(true);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeFTask* nodep) override {
|
||||
void visit(AstNodeFTask* nodep) override {
|
||||
// NodeTask: Remember its name for later resolution
|
||||
if (m_underGenerate) nodep->underGenerate(true);
|
||||
// Remember the existing symbol table scope
|
||||
|
|
@ -139,13 +139,13 @@ private:
|
|||
m_ftaskp = nullptr;
|
||||
if (nodep->dpiExport()) nodep->scopeNamep(new AstScopeName{nodep->fileline(), false});
|
||||
}
|
||||
virtual void visit(AstNodeFTaskRef* nodep) override {
|
||||
void visit(AstNodeFTaskRef* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
if (nodep->taskp() && (nodep->taskp()->dpiContext() || nodep->taskp()->dpiExport())) {
|
||||
nodep->scopeNamep(new AstScopeName{nodep->fileline(), false});
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodePreSel* nodep) override {
|
||||
void visit(AstNodePreSel* nodep) override {
|
||||
if (!nodep->attrp()) {
|
||||
iterateChildren(nodep);
|
||||
// Constification may change the fromp() to a constant, which will lose the
|
||||
|
|
@ -180,7 +180,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstCaseItem* nodep) override {
|
||||
void visit(AstCaseItem* nodep) override {
|
||||
// Move default caseItems to the bottom of the list
|
||||
// That saves us from having to search each case list twice, for non-defaults and defaults
|
||||
iterateChildren(nodep);
|
||||
|
|
@ -192,7 +192,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstPragma* nodep) override {
|
||||
void visit(AstPragma* nodep) override {
|
||||
if (nodep->pragType() == VPragmaType::HIER_BLOCK) {
|
||||
UASSERT_OBJ(m_modp, nodep, "HIER_BLOCK not under a module");
|
||||
// If this is hierarchical mode which is to lib-create,
|
||||
|
|
@ -342,39 +342,39 @@ private:
|
|||
if (filep && filep->varp()) filep->varp()->attrFileDescr(true);
|
||||
}
|
||||
|
||||
virtual void visit(AstFOpen* nodep) override {
|
||||
void visit(AstFOpen* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
expectDescriptor(nodep, VN_CAST(nodep->filep(), NodeVarRef));
|
||||
}
|
||||
virtual void visit(AstFOpenMcd* nodep) override {
|
||||
void visit(AstFOpenMcd* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
expectDescriptor(nodep, VN_CAST(nodep->filep(), NodeVarRef));
|
||||
}
|
||||
virtual void visit(AstFClose* nodep) override {
|
||||
void visit(AstFClose* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
expectDescriptor(nodep, VN_CAST(nodep->filep(), NodeVarRef));
|
||||
}
|
||||
virtual void visit(AstFError* nodep) override {
|
||||
void visit(AstFError* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
expectDescriptor(nodep, VN_CAST(nodep->filep(), NodeVarRef));
|
||||
}
|
||||
virtual void visit(AstFEof* nodep) override {
|
||||
void visit(AstFEof* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
expectDescriptor(nodep, VN_CAST(nodep->filep(), NodeVarRef));
|
||||
}
|
||||
virtual void visit(AstFRead* nodep) override {
|
||||
void visit(AstFRead* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
expectDescriptor(nodep, VN_CAST(nodep->filep(), NodeVarRef));
|
||||
}
|
||||
virtual void visit(AstFScanF* nodep) override {
|
||||
void visit(AstFScanF* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
expectFormat(nodep, nodep->text(), nodep->exprsp(), true);
|
||||
}
|
||||
virtual void visit(AstSScanF* nodep) override {
|
||||
void visit(AstSScanF* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
expectFormat(nodep, nodep->text(), nodep->exprsp(), true);
|
||||
}
|
||||
virtual void visit(AstSFormatF* nodep) override {
|
||||
void visit(AstSFormatF* nodep) override {
|
||||
iterateChildren(nodep);
|
||||
// Cleanup old-school displays without format arguments
|
||||
if (!nodep->hasFormat()) {
|
||||
|
|
@ -397,7 +397,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstUdpTable* nodep) override {
|
||||
void visit(AstUdpTable* nodep) override {
|
||||
UINFO(5, "UDPTABLE " << nodep << endl);
|
||||
if (!v3Global.opt.bboxUnsup()) {
|
||||
// We don't warn until V3Inst, so that UDPs that are in libraries and
|
||||
|
|
@ -428,49 +428,49 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstScCtor* nodep) override {
|
||||
void visit(AstScCtor* nodep) override {
|
||||
// Constructor info means the module must remain public
|
||||
m_modp->modPublic(true);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstScDtor* nodep) override {
|
||||
void visit(AstScDtor* nodep) override {
|
||||
// Destructor info means the module must remain public
|
||||
m_modp->modPublic(true);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstScInt* nodep) override {
|
||||
void visit(AstScInt* nodep) override {
|
||||
// Special class info means the module must remain public
|
||||
m_modp->modPublic(true);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstIfaceRefDType* nodep) override {
|
||||
void visit(AstIfaceRefDType* nodep) override {
|
||||
// LinkDot checked modports, now remove references to them
|
||||
// Keeping them later caused problems with InstDeArray,
|
||||
// as it needed to make new modport arrays and such
|
||||
nodep->modportp(nullptr);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
// virtual void visit(AstModport* nodep) override { ... }
|
||||
// void visit(AstModport* nodep) override { ... }
|
||||
// We keep Modport's themselves around for XML dump purposes
|
||||
|
||||
virtual void visit(AstGenFor* nodep) override {
|
||||
void visit(AstGenFor* nodep) override {
|
||||
VL_RESTORER(m_underGenerate);
|
||||
m_underGenerate = true;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
virtual void visit(AstGenIf* nodep) override {
|
||||
void visit(AstGenIf* nodep) override {
|
||||
VL_RESTORER(m_underGenerate);
|
||||
m_underGenerate = true;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit LinkResolveVisitor(AstNetlist* rootp) { iterate(rootp); }
|
||||
virtual ~LinkResolveVisitor() override = default;
|
||||
~LinkResolveVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
@ -487,29 +487,29 @@ private:
|
|||
VL_DEBUG_FUNC; // Declare debug()
|
||||
|
||||
// VISITs
|
||||
virtual void visit(AstNetlist* nodep) override {
|
||||
void visit(AstNetlist* nodep) override {
|
||||
// Iterate modules backwards, in bottom-up order.
|
||||
iterateChildrenBackwards(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
VL_RESTORER(m_modp);
|
||||
{
|
||||
m_modp = nodep;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCell* nodep) override {
|
||||
void visit(AstCell* nodep) override {
|
||||
// Parent module inherits child's publicity
|
||||
if (nodep->modp()->modPublic()) m_modp->modPublic(true);
|
||||
//** No iteration for speed
|
||||
}
|
||||
virtual void visit(AstNodeMath*) override {} // Accelerate
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNodeMath*) override {} // Accelerate
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit LinkBotupVisitor(AstNetlist* rootp) { iterate(rootp); }
|
||||
virtual ~LinkBotupVisitor() override = default;
|
||||
~LinkBotupVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -123,12 +123,12 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep) override {
|
||||
void visit(AstNetlist* nodep) override {
|
||||
iterateChildrenConst(nodep);
|
||||
moveVarScopes();
|
||||
}
|
||||
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
UINFO(4, " CFUNC " << nodep << endl);
|
||||
VL_RESTORER(m_cfuncp);
|
||||
VL_RESTORER(m_nodeDepth);
|
||||
|
|
@ -140,12 +140,12 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstCCall* nodep) override {
|
||||
void visit(AstCCall* nodep) override {
|
||||
m_cfuncp->user1(true); // Mark caller as not a leaf function
|
||||
iterateChildrenConst(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeAssign* nodep) override {
|
||||
void visit(AstNodeAssign* nodep) override {
|
||||
// Analyze RHS first so "a = a + 1" is detected as a read before write
|
||||
iterate(nodep->rhsp());
|
||||
// For now we only consider an assignment that is directly under the function, (in
|
||||
|
|
@ -163,7 +163,7 @@ private:
|
|||
iterate(nodep->lhsp());
|
||||
}
|
||||
|
||||
virtual void visit(AstVarScope* nodep) override {
|
||||
void visit(AstVarScope* nodep) override {
|
||||
if (!nodep->varp()->isPrimaryIO() // Not an IO the user wants to interact with
|
||||
&& !nodep->varp()->isSigPublic() // Not something the user wants to interact with
|
||||
&& !nodep->varp()->isFuncLocal() // Not already a function local (e.g.: argument)
|
||||
|
|
@ -177,7 +177,7 @@ private:
|
|||
// No iterate; Don't want varrefs under it (e.g.: in child dtype?)
|
||||
}
|
||||
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
UASSERT_OBJ(m_cfuncp, nodep, "AstVarRef not under function");
|
||||
|
||||
AstVarScope* const varScopep = nodep->varScopep();
|
||||
|
|
@ -201,7 +201,7 @@ private:
|
|||
// No iterate; Don't want varrefs under it (e.g.: in child dtype?)
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep) override {
|
||||
void visit(AstNode* nodep) override {
|
||||
++m_nodeDepth;
|
||||
iterateChildrenConst(nodep);
|
||||
--m_nodeDepth;
|
||||
|
|
@ -210,7 +210,7 @@ private:
|
|||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit LocalizeVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
virtual ~LocalizeVisitor() override {
|
||||
~LocalizeVisitor() override {
|
||||
V3Stats::addStat("Optimizations, Vars localized", m_statLocVars);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -823,7 +823,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeAssign* nodep) override {
|
||||
void visit(AstNodeAssign* nodep) override {
|
||||
if (AstNode* const condp = (*m_stmtPropertiesp)(nodep).m_condp) {
|
||||
// Check if mergeable
|
||||
if (!checkOrMakeMergeable(nodep)) return;
|
||||
|
|
@ -836,7 +836,7 @@ private:
|
|||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeIf* nodep) override {
|
||||
void visit(AstNodeIf* nodep) override {
|
||||
// Check if mergeable
|
||||
if (!checkOrMakeMergeable(nodep)) {
|
||||
// If not mergeable, try to merge the branches
|
||||
|
|
@ -850,25 +850,25 @@ private:
|
|||
addToList(nodep, nodep->condp());
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeStmt* nodep) override {
|
||||
void visit(AstNodeStmt* nodep) override {
|
||||
if (m_mgFirstp && addIfHelpfulElseEndMerge(nodep)) return;
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
// Merge function body
|
||||
if (nodep->stmtsp()) process(nodep->stmtsp());
|
||||
}
|
||||
|
||||
// For speed, only iterate what is necessary.
|
||||
virtual void visit(AstNetlist* nodep) override { iterateAndNextNull(nodep->modulesp()); }
|
||||
virtual void visit(AstNodeModule* nodep) override { iterateAndNextNull(nodep->stmtsp()); }
|
||||
virtual void visit(AstNode* nodep) override {}
|
||||
void visit(AstNetlist* nodep) override { iterateAndNextNull(nodep->modulesp()); }
|
||||
void visit(AstNodeModule* nodep) override { iterateAndNextNull(nodep->stmtsp()); }
|
||||
void visit(AstNode* nodep) override {}
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit MergeCondVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
virtual ~MergeCondVisitor() override {
|
||||
~MergeCondVisitor() override {
|
||||
V3Stats::addStat("Optimizations, MergeCond merges", m_statMerges);
|
||||
V3Stats::addStat("Optimizations, MergeCond merged items", m_statMergedItems);
|
||||
V3Stats::addStat("Optimizations, MergeCond longest merge", m_statLongestList);
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ private:
|
|||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep) override {
|
||||
void visit(AstNodeModule* nodep) override {
|
||||
VL_RESTORER(m_modp);
|
||||
{
|
||||
m_modp = nodep;
|
||||
|
|
@ -76,44 +76,44 @@ private:
|
|||
}
|
||||
}
|
||||
// Add __PVT__ to names of local signals
|
||||
virtual void visit(AstVar* nodep) override {
|
||||
void visit(AstVar* nodep) override {
|
||||
// Don't iterate... Don't need temps for RANGES under the Var.
|
||||
rename(nodep,
|
||||
((!m_modp || !m_modp->isTop()) && !nodep->isSigPublic()
|
||||
&& !nodep->isFuncLocal() // Isn't exposed, and would mess up dpi import wrappers
|
||||
&& !nodep->isTemp())); // Don't bother to rename internal signals
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep) override {
|
||||
void visit(AstCFunc* nodep) override {
|
||||
if (!nodep->user1()) {
|
||||
iterateChildren(nodep);
|
||||
rename(nodep, false);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep) override {
|
||||
void visit(AstVarRef* nodep) override {
|
||||
if (nodep->varp()) {
|
||||
iterate(nodep->varp());
|
||||
nodep->name(nodep->varp()->name());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCell* nodep) override {
|
||||
void visit(AstCell* nodep) override {
|
||||
if (!nodep->user1()) {
|
||||
rename(nodep, (!nodep->modp()->modPublic() && !VN_IS(nodep->modp(), ClassPackage)));
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstMemberDType* nodep) override {
|
||||
void visit(AstMemberDType* nodep) override {
|
||||
if (!nodep->user1()) {
|
||||
rename(nodep, false);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstMemberSel* nodep) override {
|
||||
void visit(AstMemberSel* nodep) override {
|
||||
if (!nodep->user1()) {
|
||||
rename(nodep, false);
|
||||
iterateChildren(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstScope* nodep) override {
|
||||
void visit(AstScope* nodep) override {
|
||||
if (!nodep->user1SetOnce()) {
|
||||
if (nodep->aboveScopep()) iterate(nodep->aboveScopep());
|
||||
if (nodep->aboveCellp()) iterate(nodep->aboveCellp());
|
||||
|
|
@ -130,12 +130,12 @@ private:
|
|||
}
|
||||
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
void visit(AstNode* nodep) override { iterateChildren(nodep); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit NameVisitor(AstNetlist* nodep) { iterate(nodep); }
|
||||
virtual ~NameVisitor() override = default;
|
||||
~NameVisitor() override = default;
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
|
|
|||
|
|
@ -39,12 +39,12 @@ struct V3OptionParser::Impl {
|
|||
class ActionBase VL_NOT_FINAL : public ActionIfs {
|
||||
bool m_undocumented = false; // This option is not documented
|
||||
public:
|
||||
virtual bool isValueNeeded() const override final { return MODE == en::VALUE; }
|
||||
virtual bool isFOnOffAllowed() const override final { return MODE == en::FONOFF; }
|
||||
virtual bool isOnOffAllowed() const override final { return MODE == en::ONOFF; }
|
||||
virtual bool isPartialMatchAllowed() const override final { return ALLOW_PARTIAL_MATCH; }
|
||||
virtual bool isUndocumented() const override { return m_undocumented; }
|
||||
virtual void undocumented() override { m_undocumented = true; }
|
||||
bool isValueNeeded() const override final { return MODE == en::VALUE; }
|
||||
bool isFOnOffAllowed() const override final { return MODE == en::FONOFF; }
|
||||
bool isOnOffAllowed() const override final { return MODE == en::ONOFF; }
|
||||
bool isPartialMatchAllowed() const override final { return ALLOW_PARTIAL_MATCH; }
|
||||
bool isUndocumented() const override { return m_undocumented; }
|
||||
void undocumented() override { m_undocumented = true; }
|
||||
};
|
||||
|
||||
// Actual action classes
|
||||
|
|
@ -78,7 +78,7 @@ struct V3OptionParser::Impl {
|
|||
public: \
|
||||
explicit className(type* valp) \
|
||||
: m_valp(valp) {} \
|
||||
virtual void exec(const char* optp, const char* argp) override { body; } \
|
||||
void exec(const char* optp, const char* argp) override { body; } \
|
||||
}
|
||||
|
||||
V3OPTION_PARSER_DEF_ACT_CLASS(ActionSet, bool, *m_valp = true, en::NONE);
|
||||
|
|
@ -104,7 +104,7 @@ V3OPTION_PARSER_DEF_ACT_CLASS(ActionOnOff, VOptionBool, m_valp->setTrueOrFalse(!
|
|||
using CbType = std::function<funcType>; \
|
||||
explicit className(CbType cb) \
|
||||
: m_cb(std::move(cb)) {} \
|
||||
virtual void exec(const char* optp, const char* argp) override { body; } \
|
||||
void exec(const char* optp, const char* argp) override { body; } \
|
||||
}
|
||||
|
||||
V3OPTION_PARSER_DEF_ACT_CB_CLASS(ActionCbCall, void(void), m_cb(), en::NONE);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <set>
|
||||
|
||||
#include "config_rev.h"
|
||||
|
|
@ -112,7 +113,7 @@ public:
|
|||
V3LangCode::V3LangCode(const char* textp) {
|
||||
// Return code for given string, or ERROR, which is a bad code
|
||||
for (int codei = V3LangCode::L_ERROR; codei < V3LangCode::_ENUM_END; ++codei) {
|
||||
const V3LangCode code = V3LangCode(codei);
|
||||
const V3LangCode code{codei};
|
||||
if (0 == VL_STRCASECMP(textp, code.ascii())) {
|
||||
m_e = code;
|
||||
return;
|
||||
|
|
@ -264,7 +265,7 @@ void VTimescale::parseSlashed(FileLine* fl, const char* textp, VTimescale& unitr
|
|||
if (!precStr.empty()) {
|
||||
VTimescale prec(VTimescale::NONE);
|
||||
bool precbad;
|
||||
prec = VTimescale(precStr, precbad /*ref*/);
|
||||
prec = VTimescale{precStr, precbad /*ref*/};
|
||||
if (precbad) {
|
||||
fl->v3error("`timescale timeprecision syntax error: '" << precStr << "'");
|
||||
return;
|
||||
|
|
@ -1014,6 +1015,17 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
|||
});
|
||||
DECL_OPTION("-bin", Set, &m_bin);
|
||||
DECL_OPTION("-build", Set, &m_build);
|
||||
DECL_OPTION("-build-jobs", CbVal, [this, fl](const char* valp) {
|
||||
int val = std::atoi(valp);
|
||||
if (val < 0) {
|
||||
fl->v3fatal("--build-jobs requires a non-negative integer, but '" << valp
|
||||
<< "' was passed");
|
||||
val = 1;
|
||||
} else if (val == 0) {
|
||||
val = std::thread::hardware_concurrency();
|
||||
}
|
||||
m_buildJobs = val;
|
||||
});
|
||||
|
||||
DECL_OPTION("-CFLAGS", CbVal, callStrSetter(&V3Options::addCFlags));
|
||||
DECL_OPTION("-cc", CbCall, [this]() { ccSet(); });
|
||||
|
|
@ -1160,7 +1172,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
|||
|
||||
DECL_OPTION("-LDFLAGS", CbVal, callStrSetter(&V3Options::addLdLibs));
|
||||
const auto setLang = [this, fl](const char* valp) {
|
||||
const V3LangCode optval = V3LangCode(valp);
|
||||
const V3LangCode optval{valp};
|
||||
if (optval.legal()) {
|
||||
m_defaultLanguage = optval;
|
||||
} else {
|
||||
|
|
@ -1525,14 +1537,19 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
|||
if (!std::strcmp(argv[i], "-j")
|
||||
|| !std::strcmp(argv[i], "--j")) { // Allow gnu -- switches
|
||||
++i;
|
||||
m_buildJobs = 0; // Unlimited parallelism
|
||||
int val = 0;
|
||||
if (i < argc && isdigit(argv[i][0])) {
|
||||
m_buildJobs = std::atoi(argv[i]);
|
||||
if (m_buildJobs <= 0) {
|
||||
fl->v3error("-j accepts positive integer, but '" << argv[i] << "' is passed");
|
||||
val = atoi(argv[i]);
|
||||
if (val < 0) {
|
||||
fl->v3error("-j requires a non-negative integer argument, but '"
|
||||
<< argv[i] << "' was passed");
|
||||
val = 1; // Fall-back value, though we will exit on error.
|
||||
} else if (val == 0) {
|
||||
val = std::thread::hardware_concurrency();
|
||||
}
|
||||
++i;
|
||||
}
|
||||
if (m_buildJobs == -1) m_buildJobs = val;
|
||||
} else if (argv[i][0] == '-' || argv[i][0] == '+') {
|
||||
const char* argvNoDashp = (argv[i][1] == '-') ? (argv[i] + 2) : (argv[i] + 1);
|
||||
if (const int consumed = parser.parse(i, argc, argv)) {
|
||||
|
|
@ -1564,6 +1581,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
|||
++i;
|
||||
}
|
||||
}
|
||||
if (m_buildJobs == -1) m_buildJobs = 1;
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
|
|
|||
|
|
@ -39,12 +39,12 @@ class VOptionBool final {
|
|||
public:
|
||||
enum en : uint8_t { OPT_DEFAULT_FALSE = 0, OPT_DEFAULT_TRUE, OPT_TRUE, OPT_FALSE };
|
||||
enum en m_e;
|
||||
inline VOptionBool()
|
||||
VOptionBool()
|
||||
: m_e{OPT_DEFAULT_FALSE} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VOptionBool(en _e)
|
||||
VOptionBool(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VOptionBool(int _e)
|
||||
explicit VOptionBool(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
bool isDefault() const { return m_e == OPT_DEFAULT_FALSE || m_e == OPT_DEFAULT_TRUE; }
|
||||
|
|
@ -78,12 +78,12 @@ public:
|
|||
enum : uint8_t { TS_DEFAULT = TS_1PS };
|
||||
enum en m_e;
|
||||
// CONSTRUCTOR
|
||||
inline VTimescale()
|
||||
VTimescale()
|
||||
: m_e{NONE} {}
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline VTimescale(en _e)
|
||||
VTimescale(en _e)
|
||||
: m_e{_e} {}
|
||||
explicit inline VTimescale(int _e)
|
||||
explicit VTimescale(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
// Construct from string
|
||||
VTimescale(const string& value, bool& badr);
|
||||
|
|
@ -131,9 +131,9 @@ class TraceFormat final {
|
|||
public:
|
||||
enum en : uint8_t { VCD = 0, FST } m_e;
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
inline TraceFormat(en _e = VCD)
|
||||
TraceFormat(en _e = VCD)
|
||||
: m_e{_e} {}
|
||||
explicit inline TraceFormat(int _e)
|
||||
explicit TraceFormat(int _e)
|
||||
: m_e(static_cast<en>(_e)) {} // Need () or GCC 4.8 false warning
|
||||
operator en() const { return m_e; }
|
||||
bool fst() const { return m_e == FST; }
|
||||
|
|
@ -283,7 +283,7 @@ private:
|
|||
bool m_xInitialEdge = false; // main switch: --x-initial-edge
|
||||
bool m_xmlOnly = false; // main switch: --xml-only
|
||||
|
||||
int m_buildJobs = 1; // main switch: -j
|
||||
int m_buildJobs = -1; // main switch: --build-jobs, -j
|
||||
int m_convergeLimit = 100; // main switch: --converge-limit
|
||||
int m_coverageMaxWidth = 256; // main switch: --coverage-max-width
|
||||
int m_dumpTree = 0; // main switch: --dump-tree
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue