Internals: Fix spacing of function calls. No functional change.
This commit is contained in:
parent
ec538c02d8
commit
75f28fd446
|
@ -20,8 +20,8 @@
|
||||||
// Current simulation time (64-bit unsigned)
|
// Current simulation time (64-bit unsigned)
|
||||||
vluint64_t main_time = 0;
|
vluint64_t main_time = 0;
|
||||||
// Called by $time in Verilog
|
// Called by $time in Verilog
|
||||||
double sc_time_stamp () {
|
double sc_time_stamp() {
|
||||||
return main_time; // Note does conversion to real, to match SystemC
|
return main_time; // Note does conversion to real, to match SystemC
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv, char** env) {
|
int main(int argc, char** argv, char** env) {
|
||||||
|
|
|
@ -49,7 +49,7 @@ VerilatedImp VerilatedImp::s_s;
|
||||||
// User definable functions
|
// User definable functions
|
||||||
|
|
||||||
#ifndef VL_USER_FINISH // Define this to override this function
|
#ifndef VL_USER_FINISH // Define this to override this function
|
||||||
void vl_finish (const char* filename, int linenum, const char* hier) VL_MT_UNSAFE {
|
void vl_finish(const char* filename, int linenum, const char* hier) VL_MT_UNSAFE {
|
||||||
if (0 && hier) {}
|
if (0 && hier) {}
|
||||||
VL_PRINTF("- %s:%d: Verilog $finish\n", filename, linenum); // Not VL_PRINTF_MT, already on main thread
|
VL_PRINTF("- %s:%d: Verilog $finish\n", filename, linenum); // Not VL_PRINTF_MT, already on main thread
|
||||||
if (Verilated::gotFinish()) {
|
if (Verilated::gotFinish()) {
|
||||||
|
@ -62,15 +62,15 @@ void vl_finish (const char* filename, int linenum, const char* hier) VL_MT_UNSAF
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef VL_USER_STOP // Define this to override this function
|
#ifndef VL_USER_STOP // Define this to override this function
|
||||||
void vl_stop (const char* filename, int linenum, const char* hier) VL_MT_UNSAFE {
|
void vl_stop(const char* filename, int linenum, const char* hier) VL_MT_UNSAFE {
|
||||||
Verilated::gotFinish(true);
|
Verilated::gotFinish(true);
|
||||||
Verilated::flushCall();
|
Verilated::flushCall();
|
||||||
vl_fatal (filename,linenum,hier,"Verilog $stop");
|
vl_fatal(filename,linenum,hier,"Verilog $stop");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef VL_USER_FATAL // Define this to override this function
|
#ifndef VL_USER_FATAL // Define this to override this function
|
||||||
void vl_fatal (const char* filename, int linenum, const char* hier, const char* msg) VL_MT_UNSAFE {
|
void vl_fatal(const char* filename, int linenum, const char* hier, const char* msg) VL_MT_UNSAFE {
|
||||||
if (0 && hier) {}
|
if (0 && hier) {}
|
||||||
Verilated::gotFinish(true);
|
Verilated::gotFinish(true);
|
||||||
VL_PRINTF("%%Error: %s:%d: %s\n", filename, linenum, msg); // Not VL_PRINTF_MT, already on main thread
|
VL_PRINTF("%%Error: %s:%d: %s\n", filename, linenum, msg); // Not VL_PRINTF_MT, already on main thread
|
||||||
|
@ -85,7 +85,7 @@ void vl_fatal (const char* filename, int linenum, const char* hier, const char*
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
// Wrapper to call certain functions via messages when multithreaded
|
// Wrapper to call certain functions via messages when multithreaded
|
||||||
|
|
||||||
void VL_FINISH_MT (const char* filename, int linenum, const char* hier) VL_MT_SAFE {
|
void VL_FINISH_MT(const char* filename, int linenum, const char* hier) VL_MT_SAFE {
|
||||||
#ifdef VL_THREADED
|
#ifdef VL_THREADED
|
||||||
VerilatedThreadMsgQueue::post(VerilatedMsg([=](){
|
VerilatedThreadMsgQueue::post(VerilatedMsg([=](){
|
||||||
vl_finish(filename, linenum, hier);
|
vl_finish(filename, linenum, hier);
|
||||||
|
@ -95,7 +95,7 @@ void VL_FINISH_MT (const char* filename, int linenum, const char* hier) VL_MT_SA
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void VL_STOP_MT (const char* filename, int linenum, const char* hier) VL_MT_SAFE {
|
void VL_STOP_MT(const char* filename, int linenum, const char* hier) VL_MT_SAFE {
|
||||||
#ifdef VL_THREADED
|
#ifdef VL_THREADED
|
||||||
VerilatedThreadMsgQueue::post(VerilatedMsg([=](){
|
VerilatedThreadMsgQueue::post(VerilatedMsg([=](){
|
||||||
vl_stop(filename, linenum, hier);
|
vl_stop(filename, linenum, hier);
|
||||||
|
@ -105,7 +105,7 @@ void VL_STOP_MT (const char* filename, int linenum, const char* hier) VL_MT_SAFE
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void VL_FATAL_MT (const char* filename, int linenum, const char* hier, const char* msg) VL_MT_SAFE {
|
void VL_FATAL_MT(const char* filename, int linenum, const char* hier, const char* msg) VL_MT_SAFE {
|
||||||
#ifdef VL_THREADED
|
#ifdef VL_THREADED
|
||||||
VerilatedThreadMsgQueue::post(VerilatedMsg([=](){
|
VerilatedThreadMsgQueue::post(VerilatedMsg([=](){
|
||||||
vl_fatal(filename, linenum, hier, msg);
|
vl_fatal(filename, linenum, hier, msg);
|
||||||
|
@ -1379,7 +1379,7 @@ void VL_READMEM_N(
|
||||||
FILE* fp = fopen(ofilenamep.c_str(), "r");
|
FILE* fp = fopen(ofilenamep.c_str(), "r");
|
||||||
if (VL_UNLIKELY(!fp)) {
|
if (VL_UNLIKELY(!fp)) {
|
||||||
// We don't report the Verilog source filename as it slow to have to pass it down
|
// We don't report the Verilog source filename as it slow to have to pass it down
|
||||||
VL_FATAL_MT (ofilenamep.c_str(), 0, "", "$readmem file not found");
|
VL_FATAL_MT(ofilenamep.c_str(), 0, "", "$readmem file not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Prep for reading
|
// Prep for reading
|
||||||
|
@ -1426,8 +1426,8 @@ void VL_READMEM_N(
|
||||||
//printf(" Value width=%d @%x = %c\n", width, addr, c);
|
//printf(" Value width=%d @%x = %c\n", width, addr, c);
|
||||||
if (VL_UNLIKELY(addr >= static_cast<IData>(depth+array_lsb)
|
if (VL_UNLIKELY(addr >= static_cast<IData>(depth+array_lsb)
|
||||||
|| addr < static_cast<IData>(array_lsb))) {
|
|| addr < static_cast<IData>(array_lsb))) {
|
||||||
VL_FATAL_MT (ofilenamep.c_str(), linenum, "",
|
VL_FATAL_MT(ofilenamep.c_str(), linenum, "",
|
||||||
"$readmem file address beyond bounds of array");
|
"$readmem file address beyond bounds of array");
|
||||||
} else {
|
} else {
|
||||||
int entry = addr - array_lsb;
|
int entry = addr - array_lsb;
|
||||||
QData shift = hex ? VL_ULL(4) : VL_ULL(1);
|
QData shift = hex ? VL_ULL(4) : VL_ULL(1);
|
||||||
|
@ -1456,15 +1456,15 @@ void VL_READMEM_N(
|
||||||
datap[0] |= value;
|
datap[0] |= value;
|
||||||
}
|
}
|
||||||
if (VL_UNLIKELY(value>=(1<<shift))) {
|
if (VL_UNLIKELY(value>=(1<<shift))) {
|
||||||
VL_FATAL_MT (ofilenamep.c_str(), linenum, "",
|
VL_FATAL_MT(ofilenamep.c_str(), linenum, "",
|
||||||
"$readmemb (binary) file contains hex characters");
|
"$readmemb (binary) file contains hex characters");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
innum = true;
|
innum = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VL_FATAL_MT (ofilenamep.c_str(), linenum, "", "$readmem file syntax error");
|
VL_FATAL_MT(ofilenamep.c_str(), linenum, "", "$readmem file syntax error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lastc = c;
|
lastc = c;
|
||||||
|
@ -1474,7 +1474,7 @@ void VL_READMEM_N(
|
||||||
// Final checks
|
// Final checks
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
if (VL_UNLIKELY(end != VL_UL(0xffffffff) && addr != (end+1))) {
|
if (VL_UNLIKELY(end != VL_UL(0xffffffff) && addr != (end+1))) {
|
||||||
VL_FATAL_MT (ofilenamep.c_str(), linenum, "", "$readmem file ended before specified ending-address");
|
VL_FATAL_MT(ofilenamep.c_str(), linenum, "", "$readmem file ended before specified ending-address");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1985,7 +1985,7 @@ void VerilatedScope::varInsert(int finalize, const char* namep, void* datap,
|
||||||
if (!finalize) return;
|
if (!finalize) return;
|
||||||
|
|
||||||
if (!m_varsp) m_varsp = new VerilatedVarNameMap();
|
if (!m_varsp) m_varsp = new VerilatedVarNameMap();
|
||||||
VerilatedVar var (namep, datap, vltype, (VerilatedVarFlags)vlflags, dims);
|
VerilatedVar var(namep, datap, vltype, (VerilatedVarFlags)vlflags, dims);
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap,dims);
|
va_start(ap,dims);
|
||||||
|
|
|
@ -519,31 +519,31 @@ private:
|
||||||
/// User code may wish to replace this function, to do so, define VL_USER_FINISH.
|
/// User code may wish to replace this function, to do so, define VL_USER_FINISH.
|
||||||
/// This code does not have to be thread safe.
|
/// This code does not have to be thread safe.
|
||||||
/// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this.
|
/// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this.
|
||||||
extern void vl_finish (const char* filename, int linenum, const char* hier);
|
extern void vl_finish(const char* filename, int linenum, const char* hier);
|
||||||
|
|
||||||
/// Routine to call for $stop
|
/// Routine to call for $stop
|
||||||
/// User code may wish to replace this function, to do so, define VL_USER_STOP.
|
/// User code may wish to replace this function, to do so, define VL_USER_STOP.
|
||||||
/// This code does not have to be thread safe.
|
/// This code does not have to be thread safe.
|
||||||
/// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this.
|
/// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this.
|
||||||
extern void vl_stop (const char* filename, int linenum, const char* hier);
|
extern void vl_stop(const char* filename, int linenum, const char* hier);
|
||||||
|
|
||||||
/// Routine to call for a couple of fatal messages
|
/// Routine to call for a couple of fatal messages
|
||||||
/// User code may wish to replace this function, to do so, define VL_USER_FATAL.
|
/// User code may wish to replace this function, to do so, define VL_USER_FATAL.
|
||||||
/// This code does not have to be thread safe.
|
/// This code does not have to be thread safe.
|
||||||
/// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this.
|
/// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this.
|
||||||
extern void vl_fatal (const char* filename, int linenum, const char* hier,
|
extern void vl_fatal(const char* filename, int linenum, const char* hier,
|
||||||
const char* msg);
|
const char* msg);
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Extern functions -- Slow path
|
// Extern functions -- Slow path
|
||||||
|
|
||||||
/// Multithread safe wrapper for calls to $finish
|
/// Multithread safe wrapper for calls to $finish
|
||||||
extern void VL_FINISH_MT (const char* filename, int linenum, const char* hier) VL_MT_SAFE;
|
extern void VL_FINISH_MT(const char* filename, int linenum, const char* hier) VL_MT_SAFE;
|
||||||
/// Multithread safe wrapper for calls to $stop
|
/// Multithread safe wrapper for calls to $stop
|
||||||
extern void VL_STOP_MT (const char* filename, int linenum, const char* hier) VL_MT_SAFE;
|
extern void VL_STOP_MT(const char* filename, int linenum, const char* hier) VL_MT_SAFE;
|
||||||
/// Multithread safe wrapper to call for a couple of fatal messages
|
/// Multithread safe wrapper to call for a couple of fatal messages
|
||||||
extern void VL_FATAL_MT (const char* filename, int linenum, const char* hier,
|
extern void VL_FATAL_MT(const char* filename, int linenum, const char* hier,
|
||||||
const char* msg) VL_MT_SAFE;
|
const char* msg) VL_MT_SAFE;
|
||||||
|
|
||||||
/// Print a string, multithread safe. Eventually VL_PRINTF will get called.
|
/// Print a string, multithread safe. Eventually VL_PRINTF will get called.
|
||||||
#ifdef VL_THREADED
|
#ifdef VL_THREADED
|
||||||
|
|
|
@ -261,18 +261,18 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// We assume there's always call to i/f/p in that order
|
// We assume there's always call to i/f/p in that order
|
||||||
void inserti (VerilatedCovImpItem* itemp) VL_EXCLUDES(m_mutex) {
|
void inserti(VerilatedCovImpItem* itemp) VL_EXCLUDES(m_mutex) {
|
||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
assert(!m_insertp);
|
assert(!m_insertp);
|
||||||
m_insertp = itemp;
|
m_insertp = itemp;
|
||||||
}
|
}
|
||||||
void insertf (const char* filenamep, int lineno) VL_EXCLUDES(m_mutex) {
|
void insertf(const char* filenamep, int lineno) VL_EXCLUDES(m_mutex) {
|
||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
m_insertFilenamep = filenamep;
|
m_insertFilenamep = filenamep;
|
||||||
m_insertLineno = lineno;
|
m_insertLineno = lineno;
|
||||||
}
|
}
|
||||||
void insertp (const char* ckeyps[MAX_KEYS],
|
void insertp(const char* ckeyps[MAX_KEYS],
|
||||||
const char* valps[MAX_KEYS]) VL_EXCLUDES(m_mutex) {
|
const char* valps[MAX_KEYS]) VL_EXCLUDES(m_mutex) {
|
||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
assert(m_insertp);
|
assert(m_insertp);
|
||||||
// First two key/vals are filename
|
// First two key/vals are filename
|
||||||
|
@ -334,7 +334,7 @@ public:
|
||||||
#endif
|
#endif
|
||||||
selftest();
|
selftest();
|
||||||
|
|
||||||
std::ofstream os (filename);
|
std::ofstream os(filename);
|
||||||
if (os.fail()) {
|
if (os.fail()) {
|
||||||
std::string msg = std::string("%Error: Can't write '")+filename+"'";
|
std::string msg = std::string("%Error: Can't write '")+filename+"'";
|
||||||
VL_FATAL_MT("",0,"",msg.c_str());
|
VL_FATAL_MT("",0,"",msg.c_str());
|
||||||
|
@ -427,9 +427,9 @@ void VerilatedCov::_insertf(const char* filename, int lineno) VL_MT_SAFE {
|
||||||
#define A(n) const char* key ## n, const char* val ## n // Argument list
|
#define A(n) const char* key ## n, const char* val ## n // Argument list
|
||||||
#define C(n) key ## n, val ## n // Calling argument list
|
#define C(n) key ## n, val ## n // Calling argument list
|
||||||
#define N(n) "","" // Null argument list
|
#define N(n) "","" // Null argument list
|
||||||
void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
|
void VerilatedCov::_insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
|
||||||
A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19),
|
A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19),
|
||||||
A(20),A(21),A(22),A(23),A(24),A(25),A(26),A(27),A(28),A(29)) VL_MT_SAFE {
|
A(20),A(21),A(22),A(23),A(24),A(25),A(26),A(27),A(28),A(29)) VL_MT_SAFE {
|
||||||
const char* keyps[VerilatedCovImpBase::MAX_KEYS]
|
const char* keyps[VerilatedCovImpBase::MAX_KEYS]
|
||||||
= {NULL,NULL,NULL, // filename,lineno,page
|
= {NULL,NULL,NULL, // filename,lineno,page
|
||||||
key0,key1,key2,key3,key4,key5,key6,key7,key8,key9,
|
key0,key1,key2,key3,key4,key5,key6,key7,key8,key9,
|
||||||
|
@ -444,20 +444,20 @@ void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
|
||||||
}
|
}
|
||||||
|
|
||||||
// And versions with fewer arguments (oh for a language with named parameters!)
|
// And versions with fewer arguments (oh for a language with named parameters!)
|
||||||
void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)) VL_MT_SAFE {
|
void VerilatedCov::_insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)) VL_MT_SAFE {
|
||||||
_insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9),
|
_insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9),
|
||||||
N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19),
|
N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19),
|
||||||
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
||||||
}
|
}
|
||||||
void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
|
void VerilatedCov::_insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
|
||||||
A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19)) VL_MT_SAFE {
|
A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19)) VL_MT_SAFE {
|
||||||
_insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9),
|
_insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9),
|
||||||
C(10),C(11),C(12),C(13),C(14),C(15),C(16),C(17),C(18),C(19),
|
C(10),C(11),C(12),C(13),C(14),C(15),C(16),C(17),C(18),C(19),
|
||||||
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
||||||
}
|
}
|
||||||
// Backward compatibility for Verilator
|
// Backward compatibility for Verilator
|
||||||
void VerilatedCov::_insertp (A(0), A(1), K(2),int val2, K(3),int val3,
|
void VerilatedCov::_insertp(A(0), A(1), K(2),int val2, K(3),int val3,
|
||||||
K(4),const std::string& val4, A(5),A(6)) VL_MT_SAFE {
|
K(4),const std::string& val4, A(5),A(6)) VL_MT_SAFE {
|
||||||
std::string val2str = vlCovCvtToStr(val2);
|
std::string val2str = vlCovCvtToStr(val2);
|
||||||
std::string val3str = vlCovCvtToStr(val3);
|
std::string val3str = vlCovCvtToStr(val3);
|
||||||
_insertp(C(0),C(1),
|
_insertp(C(0),C(1),
|
||||||
|
|
|
@ -73,7 +73,7 @@
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
/// Convert VL_COVER_INSERT value arguments to strings
|
/// Convert VL_COVER_INSERT value arguments to strings
|
||||||
|
|
||||||
template< class T> std::string vlCovCvtToStr (const T& t) VL_PURE {
|
template< class T> std::string vlCovCvtToStr(const T& t) VL_PURE {
|
||||||
std::ostringstream os; os<<t; return os.str();
|
std::ostringstream os; os<<t; return os.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,16 +91,16 @@ public:
|
||||||
/// Return default filename
|
/// Return default filename
|
||||||
static const char* defaultFilename() VL_PURE { return "coverage.dat"; }
|
static const char* defaultFilename() VL_PURE { return "coverage.dat"; }
|
||||||
/// Write all coverage data to a file
|
/// Write all coverage data to a file
|
||||||
static void write (const char* filenamep = defaultFilename()) VL_MT_SAFE;
|
static void write(const char* filenamep = defaultFilename()) VL_MT_SAFE;
|
||||||
/// Insert a coverage item
|
/// Insert a coverage item
|
||||||
/// We accept from 1-30 key/value pairs, all as strings.
|
/// We accept from 1-30 key/value pairs, all as strings.
|
||||||
/// Call _insert1, followed by _insert2 and _insert3
|
/// Call _insert1, followed by _insert2 and _insert3
|
||||||
/// Do not call directly; use VL_COVER_INSERT or higher level macros instead
|
/// Do not call directly; use VL_COVER_INSERT or higher level macros instead
|
||||||
// _insert1: Remember item pointer with count. (Not const, as may add zeroing function)
|
// _insert1: Remember item pointer with count. (Not const, as may add zeroing function)
|
||||||
static void _inserti (vluint32_t* itemp) VL_MT_SAFE;
|
static void _inserti(vluint32_t* itemp) VL_MT_SAFE;
|
||||||
static void _inserti (vluint64_t* itemp) VL_MT_SAFE;
|
static void _inserti(vluint64_t* itemp) VL_MT_SAFE;
|
||||||
// _insert2: Set default filename and line number
|
// _insert2: Set default filename and line number
|
||||||
static void _insertf (const char* filename, int lineno) VL_MT_SAFE;
|
static void _insertf(const char* filename, int lineno) VL_MT_SAFE;
|
||||||
// _insert3: Set parameters
|
// _insert3: Set parameters
|
||||||
// We could have just the maximum argument version, but this compiles
|
// We could have just the maximum argument version, but this compiles
|
||||||
// much slower (nearly 2x) than having smaller versions also. However
|
// much slower (nearly 2x) than having smaller versions also. However
|
||||||
|
@ -108,15 +108,15 @@ public:
|
||||||
#define K(n) const char* key ## n
|
#define K(n) const char* key ## n
|
||||||
#define A(n) const char* key ## n, const char* valp ## n // Argument list
|
#define A(n) const char* key ## n, const char* valp ## n // Argument list
|
||||||
#define D(n) const char* key ## n = NULL, const char* valp ## n = NULL // Argument list
|
#define D(n) const char* key ## n = NULL, const char* valp ## n = NULL // Argument list
|
||||||
static void _insertp (D(0),D(1),D(2),D(3),D(4),D(5),D(6),D(7),D(8),D(9));
|
static void _insertp(D(0),D(1),D(2),D(3),D(4),D(5),D(6),D(7),D(8),D(9));
|
||||||
static void _insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)
|
static void _insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)
|
||||||
,A(10),D(11),D(12),D(13),D(14),D(15),D(16),D(17),D(18),D(19));
|
,A(10),D(11),D(12),D(13),D(14),D(15),D(16),D(17),D(18),D(19));
|
||||||
static void _insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)
|
static void _insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)
|
||||||
,A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19)
|
,A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19)
|
||||||
,A(20),D(21),D(22),D(23),D(24),D(25),D(26),D(27),D(28),D(29));
|
,A(20),D(21),D(22),D(23),D(24),D(25),D(26),D(27),D(28),D(29));
|
||||||
// Backward compatibility for Verilator
|
// Backward compatibility for Verilator
|
||||||
static void _insertp (A(0), A(1), K(2),int val2, K(3),int val3,
|
static void _insertp(A(0), A(1), K(2),int val2, K(3),int val3,
|
||||||
K(4),const std::string& val4, A(5),A(6));
|
K(4),const std::string& val4, A(5),A(6));
|
||||||
|
|
||||||
#undef K
|
#undef K
|
||||||
#undef A
|
#undef A
|
||||||
|
@ -124,7 +124,7 @@ public:
|
||||||
/// Clear coverage points (and call delete on all items)
|
/// Clear coverage points (and call delete on all items)
|
||||||
static void clear() VL_MT_SAFE;
|
static void clear() VL_MT_SAFE;
|
||||||
/// Clear items not matching the provided string
|
/// Clear items not matching the provided string
|
||||||
static void clearNonMatch (const char* matchp) VL_MT_SAFE;
|
static void clearNonMatch(const char* matchp) VL_MT_SAFE;
|
||||||
/// Zero coverage points
|
/// Zero coverage points
|
||||||
static void zero() VL_MT_SAFE;
|
static void zero() VL_MT_SAFE;
|
||||||
};
|
};
|
||||||
|
|
|
@ -48,7 +48,7 @@ static const char* const VLTSAVE_TRAILER_STR = "vltsaved"; ///< Value of last by
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Searalization
|
// Searalization
|
||||||
|
|
||||||
bool VerilatedDeserialize::readDiffers (const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
bool VerilatedDeserialize::readDiffers(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
||||||
bufferCheck();
|
bufferCheck();
|
||||||
const vluint8_t* __restrict dp = (const vluint8_t* __restrict)datap;
|
const vluint8_t* __restrict dp = (const vluint8_t* __restrict)datap;
|
||||||
vluint8_t miss = 0;
|
vluint8_t miss = 0;
|
||||||
|
@ -58,7 +58,7 @@ bool VerilatedDeserialize::readDiffers (const void* __restrict datap, size_t siz
|
||||||
return (miss!=0);
|
return (miss!=0);
|
||||||
}
|
}
|
||||||
|
|
||||||
VerilatedDeserialize& VerilatedDeserialize::readAssert (const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
VerilatedDeserialize& VerilatedDeserialize::readAssert(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
||||||
if (VL_UNLIKELY(readDiffers(datap,size))) {
|
if (VL_UNLIKELY(readDiffers(datap,size))) {
|
||||||
std::string fn = filename();
|
std::string fn = filename();
|
||||||
std::string msg = std::string("Can't deserialize save-restore file as was made from different model");
|
std::string msg = std::string("Can't deserialize save-restore file as was made from different model");
|
||||||
|
@ -119,8 +119,8 @@ void VerilatedSave::open(const char* filenamep) VL_MT_UNSAFE_ONE {
|
||||||
assert(0); // Not supported yet.
|
assert(0); // Not supported yet.
|
||||||
} else {
|
} else {
|
||||||
// cppcheck-suppress duplicateExpression
|
// cppcheck-suppress duplicateExpression
|
||||||
m_fd = ::open (filenamep, O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK
|
m_fd = ::open(filenamep, O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK
|
||||||
, 0666);
|
, 0666);
|
||||||
if (m_fd<0) {
|
if (m_fd<0) {
|
||||||
// User code can check isOpen()
|
// User code can check isOpen()
|
||||||
m_isOpen = false;
|
m_isOpen = false;
|
||||||
|
@ -142,8 +142,8 @@ void VerilatedRestore::open(const char* filenamep) VL_MT_UNSAFE_ONE {
|
||||||
assert(0); // Not supported yet.
|
assert(0); // Not supported yet.
|
||||||
} else {
|
} else {
|
||||||
// cppcheck-suppress duplicateExpression
|
// cppcheck-suppress duplicateExpression
|
||||||
m_fd = ::open (filenamep, O_CREAT|O_RDONLY|O_LARGEFILE
|
m_fd = ::open(filenamep, O_CREAT|O_RDONLY|O_LARGEFILE
|
||||||
, 0666);
|
, 0666);
|
||||||
if (m_fd<0) {
|
if (m_fd<0) {
|
||||||
// User code can check isOpen()
|
// User code can check isOpen()
|
||||||
m_isOpen = false;
|
m_isOpen = false;
|
||||||
|
@ -184,7 +184,7 @@ void VerilatedSave::flush() VL_MT_UNSAFE_ONE {
|
||||||
ssize_t remaining = (m_cp - wp);
|
ssize_t remaining = (m_cp - wp);
|
||||||
if (remaining==0) break;
|
if (remaining==0) break;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
ssize_t got = ::write (m_fd, wp, remaining);
|
ssize_t got = ::write(m_fd, wp, remaining);
|
||||||
if (got>0) {
|
if (got>0) {
|
||||||
wp += got;
|
wp += got;
|
||||||
} else if (got < 0) {
|
} else if (got < 0) {
|
||||||
|
@ -213,7 +213,7 @@ void VerilatedRestore::fill() VL_MT_UNSAFE_ONE {
|
||||||
ssize_t remaining = (m_bufp+bufferSize() - m_endp);
|
ssize_t remaining = (m_bufp+bufferSize() - m_endp);
|
||||||
if (remaining==0) break;
|
if (remaining==0) break;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
ssize_t got = ::read (m_fd, m_endp, remaining);
|
ssize_t got = ::read(m_fd, m_endp, remaining);
|
||||||
if (got>0) {
|
if (got>0) {
|
||||||
m_endp += got;
|
m_endp += got;
|
||||||
} else if (got < 0) {
|
} else if (got < 0) {
|
||||||
|
|
|
@ -1884,7 +1884,7 @@ PLI_INT32 vpi_free_object(vpiHandle object) {
|
||||||
return vpi_release_handle(object); // Deprecated
|
return vpi_release_handle(object); // Deprecated
|
||||||
}
|
}
|
||||||
|
|
||||||
PLI_INT32 vpi_release_handle (vpiHandle object) {
|
PLI_INT32 vpi_release_handle(vpiHandle object) {
|
||||||
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_release_handle %p\n",object););
|
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_release_handle %p\n",object););
|
||||||
VerilatedVpiImp::assertOneCheck();
|
VerilatedVpiImp::assertOneCheck();
|
||||||
VerilatedVpio* vop = VerilatedVpio::castp(object);
|
VerilatedVpio* vop = VerilatedVpio::castp(object);
|
||||||
|
|
|
@ -33,7 +33,7 @@ if (! GetOptions (
|
||||||
}
|
}
|
||||||
|
|
||||||
dotread ($opt_filename);
|
dotread ($opt_filename);
|
||||||
cwrite ("graph_export.cpp");
|
cwrite("graph_export.cpp");
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -179,9 +179,9 @@ private:
|
||||||
nodep->v3warn(COMBDLY, "Delayed assignments (<=) in non-clocked"
|
nodep->v3warn(COMBDLY, "Delayed assignments (<=) in non-clocked"
|
||||||
" (non flop or latch) block; suggest blocking assignments (=).");
|
" (non flop or latch) block; suggest blocking assignments (=).");
|
||||||
}
|
}
|
||||||
AstNode* newp = new AstAssign (nodep->fileline(),
|
AstNode* newp = new AstAssign(nodep->fileline(),
|
||||||
nodep->lhsp()->unlinkFrBack(),
|
nodep->lhsp()->unlinkFrBack(),
|
||||||
nodep->rhsp()->unlinkFrBack());
|
nodep->rhsp()->unlinkFrBack());
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,8 +89,8 @@ private:
|
||||||
// Copy combo tree to settlement tree with duplicated statements
|
// Copy combo tree to settlement tree with duplicated statements
|
||||||
if (sensesp->hasCombo()) {
|
if (sensesp->hasCombo()) {
|
||||||
AstSenTree* newsentreep
|
AstSenTree* newsentreep
|
||||||
= new AstSenTree (nodep->fileline(),
|
= new AstSenTree(nodep->fileline(),
|
||||||
new AstSenItem (nodep->fileline(), AstSenItem::Settle()));
|
new AstSenItem (nodep->fileline(), AstSenItem::Settle()));
|
||||||
AstActive* newp = new AstActive(nodep->fileline(),"settle", newsentreep);
|
AstActive* newp = new AstActive(nodep->fileline(),"settle", newsentreep);
|
||||||
newp->sensesStorep(newsentreep);
|
newp->sensesStorep(newsentreep);
|
||||||
if (nodep->stmtsp()) newp->addStmtsp(nodep->stmtsp()->cloneTree(true));
|
if (nodep->stmtsp()) newp->addStmtsp(nodep->stmtsp()->cloneTree(true));
|
||||||
|
|
|
@ -77,23 +77,23 @@ private:
|
||||||
// Add a internal if to check assertions are on.
|
// Add a internal if to check assertions are on.
|
||||||
// Don't make this a AND term, as it's unlikely to need to test this.
|
// Don't make this a AND term, as it's unlikely to need to test this.
|
||||||
AstNode* newp
|
AstNode* newp
|
||||||
= new AstIf (nodep->fileline(),
|
= new AstIf(nodep->fileline(),
|
||||||
// If assertions are off, have constant propagation rip them out later
|
// If assertions are off, have constant propagation rip them out later
|
||||||
// This allows syntax errors and such to be detected normally.
|
// This allows syntax errors and such to be detected normally.
|
||||||
(v3Global.opt.assertOn()
|
(v3Global.opt.assertOn()
|
||||||
? (AstNode*)(new AstCMath(nodep->fileline(), "Verilated::assertOn()", 1))
|
? (AstNode*)(new AstCMath(nodep->fileline(), "Verilated::assertOn()", 1))
|
||||||
: (AstNode*)(new AstConst(nodep->fileline(), AstConst::LogicFalse()))),
|
: (AstNode*)(new AstConst(nodep->fileline(), AstConst::LogicFalse()))),
|
||||||
nodep, NULL);
|
nodep, NULL);
|
||||||
newp->user1(true); // Don't assert/cover this if
|
newp->user1(true); // Don't assert/cover this if
|
||||||
return newp;
|
return newp;
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode* newFireAssertUnchecked(AstNode* nodep, const string& message) {
|
AstNode* newFireAssertUnchecked(AstNode* nodep, const string& message) {
|
||||||
// Like newFireAssert() but omits the asserts-on check
|
// Like newFireAssert() but omits the asserts-on check
|
||||||
AstDisplay* dispp = new AstDisplay (nodep->fileline(), AstDisplayType::DT_ERROR, message, NULL, NULL);
|
AstDisplay* dispp = new AstDisplay(nodep->fileline(), AstDisplayType::DT_ERROR, message, NULL, NULL);
|
||||||
AstNode* bodysp = dispp;
|
AstNode* bodysp = dispp;
|
||||||
replaceDisplay(dispp, "%%Error"); // Convert to standard DISPLAY format
|
replaceDisplay(dispp, "%%Error"); // Convert to standard DISPLAY format
|
||||||
bodysp->addNext(new AstStop (nodep->fileline()));
|
bodysp->addNext(new AstStop(nodep->fileline()));
|
||||||
return bodysp;
|
return bodysp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bodysp && stmtsp) bodysp = bodysp->addNext(stmtsp);
|
if (bodysp && stmtsp) bodysp = bodysp->addNext(stmtsp);
|
||||||
ifp = new AstIf (nodep->fileline(), propp, bodysp, NULL);
|
ifp = new AstIf(nodep->fileline(), propp, bodysp, NULL);
|
||||||
bodysp = ifp;
|
bodysp = ifp;
|
||||||
|
|
||||||
} else if (VN_IS(nodep, PslAssert)) {
|
} else if (VN_IS(nodep, PslAssert)) {
|
||||||
|
@ -148,10 +148,8 @@ private:
|
||||||
nodep->v3fatalSrc("Unknown node type");
|
nodep->v3fatalSrc("Unknown node type");
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode* newp = new AstAlways (nodep->fileline(),
|
AstNode* newp = new AstAlways(nodep->fileline(),
|
||||||
VAlwaysKwd::ALWAYS,
|
VAlwaysKwd::ALWAYS, sentreep, bodysp);
|
||||||
sentreep,
|
|
||||||
bodysp);
|
|
||||||
// Install it
|
// Install it
|
||||||
if (selfDestruct) {
|
if (selfDestruct) {
|
||||||
// Delete it after making the tree. This way we can tell the user
|
// Delete it after making the tree. This way we can tell the user
|
||||||
|
@ -177,7 +175,7 @@ private:
|
||||||
nodep->v3fatalSrc("Unknown node type");
|
nodep->v3fatalSrc("Unknown node type");
|
||||||
}
|
}
|
||||||
|
|
||||||
AstIf* ifp = new AstIf (nodep->fileline(), propp, passsp, failsp);
|
AstIf* ifp = new AstIf(nodep->fileline(), propp, passsp, failsp);
|
||||||
AstNode* newp = ifp;
|
AstNode* newp = ifp;
|
||||||
if (VN_IS(nodep, VAssert)) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
|
if (VN_IS(nodep, VAssert)) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
|
||||||
//
|
//
|
||||||
|
@ -234,10 +232,10 @@ private:
|
||||||
AstNode* ohot = ((allow_none || hasDefaultElse)
|
AstNode* ohot = ((allow_none || hasDefaultElse)
|
||||||
? static_cast<AstNode*>(new AstOneHot0(nodep->fileline(), propp))
|
? static_cast<AstNode*>(new AstOneHot0(nodep->fileline(), propp))
|
||||||
: static_cast<AstNode*>(new AstOneHot (nodep->fileline(), propp)));
|
: static_cast<AstNode*>(new AstOneHot (nodep->fileline(), propp)));
|
||||||
AstIf* checkifp = new AstIf (nodep->fileline(),
|
AstIf* checkifp = new AstIf(nodep->fileline(),
|
||||||
new AstLogNot (nodep->fileline(), ohot),
|
new AstLogNot(nodep->fileline(), ohot),
|
||||||
newFireAssert(nodep, "'unique if' statement violated"),
|
newFireAssert(nodep, "'unique if' statement violated"),
|
||||||
newifp);
|
newifp);
|
||||||
checkifp->branchPred(AstBranchPred::BP_UNLIKELY);
|
checkifp->branchPred(AstBranchPred::BP_UNLIKELY);
|
||||||
nodep->replaceWith(checkifp);
|
nodep->replaceWith(checkifp);
|
||||||
pushDeletep(nodep);
|
pushDeletep(nodep);
|
||||||
|
@ -293,10 +291,10 @@ private:
|
||||||
AstNode* ohot = (allow_none
|
AstNode* ohot = (allow_none
|
||||||
? static_cast<AstNode*>(new AstOneHot0(nodep->fileline(), propp))
|
? static_cast<AstNode*>(new AstOneHot0(nodep->fileline(), propp))
|
||||||
: static_cast<AstNode*>(new AstOneHot (nodep->fileline(), propp)));
|
: static_cast<AstNode*>(new AstOneHot (nodep->fileline(), propp)));
|
||||||
AstIf* ifp = new AstIf (nodep->fileline(),
|
AstIf* ifp = new AstIf(nodep->fileline(),
|
||||||
new AstLogNot (nodep->fileline(), ohot),
|
new AstLogNot(nodep->fileline(), ohot),
|
||||||
newFireAssert(nodep, "synthesis parallel_case, but multiple matches found"),
|
newFireAssert(nodep, "synthesis parallel_case, but multiple matches found"),
|
||||||
NULL);
|
NULL);
|
||||||
ifp->branchPred(AstBranchPred::BP_UNLIKELY);
|
ifp->branchPred(AstBranchPred::BP_UNLIKELY);
|
||||||
nodep->addNotParallelp(ifp);
|
nodep->addNotParallelp(ifp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -593,7 +593,7 @@ void AstNode::relinkOneLink(AstNode*& pointpr, // Ref to pointer that gets set
|
||||||
pointpr = newp;
|
pointpr = newp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AstNode::addHereThisAsNext (AstNode* newp) {
|
void AstNode::addHereThisAsNext(AstNode* newp) {
|
||||||
// {old}->this->{next} becomes {old}->new->this->{next}
|
// {old}->this->{next} becomes {old}->new->this->{next}
|
||||||
AstNRelinker handle;
|
AstNRelinker handle;
|
||||||
this->unlinkFrBackWithNext(&handle);
|
this->unlinkFrBackWithNext(&handle);
|
||||||
|
@ -601,7 +601,7 @@ void AstNode::addHereThisAsNext (AstNode* newp) {
|
||||||
handle.relink(newp);
|
handle.relink(newp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AstNode::swapWith (AstNode* bp) {
|
void AstNode::swapWith(AstNode* bp) {
|
||||||
AstNRelinker aHandle;
|
AstNRelinker aHandle;
|
||||||
AstNRelinker bHandle;
|
AstNRelinker bHandle;
|
||||||
this->unlinkFrBack(&aHandle);
|
this->unlinkFrBack(&aHandle);
|
||||||
|
|
122
src/V3Ast.h
122
src/V3Ast.h
|
@ -69,11 +69,11 @@ public:
|
||||||
// const char* ascii() const {...};
|
// const char* ascii() const {...};
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
// cppcheck-suppress uninitVar // responsiblity of each subclass
|
// cppcheck-suppress uninitVar // responsiblity of each subclass
|
||||||
inline AstType () {}
|
inline AstType() {}
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
inline AstType (en _e) : m_e(_e) {}
|
inline AstType(en _e) : m_e(_e) {}
|
||||||
explicit inline AstType (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstType(int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en() const { return m_e; }
|
||||||
};
|
};
|
||||||
inline bool operator== (AstType lhs, AstType rhs) { return (lhs.m_e == rhs.m_e); }
|
inline bool operator== (AstType lhs, AstType rhs) { return (lhs.m_e == rhs.m_e); }
|
||||||
inline bool operator== (AstType lhs, AstType::en rhs) { return (lhs.m_e == rhs); }
|
inline bool operator== (AstType lhs, AstType::en rhs) { return (lhs.m_e == rhs); }
|
||||||
|
@ -104,19 +104,19 @@ public:
|
||||||
};
|
};
|
||||||
return names[m_e];
|
return names[m_e];
|
||||||
};
|
};
|
||||||
inline AstNumeric () : m_e(UNSIGNED) {}
|
inline AstNumeric() : m_e(UNSIGNED) {}
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
inline AstNumeric (en _e) : m_e(_e) {}
|
inline AstNumeric(en _e) : m_e(_e) {}
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
inline AstNumeric (VSignedState signst) {
|
inline AstNumeric(VSignedState signst) {
|
||||||
if (signst==signedst_UNSIGNED) m_e=UNSIGNED;
|
if (signst==signedst_UNSIGNED) m_e=UNSIGNED;
|
||||||
else if (signst==signedst_SIGNED) m_e=SIGNED;
|
else if (signst==signedst_SIGNED) m_e=SIGNED;
|
||||||
else m_e=NOSIGN;
|
else m_e=NOSIGN;
|
||||||
}
|
}
|
||||||
static inline AstNumeric fromBool (bool isSigned) { // Factory method
|
static inline AstNumeric fromBool(bool isSigned) { // Factory method
|
||||||
return isSigned ? AstNumeric(SIGNED) : AstNumeric(UNSIGNED); }
|
return isSigned ? AstNumeric(SIGNED) : AstNumeric(UNSIGNED); }
|
||||||
explicit inline AstNumeric (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstNumeric(int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en() const { return m_e; }
|
||||||
inline bool isSigned() const { return m_e==SIGNED; }
|
inline bool isSigned() const { return m_e==SIGNED; }
|
||||||
inline bool isNosign() const { return m_e==NOSIGN; }
|
inline bool isNosign() const { return m_e==NOSIGN; }
|
||||||
// No isUnsigned() as it's ambiguous if NOSIGN should be included or not.
|
// No isUnsigned() as it's ambiguous if NOSIGN should be included or not.
|
||||||
|
@ -140,11 +140,11 @@ public:
|
||||||
PUBLIC_TASK
|
PUBLIC_TASK
|
||||||
};
|
};
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
inline AstPragmaType () : m_e(ILLEGAL) {}
|
inline AstPragmaType() : m_e(ILLEGAL) {}
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
inline AstPragmaType (en _e) : m_e(_e) {}
|
inline AstPragmaType(en _e) : m_e(_e) {}
|
||||||
explicit inline AstPragmaType (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstPragmaType(int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en() const { return m_e; }
|
||||||
};
|
};
|
||||||
inline bool operator== (AstPragmaType lhs, AstPragmaType rhs) { return (lhs.m_e == rhs.m_e); }
|
inline bool operator== (AstPragmaType lhs, AstPragmaType rhs) { return (lhs.m_e == rhs.m_e); }
|
||||||
inline bool operator== (AstPragmaType lhs, AstPragmaType::en rhs) { return (lhs.m_e == rhs); }
|
inline bool operator== (AstPragmaType lhs, AstPragmaType::en rhs) { return (lhs.m_e == rhs); }
|
||||||
|
@ -164,11 +164,11 @@ public:
|
||||||
TRACE_CHANGE_SUB
|
TRACE_CHANGE_SUB
|
||||||
};
|
};
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
inline AstCFuncType () : m_e(FT_NORMAL) {}
|
inline AstCFuncType() : m_e(FT_NORMAL) {}
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
inline AstCFuncType (en _e) : m_e(_e) {}
|
inline AstCFuncType(en _e) : m_e(_e) {}
|
||||||
explicit inline AstCFuncType (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstCFuncType(int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en() const { return m_e; }
|
||||||
// METHODS
|
// METHODS
|
||||||
bool isTrace() const { return (m_e==TRACE_INIT || m_e==TRACE_INIT_SUB
|
bool isTrace() const { return (m_e==TRACE_INIT || m_e==TRACE_INIT_SUB
|
||||||
|| m_e==TRACE_FULL || m_e==TRACE_FULL_SUB
|
|| m_e==TRACE_FULL || m_e==TRACE_FULL_SUB
|
||||||
|
@ -256,11 +256,11 @@ public:
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
inline AstEdgeType () : m_e(ET_ILLEGAL) {}
|
inline AstEdgeType() : m_e(ET_ILLEGAL) {}
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
inline AstEdgeType (en _e) : m_e(_e) {}
|
inline AstEdgeType(en _e) : m_e(_e) {}
|
||||||
explicit inline AstEdgeType (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstEdgeType(int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en() const { return m_e; }
|
||||||
};
|
};
|
||||||
inline bool operator== (AstEdgeType lhs, AstEdgeType rhs) { return (lhs.m_e == rhs.m_e); }
|
inline bool operator== (AstEdgeType lhs, AstEdgeType rhs) { return (lhs.m_e == rhs.m_e); }
|
||||||
inline bool operator== (AstEdgeType lhs, AstEdgeType::en rhs) { return (lhs.m_e == rhs); }
|
inline bool operator== (AstEdgeType lhs, AstEdgeType::en rhs) { return (lhs.m_e == rhs); }
|
||||||
|
@ -324,11 +324,11 @@ public:
|
||||||
};
|
};
|
||||||
return names[m_e];
|
return names[m_e];
|
||||||
};
|
};
|
||||||
inline AstAttrType () : m_e(ILLEGAL) {}
|
inline AstAttrType() : m_e(ILLEGAL) {}
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
inline AstAttrType (en _e) : m_e(_e) {}
|
inline AstAttrType(en _e) : m_e(_e) {}
|
||||||
explicit inline AstAttrType (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstAttrType(int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en() const { return m_e; }
|
||||||
};
|
};
|
||||||
inline bool operator== (AstAttrType lhs, AstAttrType rhs) { return (lhs.m_e == rhs.m_e); }
|
inline bool operator== (AstAttrType lhs, AstAttrType rhs) { return (lhs.m_e == rhs.m_e); }
|
||||||
inline bool operator== (AstAttrType lhs, AstAttrType::en rhs) { return (lhs.m_e == rhs); }
|
inline bool operator== (AstAttrType lhs, AstAttrType::en rhs) { return (lhs.m_e == rhs); }
|
||||||
|
@ -384,11 +384,11 @@ public:
|
||||||
UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).ascii()," MAX"), "SelfTest: Enum mismatch");
|
UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).ascii()," MAX"), "SelfTest: Enum mismatch");
|
||||||
UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).dpiType()," MAX"),"SelfTest: Enum mismatch");
|
UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).dpiType()," MAX"),"SelfTest: Enum mismatch");
|
||||||
}
|
}
|
||||||
inline AstBasicDTypeKwd () : m_e(UNKNOWN) {}
|
inline AstBasicDTypeKwd() : m_e(UNKNOWN) {}
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
inline AstBasicDTypeKwd (en _e) : m_e(_e) {}
|
inline AstBasicDTypeKwd(en _e) : m_e(_e) {}
|
||||||
explicit inline AstBasicDTypeKwd (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstBasicDTypeKwd(int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en() const { return m_e; }
|
||||||
int width() const {
|
int width() const {
|
||||||
switch (m_e) {
|
switch (m_e) {
|
||||||
case BIT: return 1; // scalar, can't bit extract unless ranged
|
case BIT: return 1; // scalar, can't bit extract unless ranged
|
||||||
|
@ -490,11 +490,11 @@ public:
|
||||||
IFACEREF // Used to link Interfaces between modules
|
IFACEREF // Used to link Interfaces between modules
|
||||||
};
|
};
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
inline AstVarType () : m_e(UNKNOWN) {}
|
inline AstVarType() : m_e(UNKNOWN) {}
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
inline AstVarType (en _e) : m_e(_e) {}
|
inline AstVarType(en _e) : m_e(_e) {}
|
||||||
explicit inline AstVarType (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstVarType(int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en() const { return m_e; }
|
||||||
const char* ascii() const {
|
const char* ascii() const {
|
||||||
static const char* const names[] = {
|
static const char* const names[] = {
|
||||||
"?","GPARAM","LPARAM","GENVAR",
|
"?","GPARAM","LPARAM","GENVAR",
|
||||||
|
@ -528,11 +528,11 @@ public:
|
||||||
};
|
};
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
// CONSTRUCTOR - note defaults to *UNKNOWN*
|
// CONSTRUCTOR - note defaults to *UNKNOWN*
|
||||||
inline AstBranchPred () : m_e(BP_UNKNOWN) {}
|
inline AstBranchPred() : m_e(BP_UNKNOWN) {}
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
inline AstBranchPred (en _e) : m_e(_e) {}
|
inline AstBranchPred(en _e) : m_e(_e) {}
|
||||||
explicit inline AstBranchPred (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstBranchPred(int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en() const { return m_e; }
|
||||||
AstBranchPred invert() const {
|
AstBranchPred invert() const {
|
||||||
if (m_e==BP_UNLIKELY) return BP_LIKELY;
|
if (m_e==BP_UNLIKELY) return BP_LIKELY;
|
||||||
else if (m_e==BP_LIKELY) return BP_UNLIKELY;
|
else if (m_e==BP_LIKELY) return BP_UNLIKELY;
|
||||||
|
@ -560,11 +560,11 @@ public:
|
||||||
};
|
};
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
// CONSTRUCTOR - note defaults to *UNKNOWN*
|
// CONSTRUCTOR - note defaults to *UNKNOWN*
|
||||||
inline AstVarAttrClocker () : m_e(CLOCKER_UNKNOWN) {}
|
inline AstVarAttrClocker() : m_e(CLOCKER_UNKNOWN) {}
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
inline AstVarAttrClocker (en _e) : m_e(_e) {}
|
inline AstVarAttrClocker(en _e) : m_e(_e) {}
|
||||||
explicit inline AstVarAttrClocker (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstVarAttrClocker(int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en() const { return m_e; }
|
||||||
bool unknown() const { return m_e==CLOCKER_UNKNOWN; }
|
bool unknown() const { return m_e==CLOCKER_UNKNOWN; }
|
||||||
AstVarAttrClocker invert() const {
|
AstVarAttrClocker invert() const {
|
||||||
if (m_e==CLOCKER_YES) return CLOCKER_NO;
|
if (m_e==CLOCKER_YES) return CLOCKER_NO;
|
||||||
|
@ -592,11 +592,11 @@ public:
|
||||||
ALWAYS_COMB
|
ALWAYS_COMB
|
||||||
};
|
};
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
inline VAlwaysKwd () : m_e(ALWAYS) {}
|
inline VAlwaysKwd() : m_e(ALWAYS) {}
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
inline VAlwaysKwd (en _e) : m_e(_e) {}
|
inline VAlwaysKwd(en _e) : m_e(_e) {}
|
||||||
explicit inline VAlwaysKwd (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline VAlwaysKwd(int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en() const { return m_e; }
|
||||||
const char* ascii() const {
|
const char* ascii() const {
|
||||||
static const char* const names[] = {
|
static const char* const names[] = {
|
||||||
"always","always_ff","always_latch","always_comb"};
|
"always","always_ff","always_latch","always_comb"};
|
||||||
|
@ -617,11 +617,11 @@ public:
|
||||||
CT_CASEINSIDE
|
CT_CASEINSIDE
|
||||||
};
|
};
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
inline VCaseType () : m_e(CT_CASE) {}
|
inline VCaseType() : m_e(CT_CASE) {}
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
inline VCaseType (en _e) : m_e(_e) {}
|
inline VCaseType(en _e) : m_e(_e) {}
|
||||||
explicit inline VCaseType (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline VCaseType(int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en() const { return m_e; }
|
||||||
};
|
};
|
||||||
inline bool operator== (VCaseType lhs, VCaseType rhs) { return (lhs.m_e == rhs.m_e); }
|
inline bool operator== (VCaseType lhs, VCaseType rhs) { return (lhs.m_e == rhs.m_e); }
|
||||||
inline bool operator== (VCaseType lhs, VCaseType::en rhs) { return (lhs.m_e == rhs); }
|
inline bool operator== (VCaseType lhs, VCaseType::en rhs) { return (lhs.m_e == rhs); }
|
||||||
|
@ -640,11 +640,11 @@ public:
|
||||||
DT_FATAL
|
DT_FATAL
|
||||||
};
|
};
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
inline AstDisplayType () : m_e(DT_DISPLAY) {}
|
inline AstDisplayType() : m_e(DT_DISPLAY) {}
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
inline AstDisplayType (en _e) : m_e(_e) {}
|
inline AstDisplayType(en _e) : m_e(_e) {}
|
||||||
explicit inline AstDisplayType (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstDisplayType(int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en() const { return m_e; }
|
||||||
bool addNewline() const { return m_e!=DT_WRITE; }
|
bool addNewline() const { return m_e!=DT_WRITE; }
|
||||||
bool needScopeTracking() const { return m_e!=DT_DISPLAY && m_e!=DT_WRITE; }
|
bool needScopeTracking() const { return m_e!=DT_DISPLAY && m_e!=DT_WRITE; }
|
||||||
const char* ascii() const {
|
const char* ascii() const {
|
||||||
|
@ -667,9 +667,9 @@ public:
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
inline AstParseRefExp() : m_e(PX_NONE) {}
|
inline AstParseRefExp() : m_e(PX_NONE) {}
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
inline AstParseRefExp (en _e) : m_e(_e) {}
|
inline AstParseRefExp(en _e) : m_e(_e) {}
|
||||||
explicit inline AstParseRefExp (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline AstParseRefExp(int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en() const { return m_e; }
|
||||||
const char* ascii() const {
|
const char* ascii() const {
|
||||||
static const char* const names[] = {
|
static const char* const names[] = {
|
||||||
"","TEXT","PREDOT"};
|
"","TEXT","PREDOT"};
|
||||||
|
@ -803,8 +803,8 @@ public:
|
||||||
inline int toInt() {
|
inline int toInt() {
|
||||||
return m_u.ui;
|
return m_u.ui;
|
||||||
}
|
}
|
||||||
static inline VNUser fromZero () { return VNUser(0); }
|
static inline VNUser fromZero() { return VNUser(0); }
|
||||||
static inline VNUser fromInt (int i) { return VNUser(i); }
|
static inline VNUser fromInt(int i) { return VNUser(i); }
|
||||||
};
|
};
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
@ -2071,7 +2071,7 @@ private:
|
||||||
int m_typeNum; // Incrementing implicit type number
|
int m_typeNum; // Incrementing implicit type number
|
||||||
public:
|
public:
|
||||||
AstNodeModule(FileLine* fl, const string& name)
|
AstNodeModule(FileLine* fl, const string& name)
|
||||||
: AstNode (fl)
|
: AstNode(fl)
|
||||||
,m_name(name), m_origName(name)
|
,m_name(name), m_origName(name)
|
||||||
,m_modPublic(false), m_modTrace(false), m_inLibrary(false), m_dead(false)
|
,m_modPublic(false), m_modTrace(false), m_inLibrary(false), m_dead(false)
|
||||||
,m_internal(false), m_recursive(false), m_recursiveClone(false)
|
,m_internal(false), m_recursive(false), m_recursiveClone(false)
|
||||||
|
@ -2113,7 +2113,7 @@ public:
|
||||||
class AstNodeRange : public AstNode {
|
class AstNodeRange : public AstNode {
|
||||||
// A range, sized or unsized
|
// A range, sized or unsized
|
||||||
public:
|
public:
|
||||||
explicit AstNodeRange(FileLine* fl) : AstNode (fl) { }
|
explicit AstNodeRange(FileLine* fl) : AstNode(fl) { }
|
||||||
ASTNODE_BASE_FUNCS(NodeRange)
|
ASTNODE_BASE_FUNCS(NodeRange)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1599,7 +1599,7 @@ class AstModule : public AstNodeModule {
|
||||||
// A module declaration
|
// A module declaration
|
||||||
public:
|
public:
|
||||||
AstModule(FileLine* fl, const string& name)
|
AstModule(FileLine* fl, const string& name)
|
||||||
: AstNodeModule (fl,name) {}
|
: AstNodeModule(fl,name) {}
|
||||||
ASTNODE_NODE_FUNCS(Module)
|
ASTNODE_NODE_FUNCS(Module)
|
||||||
virtual string verilogKwd() const { return "module"; }
|
virtual string verilogKwd() const { return "module"; }
|
||||||
};
|
};
|
||||||
|
@ -1608,7 +1608,7 @@ class AstNotFoundModule : public AstNodeModule {
|
||||||
// A missing module declaration
|
// A missing module declaration
|
||||||
public:
|
public:
|
||||||
AstNotFoundModule(FileLine* fl, const string& name)
|
AstNotFoundModule(FileLine* fl, const string& name)
|
||||||
: AstNodeModule (fl,name) {}
|
: AstNodeModule(fl,name) {}
|
||||||
ASTNODE_NODE_FUNCS(NotFoundModule)
|
ASTNODE_NODE_FUNCS(NotFoundModule)
|
||||||
virtual string verilogKwd() const { return "/*not-found-*/ module"; }
|
virtual string verilogKwd() const { return "/*not-found-*/ module"; }
|
||||||
};
|
};
|
||||||
|
@ -1617,7 +1617,7 @@ class AstPackage : public AstNodeModule {
|
||||||
// A package declaration
|
// A package declaration
|
||||||
public:
|
public:
|
||||||
AstPackage(FileLine* fl, const string& name)
|
AstPackage(FileLine* fl, const string& name)
|
||||||
: AstNodeModule (fl,name) {}
|
: AstNodeModule(fl,name) {}
|
||||||
ASTNODE_NODE_FUNCS(Package)
|
ASTNODE_NODE_FUNCS(Package)
|
||||||
virtual string verilogKwd() const { return "package"; }
|
virtual string verilogKwd() const { return "package"; }
|
||||||
static string dollarUnitName() { return AstNode::encodeName("$unit"); }
|
static string dollarUnitName() { return AstNode::encodeName("$unit"); }
|
||||||
|
@ -1628,7 +1628,7 @@ class AstPrimitive : public AstNodeModule {
|
||||||
// A primitive declaration
|
// A primitive declaration
|
||||||
public:
|
public:
|
||||||
AstPrimitive(FileLine* fl, const string& name)
|
AstPrimitive(FileLine* fl, const string& name)
|
||||||
: AstNodeModule (fl,name) {}
|
: AstNodeModule(fl,name) {}
|
||||||
ASTNODE_NODE_FUNCS(Primitive)
|
ASTNODE_NODE_FUNCS(Primitive)
|
||||||
virtual string verilogKwd() const { return "primitive"; }
|
virtual string verilogKwd() const { return "primitive"; }
|
||||||
};
|
};
|
||||||
|
@ -1638,7 +1638,7 @@ class AstPackageExportStarStar : public AstNode {
|
||||||
public:
|
public:
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
AstPackageExportStarStar(FileLine* fl)
|
AstPackageExportStarStar(FileLine* fl)
|
||||||
: AstNode (fl) {}
|
: AstNode(fl) {}
|
||||||
ASTNODE_NODE_FUNCS(PackageExportStarStar)
|
ASTNODE_NODE_FUNCS(PackageExportStarStar)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1649,7 +1649,7 @@ private:
|
||||||
AstPackage* m_packagep; // Package hierarchy
|
AstPackage* m_packagep; // Package hierarchy
|
||||||
public:
|
public:
|
||||||
AstPackageExport(FileLine* fl, AstPackage* packagep, const string& name)
|
AstPackageExport(FileLine* fl, AstPackage* packagep, const string& name)
|
||||||
: AstNode (fl), m_name(name), m_packagep(packagep) {}
|
: AstNode(fl), m_name(name), m_packagep(packagep) {}
|
||||||
ASTNODE_NODE_FUNCS(PackageExport)
|
ASTNODE_NODE_FUNCS(PackageExport)
|
||||||
virtual const char* broken() const { BROKEN_RTN(!m_packagep || !m_packagep->brokeExists()); return NULL; }
|
virtual const char* broken() const { BROKEN_RTN(!m_packagep || !m_packagep->brokeExists()); return NULL; }
|
||||||
virtual void cloneRelink() { if (m_packagep && m_packagep->clonep()) m_packagep = m_packagep->clonep(); }
|
virtual void cloneRelink() { if (m_packagep && m_packagep->clonep()) m_packagep = m_packagep->clonep(); }
|
||||||
|
@ -1666,7 +1666,7 @@ private:
|
||||||
AstPackage* m_packagep; // Package hierarchy
|
AstPackage* m_packagep; // Package hierarchy
|
||||||
public:
|
public:
|
||||||
AstPackageImport(FileLine* fl, AstPackage* packagep, const string& name)
|
AstPackageImport(FileLine* fl, AstPackage* packagep, const string& name)
|
||||||
: AstNode (fl), m_name(name), m_packagep(packagep) {}
|
: AstNode(fl), m_name(name), m_packagep(packagep) {}
|
||||||
ASTNODE_NODE_FUNCS(PackageImport)
|
ASTNODE_NODE_FUNCS(PackageImport)
|
||||||
virtual const char* broken() const { BROKEN_RTN(!m_packagep || !m_packagep->brokeExists()); return NULL; }
|
virtual const char* broken() const { BROKEN_RTN(!m_packagep || !m_packagep->brokeExists()); return NULL; }
|
||||||
virtual void cloneRelink() { if (m_packagep && m_packagep->clonep()) m_packagep = m_packagep->clonep(); }
|
virtual void cloneRelink() { if (m_packagep && m_packagep->clonep()) m_packagep = m_packagep->clonep(); }
|
||||||
|
@ -1680,7 +1680,7 @@ class AstIface : public AstNodeModule {
|
||||||
// A module declaration
|
// A module declaration
|
||||||
public:
|
public:
|
||||||
AstIface(FileLine* fl, const string& name)
|
AstIface(FileLine* fl, const string& name)
|
||||||
: AstNodeModule (fl,name) { }
|
: AstNodeModule(fl,name) { }
|
||||||
ASTNODE_NODE_FUNCS(Iface)
|
ASTNODE_NODE_FUNCS(Iface)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2234,8 +2234,8 @@ public:
|
||||||
AstAlways* convertToAlways() {
|
AstAlways* convertToAlways() {
|
||||||
AstNode* lhs1p = lhsp()->unlinkFrBack();
|
AstNode* lhs1p = lhsp()->unlinkFrBack();
|
||||||
AstNode* rhs1p = rhsp()->unlinkFrBack();
|
AstNode* rhs1p = rhsp()->unlinkFrBack();
|
||||||
AstAlways* newp = new AstAlways (fileline(), VAlwaysKwd::ALWAYS, NULL,
|
AstAlways* newp = new AstAlways(fileline(), VAlwaysKwd::ALWAYS, NULL,
|
||||||
new AstAssign (fileline(), lhs1p, rhs1p));
|
new AstAssign(fileline(), lhs1p, rhs1p));
|
||||||
replaceWith(newp); // User expected to then deleteTree();
|
replaceWith(newp); // User expected to then deleteTree();
|
||||||
return newp;
|
return newp;
|
||||||
}
|
}
|
||||||
|
@ -2553,13 +2553,13 @@ private:
|
||||||
AstDisplayType m_displayType;
|
AstDisplayType m_displayType;
|
||||||
public:
|
public:
|
||||||
AstDisplay(FileLine* fileline, AstDisplayType dispType, const string& text, AstNode* filep, AstNode* exprsp)
|
AstDisplay(FileLine* fileline, AstDisplayType dispType, const string& text, AstNode* filep, AstNode* exprsp)
|
||||||
: AstNodeStmt (fileline) {
|
: AstNodeStmt(fileline) {
|
||||||
setOp1p(new AstSFormatF(fileline,text,true,exprsp));
|
setOp1p(new AstSFormatF(fileline,text,true,exprsp));
|
||||||
setNOp3p(filep);
|
setNOp3p(filep);
|
||||||
m_displayType = dispType;
|
m_displayType = dispType;
|
||||||
}
|
}
|
||||||
AstDisplay(FileLine* fileline, AstDisplayType dispType, AstNode* filep, AstNode* exprsp)
|
AstDisplay(FileLine* fileline, AstDisplayType dispType, AstNode* filep, AstNode* exprsp)
|
||||||
: AstNodeStmt (fileline) {
|
: AstNodeStmt(fileline) {
|
||||||
setOp1p(new AstSFormatF(fileline, AstSFormatF::NoFormat(), exprsp));
|
setOp1p(new AstSFormatF(fileline, AstSFormatF::NoFormat(), exprsp));
|
||||||
setNOp3p(filep);
|
setNOp3p(filep);
|
||||||
m_displayType = dispType;
|
m_displayType = dispType;
|
||||||
|
@ -2593,7 +2593,7 @@ class AstSFormat : public AstNodeStmt {
|
||||||
// Children: SFORMATF to generate print string
|
// Children: SFORMATF to generate print string
|
||||||
public:
|
public:
|
||||||
AstSFormat(FileLine* fileline, AstNode* lhsp, const string& text, AstNode* exprsp)
|
AstSFormat(FileLine* fileline, AstNode* lhsp, const string& text, AstNode* exprsp)
|
||||||
: AstNodeStmt (fileline) {
|
: AstNodeStmt(fileline) {
|
||||||
setOp1p(new AstSFormatF(fileline,text,true,exprsp));
|
setOp1p(new AstSFormatF(fileline,text,true,exprsp));
|
||||||
setOp3p(lhsp);
|
setOp3p(lhsp);
|
||||||
}
|
}
|
||||||
|
@ -2622,7 +2622,7 @@ class AstSysFuncAsTask : public AstNodeStmt {
|
||||||
// Children: a system function
|
// Children: a system function
|
||||||
public:
|
public:
|
||||||
AstSysFuncAsTask(FileLine* fileline, AstNode* exprsp)
|
AstSysFuncAsTask(FileLine* fileline, AstNode* exprsp)
|
||||||
: AstNodeStmt (fileline) { addNOp1p(exprsp); }
|
: AstNodeStmt(fileline) { addNOp1p(exprsp); }
|
||||||
ASTNODE_NODE_FUNCS(SysFuncAsTask)
|
ASTNODE_NODE_FUNCS(SysFuncAsTask)
|
||||||
virtual string verilogKwd() const { return ""; }
|
virtual string verilogKwd() const { return ""; }
|
||||||
virtual bool isGateOptimizable() const { return true; }
|
virtual bool isGateOptimizable() const { return true; }
|
||||||
|
@ -2641,7 +2641,7 @@ class AstSysIgnore : public AstNodeStmt {
|
||||||
// Children: varrefs or exprs
|
// Children: varrefs or exprs
|
||||||
public:
|
public:
|
||||||
AstSysIgnore(FileLine* fileline, AstNode* exprsp)
|
AstSysIgnore(FileLine* fileline, AstNode* exprsp)
|
||||||
: AstNodeStmt (fileline) { addNOp1p(exprsp); }
|
: AstNodeStmt(fileline) { addNOp1p(exprsp); }
|
||||||
ASTNODE_NODE_FUNCS(SysIgnore)
|
ASTNODE_NODE_FUNCS(SysIgnore)
|
||||||
virtual string verilogKwd() const { return "$ignored"; }
|
virtual string verilogKwd() const { return "$ignored"; }
|
||||||
virtual bool isGateOptimizable() const { return false; } // Though deleted before opt
|
virtual bool isGateOptimizable() const { return false; } // Though deleted before opt
|
||||||
|
@ -2658,7 +2658,7 @@ class AstFClose : public AstNodeStmt {
|
||||||
// Children: file which must be a varref
|
// Children: file which must be a varref
|
||||||
public:
|
public:
|
||||||
AstFClose(FileLine* fileline, AstNode* filep)
|
AstFClose(FileLine* fileline, AstNode* filep)
|
||||||
: AstNodeStmt (fileline) {
|
: AstNodeStmt(fileline) {
|
||||||
setNOp2p(filep);
|
setNOp2p(filep);
|
||||||
}
|
}
|
||||||
ASTNODE_NODE_FUNCS(FClose)
|
ASTNODE_NODE_FUNCS(FClose)
|
||||||
|
@ -2678,7 +2678,7 @@ class AstFOpen : public AstNodeStmt {
|
||||||
// Although a system function in IEEE, here a statement which sets the file pointer (MCD)
|
// Although a system function in IEEE, here a statement which sets the file pointer (MCD)
|
||||||
public:
|
public:
|
||||||
AstFOpen(FileLine* fileline, AstNode* filep, AstNode* filenamep, AstNode* modep)
|
AstFOpen(FileLine* fileline, AstNode* filep, AstNode* filenamep, AstNode* modep)
|
||||||
: AstNodeStmt (fileline) {
|
: AstNodeStmt(fileline) {
|
||||||
setOp1p(filep);
|
setOp1p(filep);
|
||||||
setOp2p(filenamep);
|
setOp2p(filenamep);
|
||||||
setOp3p(modep);
|
setOp3p(modep);
|
||||||
|
@ -2702,7 +2702,7 @@ class AstFFlush : public AstNodeStmt {
|
||||||
// Children: file which must be a varref
|
// Children: file which must be a varref
|
||||||
public:
|
public:
|
||||||
AstFFlush(FileLine* fileline, AstNode* filep)
|
AstFFlush(FileLine* fileline, AstNode* filep)
|
||||||
: AstNodeStmt (fileline) {
|
: AstNodeStmt(fileline) {
|
||||||
setNOp2p(filep);
|
setNOp2p(filep);
|
||||||
}
|
}
|
||||||
ASTNODE_NODE_FUNCS(FFlush)
|
ASTNODE_NODE_FUNCS(FFlush)
|
||||||
|
@ -2726,7 +2726,7 @@ private:
|
||||||
string m_text;
|
string m_text;
|
||||||
public:
|
public:
|
||||||
AstFScanF(FileLine* fileline, const string& text, AstNode* filep, AstNode* exprsp)
|
AstFScanF(FileLine* fileline, const string& text, AstNode* filep, AstNode* exprsp)
|
||||||
: AstNodeMath (fileline), m_text(text) {
|
: AstNodeMath(fileline), m_text(text) {
|
||||||
addNOp1p(exprsp);
|
addNOp1p(exprsp);
|
||||||
setNOp2p(filep);
|
setNOp2p(filep);
|
||||||
}
|
}
|
||||||
|
@ -2759,7 +2759,7 @@ private:
|
||||||
string m_text;
|
string m_text;
|
||||||
public:
|
public:
|
||||||
AstSScanF(FileLine* fileline, const string& text, AstNode* fromp, AstNode* exprsp)
|
AstSScanF(FileLine* fileline, const string& text, AstNode* fromp, AstNode* exprsp)
|
||||||
: AstNodeMath (fileline), m_text(text) {
|
: AstNodeMath(fileline), m_text(text) {
|
||||||
addNOp1p(exprsp);
|
addNOp1p(exprsp);
|
||||||
setOp2p(fromp);
|
setOp2p(fromp);
|
||||||
}
|
}
|
||||||
|
@ -2791,7 +2791,7 @@ public:
|
||||||
AstNodeReadWriteMem(FileLine* fileline, bool hex,
|
AstNodeReadWriteMem(FileLine* fileline, bool hex,
|
||||||
AstNode* filenamep, AstNode* memp,
|
AstNode* filenamep, AstNode* memp,
|
||||||
AstNode* lsbp, AstNode* msbp)
|
AstNode* lsbp, AstNode* msbp)
|
||||||
: AstNodeStmt (fileline), m_isHex(hex) {
|
: AstNodeStmt(fileline), m_isHex(hex) {
|
||||||
setOp1p(filenamep); setOp2p(memp); setNOp3p(lsbp); setNOp4p(msbp);
|
setOp1p(filenamep); setOp2p(memp); setNOp3p(lsbp); setNOp4p(msbp);
|
||||||
}
|
}
|
||||||
virtual bool isGateOptimizable() const { return false; }
|
virtual bool isGateOptimizable() const { return false; }
|
||||||
|
@ -2836,7 +2836,7 @@ class AstSystemT : public AstNodeStmt {
|
||||||
// $system used as task
|
// $system used as task
|
||||||
public:
|
public:
|
||||||
AstSystemT(FileLine* fileline, AstNode* lhsp)
|
AstSystemT(FileLine* fileline, AstNode* lhsp)
|
||||||
: AstNodeStmt (fileline) {
|
: AstNodeStmt(fileline) {
|
||||||
setOp1p(lhsp);
|
setOp1p(lhsp);
|
||||||
}
|
}
|
||||||
ASTNODE_NODE_FUNCS(SystemT)
|
ASTNODE_NODE_FUNCS(SystemT)
|
||||||
|
@ -2855,7 +2855,7 @@ class AstSystemF : public AstNodeMath {
|
||||||
// $system used as function
|
// $system used as function
|
||||||
public:
|
public:
|
||||||
AstSystemF(FileLine* fileline, AstNode* lhsp)
|
AstSystemF(FileLine* fileline, AstNode* lhsp)
|
||||||
: AstNodeMath (fileline) {
|
: AstNodeMath(fileline) {
|
||||||
setOp1p(lhsp);
|
setOp1p(lhsp);
|
||||||
}
|
}
|
||||||
ASTNODE_NODE_FUNCS(SystemF)
|
ASTNODE_NODE_FUNCS(SystemF)
|
||||||
|
@ -2878,7 +2878,7 @@ class AstValuePlusArgs : public AstNodeMath {
|
||||||
// Child: variable to set. If NULL then this is a $test$plusargs instead of $value$plusargs
|
// Child: variable to set. If NULL then this is a $test$plusargs instead of $value$plusargs
|
||||||
public:
|
public:
|
||||||
AstValuePlusArgs(FileLine* fileline, AstNode* searchp, AstNode* outp)
|
AstValuePlusArgs(FileLine* fileline, AstNode* searchp, AstNode* outp)
|
||||||
: AstNodeMath (fileline) {
|
: AstNodeMath(fileline) {
|
||||||
setOp1p(searchp); setOp2p(outp);
|
setOp1p(searchp); setOp2p(outp);
|
||||||
}
|
}
|
||||||
ASTNODE_NODE_FUNCS(ValuePlusArgs)
|
ASTNODE_NODE_FUNCS(ValuePlusArgs)
|
||||||
|
@ -2903,7 +2903,7 @@ private:
|
||||||
string m_text;
|
string m_text;
|
||||||
public:
|
public:
|
||||||
AstTestPlusArgs(FileLine* fileline, const string& text)
|
AstTestPlusArgs(FileLine* fileline, const string& text)
|
||||||
: AstNodeMath (fileline), m_text(text) { }
|
: AstNodeMath(fileline), m_text(text) { }
|
||||||
ASTNODE_NODE_FUNCS(TestPlusArgs)
|
ASTNODE_NODE_FUNCS(TestPlusArgs)
|
||||||
virtual string name() const { return m_text; }
|
virtual string name() const { return m_text; }
|
||||||
virtual string verilogKwd() const { return "$test$plusargs"; }
|
virtual string verilogKwd() const { return "$test$plusargs"; }
|
||||||
|
@ -2985,7 +2985,7 @@ public:
|
||||||
class AstBreak : public AstNodeStmt {
|
class AstBreak : public AstNodeStmt {
|
||||||
public:
|
public:
|
||||||
explicit AstBreak(FileLine* fileline)
|
explicit AstBreak(FileLine* fileline)
|
||||||
: AstNodeStmt (fileline) {}
|
: AstNodeStmt(fileline) {}
|
||||||
ASTNODE_NODE_FUNCS(Break)
|
ASTNODE_NODE_FUNCS(Break)
|
||||||
virtual string verilogKwd() const { return "break"; };
|
virtual string verilogKwd() const { return "break"; };
|
||||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||||
|
@ -2995,7 +2995,7 @@ public:
|
||||||
class AstContinue : public AstNodeStmt {
|
class AstContinue : public AstNodeStmt {
|
||||||
public:
|
public:
|
||||||
explicit AstContinue(FileLine* fileline)
|
explicit AstContinue(FileLine* fileline)
|
||||||
: AstNodeStmt (fileline) {}
|
: AstNodeStmt(fileline) {}
|
||||||
ASTNODE_NODE_FUNCS(Continue)
|
ASTNODE_NODE_FUNCS(Continue)
|
||||||
virtual string verilogKwd() const { return "continue"; };
|
virtual string verilogKwd() const { return "continue"; };
|
||||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||||
|
@ -3017,7 +3017,7 @@ public:
|
||||||
class AstReturn : public AstNodeStmt {
|
class AstReturn : public AstNodeStmt {
|
||||||
public:
|
public:
|
||||||
AstReturn(FileLine* fileline, AstNode* lhsp=NULL)
|
AstReturn(FileLine* fileline, AstNode* lhsp=NULL)
|
||||||
: AstNodeStmt (fileline) {
|
: AstNodeStmt(fileline) {
|
||||||
setNOp1p(lhsp);
|
setNOp1p(lhsp);
|
||||||
}
|
}
|
||||||
ASTNODE_NODE_FUNCS(Return)
|
ASTNODE_NODE_FUNCS(Return)
|
||||||
|
@ -3278,7 +3278,7 @@ public:
|
||||||
m_indices.push_back(m_indices.size());
|
m_indices.push_back(m_indices.size());
|
||||||
}
|
}
|
||||||
int posIndex(int listPos) {
|
int posIndex(int listPos) {
|
||||||
UASSERT (listPos < (int)m_indices.size(), "InitArray past end of indices list");
|
UASSERT(listPos < (int)m_indices.size(), "InitArray past end of indices list");
|
||||||
return m_indices[listPos]; }
|
return m_indices[listPos]; }
|
||||||
virtual bool hasDType() const { return true; }
|
virtual bool hasDType() const { return true; }
|
||||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||||
|
|
|
@ -72,14 +72,14 @@ private:
|
||||||
AstNRelinker relinkHandle;
|
AstNRelinker relinkHandle;
|
||||||
nodep->unlinkFrBack(&relinkHandle);
|
nodep->unlinkFrBack(&relinkHandle);
|
||||||
//
|
//
|
||||||
AstCCast* castp = new AstCCast (nodep->fileline(), nodep, needsize, nodep->widthMin());
|
AstCCast* castp = new AstCCast(nodep->fileline(), nodep, needsize, nodep->widthMin());
|
||||||
relinkHandle.relink(castp);
|
relinkHandle.relink(castp);
|
||||||
//if (debug()>8) castp->dumpTree(cout,"-castins: ");
|
//if (debug()>8) castp->dumpTree(cout,"-castins: ");
|
||||||
//
|
//
|
||||||
insureLower32Cast(castp);
|
insureLower32Cast(castp);
|
||||||
nodep->user1(1); // Now must be of known size
|
nodep->user1(1); // Now must be of known size
|
||||||
}
|
}
|
||||||
int castSize (AstNode* nodep) {
|
int castSize(AstNode* nodep) {
|
||||||
if (nodep->isQuad()) return VL_QUADSIZE;
|
if (nodep->isQuad()) return VL_QUADSIZE;
|
||||||
else if (nodep->width()<=8) return 8;
|
else if (nodep->width()<=8) return 8;
|
||||||
else if (nodep->width()<=16) return 16;
|
else if (nodep->width()<=16) return 16;
|
||||||
|
@ -150,7 +150,7 @@ private:
|
||||||
&& castSize(nodep) != castSize(nodep->varp())) {
|
&& castSize(nodep) != castSize(nodep->varp())) {
|
||||||
// Cast vars to IData first, else below has upper bits wrongly set
|
// Cast vars to IData first, else below has upper bits wrongly set
|
||||||
// CData x=3; out = (QData)(x<<30);
|
// CData x=3; out = (QData)(x<<30);
|
||||||
insertCast (nodep, castSize(nodep));
|
insertCast(nodep, castSize(nodep));
|
||||||
}
|
}
|
||||||
nodep->user1(1);
|
nodep->user1(1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,13 +131,13 @@ private:
|
||||||
}
|
}
|
||||||
m_statep->maybeCreateChgFuncp();
|
m_statep->maybeCreateChgFuncp();
|
||||||
|
|
||||||
AstChangeDet* changep = new AstChangeDet (m_vscp->fileline(),
|
AstChangeDet* changep = new AstChangeDet(m_vscp->fileline(),
|
||||||
m_varEqnp->cloneTree(true),
|
m_varEqnp->cloneTree(true),
|
||||||
m_newRvEqnp->cloneTree(true), false);
|
m_newRvEqnp->cloneTree(true), false);
|
||||||
m_statep->m_chgFuncp->addStmtsp(changep);
|
m_statep->m_chgFuncp->addStmtsp(changep);
|
||||||
AstAssign* initp = new AstAssign (m_vscp->fileline(),
|
AstAssign* initp = new AstAssign(m_vscp->fileline(),
|
||||||
m_newLvEqnp->cloneTree(true),
|
m_newLvEqnp->cloneTree(true),
|
||||||
m_varEqnp->cloneTree(true));
|
m_varEqnp->cloneTree(true));
|
||||||
m_statep->m_chgFuncp->addFinalsp(initp);
|
m_statep->m_chgFuncp->addFinalsp(initp);
|
||||||
EmitCBaseCounterVisitor visitor(initp);
|
EmitCBaseCounterVisitor visitor(initp);
|
||||||
m_statep->m_numStmts += visitor.count();
|
m_statep->m_numStmts += visitor.count();
|
||||||
|
@ -200,7 +200,7 @@ public:
|
||||||
// ASSIGN(VARREF(_last), VARREF(var))
|
// ASSIGN(VARREF(_last), VARREF(var))
|
||||||
// ...
|
// ...
|
||||||
// CHANGEDET(VARREF(_last), VARREF(var))
|
// CHANGEDET(VARREF(_last), VARREF(var))
|
||||||
AstVar* newvarp = new AstVar (varp->fileline(), AstVarType::MODULETEMP, newvarname, varp);
|
AstVar* newvarp = new AstVar(varp->fileline(), AstVarType::MODULETEMP, newvarname, varp);
|
||||||
m_statep->m_topModp->addStmtp(newvarp);
|
m_statep->m_topModp->addStmtp(newvarp);
|
||||||
m_newvscp = new AstVarScope(m_vscp->fileline(), m_statep->m_scopetopp, newvarp);
|
m_newvscp = new AstVarScope(m_vscp->fileline(), m_statep->m_scopetopp, newvarp);
|
||||||
m_statep->m_scopetopp->addVarp(m_newvscp);
|
m_statep->m_scopetopp->addVarp(m_newvscp);
|
||||||
|
|
|
@ -67,7 +67,7 @@ private:
|
||||||
else if (nodep->width()<=VL_QUADSIZE) return VL_QUADSIZE;
|
else if (nodep->width()<=VL_QUADSIZE) return VL_QUADSIZE;
|
||||||
else return nodep->widthWords()*VL_WORDSIZE;
|
else return nodep->widthWords()*VL_WORDSIZE;
|
||||||
}
|
}
|
||||||
void setCppWidth (AstNode* nodep) {
|
void setCppWidth(AstNode* nodep) {
|
||||||
nodep->user2(true); // Don't resize it again
|
nodep->user2(true); // Don't resize it again
|
||||||
AstNodeDType* old_dtypep = nodep->dtypep();
|
AstNodeDType* old_dtypep = nodep->dtypep();
|
||||||
int width=cppWidth(nodep); // widthMin is unchanged
|
int width=cppWidth(nodep); // widthMin is unchanged
|
||||||
|
@ -84,7 +84,7 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void computeCppWidth (AstNode* nodep) {
|
void computeCppWidth(AstNode* nodep) {
|
||||||
if (!nodep->user2() && nodep->hasDType()) {
|
if (!nodep->user2() && nodep->hasDType()) {
|
||||||
if (VN_IS(nodep, Var) || VN_IS(nodep, NodeDType) // Don't want to change variable widths!
|
if (VN_IS(nodep, Var) || VN_IS(nodep, NodeDType) // Don't want to change variable widths!
|
||||||
|| VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType)) { // Or arrays
|
|| VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType)) { // Or arrays
|
||||||
|
@ -109,7 +109,7 @@ private:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
void setClean(AstNode* nodep, bool isClean) {
|
void setClean(AstNode* nodep, bool isClean) {
|
||||||
computeCppWidth (nodep); // Just to be sure it's in widthMin
|
computeCppWidth(nodep); // Just to be sure it's in widthMin
|
||||||
bool wholeUint = ((nodep->widthMin() % VL_WORDSIZE) == 0); //32,64,...
|
bool wholeUint = ((nodep->widthMin() % VL_WORDSIZE) == 0); //32,64,...
|
||||||
setCleanState(nodep, ((isClean||wholeUint) ? CS_CLEAN:CS_DIRTY));
|
setCleanState(nodep, ((isClean||wholeUint) ? CS_CLEAN:CS_DIRTY));
|
||||||
}
|
}
|
||||||
|
@ -123,9 +123,9 @@ private:
|
||||||
computeCppWidth(nodep);
|
computeCppWidth(nodep);
|
||||||
V3Number mask (nodep->fileline(), cppWidth(nodep));
|
V3Number mask (nodep->fileline(), cppWidth(nodep));
|
||||||
mask.setMask(nodep->widthMin());
|
mask.setMask(nodep->widthMin());
|
||||||
AstNode* cleanp = new AstAnd (nodep->fileline(),
|
AstNode* cleanp = new AstAnd(nodep->fileline(),
|
||||||
new AstConst (nodep->fileline(), mask),
|
new AstConst(nodep->fileline(), mask),
|
||||||
nodep);
|
nodep);
|
||||||
cleanp->dtypeFrom(nodep); // Otherwise the AND normally picks LHS
|
cleanp->dtypeFrom(nodep); // Otherwise the AND normally picks LHS
|
||||||
relinkHandle.relink(cleanp);
|
relinkHandle.relink(cleanp);
|
||||||
}
|
}
|
||||||
|
@ -181,28 +181,28 @@ private:
|
||||||
if (nodep->cleanLhs()) {
|
if (nodep->cleanLhs()) {
|
||||||
insureClean(nodep->lhsp());
|
insureClean(nodep->lhsp());
|
||||||
}
|
}
|
||||||
setClean (nodep, nodep->cleanOut());
|
setClean(nodep, nodep->cleanOut());
|
||||||
}
|
}
|
||||||
virtual void visit(AstNodeBiop* nodep) {
|
virtual void visit(AstNodeBiop* nodep) {
|
||||||
operandBiop(nodep);
|
operandBiop(nodep);
|
||||||
setClean (nodep, nodep->cleanOut());
|
setClean(nodep, nodep->cleanOut());
|
||||||
}
|
}
|
||||||
virtual void visit(AstAnd* nodep) {
|
virtual void visit(AstAnd* nodep) {
|
||||||
operandBiop(nodep);
|
operandBiop(nodep);
|
||||||
setClean (nodep, isClean(nodep->lhsp()) || isClean(nodep->rhsp()));
|
setClean(nodep, isClean(nodep->lhsp()) || isClean(nodep->rhsp()));
|
||||||
}
|
}
|
||||||
virtual void visit(AstXor* nodep) {
|
virtual void visit(AstXor* nodep) {
|
||||||
operandBiop(nodep);
|
operandBiop(nodep);
|
||||||
setClean (nodep, isClean(nodep->lhsp()) && isClean(nodep->rhsp()));
|
setClean(nodep, isClean(nodep->lhsp()) && isClean(nodep->rhsp()));
|
||||||
}
|
}
|
||||||
virtual void visit(AstOr* nodep) {
|
virtual void visit(AstOr* nodep) {
|
||||||
operandBiop(nodep);
|
operandBiop(nodep);
|
||||||
setClean (nodep, isClean(nodep->lhsp()) && isClean(nodep->rhsp()));
|
setClean(nodep, isClean(nodep->lhsp()) && isClean(nodep->rhsp()));
|
||||||
}
|
}
|
||||||
virtual void visit(AstNodeMath* nodep) {
|
virtual void visit(AstNodeMath* nodep) {
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
computeCppWidth(nodep);
|
computeCppWidth(nodep);
|
||||||
setClean (nodep, nodep->cleanOut());
|
setClean(nodep, nodep->cleanOut());
|
||||||
}
|
}
|
||||||
virtual void visit(AstNodeAssign* nodep) {
|
virtual void visit(AstNodeAssign* nodep) {
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
|
@ -212,28 +212,28 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void visit(AstText* nodep) {
|
virtual void visit(AstText* nodep) {
|
||||||
setClean (nodep, true);
|
setClean(nodep, true);
|
||||||
}
|
}
|
||||||
virtual void visit(AstScopeName* nodep) {
|
virtual void visit(AstScopeName* nodep) {
|
||||||
setClean (nodep, true);
|
setClean(nodep, true);
|
||||||
}
|
}
|
||||||
virtual void visit(AstSel* nodep) {
|
virtual void visit(AstSel* nodep) {
|
||||||
operandTriop(nodep);
|
operandTriop(nodep);
|
||||||
setClean (nodep, nodep->cleanOut());
|
setClean(nodep, nodep->cleanOut());
|
||||||
}
|
}
|
||||||
virtual void visit(AstUCFunc* nodep) {
|
virtual void visit(AstUCFunc* nodep) {
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
computeCppWidth(nodep);
|
computeCppWidth(nodep);
|
||||||
setClean (nodep, false);
|
setClean(nodep, false);
|
||||||
// We always clean, as we don't trust those pesky users.
|
// We always clean, as we don't trust those pesky users.
|
||||||
if (!VN_IS(nodep->backp(), And)) {
|
if (!VN_IS(nodep->backp(), And)) {
|
||||||
insertClean(nodep);
|
insertClean(nodep);
|
||||||
}
|
}
|
||||||
insureCleanAndNext (nodep->bodysp());
|
insureCleanAndNext(nodep->bodysp());
|
||||||
}
|
}
|
||||||
virtual void visit(AstTraceInc* nodep) {
|
virtual void visit(AstTraceInc* nodep) {
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
insureCleanAndNext (nodep->valuep());
|
insureCleanAndNext(nodep->valuep());
|
||||||
}
|
}
|
||||||
virtual void visit(AstTypedef* nodep) {
|
virtual void visit(AstTypedef* nodep) {
|
||||||
// No cleaning, or would loose pointer to enum
|
// No cleaning, or would loose pointer to enum
|
||||||
|
@ -260,17 +260,17 @@ private:
|
||||||
}
|
}
|
||||||
virtual void visit(AstSFormatF* nodep) {
|
virtual void visit(AstSFormatF* nodep) {
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
insureCleanAndNext (nodep->exprsp());
|
insureCleanAndNext(nodep->exprsp());
|
||||||
setClean(nodep, true); // generates a string, so not relevant
|
setClean(nodep, true); // generates a string, so not relevant
|
||||||
}
|
}
|
||||||
virtual void visit(AstUCStmt* nodep) {
|
virtual void visit(AstUCStmt* nodep) {
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
insureCleanAndNext (nodep->bodysp());
|
insureCleanAndNext(nodep->bodysp());
|
||||||
}
|
}
|
||||||
virtual void visit(AstCCall* nodep) {
|
virtual void visit(AstCCall* nodep) {
|
||||||
iterateChildren(nodep);
|
iterateChildren(nodep);
|
||||||
insureCleanAndNext (nodep->argsp());
|
insureCleanAndNext(nodep->argsp());
|
||||||
setClean (nodep, true);
|
setClean(nodep, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------
|
//--------------------
|
||||||
|
|
|
@ -78,16 +78,16 @@ private:
|
||||||
AstVar* varp = vscp->varp();
|
AstVar* varp = vscp->varp();
|
||||||
if (!varp->width1()) varp->v3error("Unsupported: Clock edge on non-single bit signal: "<<varp->prettyName());
|
if (!varp->width1()) varp->v3error("Unsupported: Clock edge on non-single bit signal: "<<varp->prettyName());
|
||||||
string newvarname = ((string)"__Vclklast__"+vscp->scopep()->nameDotless()+"__"+varp->name());
|
string newvarname = ((string)"__Vclklast__"+vscp->scopep()->nameDotless()+"__"+varp->name());
|
||||||
AstVar* newvarp = new AstVar (vscp->fileline(), AstVarType::MODULETEMP, newvarname, VFlagLogicPacked(), 1);
|
AstVar* newvarp = new AstVar(vscp->fileline(), AstVarType::MODULETEMP, newvarname, VFlagLogicPacked(), 1);
|
||||||
m_modp->addStmtp(newvarp);
|
m_modp->addStmtp(newvarp);
|
||||||
AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopep, newvarp);
|
AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopep, newvarp);
|
||||||
vscp->user1p(newvscp);
|
vscp->user1p(newvscp);
|
||||||
m_scopep->addVarp(newvscp);
|
m_scopep->addVarp(newvscp);
|
||||||
// At bottom, assign them
|
// At bottom, assign them
|
||||||
AstAssign* finalp
|
AstAssign* finalp
|
||||||
= new AstAssign (vscp->fileline(),
|
= new AstAssign(vscp->fileline(),
|
||||||
new AstVarRef(vscp->fileline(), newvscp, true),
|
new AstVarRef(vscp->fileline(), newvscp, true),
|
||||||
new AstVarRef(vscp->fileline(), vscp, false));
|
new AstVarRef(vscp->fileline(), vscp, false));
|
||||||
m_evalFuncp->addFinalsp(finalp);
|
m_evalFuncp->addFinalsp(finalp);
|
||||||
//
|
//
|
||||||
UINFO(4,"New Last: "<<newvscp<<endl);
|
UINFO(4,"New Last: "<<newvscp<<endl);
|
||||||
|
@ -172,8 +172,7 @@ private:
|
||||||
AstIf* makeActiveIf(AstSenTree* sensesp) {
|
AstIf* makeActiveIf(AstSenTree* sensesp) {
|
||||||
AstNode* senEqnp = createSenseEquation(sensesp->sensesp());
|
AstNode* senEqnp = createSenseEquation(sensesp->sensesp());
|
||||||
if (!senEqnp) sensesp->v3fatalSrc("No sense equation, shouldn't be in sequent activation.");
|
if (!senEqnp) sensesp->v3fatalSrc("No sense equation, shouldn't be in sequent activation.");
|
||||||
AstIf* newifp = new AstIf (sensesp->fileline(),
|
AstIf* newifp = new AstIf(sensesp->fileline(), senEqnp, NULL, NULL);
|
||||||
senEqnp, NULL, NULL);
|
|
||||||
return (newifp);
|
return (newifp);
|
||||||
}
|
}
|
||||||
void clearLastSen() {
|
void clearLastSen() {
|
||||||
|
|
|
@ -85,7 +85,7 @@ private:
|
||||||
CallMmap m_callMmap; // Associative array of {function}{call}
|
CallMmap m_callMmap; // Associative array of {function}{call}
|
||||||
// METHODS
|
// METHODS
|
||||||
public:
|
public:
|
||||||
void replaceFunc (AstCFunc* oldfuncp, AstCFunc* newfuncp) {
|
void replaceFunc(AstCFunc* oldfuncp, AstCFunc* newfuncp) {
|
||||||
if (oldfuncp==newfuncp) return;
|
if (oldfuncp==newfuncp) return;
|
||||||
if (newfuncp) {
|
if (newfuncp) {
|
||||||
UINFO(4, " Replace "<<oldfuncp<<" -WITH-> "<<newfuncp<<endl);
|
UINFO(4, " Replace "<<oldfuncp<<" -WITH-> "<<newfuncp<<endl);
|
||||||
|
@ -275,7 +275,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void walkDupCodeStart(AstNode* node1p) {
|
void walkDupCodeStart(AstNode* node1p) {
|
||||||
V3Hash hashval (node1p->user4p());
|
V3Hash hashval(node1p->user4p());
|
||||||
//UINFO(4," STMT "<<hashval<<" "<<node1p<<endl);
|
//UINFO(4," STMT "<<hashval<<" "<<node1p<<endl);
|
||||||
//
|
//
|
||||||
int bestDepth = 0; // Best substitution found in the search
|
int bestDepth = 0; // Best substitution found in the search
|
||||||
|
|
|
@ -116,7 +116,7 @@ private:
|
||||||
// METHODS
|
// METHODS
|
||||||
VL_DEBUG_FUNC; // Declare debug()
|
VL_DEBUG_FUNC; // Declare debug()
|
||||||
|
|
||||||
bool operandConst (AstNode* nodep) {
|
bool operandConst(AstNode* nodep) {
|
||||||
return VN_IS(nodep, Const);
|
return VN_IS(nodep, Const);
|
||||||
}
|
}
|
||||||
bool operandAsvConst(const AstNode* nodep) {
|
bool operandAsvConst(const AstNode* nodep) {
|
||||||
|
@ -583,7 +583,7 @@ private:
|
||||||
// Constant Replacement functions.
|
// Constant Replacement functions.
|
||||||
// These all take a node, delete its tree, and replaces it with a constant
|
// These all take a node, delete its tree, and replaces it with a constant
|
||||||
|
|
||||||
void replaceNum (AstNode* oldp, const V3Number& num) {
|
void replaceNum(AstNode* oldp, const V3Number& num) {
|
||||||
// Replace oldp node with a constant set to specified value
|
// Replace oldp node with a constant set to specified value
|
||||||
UASSERT(oldp, "Null old");
|
UASSERT(oldp, "Null old");
|
||||||
if (VN_IS(oldp, Const) && !VN_CAST(oldp, Const)->num().isFourState()) {
|
if (VN_IS(oldp, Const) && !VN_CAST(oldp, Const)->num().isFourState()) {
|
||||||
|
@ -596,7 +596,7 @@ private:
|
||||||
oldp->replaceWith(newp);
|
oldp->replaceWith(newp);
|
||||||
oldp->deleteTree(); VL_DANGLING(oldp);
|
oldp->deleteTree(); VL_DANGLING(oldp);
|
||||||
}
|
}
|
||||||
void replaceNum (AstNode* nodep, uint32_t val) {
|
void replaceNum(AstNode* nodep, uint32_t val) {
|
||||||
V3Number num (nodep->fileline(), nodep->width(), val);
|
V3Number num (nodep->fileline(), nodep->width(), val);
|
||||||
replaceNum(nodep, num); VL_DANGLING(nodep);
|
replaceNum(nodep, num); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
|
@ -630,7 +630,7 @@ private:
|
||||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void replaceAllOnes (AstNode* nodep) {
|
void replaceAllOnes(AstNode* nodep) {
|
||||||
V3Number ones (nodep->fileline(), nodep->width(), 0);
|
V3Number ones (nodep->fileline(), nodep->width(), 0);
|
||||||
ones.setMask(nodep->width());
|
ones.setMask(nodep->width());
|
||||||
replaceNum(nodep, ones); VL_DANGLING(nodep);
|
replaceNum(nodep, ones); VL_DANGLING(nodep);
|
||||||
|
@ -656,7 +656,7 @@ private:
|
||||||
replaceNum(nodep, num); VL_DANGLING(nodep);
|
replaceNum(nodep, num); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
|
|
||||||
void replaceConstString (AstNode* oldp, const string& num) {
|
void replaceConstString(AstNode* oldp, const string& num) {
|
||||||
// Replace oldp node with a constant set to specified value
|
// Replace oldp node with a constant set to specified value
|
||||||
UASSERT(oldp, "Null old");
|
UASSERT(oldp, "Null old");
|
||||||
AstNode* newp = new AstConst(oldp->fileline(), AstConst::String(), num);
|
AstNode* newp = new AstConst(oldp->fileline(), AstConst::String(), num);
|
||||||
|
@ -704,7 +704,7 @@ private:
|
||||||
// Keep RHS, remove LHS
|
// Keep RHS, remove LHS
|
||||||
replaceWChild(nodep, nodep->rhsp());
|
replaceWChild(nodep, nodep->rhsp());
|
||||||
}
|
}
|
||||||
void replaceAsv (AstNodeBiop* nodep) {
|
void replaceAsv(AstNodeBiop* nodep) {
|
||||||
// BIASV(CONSTa, BIASV(CONSTb, c)) -> BIASV( BIASV_CONSTED(a,b), c)
|
// BIASV(CONSTa, BIASV(CONSTb, c)) -> BIASV( BIASV_CONSTED(a,b), c)
|
||||||
// BIASV(SAMEa, BIASV(SAMEb, c)) -> BIASV( BIASV(SAMEa,SAMEb), c)
|
// BIASV(SAMEa, BIASV(SAMEb, c)) -> BIASV( BIASV(SAMEa,SAMEb), c)
|
||||||
//nodep->dumpTree(cout, " repAsvConst_old: ");
|
//nodep->dumpTree(cout, " repAsvConst_old: ");
|
||||||
|
@ -723,7 +723,7 @@ private:
|
||||||
if (VN_IS(rp->lhsp(), Const) && VN_IS(rp->rhsp(), Const)) replaceConst(rp);
|
if (VN_IS(rp->lhsp(), Const) && VN_IS(rp->rhsp(), Const)) replaceConst(rp);
|
||||||
//nodep->dumpTree(cout, " repAsvConst_new: ");
|
//nodep->dumpTree(cout, " repAsvConst_new: ");
|
||||||
}
|
}
|
||||||
void replaceAsvLUp (AstNodeBiop* nodep) {
|
void replaceAsvLUp(AstNodeBiop* nodep) {
|
||||||
// BIASV(BIASV(CONSTll,lr),r) -> BIASV(CONSTll,BIASV(lr,r))
|
// BIASV(BIASV(CONSTll,lr),r) -> BIASV(CONSTll,BIASV(lr,r))
|
||||||
AstNodeBiop* lp = VN_CAST(nodep->lhsp()->unlinkFrBack(), NodeBiop);
|
AstNodeBiop* lp = VN_CAST(nodep->lhsp()->unlinkFrBack(), NodeBiop);
|
||||||
AstNode* llp = lp->lhsp()->unlinkFrBack();
|
AstNode* llp = lp->lhsp()->unlinkFrBack();
|
||||||
|
@ -735,7 +735,7 @@ private:
|
||||||
lp->rhsp(rp);
|
lp->rhsp(rp);
|
||||||
//nodep->dumpTree(cout, " repAsvLUp_new: ");
|
//nodep->dumpTree(cout, " repAsvLUp_new: ");
|
||||||
}
|
}
|
||||||
void replaceAsvRUp (AstNodeBiop* nodep) {
|
void replaceAsvRUp(AstNodeBiop* nodep) {
|
||||||
// BIASV(l,BIASV(CONSTrl,rr)) -> BIASV(CONSTrl,BIASV(l,rr))
|
// BIASV(l,BIASV(CONSTrl,rr)) -> BIASV(CONSTrl,BIASV(l,rr))
|
||||||
AstNode* lp = nodep->lhsp()->unlinkFrBack();
|
AstNode* lp = nodep->lhsp()->unlinkFrBack();
|
||||||
AstNodeBiop* rp = VN_CAST(nodep->rhsp()->unlinkFrBack(), NodeBiop);
|
AstNodeBiop* rp = VN_CAST(nodep->rhsp()->unlinkFrBack(), NodeBiop);
|
||||||
|
@ -747,7 +747,7 @@ private:
|
||||||
rp->rhsp(rrp);
|
rp->rhsp(rrp);
|
||||||
//nodep->dumpTree(cout, " repAsvRUp_new: ");
|
//nodep->dumpTree(cout, " repAsvRUp_new: ");
|
||||||
}
|
}
|
||||||
void replaceAndOr (AstNodeBiop* nodep) {
|
void replaceAndOr(AstNodeBiop* nodep) {
|
||||||
// OR (AND (CONSTll,lr), AND(CONSTrl==ll,rr)) -> AND (CONSTll, OR(lr,rr))
|
// OR (AND (CONSTll,lr), AND(CONSTrl==ll,rr)) -> AND (CONSTll, OR(lr,rr))
|
||||||
// OR (AND (CONSTll,lr), AND(CONSTrl, rr=lr)) -> AND (OR(ll,rl), rr)
|
// OR (AND (CONSTll,lr), AND(CONSTrl, rr=lr)) -> AND (OR(ll,rl), rr)
|
||||||
// nodep ^lp ^llp ^lrp ^rp ^rlp ^rrp
|
// nodep ^lp ^llp ^lrp ^rp ^rlp ^rrp
|
||||||
|
@ -778,7 +778,7 @@ private:
|
||||||
}
|
}
|
||||||
//nodep->dumpTree(cout, " repAndOr_new: ");
|
//nodep->dumpTree(cout, " repAndOr_new: ");
|
||||||
}
|
}
|
||||||
void replaceShiftSame (AstNodeBiop* nodep) {
|
void replaceShiftSame(AstNodeBiop* nodep) {
|
||||||
// Or(Shift(ll,CONSTlr),Shift(rl,CONSTrr==lr)) -> Shift(Or(ll,rl),CONSTlr)
|
// Or(Shift(ll,CONSTlr),Shift(rl,CONSTrr==lr)) -> Shift(Or(ll,rl),CONSTlr)
|
||||||
// (Or/And may also be reversed)
|
// (Or/And may also be reversed)
|
||||||
AstNodeBiop* lp = VN_CAST(nodep->lhsp()->unlinkFrBack(), NodeBiop);
|
AstNodeBiop* lp = VN_CAST(nodep->lhsp()->unlinkFrBack(), NodeBiop);
|
||||||
|
@ -835,7 +835,7 @@ private:
|
||||||
iterate(lp->rhsp());
|
iterate(lp->rhsp());
|
||||||
} else nodep->v3fatalSrc("tried to merge two Concat which are not adjacent");
|
} else nodep->v3fatalSrc("tried to merge two Concat which are not adjacent");
|
||||||
}
|
}
|
||||||
void replaceExtend (AstNode* nodep, AstNode* arg0p) {
|
void replaceExtend(AstNode* nodep, AstNode* arg0p) {
|
||||||
// -> EXTEND(nodep)
|
// -> EXTEND(nodep)
|
||||||
// like a AstExtend{$rhsp}, but we need to set the width correctly from base node
|
// like a AstExtend{$rhsp}, but we need to set the width correctly from base node
|
||||||
arg0p->unlinkFrBack();
|
arg0p->unlinkFrBack();
|
||||||
|
@ -845,7 +845,7 @@ private:
|
||||||
newp->dtypeFrom(nodep);
|
newp->dtypeFrom(nodep);
|
||||||
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
|
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
void replacePowShift (AstNodeBiop* nodep) { // Pow or PowS
|
void replacePowShift(AstNodeBiop* nodep) { // Pow or PowS
|
||||||
UINFO(5,"POW(2,b)->SHIFTL(1,b) "<<nodep<<endl);
|
UINFO(5,"POW(2,b)->SHIFTL(1,b) "<<nodep<<endl);
|
||||||
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
|
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
|
||||||
AstShiftL* newp = new AstShiftL(nodep->fileline(),
|
AstShiftL* newp = new AstShiftL(nodep->fileline(),
|
||||||
|
@ -855,7 +855,7 @@ private:
|
||||||
newp->lhsp()->dtypeFrom(nodep);
|
newp->lhsp()->dtypeFrom(nodep);
|
||||||
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
|
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
void replaceMulShift (AstMul* nodep) { // Mul, but not MulS as not simple shift
|
void replaceMulShift(AstMul* nodep) { // Mul, but not MulS as not simple shift
|
||||||
UINFO(5,"MUL(2^n,b)->SHIFTL(b,n) "<<nodep<<endl);
|
UINFO(5,"MUL(2^n,b)->SHIFTL(b,n) "<<nodep<<endl);
|
||||||
int amount = VN_CAST(nodep->lhsp(), Const)->num().mostSetBitP1()-1; // 2^n->n+1
|
int amount = VN_CAST(nodep->lhsp(), Const)->num().mostSetBitP1()-1; // 2^n->n+1
|
||||||
AstNode* opp = nodep->rhsp()->unlinkFrBack();
|
AstNode* opp = nodep->rhsp()->unlinkFrBack();
|
||||||
|
@ -864,7 +864,7 @@ private:
|
||||||
newp->dtypeFrom(nodep);
|
newp->dtypeFrom(nodep);
|
||||||
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
|
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
void replaceDivShift (AstDiv* nodep) { // Mul, but not MulS as not simple shift
|
void replaceDivShift(AstDiv* nodep) { // Mul, but not MulS as not simple shift
|
||||||
UINFO(5,"DIV(b,2^n)->SHIFTR(b,n) "<<nodep<<endl);
|
UINFO(5,"DIV(b,2^n)->SHIFTR(b,n) "<<nodep<<endl);
|
||||||
int amount = VN_CAST(nodep->rhsp(), Const)->num().mostSetBitP1()-1; // 2^n->n+1
|
int amount = VN_CAST(nodep->rhsp(), Const)->num().mostSetBitP1()-1; // 2^n->n+1
|
||||||
AstNode* opp = nodep->lhsp()->unlinkFrBack();
|
AstNode* opp = nodep->lhsp()->unlinkFrBack();
|
||||||
|
@ -873,7 +873,7 @@ private:
|
||||||
newp->dtypeFrom(nodep);
|
newp->dtypeFrom(nodep);
|
||||||
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
|
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
void replaceShiftOp (AstNodeBiop* nodep) {
|
void replaceShiftOp(AstNodeBiop* nodep) {
|
||||||
UINFO(5,"SHIFT(AND(a,b),CONST)->AND(SHIFT(a,CONST),SHIFT(b,CONST)) "<<nodep<<endl);
|
UINFO(5,"SHIFT(AND(a,b),CONST)->AND(SHIFT(a,CONST),SHIFT(b,CONST)) "<<nodep<<endl);
|
||||||
AstNRelinker handle;
|
AstNRelinker handle;
|
||||||
nodep->unlinkFrBack(&handle);
|
nodep->unlinkFrBack(&handle);
|
||||||
|
@ -890,7 +890,7 @@ private:
|
||||||
handle.relink(newp);
|
handle.relink(newp);
|
||||||
iterate(newp); // Further reduce, either node may have more reductions.
|
iterate(newp); // Further reduce, either node may have more reductions.
|
||||||
}
|
}
|
||||||
void replaceShiftShift (AstNodeBiop* nodep) {
|
void replaceShiftShift(AstNodeBiop* nodep) {
|
||||||
UINFO(4,"SHIFT(SHIFT(a,s1),s2)->SHIFT(a,ADD(s1,s2)) "<<nodep<<endl);
|
UINFO(4,"SHIFT(SHIFT(a,s1),s2)->SHIFT(a,ADD(s1,s2)) "<<nodep<<endl);
|
||||||
if (debug()>=9) nodep->dumpTree(cout, " repShiftShift_old: ");
|
if (debug()>=9) nodep->dumpTree(cout, " repShiftShift_old: ");
|
||||||
AstNodeBiop* lhsp = VN_CAST(nodep->lhsp(), NodeBiop); lhsp->unlinkFrBack();
|
AstNodeBiop* lhsp = VN_CAST(nodep->lhsp(), NodeBiop); lhsp->unlinkFrBack();
|
||||||
|
@ -937,9 +937,9 @@ private:
|
||||||
new AstConst(nodep->fileline(), newshift));
|
new AstConst(nodep->fileline(), newshift));
|
||||||
}
|
}
|
||||||
newp->dtypeFrom(nodep);
|
newp->dtypeFrom(nodep);
|
||||||
newp = new AstAnd (nodep->fileline(),
|
newp = new AstAnd(nodep->fileline(),
|
||||||
newp,
|
newp,
|
||||||
new AstConst (nodep->fileline(), mask));
|
new AstConst(nodep->fileline(), mask));
|
||||||
newp->dtypeFrom(nodep);
|
newp->dtypeFrom(nodep);
|
||||||
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
|
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
|
||||||
//newp->dumpTree(cout, " repShiftShift_new: ");
|
//newp->dumpTree(cout, " repShiftShift_new: ");
|
||||||
|
@ -980,13 +980,13 @@ private:
|
||||||
AstNode* rhs2p = nextp->rhsp()->unlinkFrBack();
|
AstNode* rhs2p = nextp->rhsp()->unlinkFrBack();
|
||||||
AstNode* newp;
|
AstNode* newp;
|
||||||
if (lsbFirstAssign) {
|
if (lsbFirstAssign) {
|
||||||
newp = nodep->cloneType (new AstSel(sel1p->fileline(), varref1p->unlinkFrBack(),
|
newp = nodep->cloneType(new AstSel(sel1p->fileline(), varref1p->unlinkFrBack(),
|
||||||
sel1p->lsbConst(), sel1p->width() + sel2p->width()),
|
sel1p->lsbConst(), sel1p->width() + sel2p->width()),
|
||||||
new AstConcat(rhs1p->fileline(), rhs2p, rhs1p));
|
new AstConcat(rhs1p->fileline(), rhs2p, rhs1p));
|
||||||
} else {
|
} else {
|
||||||
newp = nodep->cloneType (new AstSel(sel1p->fileline(), varref1p->unlinkFrBack(),
|
newp = nodep->cloneType(new AstSel(sel1p->fileline(), varref1p->unlinkFrBack(),
|
||||||
sel2p->lsbConst(), sel1p->width() + sel2p->width()),
|
sel2p->lsbConst(), sel1p->width() + sel2p->width()),
|
||||||
new AstConcat(rhs1p->fileline(), rhs1p, rhs2p));
|
new AstConcat(rhs1p->fileline(), rhs1p, rhs2p));
|
||||||
}
|
}
|
||||||
//pnewp->dumpTree(cout, "conew: ");
|
//pnewp->dumpTree(cout, "conew: ");
|
||||||
nodep->replaceWith(newp); nodep->deleteTree();
|
nodep->replaceWith(newp); nodep->deleteTree();
|
||||||
|
@ -1673,7 +1673,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SenItemCmp {
|
struct SenItemCmp {
|
||||||
inline bool operator () (AstNodeSenItem* lhsp, AstNodeSenItem* rhsp) const {
|
inline bool operator() (AstNodeSenItem* lhsp, AstNodeSenItem* rhsp) const {
|
||||||
if (lhsp->type() < rhsp->type()) return true;
|
if (lhsp->type() < rhsp->type()) return true;
|
||||||
if (lhsp->type() > rhsp->type()) return false;
|
if (lhsp->type() > rhsp->type()) return false;
|
||||||
const AstSenItem* litemp = VN_CAST_CONST(lhsp, SenItem);
|
const AstSenItem* litemp = VN_CAST_CONST(lhsp, SenItem);
|
||||||
|
|
|
@ -163,7 +163,7 @@ private:
|
||||||
|
|
||||||
// Add signal to hold the old value
|
// Add signal to hold the old value
|
||||||
string newvarname = (string)"__Vtogcov__"+nodep->shortName();
|
string newvarname = (string)"__Vtogcov__"+nodep->shortName();
|
||||||
AstVar* chgVarp = new AstVar (nodep->fileline(), AstVarType::MODULETEMP, newvarname, nodep);
|
AstVar* chgVarp = new AstVar(nodep->fileline(), AstVarType::MODULETEMP, newvarname, nodep);
|
||||||
chgVarp->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true);
|
chgVarp->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true);
|
||||||
m_modp->addStmtp(chgVarp);
|
m_modp->addStmtp(chgVarp);
|
||||||
|
|
||||||
|
@ -185,11 +185,11 @@ private:
|
||||||
const ToggleEnt& above,
|
const ToggleEnt& above,
|
||||||
AstVar* varp, AstVar* chgVarp) { // Constant
|
AstVar* varp, AstVar* chgVarp) { // Constant
|
||||||
AstCoverToggle* newp
|
AstCoverToggle* newp
|
||||||
= new AstCoverToggle (varp->fileline(),
|
= new AstCoverToggle(varp->fileline(),
|
||||||
newCoverInc(varp->fileline(), "", "v_toggle",
|
newCoverInc(varp->fileline(), "", "v_toggle",
|
||||||
varp->name()+above.m_comment),
|
varp->name()+above.m_comment),
|
||||||
above.m_varRefp->cloneTree(true),
|
above.m_varRefp->cloneTree(true),
|
||||||
above.m_chgRefp->cloneTree(true));
|
above.m_chgRefp->cloneTree(true));
|
||||||
m_modp->addStmtp(newp);
|
m_modp->addStmtp(newp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,7 @@ private:
|
||||||
// The CoverDecl the duplicate pointed to now needs to point to the original's data
|
// The CoverDecl the duplicate pointed to now needs to point to the original's data
|
||||||
// IE the duplicate will get the coverage number from the non-duplicate
|
// IE the duplicate will get the coverage number from the non-duplicate
|
||||||
AstCoverDecl* datadeclp = nodep->incp()->declp()->dataDeclThisp();
|
AstCoverDecl* datadeclp = nodep->incp()->declp()->dataDeclThisp();
|
||||||
removep->incp()->declp()->dataDeclp (datadeclp);
|
removep->incp()->declp()->dataDeclp(datadeclp);
|
||||||
UINFO(8," new "<<removep->incp()->declp()<<endl);
|
UINFO(8," new "<<removep->incp()->declp()<<endl);
|
||||||
// Mark the found node as a duplicate of the first node
|
// Mark the found node as a duplicate of the first node
|
||||||
// (Not vice-versa as we have the iterator for the found node)
|
// (Not vice-versa as we have the iterator for the found node)
|
||||||
|
|
|
@ -128,25 +128,25 @@ private:
|
||||||
varp = it->second;
|
varp = it->second;
|
||||||
} else {
|
} else {
|
||||||
if (newdtypep) {
|
if (newdtypep) {
|
||||||
varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, newdtypep);
|
varp = new AstVar(oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, newdtypep);
|
||||||
} else if (width==0) {
|
} else if (width==0) {
|
||||||
varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, oldvarscp->varp());
|
varp = new AstVar(oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, oldvarscp->varp());
|
||||||
varp->dtypeFrom(oldvarscp);
|
varp->dtypeFrom(oldvarscp);
|
||||||
} else { // Used for vset and dimensions, so can zero init
|
} else { // Used for vset and dimensions, so can zero init
|
||||||
varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, VFlagBitPacked(), width);
|
varp = new AstVar(oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, VFlagBitPacked(), width);
|
||||||
}
|
}
|
||||||
addmodp->addStmtp(varp);
|
addmodp->addStmtp(varp);
|
||||||
m_modVarMap.insert(make_pair(make_pair(addmodp, name), varp));
|
m_modVarMap.insert(make_pair(make_pair(addmodp, name), varp));
|
||||||
}
|
}
|
||||||
|
|
||||||
AstVarScope* varscp = new AstVarScope (oldvarscp->fileline(), oldvarscp->scopep(), varp);
|
AstVarScope* varscp = new AstVarScope(oldvarscp->fileline(), oldvarscp->scopep(), varp);
|
||||||
oldvarscp->scopep()->addVarp(varscp);
|
oldvarscp->scopep()->addVarp(varscp);
|
||||||
return varscp;
|
return varscp;
|
||||||
}
|
}
|
||||||
|
|
||||||
AstActive* createActivePost(AstVarRef* varrefp) {
|
AstActive* createActivePost(AstVarRef* varrefp) {
|
||||||
AstActive* newactp = new AstActive (varrefp->fileline(), "sequentdly",
|
AstActive* newactp = new AstActive(varrefp->fileline(), "sequentdly",
|
||||||
m_activep->sensesp());
|
m_activep->sensesp());
|
||||||
// Was addNext(), but addNextHere() avoids a linear search.
|
// Was addNext(), but addNextHere() avoids a linear search.
|
||||||
m_activep->addNextHere(newactp);
|
m_activep->addNextHere(newactp);
|
||||||
return newactp;
|
return newactp;
|
||||||
|
@ -224,9 +224,9 @@ private:
|
||||||
+"__"+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
|
+"__"+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
|
||||||
AstVarScope* bitvscp = createVarSc(varrefp->varScopep(), bitvarname, dimp->width(), NULL);
|
AstVarScope* bitvscp = createVarSc(varrefp->varScopep(), bitvarname, dimp->width(), NULL);
|
||||||
AstAssign* bitassignp
|
AstAssign* bitassignp
|
||||||
= new AstAssign (nodep->fileline(),
|
= new AstAssign(nodep->fileline(),
|
||||||
new AstVarRef(nodep->fileline(), bitvscp, true),
|
new AstVarRef(nodep->fileline(), bitvscp, true),
|
||||||
dimp);
|
dimp);
|
||||||
nodep->addNextHere(bitassignp);
|
nodep->addNextHere(bitassignp);
|
||||||
dimreadps.push_front(new AstVarRef(nodep->fileline(), bitvscp, false));
|
dimreadps.push_front(new AstVarRef(nodep->fileline(), bitvscp, false));
|
||||||
}
|
}
|
||||||
|
@ -241,9 +241,9 @@ private:
|
||||||
} else {
|
} else {
|
||||||
string bitvarname = (string("__Vdlyvlsb__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
|
string bitvarname = (string("__Vdlyvlsb__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
|
||||||
AstVarScope* bitvscp = createVarSc(varrefp->varScopep(), bitvarname, lsbvaluep->width(), NULL);
|
AstVarScope* bitvscp = createVarSc(varrefp->varScopep(), bitvarname, lsbvaluep->width(), NULL);
|
||||||
AstAssign* bitassignp = new AstAssign (nodep->fileline(),
|
AstAssign* bitassignp = new AstAssign(nodep->fileline(),
|
||||||
new AstVarRef(nodep->fileline(), bitvscp, true),
|
new AstVarRef(nodep->fileline(), bitvscp, true),
|
||||||
lsbvaluep);
|
lsbvaluep);
|
||||||
nodep->addNextHere(bitassignp);
|
nodep->addNextHere(bitassignp);
|
||||||
bitreadp = new AstVarRef(nodep->fileline(), bitvscp, false);
|
bitreadp = new AstVarRef(nodep->fileline(), bitvscp, false);
|
||||||
}
|
}
|
||||||
|
@ -274,14 +274,14 @@ private:
|
||||||
} else { // Create new one
|
} else { // Create new one
|
||||||
string setvarname = (string("__Vdlyvset__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
|
string setvarname = (string("__Vdlyvset__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
|
||||||
setvscp = createVarSc(varrefp->varScopep(), setvarname, 1, NULL);
|
setvscp = createVarSc(varrefp->varScopep(), setvarname, 1, NULL);
|
||||||
setinitp = new AstAssignPre (nodep->fileline(),
|
setinitp = new AstAssignPre(nodep->fileline(),
|
||||||
new AstVarRef(nodep->fileline(), setvscp, true),
|
new AstVarRef(nodep->fileline(), setvscp, true),
|
||||||
new AstConst(nodep->fileline(), 0));
|
new AstConst(nodep->fileline(), 0));
|
||||||
AstAssign* setassignp
|
AstAssign* setassignp
|
||||||
= new AstAssign (nodep->fileline(),
|
= new AstAssign(nodep->fileline(),
|
||||||
new AstVarRef(nodep->fileline(), setvscp, true),
|
new AstVarRef(nodep->fileline(), setvscp, true),
|
||||||
new AstConst(nodep->fileline(),
|
new AstConst(nodep->fileline(),
|
||||||
V3Number(nodep->fileline(),1,true)));
|
V3Number(nodep->fileline(),1,true)));
|
||||||
nodep->addNextHere(setassignp);
|
nodep->addNextHere(setassignp);
|
||||||
}
|
}
|
||||||
if (m_nextDlyp) { // Tell next assigndly it can share the variable
|
if (m_nextDlyp) { // Tell next assigndly it can share the variable
|
||||||
|
@ -325,10 +325,9 @@ private:
|
||||||
postLogicp = VN_CAST(finalp->user4p(), If);
|
postLogicp = VN_CAST(finalp->user4p(), If);
|
||||||
if (!postLogicp) nodep->v3fatalSrc("Delayed assignment misoptimized; prev var found w/o associated IF");
|
if (!postLogicp) nodep->v3fatalSrc("Delayed assignment misoptimized; prev var found w/o associated IF");
|
||||||
} else {
|
} else {
|
||||||
postLogicp = new AstIf (nodep->fileline(),
|
postLogicp = new AstIf(nodep->fileline(),
|
||||||
new AstVarRef(nodep->fileline(), setvscp, false),
|
new AstVarRef(nodep->fileline(), setvscp, false),
|
||||||
NULL,
|
NULL, NULL);
|
||||||
NULL);
|
|
||||||
UINFO(9," Created "<<postLogicp<<endl);
|
UINFO(9," Created "<<postLogicp<<endl);
|
||||||
finalp->addBodysp(postLogicp);
|
finalp->addBodysp(postLogicp);
|
||||||
finalp->user3p(setvscp); // Remember IF's vset variable
|
finalp->user3p(setvscp); // Remember IF's vset variable
|
||||||
|
@ -406,13 +405,13 @@ private:
|
||||||
string newvarname = (string("__Vdly__")+nodep->varp()->shortName());
|
string newvarname = (string("__Vdly__")+nodep->varp()->shortName());
|
||||||
dlyvscp = createVarSc(oldvscp, newvarname, 0, NULL);
|
dlyvscp = createVarSc(oldvscp, newvarname, 0, NULL);
|
||||||
AstNodeAssign* prep
|
AstNodeAssign* prep
|
||||||
= new AstAssignPre (nodep->fileline(),
|
= new AstAssignPre(nodep->fileline(),
|
||||||
new AstVarRef(nodep->fileline(), dlyvscp, true),
|
new AstVarRef(nodep->fileline(), dlyvscp, true),
|
||||||
new AstVarRef(nodep->fileline(), oldvscp, false));
|
new AstVarRef(nodep->fileline(), oldvscp, false));
|
||||||
AstNodeAssign* postp
|
AstNodeAssign* postp
|
||||||
= new AstAssignPost (nodep->fileline(),
|
= new AstAssignPost(nodep->fileline(),
|
||||||
new AstVarRef(nodep->fileline(), oldvscp, true),
|
new AstVarRef(nodep->fileline(), oldvscp, true),
|
||||||
new AstVarRef(nodep->fileline(), dlyvscp, false));
|
new AstVarRef(nodep->fileline(), dlyvscp, false));
|
||||||
postp->lhsp()->user2(true); // Don't detect this assignment
|
postp->lhsp()->user2(true); // Don't detect this assignment
|
||||||
oldvscp->user1p(dlyvscp); // So we can find it later
|
oldvscp->user1p(dlyvscp); // So we can find it later
|
||||||
// Make new ACTIVE with identical sensitivity tree
|
// Make new ACTIVE with identical sensitivity tree
|
||||||
|
|
|
@ -59,21 +59,21 @@ private:
|
||||||
//if (debug()>=9) nodep->dumpTree(cout,"deep:");
|
//if (debug()>=9) nodep->dumpTree(cout,"deep:");
|
||||||
|
|
||||||
string newvarname = ((string)"__Vdeeptemp"+cvtToStr(m_modp->varNumGetInc()));
|
string newvarname = ((string)"__Vdeeptemp"+cvtToStr(m_modp->varNumGetInc()));
|
||||||
AstVar* varp = new AstVar (nodep->fileline(), AstVarType::STMTTEMP, newvarname,
|
AstVar* varp = new AstVar(nodep->fileline(), AstVarType::STMTTEMP, newvarname,
|
||||||
// Width, not widthMin, as we may be in middle of BITSEL expression which
|
// Width, not widthMin, as we may be in middle of BITSEL expression which
|
||||||
// though it's one bit wide, needs the mask in the upper bits.
|
// though it's one bit wide, needs the mask in the upper bits.
|
||||||
// (Someday we'll have a valid bitmask instead of widths....)
|
// (Someday we'll have a valid bitmask instead of widths....)
|
||||||
// See t_func_crc for an example test that requires this
|
// See t_func_crc for an example test that requires this
|
||||||
VFlagLogicPacked(), nodep->width());
|
VFlagLogicPacked(), nodep->width());
|
||||||
if (!m_funcp) nodep->v3fatalSrc("Deep expression not under a function");
|
if (!m_funcp) nodep->v3fatalSrc("Deep expression not under a function");
|
||||||
m_funcp->addInitsp(varp);
|
m_funcp->addInitsp(varp);
|
||||||
// Replace node tree with reference to var
|
// Replace node tree with reference to var
|
||||||
AstVarRef* newp = new AstVarRef (nodep->fileline(), varp, false);
|
AstVarRef* newp = new AstVarRef(nodep->fileline(), varp, false);
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
// Put assignment before the referencing statement
|
// Put assignment before the referencing statement
|
||||||
AstAssign* assp = new AstAssign (nodep->fileline(),
|
AstAssign* assp = new AstAssign(nodep->fileline(),
|
||||||
new AstVarRef(nodep->fileline(), varp, true),
|
new AstVarRef(nodep->fileline(), varp, true),
|
||||||
nodep);
|
nodep);
|
||||||
AstNRelinker linker2;
|
AstNRelinker linker2;
|
||||||
m_stmtp->unlinkFrBack(&linker2);
|
m_stmtp->unlinkFrBack(&linker2);
|
||||||
assp->addNext(m_stmtp);
|
assp->addNext(m_stmtp);
|
||||||
|
|
|
@ -192,20 +192,19 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode* returnp = new AstCReturn (funcp->fileline(),
|
AstNode* returnp = new AstCReturn(funcp->fileline(),
|
||||||
new AstCCall (funcp->fileline(),
|
new AstCCall(funcp->fileline(),
|
||||||
funcp,
|
funcp, argsp));
|
||||||
argsp));
|
|
||||||
|
|
||||||
if (moreOfSame) {
|
if (moreOfSame) {
|
||||||
AstIf* ifp = new AstIf (funcp->fileline(),
|
AstIf* ifp = new AstIf(funcp->fileline(),
|
||||||
new AstEq(funcp->fileline(),
|
new AstEq(funcp->fileline(),
|
||||||
new AstCMath(funcp->fileline(),
|
new AstCMath(funcp->fileline(),
|
||||||
"this", 64),
|
"this", 64),
|
||||||
new AstCMath(funcp->fileline(),
|
new AstCMath(funcp->fileline(),
|
||||||
string("&(")
|
string("&(")
|
||||||
+funcp->scopep()->nameVlSym()
|
+funcp->scopep()->nameVlSym()
|
||||||
+")", 64)),
|
+")", 64)),
|
||||||
returnp, NULL);
|
returnp, NULL);
|
||||||
newfuncp->addStmtsp(ifp);
|
newfuncp->addStmtsp(ifp);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -87,14 +87,14 @@ public:
|
||||||
bool emitSimpleOk(AstNodeMath* nodep);
|
bool emitSimpleOk(AstNodeMath* nodep);
|
||||||
void emitIQW(AstNode* nodep) {
|
void emitIQW(AstNode* nodep) {
|
||||||
// Other abbrevs: "C"har, "S"hort, "F"loat, "D"ouble, stri"N"g
|
// Other abbrevs: "C"har, "S"hort, "F"loat, "D"ouble, stri"N"g
|
||||||
puts (nodep->dtypep()->charIQWN());
|
puts(nodep->dtypep()->charIQWN());
|
||||||
}
|
}
|
||||||
void emitScIQW(AstVar* nodep) {
|
void emitScIQW(AstVar* nodep) {
|
||||||
if (!nodep->isSc()) nodep->v3fatalSrc("emitting SystemC operator on non-SC variable");
|
if (!nodep->isSc()) nodep->v3fatalSrc("emitting SystemC operator on non-SC variable");
|
||||||
puts (nodep->isScBigUint() ? "SB"
|
puts(nodep->isScBigUint() ? "SB"
|
||||||
: nodep->isScUint() ? "SU"
|
: nodep->isScUint() ? "SU"
|
||||||
: nodep->isScBv() ? "SW"
|
: nodep->isScBv() ? "SW"
|
||||||
: (nodep->isScQuad() ? "SQ" : "SI"));
|
: (nodep->isScQuad() ? "SQ" : "SI"));
|
||||||
}
|
}
|
||||||
void emitOpName(AstNode* nodep, const string& format,
|
void emitOpName(AstNode* nodep, const string& format,
|
||||||
AstNode* lhsp, AstNode* rhsp, AstNode* thsp);
|
AstNode* lhsp, AstNode* rhsp, AstNode* thsp);
|
||||||
|
@ -161,7 +161,7 @@ public:
|
||||||
iterateAndNextNull(selp->fromp()); puts(", ");
|
iterateAndNextNull(selp->fromp()); puts(", ");
|
||||||
} else {
|
} else {
|
||||||
putbs("VL_ASSIGNSEL_");
|
putbs("VL_ASSIGNSEL_");
|
||||||
emitIQW (selp->fromp());
|
emitIQW(selp->fromp());
|
||||||
puts("II");
|
puts("II");
|
||||||
emitIQW(nodep->rhsp());
|
emitIQW(nodep->rhsp());
|
||||||
puts("(");
|
puts("(");
|
||||||
|
@ -892,17 +892,17 @@ class EmitCImp : EmitCStmts {
|
||||||
// We should move them to a different stage.
|
// We should move them to a different stage.
|
||||||
string filename = VL_DEV_NULL;
|
string filename = VL_DEV_NULL;
|
||||||
newCFile(filename, slow, source);
|
newCFile(filename, slow, source);
|
||||||
ofp = new V3OutCFile (filename);
|
ofp = new V3OutCFile(filename);
|
||||||
}
|
}
|
||||||
else if (optSystemC()) {
|
else if (optSystemC()) {
|
||||||
string filename = filenameNoExt+(source?".cpp":".h");
|
string filename = filenameNoExt+(source?".cpp":".h");
|
||||||
newCFile(filename, slow, source);
|
newCFile(filename, slow, source);
|
||||||
ofp = new V3OutScFile (filename);
|
ofp = new V3OutScFile(filename);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
string filename = filenameNoExt+(source?".cpp":".h");
|
string filename = filenameNoExt+(source?".cpp":".h");
|
||||||
newCFile(filename, slow, source);
|
newCFile(filename, slow, source);
|
||||||
ofp = new V3OutCFile (filename);
|
ofp = new V3OutCFile(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
ofp->putsHeader();
|
ofp->putsHeader();
|
||||||
|
@ -1303,7 +1303,7 @@ void EmitCStmts::emitVarCtors(bool* firstp) {
|
||||||
puts("("); putsQuoted(varp->name()); puts(")");
|
puts("("); putsQuoted(varp->name()); puts(")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
puts ("\n#endif\n");
|
puts("\n#endif\n");
|
||||||
ofp()->indentDec();
|
ofp()->indentDec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2297,7 +2297,7 @@ void EmitCStmts::emitSortedVarList(const VarVec& anons,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CmpName {
|
struct CmpName {
|
||||||
inline bool operator () (const AstNode* lhsp, const AstNode* rhsp) const {
|
inline bool operator() (const AstNode* lhsp, const AstNode* rhsp) const {
|
||||||
return lhsp->name() < rhsp->name();
|
return lhsp->name() < rhsp->name();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -2730,7 +2730,7 @@ class EmitCTrace : EmitCStmts {
|
||||||
cfilep->support(true);
|
cfilep->support(true);
|
||||||
|
|
||||||
if (m_ofp) v3fatalSrc("Previous file not closed");
|
if (m_ofp) v3fatalSrc("Previous file not closed");
|
||||||
m_ofp = new V3OutCFile (filename);
|
m_ofp = new V3OutCFile(filename);
|
||||||
m_ofp->putsHeader();
|
m_ofp->putsHeader();
|
||||||
m_ofp->puts("// DESCR" "IPTION: Verilator output: Tracing implementation internals\n");
|
m_ofp->puts("// DESCR" "IPTION: Verilator output: Tracing implementation internals\n");
|
||||||
|
|
||||||
|
@ -2923,7 +2923,7 @@ class EmitCTrace : EmitCStmts {
|
||||||
// Close old file
|
// Close old file
|
||||||
delete m_ofp; m_ofp=NULL;
|
delete m_ofp; m_ofp=NULL;
|
||||||
// Open a new file
|
// Open a new file
|
||||||
newOutCFile (splitFilenumInc());
|
newOutCFile(splitFilenumInc());
|
||||||
}
|
}
|
||||||
|
|
||||||
splitSizeInc(nodep);
|
splitSizeInc(nodep);
|
||||||
|
|
|
@ -63,12 +63,12 @@ class EmitCSyms : EmitCBaseVisitor {
|
||||||
typedef std::pair<AstScope*,AstNodeModule*> ScopeModPair;
|
typedef std::pair<AstScope*,AstNodeModule*> ScopeModPair;
|
||||||
typedef std::pair<AstNodeModule*,AstVar*> ModVarPair;
|
typedef std::pair<AstNodeModule*,AstVar*> ModVarPair;
|
||||||
struct CmpName {
|
struct CmpName {
|
||||||
inline bool operator () (const ScopeModPair& lhsp, const ScopeModPair& rhsp) const {
|
inline bool operator() (const ScopeModPair& lhsp, const ScopeModPair& rhsp) const {
|
||||||
return lhsp.first->name() < rhsp.first->name();
|
return lhsp.first->name() < rhsp.first->name();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct CmpDpi {
|
struct CmpDpi {
|
||||||
inline bool operator () (const AstCFunc* lhsp, const AstCFunc* rhsp) const {
|
inline bool operator() (const AstCFunc* lhsp, const AstCFunc* rhsp) const {
|
||||||
if (lhsp->dpiImport() != rhsp->dpiImport()) {
|
if (lhsp->dpiImport() != rhsp->dpiImport()) {
|
||||||
// cppcheck-suppress comparisonOfFuncReturningBoolError
|
// cppcheck-suppress comparisonOfFuncReturningBoolError
|
||||||
return lhsp->dpiImport() < rhsp->dpiImport();
|
return lhsp->dpiImport() < rhsp->dpiImport();
|
||||||
|
@ -284,7 +284,7 @@ void EmitCSyms::emitSymHdr() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v3Global.dpi()) {
|
if (v3Global.dpi()) {
|
||||||
puts ("\n// DPI TYPES for DPI Export callbacks (Internal use)\n");
|
puts("\n// DPI TYPES for DPI Export callbacks (Internal use)\n");
|
||||||
std::map<string,int> types; // Remove duplicates and sort
|
std::map<string,int> types; // Remove duplicates and sort
|
||||||
for (ScopeFuncs::iterator it = m_scopeFuncs.begin(); it != m_scopeFuncs.end(); ++it) {
|
for (ScopeFuncs::iterator it = m_scopeFuncs.begin(); it != m_scopeFuncs.end(); ++it) {
|
||||||
AstCFunc* funcp = it->second.m_funcp;
|
AstCFunc* funcp = it->second.m_funcp;
|
||||||
|
|
|
@ -80,9 +80,9 @@ void V3Error::init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string V3Error::lineStr (const char* filename, int lineno) {
|
string V3Error::lineStr(const char* filename, int lineno) {
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
const char* fnslashp = strrchr (filename, '/');
|
const char* fnslashp = strrchr(filename, '/');
|
||||||
if (fnslashp) filename = fnslashp+1;
|
if (fnslashp) filename = fnslashp+1;
|
||||||
out<<filename<<":"<<std::dec<<lineno<<":";
|
out<<filename<<":"<<std::dec<<lineno<<":";
|
||||||
const char* const spaces = " ";
|
const char* const spaces = " ";
|
||||||
|
@ -94,7 +94,7 @@ string V3Error::lineStr (const char* filename, int lineno) {
|
||||||
void V3Error::incErrors() {
|
void V3Error::incErrors() {
|
||||||
s_errCount++;
|
s_errCount++;
|
||||||
if (errorCount() == errorLimit()) { // Not >= as would otherwise recurse
|
if (errorCount() == errorLimit()) { // Not >= as would otherwise recurse
|
||||||
v3fatal ("Exiting due to too many errors encountered; --error-limit="<<errorCount()<<endl);
|
v3fatal("Exiting due to too many errors encountered; --error-limit="<<errorCount()<<endl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ string V3Error::msgPrefix() {
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// Abort/exit
|
// Abort/exit
|
||||||
|
|
||||||
void V3Error::vlAbort () {
|
void V3Error::vlAbort() {
|
||||||
if (V3Error::debugDefault()) {
|
if (V3Error::debugDefault()) {
|
||||||
std::cerr<<msgPrefix()<<"Aborting since under --debug"<<endl;
|
std::cerr<<msgPrefix()<<"Aborting since under --debug"<<endl;
|
||||||
abort();
|
abort();
|
||||||
|
|
|
@ -112,12 +112,12 @@ public:
|
||||||
// ***Add new elements below also***
|
// ***Add new elements below also***
|
||||||
};
|
};
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
inline V3ErrorCode () : m_e(EC_MIN) {}
|
inline V3ErrorCode() : m_e(EC_MIN) {}
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
inline V3ErrorCode (en _e) : m_e(_e) {}
|
inline V3ErrorCode(en _e) : m_e(_e) {}
|
||||||
explicit V3ErrorCode (const char* msgp); // Matching code or ERROR
|
explicit V3ErrorCode(const char* msgp); // Matching code or ERROR
|
||||||
explicit inline V3ErrorCode (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline V3ErrorCode(int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en() const { return m_e; }
|
||||||
const char* ascii() const {
|
const char* ascii() const {
|
||||||
const char* names[] = {
|
const char* names[] = {
|
||||||
// Leading spaces indicate it can't be disabled.
|
// Leading spaces indicate it can't be disabled.
|
||||||
|
@ -243,8 +243,8 @@ class V3Error {
|
||||||
static void suppressThisWarning(); // Suppress next %Warn if user has it off
|
static void suppressThisWarning(); // Suppress next %Warn if user has it off
|
||||||
static void pretendError(V3ErrorCode code, bool flag) { s_pretendError[code]=flag; }
|
static void pretendError(V3ErrorCode code, bool flag) { s_pretendError[code]=flag; }
|
||||||
static bool isError(V3ErrorCode code, bool supp);
|
static bool isError(V3ErrorCode code, bool supp);
|
||||||
static string lineStr (const char* filename, int lineno);
|
static string lineStr(const char* filename, int lineno);
|
||||||
static V3ErrorCode errorCode() { return s_errorCode; }
|
static V3ErrorCode errorCode() { return s_errorCode; }
|
||||||
static void errorExitCb(ErrorExitCb cb) { s_errorExitCb = cb; }
|
static void errorExitCb(ErrorExitCb cb) { s_errorExitCb = cb; }
|
||||||
|
|
||||||
// When printing an error/warning, print prefix for multiline message
|
// When printing an error/warning, print prefix for multiline message
|
||||||
|
@ -318,7 +318,7 @@ inline void v3errorEndFatal(std::ostringstream& sstr) { V3Error::v3errorEnd(sstr
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
template< class T> std::string cvtToStr (const T& t) {
|
template< class T> std::string cvtToStr(const T& t) {
|
||||||
std::ostringstream os; os<<t; return os.str();
|
std::ostringstream os; os<<t; return os.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
564
src/V3Expand.cpp
564
src/V3Expand.cpp
|
@ -55,16 +55,16 @@ private:
|
||||||
// METHODS
|
// METHODS
|
||||||
VL_DEBUG_FUNC; // Declare debug()
|
VL_DEBUG_FUNC; // Declare debug()
|
||||||
|
|
||||||
int longOrQuadWidth (AstNode* nodep) {
|
int longOrQuadWidth(AstNode* nodep) {
|
||||||
// Return 32 or 64...
|
// Return 32 or 64...
|
||||||
return (nodep->width()+(VL_WORDSIZE-1)) & ~(VL_WORDSIZE-1);
|
return (nodep->width()+(VL_WORDSIZE-1)) & ~(VL_WORDSIZE-1);
|
||||||
}
|
}
|
||||||
V3Number notWideMask (AstNode* nodep) {
|
V3Number notWideMask(AstNode* nodep) {
|
||||||
return V3Number (nodep->fileline(), VL_WORDSIZE, ~VL_MASK_I(nodep->widthMin()));
|
return V3Number(nodep->fileline(), VL_WORDSIZE, ~VL_MASK_I(nodep->widthMin()));
|
||||||
}
|
}
|
||||||
V3Number wordMask (AstNode* nodep) {
|
V3Number wordMask(AstNode* nodep) {
|
||||||
if (nodep->isWide()) {
|
if (nodep->isWide()) {
|
||||||
return V3Number (nodep->fileline(), VL_WORDSIZE, VL_MASK_I(nodep->widthMin()));
|
return V3Number(nodep->fileline(), VL_WORDSIZE, VL_MASK_I(nodep->widthMin()));
|
||||||
} else {
|
} else {
|
||||||
V3Number mask (nodep->fileline(), longOrQuadWidth(nodep));
|
V3Number mask (nodep->fileline(), longOrQuadWidth(nodep));
|
||||||
mask.setMask(nodep->widthMin());
|
mask.setMask(nodep->widthMin());
|
||||||
|
@ -72,35 +72,35 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void insertBefore (AstNode* placep, AstNode* newp) {
|
void insertBefore(AstNode* placep, AstNode* newp) {
|
||||||
newp->user1(1); // Already processed, don't need to re-iterate
|
newp->user1(1); // Already processed, don't need to re-iterate
|
||||||
AstNRelinker linker;
|
AstNRelinker linker;
|
||||||
placep->unlinkFrBack(&linker);
|
placep->unlinkFrBack(&linker);
|
||||||
newp->addNext(placep);
|
newp->addNext(placep);
|
||||||
linker.relink(newp);
|
linker.relink(newp);
|
||||||
}
|
}
|
||||||
void replaceWithDelete (AstNode* nodep, AstNode* newp) {
|
void replaceWithDelete(AstNode* nodep, AstNode* newp) {
|
||||||
newp->user1(1); // Already processed, don't need to re-iterate
|
newp->user1(1); // Already processed, don't need to re-iterate
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
AstNode* newWordAssign (AstNodeAssign* placep, int word, AstNode* lhsp, AstNode* rhsp) {
|
AstNode* newWordAssign(AstNodeAssign* placep, int word, AstNode* lhsp, AstNode* rhsp) {
|
||||||
AstAssign* newp = new AstAssign (placep->fileline(),
|
AstAssign* newp = new AstAssign(placep->fileline(),
|
||||||
new AstWordSel (placep->fileline(),
|
new AstWordSel(placep->fileline(),
|
||||||
lhsp->cloneTree(true),
|
lhsp->cloneTree(true),
|
||||||
new AstConst (placep->fileline(),
|
new AstConst(placep->fileline(),
|
||||||
word)),
|
word)),
|
||||||
rhsp);
|
rhsp);
|
||||||
return newp;
|
return newp;
|
||||||
}
|
}
|
||||||
void addWordAssign (AstNodeAssign* placep, int word, AstNode* lhsp, AstNode* rhsp) {
|
void addWordAssign(AstNodeAssign* placep, int word, AstNode* lhsp, AstNode* rhsp) {
|
||||||
insertBefore (placep, newWordAssign(placep, word, lhsp, rhsp));
|
insertBefore(placep, newWordAssign(placep, word, lhsp, rhsp));
|
||||||
}
|
}
|
||||||
void addWordAssign (AstNodeAssign* placep, int word, AstNode* rhsp) {
|
void addWordAssign(AstNodeAssign* placep, int word, AstNode* rhsp) {
|
||||||
addWordAssign (placep, word, placep->lhsp(), rhsp);
|
addWordAssign(placep, word, placep->lhsp(), rhsp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fixCloneLvalue (AstNode* nodep) {
|
void fixCloneLvalue(AstNode* nodep) {
|
||||||
// In AstSel transforms, we call clone() on VarRefs that were lvalues,
|
// In AstSel transforms, we call clone() on VarRefs that were lvalues,
|
||||||
// but are now being used on the RHS of the assignment
|
// but are now being used on the RHS of the assignment
|
||||||
if (VN_IS(nodep, VarRef)) VN_CAST(nodep, VarRef)->lvalue(false);
|
if (VN_IS(nodep, VarRef)) VN_CAST(nodep, VarRef)->lvalue(false);
|
||||||
|
@ -111,57 +111,57 @@ private:
|
||||||
if (nodep->op4p()) fixCloneLvalue(nodep->op4p());
|
if (nodep->op4p()) fixCloneLvalue(nodep->op4p());
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode* newAstWordSelClone (AstNode* nodep, int word) {
|
AstNode* newAstWordSelClone(AstNode* nodep, int word) {
|
||||||
// Get the specified word number from a wide array
|
// Get the specified word number from a wide array
|
||||||
// Or, if it's a long/quad, do appropriate conversion to wide
|
// Or, if it's a long/quad, do appropriate conversion to wide
|
||||||
// Concat may pass negative word numbers, that means it wants a zero
|
// Concat may pass negative word numbers, that means it wants a zero
|
||||||
if (nodep->isWide() && word>=0 && word<nodep->widthWords()) {
|
if (nodep->isWide() && word>=0 && word<nodep->widthWords()) {
|
||||||
return new AstWordSel (nodep->fileline(),
|
return new AstWordSel(nodep->fileline(),
|
||||||
nodep->cloneTree(true),
|
nodep->cloneTree(true),
|
||||||
new AstConst(nodep->fileline(), word));
|
new AstConst(nodep->fileline(), word));
|
||||||
} else if (nodep->isQuad() && word==0) {
|
} else if (nodep->isQuad() && word==0) {
|
||||||
AstNode* quadfromp = nodep->cloneTree(true);
|
AstNode* quadfromp = nodep->cloneTree(true);
|
||||||
quadfromp->dtypeSetBitSized(VL_QUADSIZE,quadfromp->widthMin(),AstNumeric::UNSIGNED);
|
quadfromp->dtypeSetBitSized(VL_QUADSIZE,quadfromp->widthMin(),AstNumeric::UNSIGNED);
|
||||||
return new AstCCast (nodep->fileline(),
|
return new AstCCast(nodep->fileline(),
|
||||||
quadfromp,
|
quadfromp,
|
||||||
VL_WORDSIZE);
|
VL_WORDSIZE);
|
||||||
} else if (nodep->isQuad() && word==1) {
|
} else if (nodep->isQuad() && word==1) {
|
||||||
AstNode* quadfromp = nodep->cloneTree(true);
|
AstNode* quadfromp = nodep->cloneTree(true);
|
||||||
quadfromp->dtypeSetBitSized(VL_QUADSIZE,quadfromp->widthMin(),AstNumeric::UNSIGNED);
|
quadfromp->dtypeSetBitSized(VL_QUADSIZE,quadfromp->widthMin(),AstNumeric::UNSIGNED);
|
||||||
return new AstCCast (nodep->fileline(),
|
return new AstCCast(nodep->fileline(),
|
||||||
new AstShiftR (nodep->fileline(),
|
new AstShiftR(nodep->fileline(),
|
||||||
quadfromp,
|
quadfromp,
|
||||||
new AstConst (nodep->fileline(), VL_WORDSIZE),
|
new AstConst(nodep->fileline(), VL_WORDSIZE),
|
||||||
VL_WORDSIZE),
|
VL_WORDSIZE),
|
||||||
VL_WORDSIZE);
|
VL_WORDSIZE);
|
||||||
} else if (!nodep->isWide() && !nodep->isQuad() && word==0) {
|
} else if (!nodep->isWide() && !nodep->isQuad() && word==0) {
|
||||||
return nodep->cloneTree(true);
|
return nodep->cloneTree(true);
|
||||||
} else { // Out of bounds
|
} else { // Out of bounds
|
||||||
return new AstConst (nodep->fileline(), 0);
|
return new AstConst(nodep->fileline(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode* newWordGrabShift (FileLine* fl, int word, AstNode* lhsp, int shift) {
|
AstNode* newWordGrabShift(FileLine* fl, int word, AstNode* lhsp, int shift) {
|
||||||
// Extract the expression to grab the value for the specified word, if it's the shift
|
// Extract the expression to grab the value for the specified word, if it's the shift
|
||||||
// of shift bits from lhsp
|
// of shift bits from lhsp
|
||||||
AstNode* newp;
|
AstNode* newp;
|
||||||
// Negative word numbers requested for lhs when it's "before" what we want.
|
// Negative word numbers requested for lhs when it's "before" what we want.
|
||||||
// We get a 0 then.
|
// We get a 0 then.
|
||||||
int othword = word - shift/VL_WORDSIZE;
|
int othword = word - shift/VL_WORDSIZE;
|
||||||
AstNode* llowp = newAstWordSelClone (lhsp, othword);
|
AstNode* llowp = newAstWordSelClone(lhsp, othword);
|
||||||
if (int loffset = VL_BITBIT_I(shift)) {
|
if (int loffset = VL_BITBIT_I(shift)) {
|
||||||
AstNode* lhip = newAstWordSelClone (lhsp, othword-1);
|
AstNode* lhip = newAstWordSelClone(lhsp, othword-1);
|
||||||
int nbitsonright = VL_WORDSIZE-loffset; // bits that end up in lword
|
int nbitsonright = VL_WORDSIZE-loffset; // bits that end up in lword
|
||||||
newp = new AstOr
|
newp = new AstOr
|
||||||
(fl,
|
(fl,
|
||||||
new AstAnd(fl,
|
new AstAnd(fl,
|
||||||
new AstConst (fl, VL_MASK_I(loffset)),
|
new AstConst(fl, VL_MASK_I(loffset)),
|
||||||
new AstShiftR (fl,
|
new AstShiftR(fl,
|
||||||
lhip,
|
lhip,
|
||||||
new AstConst(fl, nbitsonright),
|
new AstConst(fl, nbitsonright),
|
||||||
VL_WORDSIZE)),
|
VL_WORDSIZE)),
|
||||||
new AstAnd(fl,
|
new AstAnd(fl,
|
||||||
new AstConst (fl, ~VL_MASK_I(loffset)),
|
new AstConst(fl, ~VL_MASK_I(loffset)),
|
||||||
new AstShiftL(fl,
|
new AstShiftL(fl,
|
||||||
llowp,
|
llowp,
|
||||||
new AstConst(fl, loffset),
|
new AstConst(fl, loffset),
|
||||||
|
@ -175,18 +175,18 @@ private:
|
||||||
AstNode* newSelBitWord(AstNode* lsbp, int wordAdder) {
|
AstNode* newSelBitWord(AstNode* lsbp, int wordAdder) {
|
||||||
// Return equation to get the VL_BITWORD of a constant or non-constant
|
// Return equation to get the VL_BITWORD of a constant or non-constant
|
||||||
if (VN_IS(lsbp, Const)) {
|
if (VN_IS(lsbp, Const)) {
|
||||||
return new AstConst (lsbp->fileline(),
|
return new AstConst(lsbp->fileline(),
|
||||||
wordAdder + VL_BITWORD_I(VN_CAST(lsbp, Const)->toUInt()));
|
wordAdder + VL_BITWORD_I(VN_CAST(lsbp, Const)->toUInt()));
|
||||||
} else {
|
} else {
|
||||||
AstNode* shiftp = new AstShiftR (lsbp->fileline(),
|
AstNode* shiftp = new AstShiftR(lsbp->fileline(),
|
||||||
lsbp->cloneTree(true),
|
lsbp->cloneTree(true),
|
||||||
new AstConst(lsbp->fileline(), VL_WORDSIZE_LOG2),
|
new AstConst(lsbp->fileline(), VL_WORDSIZE_LOG2),
|
||||||
VL_WORDSIZE);
|
VL_WORDSIZE);
|
||||||
if (wordAdder != 0) {
|
if (wordAdder != 0) {
|
||||||
shiftp = new AstAdd (lsbp->fileline(),
|
shiftp = new AstAdd(lsbp->fileline(),
|
||||||
// This is indexing a arraysel, so a 32 bit constant is fine
|
// This is indexing a arraysel, so a 32 bit constant is fine
|
||||||
new AstConst (lsbp->fileline(), wordAdder),
|
new AstConst(lsbp->fileline(), wordAdder),
|
||||||
shiftp);
|
shiftp);
|
||||||
}
|
}
|
||||||
return shiftp;
|
return shiftp;
|
||||||
}
|
}
|
||||||
|
@ -206,18 +206,18 @@ private:
|
||||||
AstNode* newSelBitBit(AstNode* lsbp) {
|
AstNode* newSelBitBit(AstNode* lsbp) {
|
||||||
// Return equation to get the VL_BITBIT of a constant or non-constant
|
// Return equation to get the VL_BITBIT of a constant or non-constant
|
||||||
if (VN_IS(lsbp, Const)) {
|
if (VN_IS(lsbp, Const)) {
|
||||||
return new AstConst (lsbp->fileline(),
|
return new AstConst(lsbp->fileline(),
|
||||||
VL_BITBIT_I(VN_CAST(lsbp, Const)->toUInt()));
|
VL_BITBIT_I(VN_CAST(lsbp, Const)->toUInt()));
|
||||||
} else {
|
} else {
|
||||||
return new AstAnd (lsbp->fileline(),
|
return new AstAnd(lsbp->fileline(),
|
||||||
new AstConst(lsbp->fileline(), VL_WORDSIZE-1),
|
new AstConst(lsbp->fileline(), VL_WORDSIZE-1),
|
||||||
dropCondBound(lsbp)->cloneTree(true));
|
dropCondBound(lsbp)->cloneTree(true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//====================
|
//====================
|
||||||
|
|
||||||
bool expandWide (AstNodeAssign* nodep, AstConst* rhsp) {
|
bool expandWide(AstNodeAssign* nodep, AstConst* rhsp) {
|
||||||
UINFO(8," Wordize ASSIGN(CONST) "<<nodep<<endl);
|
UINFO(8," Wordize ASSIGN(CONST) "<<nodep<<endl);
|
||||||
// -> {for each_word{ ASSIGN(WORDSEL(wide,#),WORDSEL(CONST,#))}}
|
// -> {for each_word{ ASSIGN(WORDSEL(wide,#),WORDSEL(CONST,#))}}
|
||||||
if (rhsp->num().isFourState()) {
|
if (rhsp->num().isFourState()) {
|
||||||
|
@ -225,82 +225,82 @@ private:
|
||||||
}
|
}
|
||||||
for (int w=0; w<nodep->widthWords(); w++) {
|
for (int w=0; w<nodep->widthWords(); w++) {
|
||||||
V3Number num (nodep->fileline(), VL_WORDSIZE, rhsp->num().dataWord(w));
|
V3Number num (nodep->fileline(), VL_WORDSIZE, rhsp->num().dataWord(w));
|
||||||
addWordAssign(nodep, w, new AstConst (nodep->fileline(), num));
|
addWordAssign(nodep, w, new AstConst(nodep->fileline(), num));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//-------- Uniops
|
//-------- Uniops
|
||||||
bool expandWide (AstNodeAssign* nodep, AstVarRef* rhsp) {
|
bool expandWide(AstNodeAssign* nodep, AstVarRef* rhsp) {
|
||||||
UINFO(8," Wordize ASSIGN(VARREF) "<<nodep<<endl);
|
UINFO(8," Wordize ASSIGN(VARREF) "<<nodep<<endl);
|
||||||
for (int w=0; w<nodep->widthWords(); w++) {
|
for (int w=0; w<nodep->widthWords(); w++) {
|
||||||
addWordAssign(nodep, w, newAstWordSelClone (rhsp, w));
|
addWordAssign(nodep, w, newAstWordSelClone(rhsp, w));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool expandWide (AstNodeAssign* nodep, AstArraySel* rhsp) {
|
bool expandWide(AstNodeAssign* nodep, AstArraySel* rhsp) {
|
||||||
UINFO(8," Wordize ASSIGN(ARRAYSEL) "<<nodep<<endl);
|
UINFO(8," Wordize ASSIGN(ARRAYSEL) "<<nodep<<endl);
|
||||||
if (VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType)) {
|
if (VN_IS(nodep->dtypep()->skipRefp(), UnpackArrayDType)) {
|
||||||
nodep->v3fatalSrc("ArraySel with unpacked arrays should have been removed in V3Slice");
|
nodep->v3fatalSrc("ArraySel with unpacked arrays should have been removed in V3Slice");
|
||||||
}
|
}
|
||||||
for (int w=0; w<nodep->widthWords(); w++) {
|
for (int w=0; w<nodep->widthWords(); w++) {
|
||||||
addWordAssign(nodep, w, newAstWordSelClone (rhsp, w));
|
addWordAssign(nodep, w, newAstWordSelClone(rhsp, w));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool expandWide (AstNodeAssign* nodep, AstNot* rhsp) {
|
bool expandWide(AstNodeAssign* nodep, AstNot* rhsp) {
|
||||||
UINFO(8," Wordize ASSIGN(NOT) "<<nodep<<endl);
|
UINFO(8," Wordize ASSIGN(NOT) "<<nodep<<endl);
|
||||||
// -> {for each_word{ ASSIGN(WORDSEL(wide,#),NOT(WORDSEL(lhs,#))) }}
|
// -> {for each_word{ ASSIGN(WORDSEL(wide,#),NOT(WORDSEL(lhs,#))) }}
|
||||||
for (int w=0; w<nodep->widthWords(); w++) {
|
for (int w=0; w<nodep->widthWords(); w++) {
|
||||||
addWordAssign(nodep, w, new AstNot (rhsp->fileline(),
|
addWordAssign(nodep, w, new AstNot(rhsp->fileline(),
|
||||||
newAstWordSelClone (rhsp->lhsp(), w)));
|
newAstWordSelClone(rhsp->lhsp(), w)));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//-------- Biops
|
//-------- Biops
|
||||||
bool expandWide (AstNodeAssign* nodep, AstAnd* rhsp) {
|
bool expandWide(AstNodeAssign* nodep, AstAnd* rhsp) {
|
||||||
UINFO(8," Wordize ASSIGN(AND) "<<nodep<<endl);
|
UINFO(8," Wordize ASSIGN(AND) "<<nodep<<endl);
|
||||||
for (int w=0; w<nodep->widthWords(); w++) {
|
for (int w=0; w<nodep->widthWords(); w++) {
|
||||||
addWordAssign(nodep, w, new AstAnd (nodep->fileline(),
|
addWordAssign(nodep, w, new AstAnd(nodep->fileline(),
|
||||||
newAstWordSelClone (rhsp->lhsp(), w),
|
newAstWordSelClone(rhsp->lhsp(), w),
|
||||||
newAstWordSelClone (rhsp->rhsp(), w)));
|
newAstWordSelClone(rhsp->rhsp(), w)));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool expandWide (AstNodeAssign* nodep, AstOr* rhsp) {
|
bool expandWide(AstNodeAssign* nodep, AstOr* rhsp) {
|
||||||
UINFO(8," Wordize ASSIGN(OR) "<<nodep<<endl);
|
UINFO(8," Wordize ASSIGN(OR) "<<nodep<<endl);
|
||||||
for (int w=0; w<nodep->widthWords(); w++) {
|
for (int w=0; w<nodep->widthWords(); w++) {
|
||||||
addWordAssign(nodep, w, new AstOr (nodep->fileline(),
|
addWordAssign(nodep, w, new AstOr(nodep->fileline(),
|
||||||
newAstWordSelClone (rhsp->lhsp(), w),
|
newAstWordSelClone(rhsp->lhsp(), w),
|
||||||
newAstWordSelClone (rhsp->rhsp(), w)));
|
newAstWordSelClone(rhsp->rhsp(), w)));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool expandWide (AstNodeAssign* nodep, AstXor* rhsp) {
|
bool expandWide(AstNodeAssign* nodep, AstXor* rhsp) {
|
||||||
UINFO(8," Wordize ASSIGN(XOR) "<<nodep<<endl);
|
UINFO(8," Wordize ASSIGN(XOR) "<<nodep<<endl);
|
||||||
for (int w=0; w<nodep->widthWords(); w++) {
|
for (int w=0; w<nodep->widthWords(); w++) {
|
||||||
addWordAssign(nodep, w, new AstXor (nodep->fileline(),
|
addWordAssign(nodep, w, new AstXor(nodep->fileline(),
|
||||||
newAstWordSelClone (rhsp->lhsp(), w),
|
newAstWordSelClone(rhsp->lhsp(), w),
|
||||||
newAstWordSelClone (rhsp->rhsp(), w)));
|
newAstWordSelClone(rhsp->rhsp(), w)));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
bool expandWide (AstNodeAssign* nodep, AstXnor* rhsp) {
|
bool expandWide(AstNodeAssign* nodep, AstXnor* rhsp) {
|
||||||
UINFO(8," Wordize ASSIGN(XNOR) "<<nodep<<endl);
|
UINFO(8," Wordize ASSIGN(XNOR) "<<nodep<<endl);
|
||||||
for (int w=0; w<nodep->widthWords(); w++) {
|
for (int w=0; w<nodep->widthWords(); w++) {
|
||||||
addWordAssign(nodep, w, new AstXnor (nodep->fileline(),
|
addWordAssign(nodep, w, new AstXnor(nodep->fileline(),
|
||||||
newAstWordSelClone (rhsp->lhsp(), w),
|
newAstWordSelClone(rhsp->lhsp(), w),
|
||||||
newAstWordSelClone (rhsp->rhsp(), w)));
|
newAstWordSelClone(rhsp->rhsp(), w)));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
//-------- Triops
|
//-------- Triops
|
||||||
bool expandWide (AstNodeAssign* nodep, AstNodeCond* rhsp) {
|
bool expandWide(AstNodeAssign* nodep, AstNodeCond* rhsp) {
|
||||||
UINFO(8," Wordize ASSIGN(COND) "<<nodep<<endl);
|
UINFO(8," Wordize ASSIGN(COND) "<<nodep<<endl);
|
||||||
for (int w=0; w<nodep->widthWords(); w++) {
|
for (int w=0; w<nodep->widthWords(); w++) {
|
||||||
addWordAssign(nodep, w, new AstCond (nodep->fileline(),
|
addWordAssign(nodep, w, new AstCond(nodep->fileline(),
|
||||||
rhsp->condp()->cloneTree(true),
|
rhsp->condp()->cloneTree(true),
|
||||||
newAstWordSelClone (rhsp->expr1p(), w),
|
newAstWordSelClone(rhsp->expr1p(), w),
|
||||||
newAstWordSelClone (rhsp->expr2p(), w)));
|
newAstWordSelClone(rhsp->expr2p(), w)));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -321,7 +321,7 @@ private:
|
||||||
nodep->v3fatalSrc("extending larger thing into smaller?");
|
nodep->v3fatalSrc("extending larger thing into smaller?");
|
||||||
} else {
|
} else {
|
||||||
UINFO(8," EXTEND(q<-l) "<<nodep<<endl);
|
UINFO(8," EXTEND(q<-l) "<<nodep<<endl);
|
||||||
newp = new AstCCast (nodep->fileline(), lhsp, nodep);
|
newp = new AstCCast(nodep->fileline(), lhsp, nodep);
|
||||||
}
|
}
|
||||||
} else { // Long
|
} else { // Long
|
||||||
if (lhsp->isQuad() || lhsp->isWide()) {
|
if (lhsp->isQuad() || lhsp->isWide()) {
|
||||||
|
@ -333,14 +333,14 @@ private:
|
||||||
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool expandWide (AstNodeAssign* nodep, AstExtend* rhsp) {
|
bool expandWide(AstNodeAssign* nodep, AstExtend* rhsp) {
|
||||||
UINFO(8," Wordize ASSIGN(EXTEND) "<<nodep<<endl);
|
UINFO(8," Wordize ASSIGN(EXTEND) "<<nodep<<endl);
|
||||||
int w=0;
|
int w=0;
|
||||||
for (w=0; w<rhsp->lhsp()->widthWords(); w++) {
|
for (w=0; w<rhsp->lhsp()->widthWords(); w++) {
|
||||||
addWordAssign(nodep, w, newAstWordSelClone (rhsp->lhsp(), w));
|
addWordAssign(nodep, w, newAstWordSelClone(rhsp->lhsp(), w));
|
||||||
}
|
}
|
||||||
for (; w<nodep->widthWords(); w++) {
|
for (; w<nodep->widthWords(); w++) {
|
||||||
addWordAssign(nodep, w, new AstConst (rhsp->fileline(), 0));
|
addWordAssign(nodep, w, new AstConst(rhsp->fileline(), 0));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -360,81 +360,81 @@ private:
|
||||||
// Selection amounts
|
// Selection amounts
|
||||||
// Check for constant shifts & save some constification work later.
|
// Check for constant shifts & save some constification work later.
|
||||||
// Grab lowest bit(s)
|
// Grab lowest bit(s)
|
||||||
AstNode* lowwordp = new AstWordSel (nodep->fromp()->fileline(),
|
AstNode* lowwordp = new AstWordSel(nodep->fromp()->fileline(),
|
||||||
nodep->fromp()->cloneTree(true),
|
nodep->fromp()->cloneTree(true),
|
||||||
newSelBitWord(nodep->lsbp(), 0));
|
newSelBitWord(nodep->lsbp(), 0));
|
||||||
if (nodep->isQuad() && !lowwordp->isQuad()) lowwordp = new AstCCast(nodep->fileline(), lowwordp, nodep);
|
if (nodep->isQuad() && !lowwordp->isQuad()) lowwordp = new AstCCast(nodep->fileline(), lowwordp, nodep);
|
||||||
AstNode* lowp = new AstShiftR (nodep->fileline(),
|
AstNode* lowp = new AstShiftR(nodep->fileline(),
|
||||||
lowwordp,
|
lowwordp,
|
||||||
newSelBitBit(nodep->lsbp()),
|
newSelBitBit(nodep->lsbp()),
|
||||||
nodep->width());
|
nodep->width());
|
||||||
// If > 1 bit, we might be crossing the word boundary
|
// If > 1 bit, we might be crossing the word boundary
|
||||||
AstNode* midp=NULL;
|
AstNode* midp=NULL;
|
||||||
V3Number zero (nodep->fileline(), longOrQuadWidth(nodep));
|
V3Number zero (nodep->fileline(), longOrQuadWidth(nodep));
|
||||||
if (nodep->widthConst() > 1) {
|
if (nodep->widthConst() > 1) {
|
||||||
AstNode* midwordp = // SEL(from,[1+wordnum])
|
AstNode* midwordp = // SEL(from,[1+wordnum])
|
||||||
new AstWordSel (nodep->fromp()->fileline(),
|
new AstWordSel(nodep->fromp()->fileline(),
|
||||||
nodep->fromp()->cloneTree(true),
|
nodep->fromp()->cloneTree(true),
|
||||||
newSelBitWord(nodep->lsbp(), 1));
|
newSelBitWord(nodep->lsbp(), 1));
|
||||||
if (nodep->isQuad() && !midwordp->isQuad()) midwordp = new AstCCast(nodep->fileline(), midwordp, nodep);
|
if (nodep->isQuad() && !midwordp->isQuad()) midwordp = new AstCCast(nodep->fileline(), midwordp, nodep);
|
||||||
// If we're selecting bit zero, then all 32 bits in word 1 get shifted << by 32 bits
|
// If we're selecting bit zero, then all 32 bits in word 1 get shifted << by 32 bits
|
||||||
// else we need to form the lower word, so we << by 31 or less
|
// else we need to form the lower word, so we << by 31 or less
|
||||||
// nbitsfromlow <= (lsb==0) ? 64-bitbit(lsb) : 32-bitbit(lsb)
|
// nbitsfromlow <= (lsb==0) ? 64-bitbit(lsb) : 32-bitbit(lsb)
|
||||||
AstNode* midshiftp = new AstSub (nodep->lsbp()->fileline(),
|
AstNode* midshiftp = new AstSub(nodep->lsbp()->fileline(),
|
||||||
new AstConst(nodep->lsbp()->fileline(), VL_WORDSIZE),
|
new AstConst(nodep->lsbp()->fileline(), VL_WORDSIZE),
|
||||||
newSelBitBit(nodep->lsbp()));
|
newSelBitBit(nodep->lsbp()));
|
||||||
if (nodep->isQuad()) {
|
if (nodep->isQuad()) {
|
||||||
midshiftp =
|
midshiftp =
|
||||||
new AstCond (nodep->fileline(),
|
new AstCond(nodep->fileline(),
|
||||||
new AstEq (nodep->fileline(),
|
new AstEq(nodep->fileline(),
|
||||||
new AstConst(nodep->fileline(), 0),
|
new AstConst(nodep->fileline(), 0),
|
||||||
newSelBitBit(nodep->lsbp())),
|
newSelBitBit(nodep->lsbp())),
|
||||||
new AstConst(nodep->lsbp()->fileline(), VL_WORDSIZE),
|
new AstConst(nodep->lsbp()->fileline(), VL_WORDSIZE),
|
||||||
midshiftp);
|
midshiftp);
|
||||||
}
|
}
|
||||||
AstNode* midmayp = new AstShiftL (nodep->fileline(),
|
AstNode* midmayp = new AstShiftL(nodep->fileline(),
|
||||||
midwordp,
|
midwordp,
|
||||||
midshiftp,
|
midshiftp,
|
||||||
nodep->width());
|
nodep->width());
|
||||||
if (nodep->isQuad()) {
|
if (nodep->isQuad()) {
|
||||||
midp = midmayp; // Always grab from two words
|
midp = midmayp; // Always grab from two words
|
||||||
} else {
|
} else {
|
||||||
midp = new AstCond (nodep->fileline(),
|
midp = new AstCond(nodep->fileline(),
|
||||||
new AstEq (nodep->fileline(),
|
new AstEq(nodep->fileline(),
|
||||||
new AstConst(nodep->fileline(), 0),
|
new AstConst(nodep->fileline(), 0),
|
||||||
newSelBitBit(nodep->lsbp())),
|
newSelBitBit(nodep->lsbp())),
|
||||||
new AstConst(nodep->fileline(), zero),
|
new AstConst(nodep->fileline(), zero),
|
||||||
midmayp);
|
midmayp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If > 32 bits, we might be crossing the second word boundary
|
// If > 32 bits, we might be crossing the second word boundary
|
||||||
AstNode* hip=NULL;
|
AstNode* hip=NULL;
|
||||||
if (nodep->widthConst() > VL_WORDSIZE) {
|
if (nodep->widthConst() > VL_WORDSIZE) {
|
||||||
AstNode* hiwordp = // SEL(from,[2+wordnum])
|
AstNode* hiwordp = // SEL(from,[2+wordnum])
|
||||||
new AstWordSel (nodep->fromp()->fileline(),
|
new AstWordSel(nodep->fromp()->fileline(),
|
||||||
nodep->fromp()->cloneTree(true),
|
nodep->fromp()->cloneTree(true),
|
||||||
newSelBitWord(nodep->lsbp(), 2));
|
newSelBitWord(nodep->lsbp(), 2));
|
||||||
if (nodep->isQuad() && !hiwordp->isQuad()) hiwordp = new AstCCast(nodep->fileline(), hiwordp, nodep);
|
if (nodep->isQuad() && !hiwordp->isQuad()) hiwordp = new AstCCast(nodep->fileline(), hiwordp, nodep);
|
||||||
AstNode* himayp =
|
AstNode* himayp =
|
||||||
new AstShiftL (nodep->fileline(),
|
new AstShiftL(nodep->fileline(),
|
||||||
hiwordp,
|
hiwordp,
|
||||||
// nbitsfromlow_and_mid <= 64-bitbit(lsb)
|
// nbitsfromlow_and_mid <= 64-bitbit(lsb)
|
||||||
new AstSub (nodep->lsbp()->fileline(),
|
new AstSub(nodep->lsbp()->fileline(),
|
||||||
new AstConst(nodep->lsbp()->fileline(), 64),
|
new AstConst(nodep->lsbp()->fileline(), 64),
|
||||||
newSelBitBit(nodep->lsbp())),
|
newSelBitBit(nodep->lsbp())),
|
||||||
nodep->width());
|
nodep->width());
|
||||||
// if (frombit==0) then ignore, else use it
|
// if (frombit==0) then ignore, else use it
|
||||||
hip = new AstCond (nodep->fileline(),
|
hip = new AstCond(nodep->fileline(),
|
||||||
new AstEq (nodep->fileline(),
|
new AstEq(nodep->fileline(),
|
||||||
new AstConst(nodep->fileline(), 0),
|
new AstConst(nodep->fileline(), 0),
|
||||||
newSelBitBit(nodep->lsbp())),
|
newSelBitBit(nodep->lsbp())),
|
||||||
new AstConst(nodep->fileline(), zero),
|
new AstConst(nodep->fileline(), zero),
|
||||||
himayp);
|
himayp);
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode* newp = lowp;
|
AstNode* newp = lowp;
|
||||||
if (midp) newp = new AstOr (nodep->fileline(), midp, newp);
|
if (midp) newp = new AstOr(nodep->fileline(), midp, newp);
|
||||||
if (hip) newp = new AstOr (nodep->fileline(), hip, newp);
|
if (hip) newp = new AstOr(nodep->fileline(), hip, newp);
|
||||||
newp->dtypeFrom(nodep);
|
newp->dtypeFrom(nodep);
|
||||||
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
|
@ -443,59 +443,59 @@ private:
|
||||||
AstNode* fromp = nodep->fromp()->unlinkFrBack();
|
AstNode* fromp = nodep->fromp()->unlinkFrBack();
|
||||||
AstNode* lsbp = nodep->lsbp()->unlinkFrBack();
|
AstNode* lsbp = nodep->lsbp()->unlinkFrBack();
|
||||||
if (nodep->isQuad() && !fromp->isQuad()) fromp = new AstCCast(nodep->fileline(), fromp, nodep);
|
if (nodep->isQuad() && !fromp->isQuad()) fromp = new AstCCast(nodep->fileline(), fromp, nodep);
|
||||||
AstNode* newp = new AstShiftR (nodep->fileline(),
|
AstNode* newp = new AstShiftR(nodep->fileline(),
|
||||||
fromp,
|
fromp,
|
||||||
dropCondBound(lsbp),
|
dropCondBound(lsbp),
|
||||||
fromp->width()); // {large}>>32 requires 64-bit shift operation; then cast
|
fromp->width()); // {large}>>32 requires 64-bit shift operation; then cast
|
||||||
newp->dtypeFrom(fromp);
|
newp->dtypeFrom(fromp);
|
||||||
if (!nodep->isQuad() && fromp->isQuad()) {
|
if (!nodep->isQuad() && fromp->isQuad()) {
|
||||||
newp = new AstCCast (newp->fileline(), newp, nodep);
|
newp = new AstCCast(newp->fileline(), newp, nodep);
|
||||||
}
|
}
|
||||||
newp->dtypeFrom(nodep);
|
newp->dtypeFrom(nodep);
|
||||||
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool expandWide (AstNodeAssign* nodep, AstSel* rhsp) {
|
bool expandWide(AstNodeAssign* nodep, AstSel* rhsp) {
|
||||||
if (nodep->widthMin()!=(int)rhsp->widthConst()) nodep->v3fatalSrc("Width mismatch");
|
if (nodep->widthMin()!=(int)rhsp->widthConst()) nodep->v3fatalSrc("Width mismatch");
|
||||||
if (VN_IS(rhsp->lsbp(), Const) && VL_BITBIT_I(rhsp->lsbConst())==0) {
|
if (VN_IS(rhsp->lsbp(), Const) && VL_BITBIT_I(rhsp->lsbConst())==0) {
|
||||||
int lsb = rhsp->lsbConst();
|
int lsb = rhsp->lsbConst();
|
||||||
UINFO(8," Wordize ASSIGN(SEL,align) "<<nodep<<endl);
|
UINFO(8," Wordize ASSIGN(SEL,align) "<<nodep<<endl);
|
||||||
for (int w=0; w<nodep->widthWords(); w++) {
|
for (int w=0; w<nodep->widthWords(); w++) {
|
||||||
addWordAssign(nodep, w, newAstWordSelClone (rhsp->fromp(), w + VL_BITWORD_I(lsb)));
|
addWordAssign(nodep, w, newAstWordSelClone(rhsp->fromp(), w + VL_BITWORD_I(lsb)));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
UINFO(8," Wordize ASSIGN(EXTRACT,misalign) "<<nodep<<endl);
|
UINFO(8," Wordize ASSIGN(EXTRACT,misalign) "<<nodep<<endl);
|
||||||
for (int w=0; w<nodep->widthWords(); w++) {
|
for (int w=0; w<nodep->widthWords(); w++) {
|
||||||
// Grab lowest bits
|
// Grab lowest bits
|
||||||
AstNode* lowwordp = new AstWordSel (rhsp->fileline(),
|
AstNode* lowwordp = new AstWordSel(rhsp->fileline(),
|
||||||
rhsp->fromp()->cloneTree(true),
|
rhsp->fromp()->cloneTree(true),
|
||||||
newSelBitWord(rhsp->lsbp(), w));
|
newSelBitWord(rhsp->lsbp(), w));
|
||||||
AstNode* lowp = new AstShiftR (rhsp->fileline(),
|
AstNode* lowp = new AstShiftR(rhsp->fileline(),
|
||||||
lowwordp,
|
lowwordp,
|
||||||
newSelBitBit(rhsp->lsbp()),
|
newSelBitBit(rhsp->lsbp()),
|
||||||
VL_WORDSIZE);
|
VL_WORDSIZE);
|
||||||
// Upper bits
|
// Upper bits
|
||||||
V3Number zero (nodep->fileline(), VL_WORDSIZE, 0);
|
V3Number zero (nodep->fileline(), VL_WORDSIZE, 0);
|
||||||
AstNode* midwordp = // SEL(from,[1+wordnum])
|
AstNode* midwordp = // SEL(from,[1+wordnum])
|
||||||
new AstWordSel (rhsp->fromp()->fileline(),
|
new AstWordSel(rhsp->fromp()->fileline(),
|
||||||
rhsp->fromp()->cloneTree(true),
|
rhsp->fromp()->cloneTree(true),
|
||||||
newSelBitWord(rhsp->lsbp(), w+1));
|
newSelBitWord(rhsp->lsbp(), w+1));
|
||||||
AstNode* midshiftp = new AstSub (rhsp->lsbp()->fileline(),
|
AstNode* midshiftp = new AstSub(rhsp->lsbp()->fileline(),
|
||||||
new AstConst(rhsp->lsbp()->fileline(), VL_WORDSIZE),
|
new AstConst(rhsp->lsbp()->fileline(), VL_WORDSIZE),
|
||||||
newSelBitBit(rhsp->lsbp()));
|
newSelBitBit(rhsp->lsbp()));
|
||||||
AstNode* midmayp = new AstShiftL (rhsp->fileline(),
|
AstNode* midmayp = new AstShiftL(rhsp->fileline(),
|
||||||
midwordp,
|
midwordp,
|
||||||
midshiftp,
|
midshiftp,
|
||||||
VL_WORDSIZE);
|
VL_WORDSIZE);
|
||||||
AstNode* midp = new AstCond (rhsp->fileline(),
|
AstNode* midp = new AstCond(rhsp->fileline(),
|
||||||
new AstEq (rhsp->fileline(),
|
new AstEq(rhsp->fileline(),
|
||||||
new AstConst(rhsp->fileline(), 0),
|
new AstConst(rhsp->fileline(), 0),
|
||||||
newSelBitBit(rhsp->lsbp())),
|
newSelBitBit(rhsp->lsbp())),
|
||||||
new AstConst(rhsp->fileline(), zero),
|
new AstConst(rhsp->fileline(), zero),
|
||||||
midmayp);
|
midmayp);
|
||||||
AstNode* newp = new AstOr (nodep->fileline(), midp, lowp);
|
AstNode* newp = new AstOr(nodep->fileline(), midp, lowp);
|
||||||
addWordAssign(nodep, w, newp);
|
addWordAssign(nodep, w, newp);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -526,17 +526,17 @@ private:
|
||||||
for (int w=0; w<destp->widthWords(); w++) {
|
for (int w=0; w<destp->widthWords(); w++) {
|
||||||
if (w>=VL_BITWORD_I(lsb) && w<=VL_BITWORD_I(msb)) {
|
if (w>=VL_BITWORD_I(lsb) && w<=VL_BITWORD_I(msb)) {
|
||||||
// else we would just be setting it to the same exact value
|
// else we would just be setting it to the same exact value
|
||||||
AstNode* oldvalp = newAstWordSelClone (destp, w);
|
AstNode* oldvalp = newAstWordSelClone(destp, w);
|
||||||
fixCloneLvalue(oldvalp);
|
fixCloneLvalue(oldvalp);
|
||||||
if (!ones) oldvalp = new AstAnd (lhsp->fileline(),
|
if (!ones) oldvalp = new AstAnd(lhsp->fileline(),
|
||||||
new AstConst (lhsp->fileline(), maskold.dataWord(w)),
|
new AstConst(lhsp->fileline(), maskold.dataWord(w)),
|
||||||
oldvalp);
|
oldvalp);
|
||||||
addWordAssign(nodep, w,
|
addWordAssign(nodep, w,
|
||||||
destp,
|
destp,
|
||||||
new AstOr (lhsp->fileline(),
|
new AstOr(lhsp->fileline(),
|
||||||
oldvalp,
|
oldvalp,
|
||||||
newWordGrabShift(lhsp->fileline(), w,
|
newWordGrabShift(lhsp->fileline(), w,
|
||||||
rhsp, lsb)));
|
rhsp, lsb)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rhsp->deleteTree(); VL_DANGLING(rhsp);
|
rhsp->deleteTree(); VL_DANGLING(rhsp);
|
||||||
|
@ -546,17 +546,17 @@ private:
|
||||||
if (destp->isQuad() && !rhsp->isQuad()) rhsp = new AstCCast(nodep->fileline(), rhsp, nodep);
|
if (destp->isQuad() && !rhsp->isQuad()) rhsp = new AstCCast(nodep->fileline(), rhsp, nodep);
|
||||||
AstNode* oldvalp = destp->cloneTree(true);
|
AstNode* oldvalp = destp->cloneTree(true);
|
||||||
fixCloneLvalue(oldvalp);
|
fixCloneLvalue(oldvalp);
|
||||||
if (!ones) oldvalp = new AstAnd (lhsp->fileline(),
|
if (!ones) oldvalp = new AstAnd(lhsp->fileline(),
|
||||||
new AstConst (lhsp->fileline(), maskold),
|
new AstConst(lhsp->fileline(), maskold),
|
||||||
oldvalp);
|
oldvalp);
|
||||||
AstNode* newp
|
AstNode* newp
|
||||||
= new AstOr (lhsp->fileline(),
|
= new AstOr(lhsp->fileline(),
|
||||||
oldvalp,
|
oldvalp,
|
||||||
new AstShiftL (lhsp->fileline(),
|
new AstShiftL(lhsp->fileline(),
|
||||||
rhsp,
|
rhsp,
|
||||||
new AstConst (lhsp->fileline(), lsb),
|
new AstConst(lhsp->fileline(), lsb),
|
||||||
destp->width()));
|
destp->width()));
|
||||||
newp = new AstAssign (nodep->fileline(), destp, newp);
|
newp = new AstAssign(nodep->fileline(), destp, newp);
|
||||||
insertBefore(nodep,newp);
|
insertBefore(nodep,newp);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -566,35 +566,35 @@ private:
|
||||||
UINFO(8," ASSIGNSEL(varlsb,wide,1bit) "<<nodep<<endl);
|
UINFO(8," ASSIGNSEL(varlsb,wide,1bit) "<<nodep<<endl);
|
||||||
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
|
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
|
||||||
AstNode* destp = lhsp->fromp()->unlinkFrBack();
|
AstNode* destp = lhsp->fromp()->unlinkFrBack();
|
||||||
AstNode* oldvalp = new AstWordSel (lhsp->fileline(),
|
AstNode* oldvalp = new AstWordSel(lhsp->fileline(),
|
||||||
destp->cloneTree(true),
|
destp->cloneTree(true),
|
||||||
newSelBitWord(lhsp->lsbp(), 0));
|
newSelBitWord(lhsp->lsbp(), 0));
|
||||||
fixCloneLvalue(oldvalp);
|
fixCloneLvalue(oldvalp);
|
||||||
if (!ones)
|
if (!ones)
|
||||||
oldvalp = new AstAnd (lhsp->fileline(),
|
oldvalp = new AstAnd(lhsp->fileline(),
|
||||||
new AstNot (lhsp->fileline(),
|
new AstNot(lhsp->fileline(),
|
||||||
new AstShiftL (lhsp->fileline(),
|
new AstShiftL(lhsp->fileline(),
|
||||||
new AstConst (nodep->fileline(),1),
|
new AstConst(nodep->fileline(),1),
|
||||||
// newSelBitBit may exceed the MSB of this variable.
|
// newSelBitBit may exceed the MSB of this variable.
|
||||||
// That's ok as we'd just AND with a larger value,
|
// That's ok as we'd just AND with a larger value,
|
||||||
// but oldval would clip the upper bits to sanity
|
// but oldval would clip the upper bits to sanity
|
||||||
newSelBitBit(lhsp->lsbp()),
|
newSelBitBit(lhsp->lsbp()),
|
||||||
VL_WORDSIZE)),
|
VL_WORDSIZE)),
|
||||||
oldvalp);
|
oldvalp);
|
||||||
|
|
||||||
// Restrict the shift amount to 0-31, see bug804.
|
// Restrict the shift amount to 0-31, see bug804.
|
||||||
AstNode* shiftp = new AstAnd(nodep->fileline(), lhsp->lsbp()->cloneTree(true),
|
AstNode* shiftp = new AstAnd(nodep->fileline(), lhsp->lsbp()->cloneTree(true),
|
||||||
new AstConst(nodep->fileline(), VL_WORDSIZE-1));
|
new AstConst(nodep->fileline(), VL_WORDSIZE-1));
|
||||||
AstNode* newp = new AstOr (lhsp->fileline(),
|
AstNode* newp = new AstOr(lhsp->fileline(),
|
||||||
oldvalp,
|
oldvalp,
|
||||||
new AstShiftL (lhsp->fileline(),
|
new AstShiftL(lhsp->fileline(),
|
||||||
rhsp,
|
rhsp,
|
||||||
shiftp,
|
shiftp,
|
||||||
VL_WORDSIZE));
|
VL_WORDSIZE));
|
||||||
newp = new AstAssign (nodep->fileline(),
|
newp = new AstAssign(nodep->fileline(),
|
||||||
new AstWordSel (nodep->fileline(),
|
new AstWordSel(nodep->fileline(),
|
||||||
destp,
|
destp,
|
||||||
newSelBitWord(lhsp->lsbp(), 0)),
|
newSelBitWord(lhsp->lsbp(), 0)),
|
||||||
newp);
|
newp);
|
||||||
insertBefore(nodep,newp);
|
insertBefore(nodep,newp);
|
||||||
return true;
|
return true;
|
||||||
|
@ -623,22 +623,22 @@ private:
|
||||||
|
|
||||||
if (destp->isQuad() && !rhsp->isQuad()) rhsp = new AstCCast(nodep->fileline(), rhsp, nodep);
|
if (destp->isQuad() && !rhsp->isQuad()) rhsp = new AstCCast(nodep->fileline(), rhsp, nodep);
|
||||||
if (!ones)
|
if (!ones)
|
||||||
oldvalp = new AstAnd (lhsp->fileline(),
|
oldvalp = new AstAnd(lhsp->fileline(),
|
||||||
new AstNot (lhsp->fileline(),
|
new AstNot(lhsp->fileline(),
|
||||||
new AstShiftL (lhsp->fileline(),
|
new AstShiftL(lhsp->fileline(),
|
||||||
new AstConst (nodep->fileline(),
|
new AstConst(nodep->fileline(),
|
||||||
maskwidth),
|
maskwidth),
|
||||||
lhsp->lsbp()->cloneTree(true),
|
lhsp->lsbp()->cloneTree(true),
|
||||||
destp->width())),
|
destp->width())),
|
||||||
oldvalp);
|
oldvalp);
|
||||||
AstNode* newp
|
AstNode* newp
|
||||||
= new AstOr (lhsp->fileline(),
|
= new AstOr(lhsp->fileline(),
|
||||||
oldvalp,
|
oldvalp,
|
||||||
new AstShiftL (lhsp->fileline(),
|
new AstShiftL(lhsp->fileline(),
|
||||||
rhsp,
|
rhsp,
|
||||||
lhsp->lsbp()->cloneTree(true),
|
lhsp->lsbp()->cloneTree(true),
|
||||||
destp->width()));
|
destp->width()));
|
||||||
newp = new AstAssign (nodep->fileline(), destp, newp);
|
newp = new AstAssign(nodep->fileline(), destp, newp);
|
||||||
//newp->dumpTree(cout,"- new: ");
|
//newp->dumpTree(cout,"- new: ");
|
||||||
insertBefore(nodep,newp);
|
insertBefore(nodep,newp);
|
||||||
return true;
|
return true;
|
||||||
|
@ -658,17 +658,17 @@ private:
|
||||||
int rhsshift = rhsp->widthMin();
|
int rhsshift = rhsp->widthMin();
|
||||||
if (nodep->isQuad() && !lhsp->isQuad()) lhsp = new AstCCast(nodep->fileline(), lhsp, nodep);
|
if (nodep->isQuad() && !lhsp->isQuad()) lhsp = new AstCCast(nodep->fileline(), lhsp, nodep);
|
||||||
if (nodep->isQuad() && !rhsp->isQuad()) rhsp = new AstCCast(nodep->fileline(), rhsp, nodep);
|
if (nodep->isQuad() && !rhsp->isQuad()) rhsp = new AstCCast(nodep->fileline(), rhsp, nodep);
|
||||||
AstNode* newp = new AstOr (nodep->fileline(),
|
AstNode* newp = new AstOr(nodep->fileline(),
|
||||||
new AstShiftL (nodep->fileline(),
|
new AstShiftL(nodep->fileline(),
|
||||||
lhsp,
|
lhsp,
|
||||||
new AstConst (nodep->fileline(), rhsshift),
|
new AstConst(nodep->fileline(), rhsshift),
|
||||||
nodep->width()),
|
nodep->width()),
|
||||||
rhsp);
|
rhsp);
|
||||||
newp->dtypeFrom(nodep); // Unsigned
|
newp->dtypeFrom(nodep); // Unsigned
|
||||||
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool expandWide (AstNodeAssign* nodep, AstConcat* rhsp) {
|
bool expandWide(AstNodeAssign* nodep, AstConcat* rhsp) {
|
||||||
UINFO(8," Wordize ASSIGN(CONCAT) "<<nodep<<endl);
|
UINFO(8," Wordize ASSIGN(CONCAT) "<<nodep<<endl);
|
||||||
// Lhs or Rhs may be word, long, or quad.
|
// Lhs or Rhs may be word, long, or quad.
|
||||||
// newAstWordSelClone nicely abstracts the difference.
|
// newAstWordSelClone nicely abstracts the difference.
|
||||||
|
@ -678,10 +678,10 @@ private:
|
||||||
// However V3Subst tends to rip this up, so not worth optimizing now.
|
// However V3Subst tends to rip this up, so not worth optimizing now.
|
||||||
for (int w=0; w<rhsp->widthWords(); w++) {
|
for (int w=0; w<rhsp->widthWords(); w++) {
|
||||||
addWordAssign(nodep, w,
|
addWordAssign(nodep, w,
|
||||||
new AstOr (rhsp->fileline(),
|
new AstOr(rhsp->fileline(),
|
||||||
newWordGrabShift(rhsp->fileline(), w,
|
newWordGrabShift(rhsp->fileline(), w,
|
||||||
rhsp->lhsp(), rhsshift),
|
rhsp->lhsp(), rhsshift),
|
||||||
newAstWordSelClone (rhsp->rhsp(), w)));
|
newAstWordSelClone(rhsp->rhsp(), w)));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -697,7 +697,7 @@ private:
|
||||||
int lhswidth = lhsp->widthMin();
|
int lhswidth = lhsp->widthMin();
|
||||||
if (lhswidth==1) {
|
if (lhswidth==1) {
|
||||||
UINFO(8," REPLICATE(w1) "<<nodep<<endl);
|
UINFO(8," REPLICATE(w1) "<<nodep<<endl);
|
||||||
newp = new AstNegate (nodep->fileline(), lhsp);
|
newp = new AstNegate(nodep->fileline(), lhsp);
|
||||||
} else {
|
} else {
|
||||||
UINFO(8," REPLICATE "<<nodep<<endl);
|
UINFO(8," REPLICATE "<<nodep<<endl);
|
||||||
const AstConst* constp = VN_CAST(nodep->rhsp(), Const);
|
const AstConst* constp = VN_CAST(nodep->rhsp(), Const);
|
||||||
|
@ -707,11 +707,11 @@ private:
|
||||||
newp = lhsp->cloneTree(true);
|
newp = lhsp->cloneTree(true);
|
||||||
for (unsigned repnum=1; repnum<times; repnum++) {
|
for (unsigned repnum=1; repnum<times; repnum++) {
|
||||||
int rhsshift = repnum*lhswidth;
|
int rhsshift = repnum*lhswidth;
|
||||||
newp = new AstOr (nodep->fileline(),
|
newp = new AstOr(nodep->fileline(),
|
||||||
new AstShiftL (nodep->fileline(),
|
new AstShiftL(nodep->fileline(),
|
||||||
lhsp->cloneTree(true),
|
lhsp->cloneTree(true),
|
||||||
new AstConst (nodep->fileline(), rhsshift),
|
new AstConst(nodep->fileline(), rhsshift),
|
||||||
nodep->width()),
|
nodep->width()),
|
||||||
newp);
|
newp);
|
||||||
newp->dtypeFrom(nodep); // Unsigned
|
newp->dtypeFrom(nodep); // Unsigned
|
||||||
}
|
}
|
||||||
|
@ -721,7 +721,7 @@ private:
|
||||||
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool expandWide (AstNodeAssign* nodep, AstReplicate* rhsp) {
|
bool expandWide(AstNodeAssign* nodep, AstReplicate* rhsp) {
|
||||||
UINFO(8," Wordize ASSIGN(REPLICATE) "<<nodep<<endl);
|
UINFO(8," Wordize ASSIGN(REPLICATE) "<<nodep<<endl);
|
||||||
AstNode* lhsp = rhsp->lhsp();
|
AstNode* lhsp = rhsp->lhsp();
|
||||||
int lhswidth = lhsp->widthMin();
|
int lhswidth = lhsp->widthMin();
|
||||||
|
@ -731,15 +731,15 @@ private:
|
||||||
for (int w=0; w<rhsp->widthWords(); w++) {
|
for (int w=0; w<rhsp->widthWords(); w++) {
|
||||||
AstNode* newp;
|
AstNode* newp;
|
||||||
if (lhswidth==1) {
|
if (lhswidth==1) {
|
||||||
newp = new AstNegate (nodep->fileline(), lhsp->cloneTree(true));
|
newp = new AstNegate(nodep->fileline(), lhsp->cloneTree(true));
|
||||||
newp->dtypeSetLogicSized(VL_WORDSIZE,VL_WORDSIZE,AstNumeric::UNSIGNED); // Replicate always unsigned
|
newp->dtypeSetLogicSized(VL_WORDSIZE,VL_WORDSIZE,AstNumeric::UNSIGNED); // Replicate always unsigned
|
||||||
} else {
|
} else {
|
||||||
newp = newAstWordSelClone (lhsp, w);
|
newp = newAstWordSelClone(lhsp, w);
|
||||||
for (unsigned repnum=1; repnum<times; repnum++) {
|
for (unsigned repnum=1; repnum<times; repnum++) {
|
||||||
newp = new AstOr (nodep->fileline(),
|
newp = new AstOr(nodep->fileline(),
|
||||||
newWordGrabShift(rhsp->fileline(), w, lhsp,
|
newWordGrabShift(rhsp->fileline(), w, lhsp,
|
||||||
lhswidth*repnum),
|
lhswidth*repnum),
|
||||||
newp);
|
newp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addWordAssign(nodep, w, newp);
|
addWordAssign(nodep, w, newp);
|
||||||
|
@ -754,10 +754,10 @@ private:
|
||||||
// -> (0=={or{for each_word{WORDSEL(lhs,#)^WORDSEL(rhs,#)}}}
|
// -> (0=={or{for each_word{WORDSEL(lhs,#)^WORDSEL(rhs,#)}}}
|
||||||
AstNode* newp = NULL;
|
AstNode* newp = NULL;
|
||||||
for (int w=0; w<nodep->lhsp()->widthWords(); w++) {
|
for (int w=0; w<nodep->lhsp()->widthWords(); w++) {
|
||||||
AstNode* eqp = new AstXor (nodep->fileline(),
|
AstNode* eqp = new AstXor(nodep->fileline(),
|
||||||
newAstWordSelClone (nodep->lhsp(), w),
|
newAstWordSelClone(nodep->lhsp(), w),
|
||||||
newAstWordSelClone (nodep->rhsp(), w));
|
newAstWordSelClone(nodep->rhsp(), w));
|
||||||
newp = (newp==NULL) ? eqp : (new AstOr (nodep->fileline(), newp, eqp));
|
newp = (newp==NULL) ? eqp : (new AstOr(nodep->fileline(), newp, eqp));
|
||||||
}
|
}
|
||||||
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
|
@ -770,23 +770,23 @@ private:
|
||||||
// -> (0=={or{for each_word{WORDSEL(lhs,#)^WORDSEL(rhs,#)}}}
|
// -> (0=={or{for each_word{WORDSEL(lhs,#)^WORDSEL(rhs,#)}}}
|
||||||
AstNode* newp = NULL;
|
AstNode* newp = NULL;
|
||||||
for (int w=0; w<nodep->lhsp()->widthWords(); w++) {
|
for (int w=0; w<nodep->lhsp()->widthWords(); w++) {
|
||||||
AstNode* eqp = new AstXor (nodep->fileline(),
|
AstNode* eqp = new AstXor(nodep->fileline(),
|
||||||
newAstWordSelClone (nodep->lhsp(), w),
|
newAstWordSelClone(nodep->lhsp(), w),
|
||||||
newAstWordSelClone (nodep->rhsp(), w));
|
newAstWordSelClone(nodep->rhsp(), w));
|
||||||
newp = (newp==NULL) ? eqp : (new AstOr (nodep->fileline(), newp, eqp));
|
newp = (newp==NULL) ? eqp : (new AstOr(nodep->fileline(), newp, eqp));
|
||||||
}
|
}
|
||||||
if (VN_IS(nodep, Neq)) {
|
if (VN_IS(nodep, Neq)) {
|
||||||
newp = new AstNeq (nodep->fileline(),
|
newp = new AstNeq(nodep->fileline(),
|
||||||
new AstConst (nodep->fileline(), 0), newp);
|
new AstConst(nodep->fileline(), 0), newp);
|
||||||
} else {
|
} else {
|
||||||
newp = new AstEq (nodep->fileline(),
|
newp = new AstEq(nodep->fileline(),
|
||||||
new AstConst (nodep->fileline(), 0), newp);
|
new AstConst(nodep->fileline(), 0), newp);
|
||||||
}
|
}
|
||||||
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual void visit(AstEq* nodep) { visitEqNeq (nodep); }
|
virtual void visit(AstEq* nodep) { visitEqNeq(nodep); }
|
||||||
virtual void visit(AstNeq* nodep) { visitEqNeq (nodep); }
|
virtual void visit(AstNeq* nodep) { visitEqNeq(nodep); }
|
||||||
|
|
||||||
virtual void visit(AstRedOr* nodep) {
|
virtual void visit(AstRedOr* nodep) {
|
||||||
if (nodep->user1SetOnce()) return; // Process once
|
if (nodep->user1SetOnce()) return; // Process once
|
||||||
|
@ -796,19 +796,19 @@ private:
|
||||||
// -> (0!={or{for each_word{WORDSEL(lhs,#)}}}
|
// -> (0!={or{for each_word{WORDSEL(lhs,#)}}}
|
||||||
AstNode* newp = NULL;
|
AstNode* newp = NULL;
|
||||||
for (int w=0; w<nodep->lhsp()->widthWords(); w++) {
|
for (int w=0; w<nodep->lhsp()->widthWords(); w++) {
|
||||||
AstNode* eqp = newAstWordSelClone (nodep->lhsp(), w);
|
AstNode* eqp = newAstWordSelClone(nodep->lhsp(), w);
|
||||||
newp = (newp==NULL) ? eqp : (new AstOr (nodep->fileline(), newp, eqp));
|
newp = (newp==NULL) ? eqp : (new AstOr(nodep->fileline(), newp, eqp));
|
||||||
}
|
}
|
||||||
newp = new AstNeq (nodep->fileline(),
|
newp = new AstNeq(nodep->fileline(),
|
||||||
new AstConst (nodep->fileline(), 0), newp);
|
new AstConst(nodep->fileline(), 0), newp);
|
||||||
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
||||||
} else {
|
} else {
|
||||||
UINFO(8," REDOR->EQ "<<nodep<<endl);
|
UINFO(8," REDOR->EQ "<<nodep<<endl);
|
||||||
AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
|
AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
|
||||||
V3Number zero (nodep->fileline(), longOrQuadWidth(nodep));
|
V3Number zero (nodep->fileline(), longOrQuadWidth(nodep));
|
||||||
AstNode* newp = new AstNeq (nodep->fileline(),
|
AstNode* newp = new AstNeq(nodep->fileline(),
|
||||||
new AstConst (nodep->fileline(), zero),
|
new AstConst(nodep->fileline(), zero),
|
||||||
lhsp);
|
lhsp);
|
||||||
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -820,26 +820,26 @@ private:
|
||||||
// -> (0!={and{for each_word{WORDSEL(lhs,#)}}}
|
// -> (0!={and{for each_word{WORDSEL(lhs,#)}}}
|
||||||
AstNode* newp = NULL;
|
AstNode* newp = NULL;
|
||||||
for (int w=0; w<nodep->lhsp()->widthWords(); w++) {
|
for (int w=0; w<nodep->lhsp()->widthWords(); w++) {
|
||||||
AstNode* eqp = newAstWordSelClone (nodep->lhsp(), w);
|
AstNode* eqp = newAstWordSelClone(nodep->lhsp(), w);
|
||||||
if (w==nodep->lhsp()->widthWords()-1) {
|
if (w==nodep->lhsp()->widthWords()-1) {
|
||||||
// Rather than doing a (slowish) ==##, we OR in the bits that aren't part of the mask
|
// Rather than doing a (slowish) ==##, we OR in the bits that aren't part of the mask
|
||||||
eqp = new AstOr (nodep->fileline(),
|
eqp = new AstOr(nodep->fileline(),
|
||||||
new AstConst (nodep->fileline(), notWideMask(nodep->lhsp())),
|
new AstConst(nodep->fileline(), notWideMask(nodep->lhsp())),
|
||||||
// Bug in cppcheck
|
// Bug in cppcheck
|
||||||
// cppcheck-suppress memleak
|
// cppcheck-suppress memleak
|
||||||
eqp);
|
eqp);
|
||||||
}
|
}
|
||||||
newp = (newp==NULL) ? eqp : (new AstAnd (nodep->fileline(), newp, eqp));
|
newp = (newp==NULL) ? eqp : (new AstAnd(nodep->fileline(), newp, eqp));
|
||||||
}
|
}
|
||||||
newp = new AstEq (nodep->fileline(),
|
newp = new AstEq(nodep->fileline(),
|
||||||
new AstConst (nodep->fileline(), ~0), newp);
|
new AstConst(nodep->fileline(), ~0), newp);
|
||||||
replaceWithDelete(nodep, newp); VL_DANGLING(nodep);
|
replaceWithDelete(nodep, newp); VL_DANGLING(nodep);
|
||||||
} else {
|
} else {
|
||||||
UINFO(8," REDAND->EQ "<<nodep<<endl);
|
UINFO(8," REDAND->EQ "<<nodep<<endl);
|
||||||
AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
|
AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
|
||||||
AstNode* newp = new AstEq (nodep->fileline(),
|
AstNode* newp = new AstEq(nodep->fileline(),
|
||||||
new AstConst (nodep->fileline(), wordMask(lhsp)),
|
new AstConst(nodep->fileline(), wordMask(lhsp)),
|
||||||
lhsp);
|
lhsp);
|
||||||
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -851,10 +851,10 @@ private:
|
||||||
// -> (0!={redxor{for each_word{XOR(WORDSEL(lhs,#))}}}
|
// -> (0!={redxor{for each_word{XOR(WORDSEL(lhs,#))}}}
|
||||||
AstNode* newp = NULL;
|
AstNode* newp = NULL;
|
||||||
for (int w=0; w<nodep->lhsp()->widthWords(); w++) {
|
for (int w=0; w<nodep->lhsp()->widthWords(); w++) {
|
||||||
AstNode* eqp = newAstWordSelClone (nodep->lhsp(), w);
|
AstNode* eqp = newAstWordSelClone(nodep->lhsp(), w);
|
||||||
newp = (newp==NULL) ? eqp : (new AstXor (nodep->fileline(), newp, eqp));
|
newp = (newp==NULL) ? eqp : (new AstXor(nodep->fileline(), newp, eqp));
|
||||||
}
|
}
|
||||||
newp = new AstRedXor (nodep->fileline(), newp);
|
newp = new AstRedXor(nodep->fileline(), newp);
|
||||||
UINFO(8," Wordize REDXORnew "<<newp<<endl);
|
UINFO(8," Wordize REDXORnew "<<newp<<endl);
|
||||||
replaceWithDelete(nodep, newp); VL_DANGLING(nodep);
|
replaceWithDelete(nodep, newp); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ public:
|
||||||
void addTgtDepend(const string& filename) {
|
void addTgtDepend(const string& filename) {
|
||||||
if (m_filenameSet.find(filename) == m_filenameSet.end()) {
|
if (m_filenameSet.find(filename) == m_filenameSet.end()) {
|
||||||
m_filenameSet.insert(filename);
|
m_filenameSet.insert(filename);
|
||||||
m_filenameList.insert(DependFile (filename, true));
|
m_filenameList.insert(DependFile(filename, true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void writeDepend(const string& filename);
|
void writeDepend(const string& filename);
|
||||||
|
@ -323,7 +323,7 @@ private:
|
||||||
else return readContentsFile(filename,outl);
|
else return readContentsFile(filename,outl);
|
||||||
}
|
}
|
||||||
bool readContentsFile(const string& filename, StrList& outl) {
|
bool readContentsFile(const string& filename, StrList& outl) {
|
||||||
int fd = open (filename.c_str(), O_RDONLY);
|
int fd = open(filename.c_str(), O_RDONLY);
|
||||||
if (fd<0) return false;
|
if (fd<0) return false;
|
||||||
m_readEof = false;
|
m_readEof = false;
|
||||||
readBlocks(fd, -1, outl);
|
readBlocks(fd, -1, outl);
|
||||||
|
@ -369,7 +369,7 @@ private:
|
||||||
ssize_t todo = INFILTER_IPC_BUFSIZ;
|
ssize_t todo = INFILTER_IPC_BUFSIZ;
|
||||||
if (size>0 && size<todo) todo = size;
|
if (size>0 && size<todo) todo = size;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
ssize_t got = read (fd, buf, todo);
|
ssize_t got = read(fd, buf, todo);
|
||||||
//UINFO(9,"RD GOT g "<< got<<" e "<<errno<<" "<<strerror(errno)<<endl); usleep(50*1000);
|
//UINFO(9,"RD GOT g "<< got<<" e "<<errno<<" "<<strerror(errno)<<endl); usleep(50*1000);
|
||||||
if (got>0) {
|
if (got>0) {
|
||||||
outl.push_back(string(buf, got));
|
outl.push_back(string(buf, got));
|
||||||
|
@ -411,7 +411,7 @@ private:
|
||||||
unsigned offset = 0;
|
unsigned offset = 0;
|
||||||
while (!m_readEof && out.length()>offset) {
|
while (!m_readEof && out.length()>offset) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
int got = write (m_writeFd, (out.c_str())+offset, out.length()-offset);
|
int got = write(m_writeFd, (out.c_str())+offset, out.length()-offset);
|
||||||
//UINFO(9,"WR GOT g "<< got<<" e "<<errno<<" "<<strerror(errno)<<endl); usleep(50*1000);
|
//UINFO(9,"WR GOT g "<< got<<" e "<<errno<<" "<<strerror(errno)<<endl); usleep(50*1000);
|
||||||
if (got>0) offset += got;
|
if (got>0) offset += got;
|
||||||
else if (errno == EINTR || errno == EAGAIN
|
else if (errno == EINTR || errno == EAGAIN
|
||||||
|
@ -629,7 +629,7 @@ bool V3OutFormatter::tokenEnd(const char* cp) {
|
||||||
|| tokenStart(cp,"endmodule"));
|
|| tokenStart(cp,"endmodule"));
|
||||||
}
|
}
|
||||||
|
|
||||||
int V3OutFormatter::endLevels (const char *strg) {
|
int V3OutFormatter::endLevels(const char *strg) {
|
||||||
int levels=m_indentLevel;
|
int levels=m_indentLevel;
|
||||||
{
|
{
|
||||||
const char* cp=strg;
|
const char* cp=strg;
|
||||||
|
@ -674,14 +674,14 @@ int V3OutFormatter::endLevels (const char *strg) {
|
||||||
return (levels);
|
return (levels);
|
||||||
}
|
}
|
||||||
|
|
||||||
void V3OutFormatter::puts (const char *strg) {
|
void V3OutFormatter::puts(const char *strg) {
|
||||||
if (m_prependIndent) {
|
if (m_prependIndent) {
|
||||||
putsNoTracking(indentStr(endLevels(strg)));
|
putsNoTracking(indentStr(endLevels(strg)));
|
||||||
m_prependIndent = false;
|
m_prependIndent = false;
|
||||||
}
|
}
|
||||||
bool wordstart = true;
|
bool wordstart = true;
|
||||||
for (const char* cp=strg; *cp; cp++) {
|
for (const char* cp=strg; *cp; cp++) {
|
||||||
putcNoTracking (*cp);
|
putcNoTracking(*cp);
|
||||||
switch (*cp) {
|
switch (*cp) {
|
||||||
case '\n':
|
case '\n':
|
||||||
m_lineno++;
|
m_lineno++;
|
||||||
|
@ -764,12 +764,12 @@ void V3OutFormatter::puts (const char *strg) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void V3OutFormatter::putBreakExpr () {
|
void V3OutFormatter::putBreakExpr() {
|
||||||
if (!m_parenVec.empty()) putBreak();
|
if (!m_parenVec.empty()) putBreak();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a line break if too wide
|
// Add a line break if too wide
|
||||||
void V3OutFormatter::putBreak () {
|
void V3OutFormatter::putBreak() {
|
||||||
if (!m_nobreak) {
|
if (!m_nobreak) {
|
||||||
//char s[1000]; sprintf(s,"{%d,%d}",m_column,m_parenVec.top()); putsNoTracking(s);
|
//char s[1000]; sprintf(s,"{%d,%d}",m_column,m_parenVec.top()); putsNoTracking(s);
|
||||||
if (exceededWidth()) {
|
if (exceededWidth()) {
|
||||||
|
@ -785,18 +785,18 @@ void V3OutFormatter::putsQuoted(const string& strg) {
|
||||||
putcNoTracking('"');
|
putcNoTracking('"');
|
||||||
string quoted = V3Number::quoteNameControls(strg);
|
string quoted = V3Number::quoteNameControls(strg);
|
||||||
for (string::const_iterator cp=quoted.begin(); cp!=quoted.end(); ++cp) {
|
for (string::const_iterator cp=quoted.begin(); cp!=quoted.end(); ++cp) {
|
||||||
putcNoTracking (*cp);
|
putcNoTracking(*cp);
|
||||||
}
|
}
|
||||||
putcNoTracking('"');
|
putcNoTracking('"');
|
||||||
}
|
}
|
||||||
void V3OutFormatter::putsNoTracking (const string& strg) {
|
void V3OutFormatter::putsNoTracking(const string& strg) {
|
||||||
// Don't track {}'s, probably because it's a $display format string
|
// Don't track {}'s, probably because it's a $display format string
|
||||||
for (string::const_iterator cp=strg.begin(); cp!=strg.end(); ++cp) {
|
for (string::const_iterator cp=strg.begin(); cp!=strg.end(); ++cp) {
|
||||||
putcNoTracking (*cp);
|
putcNoTracking(*cp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void V3OutFormatter::putcNoTracking (char chr) {
|
void V3OutFormatter::putcNoTracking(char chr) {
|
||||||
switch (chr) {
|
switch (chr) {
|
||||||
case '\n':
|
case '\n':
|
||||||
m_lineno++;
|
m_lineno++;
|
||||||
|
@ -817,13 +817,13 @@ void V3OutFormatter::putcNoTracking (char chr) {
|
||||||
m_nobreak=false;
|
m_nobreak=false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
putcOutput (chr);
|
putcOutput(chr);
|
||||||
}
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// Simple wrappers
|
// Simple wrappers
|
||||||
|
|
||||||
void V3OutFormatter::printf (const char *fmt...) {
|
void V3OutFormatter::printf(const char *fmt...) {
|
||||||
char sbuff[5000];
|
char sbuff[5000];
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap,fmt);
|
va_start(ap,fmt);
|
||||||
|
|
|
@ -36,14 +36,14 @@ class V3File {
|
||||||
public:
|
public:
|
||||||
static std::ifstream* new_ifstream(const string& filename) {
|
static std::ifstream* new_ifstream(const string& filename) {
|
||||||
addSrcDepend(filename);
|
addSrcDepend(filename);
|
||||||
return new_ifstream_nodepend (filename);
|
return new_ifstream_nodepend(filename);
|
||||||
}
|
}
|
||||||
static std::ifstream* new_ifstream_nodepend(const string& filename) {
|
static std::ifstream* new_ifstream_nodepend(const string& filename) {
|
||||||
return new std::ifstream(filename.c_str());
|
return new std::ifstream(filename.c_str());
|
||||||
}
|
}
|
||||||
static std::ofstream* new_ofstream(const string& filename, bool append=false) {
|
static std::ofstream* new_ofstream(const string& filename, bool append=false) {
|
||||||
addTgtDepend(filename);
|
addTgtDepend(filename);
|
||||||
return new_ofstream_nodepend (filename, append);
|
return new_ofstream_nodepend(filename, append);
|
||||||
}
|
}
|
||||||
static std::ofstream* new_ofstream_nodepend(const string& filename, bool append=false) {
|
static std::ofstream* new_ofstream_nodepend(const string& filename, bool append=false) {
|
||||||
if (filename != VL_DEV_NULL) createMakeDir();
|
if (filename != VL_DEV_NULL) createMakeDir();
|
||||||
|
|
|
@ -92,19 +92,19 @@ protected:
|
||||||
friend class V3PreLex;
|
friend class V3PreLex;
|
||||||
friend class V3PreProcImp;
|
friend class V3PreProcImp;
|
||||||
void lineno(int num) { m_lineno = num; }
|
void lineno(int num) { m_lineno = num; }
|
||||||
void language (V3LangCode lang) { singleton().numberToLang(m_filenameno, lang); }
|
void language(V3LangCode lang) { singleton().numberToLang(m_filenameno, lang); }
|
||||||
void filename(const string& name) { m_filenameno = singleton().nameToNumber(name); }
|
void filename(const string& name) { m_filenameno = singleton().nameToNumber(name); }
|
||||||
void lineDirective(const char* textp, int& enterExitRef);
|
void lineDirective(const char* textp, int& enterExitRef);
|
||||||
void linenoInc() { m_lineno++; }
|
void linenoInc() { m_lineno++; }
|
||||||
void linenoIncInPlace() { m_lineno++; }
|
void linenoIncInPlace() { m_lineno++; }
|
||||||
FileLine* copyOrSameFileLine();
|
FileLine* copyOrSameFileLine();
|
||||||
public:
|
public:
|
||||||
FileLine (const string& filename, int lineno) {
|
FileLine(const string& filename, int lineno) {
|
||||||
m_lineno=lineno; m_filenameno = singleton().nameToNumber(filename);
|
m_lineno=lineno; m_filenameno = singleton().nameToNumber(filename);
|
||||||
m_warnOn=defaultFileLine().m_warnOn; }
|
m_warnOn=defaultFileLine().m_warnOn; }
|
||||||
explicit FileLine (FileLine* fromp) {
|
explicit FileLine(FileLine* fromp) {
|
||||||
m_lineno=fromp->m_lineno; m_filenameno = fromp->m_filenameno; m_warnOn=fromp->m_warnOn; }
|
m_lineno=fromp->m_lineno; m_filenameno = fromp->m_filenameno; m_warnOn=fromp->m_warnOn; }
|
||||||
explicit FileLine (EmptySecret);
|
explicit FileLine(EmptySecret);
|
||||||
~FileLine() { }
|
~FileLine() { }
|
||||||
FileLine* create(const string& filename, int lineno) { return new FileLine(filename,lineno); }
|
FileLine* create(const string& filename, int lineno) { return new FileLine(filename,lineno); }
|
||||||
FileLine* create(int lineno) { return create(filename(), lineno); }
|
FileLine* create(int lineno) { return create(filename(), lineno); }
|
||||||
|
@ -114,13 +114,13 @@ public:
|
||||||
static void operator delete(void* obj, size_t size);
|
static void operator delete(void* obj, size_t size);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int lineno () const { return m_lineno; }
|
int lineno() const { return m_lineno; }
|
||||||
V3LangCode language () const { return singleton().numberToLang(m_filenameno); }
|
V3LangCode language() const { return singleton().numberToLang(m_filenameno); }
|
||||||
string ascii() const;
|
string ascii() const;
|
||||||
const string filename () const { return singleton().numberToName(m_filenameno); }
|
const string filename() const { return singleton().numberToName(m_filenameno); }
|
||||||
const string filenameLetters() const { return singleton().filenameLetters(m_filenameno); }
|
const string filenameLetters() const { return singleton().filenameLetters(m_filenameno); }
|
||||||
const string filebasename () const;
|
const string filebasename() const;
|
||||||
const string filebasenameNoExt () const;
|
const string filebasenameNoExt() const;
|
||||||
const string profileFuncname() const;
|
const string profileFuncname() const;
|
||||||
const string xml() const { return "fl=\""+filenameLetters()+cvtToStr(lineno())+"\""; }
|
const string xml() const { return "fl=\""+filenameLetters()+cvtToStr(lineno())+"\""; }
|
||||||
string lineDirectiveStrg(int enter_exit_level) const;
|
string lineDirectiveStrg(int enter_exit_level) const;
|
||||||
|
|
|
@ -68,13 +68,13 @@ private:
|
||||||
// Create: VARREF(inpclk)
|
// Create: VARREF(inpclk)
|
||||||
// ...
|
// ...
|
||||||
// ASSIGN(VARREF(inpclk), VARREF(var))
|
// ASSIGN(VARREF(inpclk), VARREF(var))
|
||||||
AstVar* newvarp = new AstVar (varp->fileline(), AstVarType::MODULETEMP, newvarname, varp);
|
AstVar* newvarp = new AstVar(varp->fileline(), AstVarType::MODULETEMP, newvarname, varp);
|
||||||
m_topModp->addStmtp(newvarp);
|
m_topModp->addStmtp(newvarp);
|
||||||
AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopetopp, newvarp);
|
AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopetopp, newvarp);
|
||||||
m_scopetopp->addVarp(newvscp);
|
m_scopetopp->addVarp(newvscp);
|
||||||
AstAssign* asninitp = new AstAssign (vscp->fileline(),
|
AstAssign* asninitp = new AstAssign(vscp->fileline(),
|
||||||
new AstVarRef(vscp->fileline(), newvscp, true),
|
new AstVarRef(vscp->fileline(), newvscp, true),
|
||||||
new AstVarRef(vscp->fileline(), vscp, false));
|
new AstVarRef(vscp->fileline(), vscp, false));
|
||||||
m_scopetopp->addFinalClkp(asninitp);
|
m_scopetopp->addFinalClkp(asninitp);
|
||||||
//
|
//
|
||||||
vscp->user2p(newvscp);
|
vscp->user2p(newvscp);
|
||||||
|
|
|
@ -49,11 +49,11 @@ public:
|
||||||
VERILOG_WIDTH
|
VERILOG_WIDTH
|
||||||
};
|
};
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
inline VWidthMinUsage () : m_e(LINT_WIDTH) {}
|
inline VWidthMinUsage() : m_e(LINT_WIDTH) {}
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
inline VWidthMinUsage (en _e) : m_e(_e) {}
|
inline VWidthMinUsage(en _e) : m_e(_e) {}
|
||||||
explicit inline VWidthMinUsage (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline VWidthMinUsage(int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en() const { return m_e; }
|
||||||
};
|
};
|
||||||
inline bool operator== (VWidthMinUsage lhs, VWidthMinUsage rhs) { return (lhs.m_e == rhs.m_e); }
|
inline bool operator== (VWidthMinUsage lhs, VWidthMinUsage rhs) { return (lhs.m_e == rhs.m_e); }
|
||||||
inline bool operator== (VWidthMinUsage lhs, VWidthMinUsage::en rhs) { return (lhs.m_e == rhs); }
|
inline bool operator== (VWidthMinUsage lhs, VWidthMinUsage::en rhs) { return (lhs.m_e == rhs); }
|
||||||
|
|
|
@ -81,9 +81,9 @@ void V3GraphVertex::rerouteEdges(V3Graph* graphp) {
|
||||||
// Make new edges for each from/to pair
|
// Make new edges for each from/to pair
|
||||||
for (V3GraphEdge* iedgep = inBeginp(); iedgep; iedgep=iedgep->inNextp()) {
|
for (V3GraphEdge* iedgep = inBeginp(); iedgep; iedgep=iedgep->inNextp()) {
|
||||||
for (V3GraphEdge* oedgep = outBeginp(); oedgep; oedgep=oedgep->outNextp()) {
|
for (V3GraphEdge* oedgep = outBeginp(); oedgep; oedgep=oedgep->outNextp()) {
|
||||||
new V3GraphEdge (graphp, iedgep->fromp(), oedgep->top(),
|
new V3GraphEdge(graphp, iedgep->fromp(), oedgep->top(),
|
||||||
std::min(iedgep->weight(),oedgep->weight()),
|
std::min(iedgep->weight(),oedgep->weight()),
|
||||||
iedgep->cutable() && oedgep->cutable());
|
iedgep->cutable() && oedgep->cutable());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Remove old edges
|
// Remove old edges
|
||||||
|
@ -292,10 +292,10 @@ void V3Graph::dump(std::ostream& os) {
|
||||||
os<<endl;
|
os<<endl;
|
||||||
// Print edges
|
// Print edges
|
||||||
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep=edgep->inNextp()) {
|
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep=edgep->inNextp()) {
|
||||||
dumpEdge (os, vertexp, edgep);
|
dumpEdge(os, vertexp, edgep);
|
||||||
}
|
}
|
||||||
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
|
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
|
||||||
dumpEdge (os, vertexp, edgep);
|
dumpEdge(os, vertexp, edgep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ public:
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
struct GraphAcycEdgeCmp {
|
struct GraphAcycEdgeCmp {
|
||||||
inline bool operator () (const V3GraphEdge* lhsp, const V3GraphEdge* rhsp) const {
|
inline bool operator() (const V3GraphEdge* lhsp, const V3GraphEdge* rhsp) const {
|
||||||
if (lhsp->weight() > rhsp->weight()) return 1; // LHS goes first
|
if (lhsp->weight() > rhsp->weight()) return 1; // LHS goes first
|
||||||
if (lhsp->weight() < rhsp->weight()) return 0; // RHS goes first
|
if (lhsp->weight() < rhsp->weight()) return 0; // RHS goes first
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -112,15 +112,15 @@ private:
|
||||||
static int debug() { return V3Graph::debug(); }
|
static int debug() { return V3Graph::debug(); }
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
void buildGraph (V3Graph* origGraphp);
|
void buildGraph(V3Graph* origGraphp);
|
||||||
void buildGraphIterate (V3GraphVertex* overtexp, GraphAcycVertex* avertexp);
|
void buildGraphIterate(V3GraphVertex* overtexp, GraphAcycVertex* avertexp);
|
||||||
void simplify (bool allowCut);
|
void simplify(bool allowCut);
|
||||||
void simplifyNone (GraphAcycVertex* vertexp);
|
void simplifyNone(GraphAcycVertex* vertexp);
|
||||||
void simplifyOne (GraphAcycVertex* vertexp);
|
void simplifyOne(GraphAcycVertex* vertexp);
|
||||||
void simplifyOut (GraphAcycVertex* vertexp);
|
void simplifyOut(GraphAcycVertex* vertexp);
|
||||||
void simplifyDup (GraphAcycVertex* vertexp);
|
void simplifyDup(GraphAcycVertex* vertexp);
|
||||||
void cutBasic (GraphAcycVertex* vertexp);
|
void cutBasic(GraphAcycVertex* vertexp);
|
||||||
void cutBackward (GraphAcycVertex* vertexp);
|
void cutBackward(GraphAcycVertex* vertexp);
|
||||||
void deleteMarked();
|
void deleteMarked();
|
||||||
void place();
|
void place();
|
||||||
void placeTryEdge(V3GraphEdge* edgep);
|
void placeTryEdge(V3GraphEdge* edgep);
|
||||||
|
@ -129,14 +129,14 @@ private:
|
||||||
inline bool origFollowEdge(V3GraphEdge* edgep) {
|
inline bool origFollowEdge(V3GraphEdge* edgep) {
|
||||||
return (edgep->weight() && (m_origEdgeFuncp)(edgep));
|
return (edgep->weight() && (m_origEdgeFuncp)(edgep));
|
||||||
}
|
}
|
||||||
V3GraphEdge* edgeFromEdge (V3GraphEdge* oldedgep, V3GraphVertex* fromp, V3GraphVertex* top) {
|
V3GraphEdge* edgeFromEdge(V3GraphEdge* oldedgep, V3GraphVertex* fromp, V3GraphVertex* top) {
|
||||||
// Make new breakGraph edge, with old edge as a template
|
// Make new breakGraph edge, with old edge as a template
|
||||||
GraphAcycEdge* newEdgep = new GraphAcycEdge (&m_breakGraph, fromp, top,
|
GraphAcycEdge* newEdgep = new GraphAcycEdge(&m_breakGraph, fromp, top,
|
||||||
oldedgep->weight(), oldedgep->cutable());
|
oldedgep->weight(), oldedgep->cutable());
|
||||||
newEdgep->userp(oldedgep->userp()); // Keep pointer to OrigEdgeList
|
newEdgep->userp(oldedgep->userp()); // Keep pointer to OrigEdgeList
|
||||||
return newEdgep;
|
return newEdgep;
|
||||||
}
|
}
|
||||||
void addOrigEdgep (V3GraphEdge* toEdgep, V3GraphEdge* addEdgep) {
|
void addOrigEdgep(V3GraphEdge* toEdgep, V3GraphEdge* addEdgep) {
|
||||||
// Add addEdge (or it's list) to list of edges that break edge represents
|
// Add addEdge (or it's list) to list of edges that break edge represents
|
||||||
// Note addEdge may already have a bunch of similar linked edge representations. Yuk.
|
// Note addEdge may already have a bunch of similar linked edge representations. Yuk.
|
||||||
UASSERT(addEdgep, "Adding NULL");
|
UASSERT(addEdgep, "Adding NULL");
|
||||||
|
@ -155,7 +155,7 @@ private:
|
||||||
oEListp->push_back(addEdgep);
|
oEListp->push_back(addEdgep);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void cutOrigEdge (V3GraphEdge* breakEdgep, const char* why) {
|
void cutOrigEdge(V3GraphEdge* breakEdgep, const char* why) {
|
||||||
// From the break edge, cut edges in original graph it represents
|
// From the break edge, cut edges in original graph it represents
|
||||||
UINFO(8,why<<" CUT "<<breakEdgep->fromp()<<endl);
|
UINFO(8,why<<" CUT "<<breakEdgep->fromp()<<endl);
|
||||||
breakEdgep->cut();
|
breakEdgep->cut();
|
||||||
|
@ -200,7 +200,7 @@ public:
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
void GraphAcyc::buildGraph (V3Graph* origGraphp) {
|
void GraphAcyc::buildGraph(V3Graph* origGraphp) {
|
||||||
// Presumes the graph has been strongly ordered,
|
// Presumes the graph has been strongly ordered,
|
||||||
// and thus there's a unique color if there are loops in this subgraph.
|
// and thus there's a unique color if there are loops in this subgraph.
|
||||||
|
|
||||||
|
@ -223,7 +223,7 @@ void GraphAcyc::buildGraph (V3Graph* origGraphp) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphAcyc::buildGraphIterate (V3GraphVertex* overtexp, GraphAcycVertex* avertexp) {
|
void GraphAcyc::buildGraphIterate(V3GraphVertex* overtexp, GraphAcycVertex* avertexp) {
|
||||||
// Make new edges
|
// Make new edges
|
||||||
for (V3GraphEdge* edgep = overtexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
|
for (V3GraphEdge* edgep = overtexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
|
||||||
if (origFollowEdge(edgep)) { // not cut
|
if (origFollowEdge(edgep)) { // not cut
|
||||||
|
@ -234,13 +234,13 @@ void GraphAcyc::buildGraphIterate (V3GraphVertex* overtexp, GraphAcycVertex* ave
|
||||||
// There may be multiple edges between same pairs of vertices
|
// There may be multiple edges between same pairs of vertices
|
||||||
V3GraphEdge* breakEdgep = new GraphAcycEdge
|
V3GraphEdge* breakEdgep = new GraphAcycEdge
|
||||||
(&m_breakGraph, avertexp, toAVertexp, edgep->weight(), edgep->cutable());
|
(&m_breakGraph, avertexp, toAVertexp, edgep->weight(), edgep->cutable());
|
||||||
addOrigEdgep (breakEdgep, edgep); // So can find original edge
|
addOrigEdgep(breakEdgep, edgep); // So can find original edge
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphAcyc::simplify (bool allowCut) {
|
void GraphAcyc::simplify(bool allowCut) {
|
||||||
// Add all nodes to list of work to do
|
// Add all nodes to list of work to do
|
||||||
for (V3GraphVertex* vertexp = m_breakGraph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
|
for (V3GraphVertex* vertexp = m_breakGraph.verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
|
||||||
workPush(vertexp);
|
workPush(vertexp);
|
||||||
|
@ -264,7 +264,7 @@ void GraphAcyc::simplify (bool allowCut) {
|
||||||
deleteMarked();
|
deleteMarked();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphAcyc::deleteMarked () {
|
void GraphAcyc::deleteMarked() {
|
||||||
// Delete nodes marked for removal
|
// Delete nodes marked for removal
|
||||||
for (V3GraphVertex* nextp, *vertexp = m_breakGraph.verticesBeginp(); vertexp; vertexp=nextp) {
|
for (V3GraphVertex* nextp, *vertexp = m_breakGraph.verticesBeginp(); vertexp; vertexp=nextp) {
|
||||||
nextp = vertexp->verticesNextp();
|
nextp = vertexp->verticesNextp();
|
||||||
|
@ -275,7 +275,7 @@ void GraphAcyc::deleteMarked () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphAcyc::simplifyNone (GraphAcycVertex* avertexp) {
|
void GraphAcyc::simplifyNone(GraphAcycVertex* avertexp) {
|
||||||
// Don't need any vertices with no inputs, There's no way they can have a loop.
|
// Don't need any vertices with no inputs, There's no way they can have a loop.
|
||||||
// Likewise, vertices with no outputs
|
// Likewise, vertices with no outputs
|
||||||
if (avertexp->isDelete()) return;
|
if (avertexp->isDelete()) return;
|
||||||
|
@ -298,7 +298,7 @@ void GraphAcyc::simplifyNone (GraphAcycVertex* avertexp) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphAcyc::simplifyOne (GraphAcycVertex* avertexp) {
|
void GraphAcyc::simplifyOne(GraphAcycVertex* avertexp) {
|
||||||
// If a node has one input and one output, we can remove it and change the edges
|
// If a node has one input and one output, we can remove it and change the edges
|
||||||
if (avertexp->isDelete()) return;
|
if (avertexp->isDelete()) return;
|
||||||
if (avertexp->inSize1() && avertexp->outSize1()) {
|
if (avertexp->inSize1() && avertexp->outSize1()) {
|
||||||
|
@ -331,7 +331,7 @@ void GraphAcyc::simplifyOne (GraphAcycVertex* avertexp) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphAcyc::simplifyOut (GraphAcycVertex* avertexp) {
|
void GraphAcyc::simplifyOut(GraphAcycVertex* avertexp) {
|
||||||
// If a node has one output that's not cutable, all its inputs can be reassigned
|
// If a node has one output that's not cutable, all its inputs can be reassigned
|
||||||
// to the next node in the list
|
// to the next node in the list
|
||||||
if (avertexp->isDelete()) return;
|
if (avertexp->isDelete()) return;
|
||||||
|
@ -367,7 +367,7 @@ void GraphAcyc::simplifyOut (GraphAcycVertex* avertexp) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphAcyc::simplifyDup (GraphAcycVertex* avertexp) {
|
void GraphAcyc::simplifyDup(GraphAcycVertex* avertexp) {
|
||||||
// Remove redundant edges
|
// Remove redundant edges
|
||||||
if (avertexp->isDelete()) return;
|
if (avertexp->isDelete()) return;
|
||||||
// Clear marks
|
// Clear marks
|
||||||
|
@ -393,8 +393,8 @@ void GraphAcyc::simplifyDup (GraphAcycVertex* avertexp) {
|
||||||
} else {
|
} else {
|
||||||
// cutable duplicates prev cutable: combine weights
|
// cutable duplicates prev cutable: combine weights
|
||||||
UINFO(8," DelDupComb "<<avertexp<<" -> "<<edgep->top()<<endl);
|
UINFO(8," DelDupComb "<<avertexp<<" -> "<<edgep->top()<<endl);
|
||||||
prevEdgep->weight (prevEdgep->weight() + edgep->weight());
|
prevEdgep->weight(prevEdgep->weight() + edgep->weight());
|
||||||
addOrigEdgep (prevEdgep, edgep);
|
addOrigEdgep(prevEdgep, edgep);
|
||||||
edgep->unlinkDelete(); VL_DANGLING(edgep);
|
edgep->unlinkDelete(); VL_DANGLING(edgep);
|
||||||
}
|
}
|
||||||
workPush(outVertexp);
|
workPush(outVertexp);
|
||||||
|
@ -406,20 +406,20 @@ void GraphAcyc::simplifyDup (GraphAcycVertex* avertexp) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphAcyc::cutBasic (GraphAcycVertex* avertexp) {
|
void GraphAcyc::cutBasic(GraphAcycVertex* avertexp) {
|
||||||
// Detect and cleanup any loops from node to itself
|
// Detect and cleanup any loops from node to itself
|
||||||
if (avertexp->isDelete()) return;
|
if (avertexp->isDelete()) return;
|
||||||
for (V3GraphEdge* nextp, *edgep = avertexp->outBeginp(); edgep; edgep=nextp) {
|
for (V3GraphEdge* nextp, *edgep = avertexp->outBeginp(); edgep; edgep=nextp) {
|
||||||
nextp = edgep->outNextp();
|
nextp = edgep->outNextp();
|
||||||
if (edgep->cutable() && edgep->top()==avertexp) {
|
if (edgep->cutable() && edgep->top()==avertexp) {
|
||||||
cutOrigEdge (edgep, " Cut Basic");
|
cutOrigEdge(edgep, " Cut Basic");
|
||||||
edgep->unlinkDelete(); VL_DANGLING(edgep);
|
edgep->unlinkDelete(); VL_DANGLING(edgep);
|
||||||
workPush(avertexp);
|
workPush(avertexp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphAcyc::cutBackward (GraphAcycVertex* avertexp) {
|
void GraphAcyc::cutBackward(GraphAcycVertex* avertexp) {
|
||||||
// If a cutable edge is from A->B, and there's a non-cutable edge B->A, then must cut!
|
// If a cutable edge is from A->B, and there's a non-cutable edge B->A, then must cut!
|
||||||
if (avertexp->isDelete()) return;
|
if (avertexp->isDelete()) return;
|
||||||
// Clear marks
|
// Clear marks
|
||||||
|
@ -433,7 +433,7 @@ void GraphAcyc::cutBackward (GraphAcycVertex* avertexp) {
|
||||||
for (V3GraphEdge* nextp, *edgep = avertexp->outBeginp(); edgep; edgep=nextp) {
|
for (V3GraphEdge* nextp, *edgep = avertexp->outBeginp(); edgep; edgep=nextp) {
|
||||||
nextp = edgep->outNextp();
|
nextp = edgep->outNextp();
|
||||||
if (edgep->cutable() && edgep->top()->user()) {
|
if (edgep->cutable() && edgep->top()->user()) {
|
||||||
cutOrigEdge (edgep, " Cut A->B->A");
|
cutOrigEdge(edgep, " Cut A->B->A");
|
||||||
edgep->unlinkDelete(); VL_DANGLING(edgep);
|
edgep->unlinkDelete(); VL_DANGLING(edgep);
|
||||||
workPush(avertexp);
|
workPush(avertexp);
|
||||||
}
|
}
|
||||||
|
@ -497,7 +497,7 @@ void GraphAcyc::placeTryEdge(V3GraphEdge* edgep) {
|
||||||
} else {
|
} else {
|
||||||
// Adding this edge would cause a loop, kill it
|
// Adding this edge would cause a loop, kill it
|
||||||
edgep->cutable(true); // So graph still looks pretty
|
edgep->cutable(true); // So graph still looks pretty
|
||||||
cutOrigEdge (edgep, " Cut loop");
|
cutOrigEdge(edgep, " Cut loop");
|
||||||
edgep->unlinkDelete(); VL_DANGLING(edgep);
|
edgep->unlinkDelete(); VL_DANGLING(edgep);
|
||||||
// Backout the ranks we calculated
|
// Backout the ranks we calculated
|
||||||
while (GraphAcycVertex* vertexp = workBeginp()) {
|
while (GraphAcycVertex* vertexp = workBeginp()) {
|
||||||
|
@ -536,7 +536,7 @@ bool GraphAcyc::placeIterate(GraphAcycVertex* vertexp, uint32_t currentRank) {
|
||||||
|
|
||||||
//----- Main algorithm entry point
|
//----- Main algorithm entry point
|
||||||
|
|
||||||
void GraphAcyc::main () {
|
void GraphAcyc::main() {
|
||||||
m_breakGraph.userClearEdges();
|
m_breakGraph.userClearEdges();
|
||||||
|
|
||||||
// Color based on possible loops
|
// Color based on possible loops
|
||||||
|
@ -546,7 +546,7 @@ void GraphAcyc::main () {
|
||||||
// for each group of old vertices that are interconnected with unbreakable
|
// for each group of old vertices that are interconnected with unbreakable
|
||||||
// edges (and thus can't represent loops - if we did the unbreakable
|
// edges (and thus can't represent loops - if we did the unbreakable
|
||||||
// marking right, anyways)
|
// marking right, anyways)
|
||||||
buildGraph (m_origGraphp);
|
buildGraph(m_origGraphp);
|
||||||
if (debug()>=6) m_breakGraph.dumpDotFilePrefixed("acyc_pre");
|
if (debug()>=6) m_breakGraph.dumpDotFilePrefixed("acyc_pre");
|
||||||
|
|
||||||
// Perform simple optimizations before any cuttings
|
// Perform simple optimizations before any cuttings
|
||||||
|
|
|
@ -129,10 +129,10 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
void V3Graph::removeRedundantEdges(V3EdgeFuncP edgeFuncp) {
|
void V3Graph::removeRedundantEdges(V3EdgeFuncP edgeFuncp) {
|
||||||
GraphRemoveRedundant (this, edgeFuncp, false);
|
GraphRemoveRedundant(this, edgeFuncp, false);
|
||||||
}
|
}
|
||||||
void V3Graph::removeRedundantEdgesSum(V3EdgeFuncP edgeFuncp) {
|
void V3Graph::removeRedundantEdgesSum(V3EdgeFuncP edgeFuncp) {
|
||||||
GraphRemoveRedundant (this, edgeFuncp, true);
|
GraphRemoveRedundant(this, edgeFuncp, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
@ -217,7 +217,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
void V3Graph::weaklyConnected(V3EdgeFuncP edgeFuncp) {
|
void V3Graph::weaklyConnected(V3EdgeFuncP edgeFuncp) {
|
||||||
GraphAlgWeakly (this, edgeFuncp);
|
GraphAlgWeakly(this, edgeFuncp);
|
||||||
}
|
}
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
@ -303,7 +303,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
void V3Graph::stronglyConnected(V3EdgeFuncP edgeFuncp) {
|
void V3Graph::stronglyConnected(V3EdgeFuncP edgeFuncp) {
|
||||||
GraphAlgStrongly (this, edgeFuncp);
|
GraphAlgStrongly(this, edgeFuncp);
|
||||||
}
|
}
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
@ -355,11 +355,11 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
void V3Graph::rank() {
|
void V3Graph::rank() {
|
||||||
GraphAlgRank (this, &V3GraphEdge::followAlwaysTrue);
|
GraphAlgRank(this, &V3GraphEdge::followAlwaysTrue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void V3Graph::rank(V3EdgeFuncP edgeFuncp) {
|
void V3Graph::rank(V3EdgeFuncP edgeFuncp) {
|
||||||
GraphAlgRank (this, edgeFuncp);
|
GraphAlgRank(this, edgeFuncp);
|
||||||
}
|
}
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
@ -414,7 +414,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
void V3Graph::reportLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp) {
|
void V3Graph::reportLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp) {
|
||||||
GraphAlgRLoops (this, edgeFuncp, vertexp);
|
GraphAlgRLoops(this, edgeFuncp, vertexp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -453,7 +453,7 @@ private:
|
||||||
public:
|
public:
|
||||||
GraphAlgSubtrees(V3Graph* graphp, V3Graph* loopGraphp,
|
GraphAlgSubtrees(V3Graph* graphp, V3Graph* loopGraphp,
|
||||||
V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp)
|
V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp)
|
||||||
: GraphAlg<>(graphp, edgeFuncp), m_loopGraphp (loopGraphp) {
|
: GraphAlg<>(graphp, edgeFuncp), m_loopGraphp(loopGraphp) {
|
||||||
// Vertex::m_userp - New vertex if we have seen this vertex already
|
// Vertex::m_userp - New vertex if we have seen this vertex already
|
||||||
// Edge::m_userp - New edge if we have seen this edge already
|
// Edge::m_userp - New edge if we have seen this edge already
|
||||||
m_graphp->userClearVertices();
|
m_graphp->userClearVertices();
|
||||||
|
@ -466,7 +466,7 @@ public:
|
||||||
//! Report the entire connected graph with a loop or loops
|
//! Report the entire connected graph with a loop or loops
|
||||||
void V3Graph::subtreeLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp,
|
void V3Graph::subtreeLoops(V3EdgeFuncP edgeFuncp, V3GraphVertex* vertexp,
|
||||||
V3Graph* loopGraphp) {
|
V3Graph* loopGraphp) {
|
||||||
GraphAlgSubtrees (this, loopGraphp, edgeFuncp, vertexp);
|
GraphAlgSubtrees(this, loopGraphp, edgeFuncp, vertexp);
|
||||||
}
|
}
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
@ -489,12 +489,12 @@ void V3Graph::makeEdgesNonCutable(V3EdgeFuncP edgeFuncp) {
|
||||||
// Algorithms - sorting
|
// Algorithms - sorting
|
||||||
|
|
||||||
struct GraphSortVertexCmp {
|
struct GraphSortVertexCmp {
|
||||||
inline bool operator () (const V3GraphVertex* lhsp, const V3GraphVertex* rhsp) const {
|
inline bool operator() (const V3GraphVertex* lhsp, const V3GraphVertex* rhsp) const {
|
||||||
return lhsp->sortCmp(rhsp) < 0;
|
return lhsp->sortCmp(rhsp) < 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct GraphSortEdgeCmp {
|
struct GraphSortEdgeCmp {
|
||||||
inline bool operator () (const V3GraphEdge* lhsp, const V3GraphEdge* rhsp) const {
|
inline bool operator() (const V3GraphEdge* lhsp, const V3GraphEdge* rhsp) const {
|
||||||
return lhsp->sortCmp(rhsp) < 0;
|
return lhsp->sortCmp(rhsp) < 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -89,7 +89,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
DfaVertex* newDfaVertex(DfaVertex* nfaTemplatep=NULL) {
|
DfaVertex* newDfaVertex(DfaVertex* nfaTemplatep=NULL) {
|
||||||
DfaVertex* vertexp = new DfaVertex (graphp());
|
DfaVertex* vertexp = new DfaVertex(graphp());
|
||||||
vertexp->color(1); // Mark as dfa
|
vertexp->color(1); // Mark as dfa
|
||||||
if (nfaTemplatep && nfaTemplatep->start()) vertexp->start(true);
|
if (nfaTemplatep && nfaTemplatep->start()) vertexp->start(true);
|
||||||
if (nfaTemplatep && nfaTemplatep->accepting()) vertexp->accepting(true);
|
if (nfaTemplatep && nfaTemplatep->accepting()) vertexp->accepting(true);
|
||||||
|
@ -320,13 +320,13 @@ private:
|
||||||
// Track what nfa's point to it.
|
// Track what nfa's point to it.
|
||||||
for (DfaStates::const_iterator nfaIt=nfasWithInput.begin(); nfaIt!=nfasWithInput.end(); ++nfaIt) {
|
for (DfaStates::const_iterator nfaIt=nfasWithInput.begin(); nfaIt!=nfasWithInput.end(); ++nfaIt) {
|
||||||
UINFO(9," NewContainsNfa "<<*nfaIt<<endl);
|
UINFO(9," NewContainsNfa "<<*nfaIt<<endl);
|
||||||
new DfaEdge (graphp(), toDfaStatep, *nfaIt, DfaEdge::NA());
|
new DfaEdge(graphp(), toDfaStatep, *nfaIt, DfaEdge::NA());
|
||||||
if ((*nfaIt)->accepting()) toDfaStatep->accepting(true);
|
if ((*nfaIt)->accepting()) toDfaStatep->accepting(true);
|
||||||
}
|
}
|
||||||
insertDfaOrigins(toDfaStatep);
|
insertDfaOrigins(toDfaStatep);
|
||||||
}
|
}
|
||||||
// Add input transition
|
// Add input transition
|
||||||
new DfaEdge (graphp(), dfaStatep, toDfaStatep, input);
|
new DfaEdge(graphp(), dfaStatep, toDfaStatep, input);
|
||||||
|
|
||||||
if (debug()>=6) m_graphp->dumpDotFilePrefixed("step");
|
if (debug()>=6) m_graphp->dumpDotFilePrefixed("step");
|
||||||
}
|
}
|
||||||
|
@ -356,7 +356,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
void DfaGraph::nfaToDfa() {
|
void DfaGraph::nfaToDfa() {
|
||||||
GraphNfaToDfa (this, &V3GraphEdge::followAlwaysTrue);
|
GraphNfaToDfa(this, &V3GraphEdge::followAlwaysTrue);
|
||||||
}
|
}
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
@ -484,7 +484,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
void DfaGraph::dfaReduce() {
|
void DfaGraph::dfaReduce() {
|
||||||
DfaGraphReduce (this, &V3GraphEdge::followAlwaysTrue);
|
DfaGraphReduce(this, &V3GraphEdge::followAlwaysTrue);
|
||||||
}
|
}
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
@ -549,7 +549,7 @@ private:
|
||||||
// We make a edge for each value to OR, IE
|
// We make a edge for each value to OR, IE
|
||||||
// edge(complemented,a) edge(complemented,b) means !(a | b)
|
// edge(complemented,a) edge(complemented,b) means !(a | b)
|
||||||
if (!tovertexp->accepting()) { // Note we must include edges moved above to reject
|
if (!tovertexp->accepting()) { // Note we must include edges moved above to reject
|
||||||
DfaEdge* newp = new DfaEdge (graphp(), vvertexp, acceptp, vedgep);
|
DfaEdge* newp = new DfaEdge(graphp(), vvertexp, acceptp, vedgep);
|
||||||
newp->complement(!newp->complement());
|
newp->complement(!newp->complement());
|
||||||
newp->user(1);
|
newp->user(1);
|
||||||
}
|
}
|
||||||
|
@ -578,5 +578,5 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
void DfaGraph::dfaComplement() {
|
void DfaGraph::dfaComplement() {
|
||||||
DfaGraphComplement (this, &V3GraphEdge::followAlwaysTrue);
|
DfaGraphComplement(this, &V3GraphEdge::followAlwaysTrue);
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,8 +82,8 @@ private:
|
||||||
if (nodep->modVarp()->isInout()) {
|
if (nodep->modVarp()->isInout()) {
|
||||||
nodep->v3fatalSrc("Unsupported: Verilator is a 2-state simulator");
|
nodep->v3fatalSrc("Unsupported: Verilator is a 2-state simulator");
|
||||||
} else if (nodep->modVarp()->isOutput()) {
|
} else if (nodep->modVarp()->isOutput()) {
|
||||||
AstNode* rhsp = new AstVarXRef (exprp->fileline(), nodep->modVarp(), m_cellp->name(), false);
|
AstNode* rhsp = new AstVarXRef(exprp->fileline(), nodep->modVarp(), m_cellp->name(), false);
|
||||||
AstAssignW* assp = new AstAssignW (exprp->fileline(), exprp, rhsp);
|
AstAssignW* assp = new AstAssignW(exprp->fileline(), exprp, rhsp);
|
||||||
m_cellp->addNextHere(assp);
|
m_cellp->addNextHere(assp);
|
||||||
} else if (nodep->modVarp()->isInput()) {
|
} else if (nodep->modVarp()->isInput()) {
|
||||||
// Don't bother moving constants now,
|
// Don't bother moving constants now,
|
||||||
|
@ -98,7 +98,7 @@ private:
|
||||||
|| (VN_IS(nodep->modVarp()->subDTypep(), UnpackArrayDType)
|
|| (VN_IS(nodep->modVarp()->subDTypep(), UnpackArrayDType)
|
||||||
&& VN_IS(VN_CAST(nodep->modVarp()->subDTypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType))) {
|
&& VN_IS(VN_CAST(nodep->modVarp()->subDTypep(), UnpackArrayDType)->subDTypep(), IfaceRefDType))) {
|
||||||
// Create an AstAssignVarScope for Vars to Cells so we can link with their scope later
|
// Create an AstAssignVarScope for Vars to Cells so we can link with their scope later
|
||||||
AstNode* lhsp = new AstVarXRef (exprp->fileline(), nodep->modVarp(), m_cellp->name(), false);
|
AstNode* lhsp = new AstVarXRef(exprp->fileline(), nodep->modVarp(), m_cellp->name(), false);
|
||||||
const AstVarRef* refp = VN_CAST(exprp, VarRef);
|
const AstVarRef* refp = VN_CAST(exprp, VarRef);
|
||||||
const AstVarXRef* xrefp = VN_CAST(exprp, VarXRef);
|
const AstVarXRef* xrefp = VN_CAST(exprp, VarXRef);
|
||||||
if (!refp && !xrefp) exprp->v3fatalSrc("Interfaces: Pin is not connected to a VarRef or VarXRef");
|
if (!refp && !xrefp) exprp->v3fatalSrc("Interfaces: Pin is not connected to a VarRef or VarXRef");
|
||||||
|
@ -323,8 +323,7 @@ private:
|
||||||
if (expDim.first == pinDim.first && expDim.second == pinDim.second+1) {
|
if (expDim.first == pinDim.first && expDim.second == pinDim.second+1) {
|
||||||
// Connection to array, where array dimensions match the instant dimension
|
// Connection to array, where array dimensions match the instant dimension
|
||||||
AstNode* exprp = nodep->exprp()->unlinkFrBack();
|
AstNode* exprp = nodep->exprp()->unlinkFrBack();
|
||||||
exprp = new AstArraySel (exprp->fileline(), exprp,
|
exprp = new AstArraySel(exprp->fileline(), exprp, m_instSelNum);
|
||||||
m_instSelNum);
|
|
||||||
nodep->exprp(exprp);
|
nodep->exprp(exprp);
|
||||||
} else if (expwidth == pinwidth) {
|
} else if (expwidth == pinwidth) {
|
||||||
// NOP: Arrayed instants: widths match so connect to each instance
|
// NOP: Arrayed instants: widths match so connect to each instance
|
||||||
|
@ -342,9 +341,9 @@ private:
|
||||||
nodep->v3error("Unsupported: Per-bit array instantiations with output connections to non-wires.");
|
nodep->v3error("Unsupported: Per-bit array instantiations with output connections to non-wires.");
|
||||||
// Note spec allows more complicated matches such as slices and such
|
// Note spec allows more complicated matches such as slices and such
|
||||||
}
|
}
|
||||||
exprp = new AstSel (exprp->fileline(), exprp,
|
exprp = new AstSel(exprp->fileline(), exprp,
|
||||||
pinwidth*m_instSelNum,
|
pinwidth*m_instSelNum,
|
||||||
pinwidth);
|
pinwidth);
|
||||||
nodep->exprp(exprp);
|
nodep->exprp(exprp);
|
||||||
} else {
|
} else {
|
||||||
nodep->v3fatalSrc("Width mismatch; V3Width should have errored out.");
|
nodep->v3fatalSrc("Width mismatch; V3Width should have errored out.");
|
||||||
|
@ -411,7 +410,7 @@ private:
|
||||||
// And replace exprp with a new varxref
|
// And replace exprp with a new varxref
|
||||||
const AstVarRef* varrefp = VN_CAST(newp->exprp(), VarRef);
|
const AstVarRef* varrefp = VN_CAST(newp->exprp(), VarRef);
|
||||||
string newname = varrefp->name() + "__BRA__" + cvtToStr(i) + "__KET__";
|
string newname = varrefp->name() + "__BRA__" + cvtToStr(i) + "__KET__";
|
||||||
AstVarXRef* newVarXRefp = new AstVarXRef (nodep->fileline(), newname, "", true);
|
AstVarXRef* newVarXRefp = new AstVarXRef(nodep->fileline(), newname, "", true);
|
||||||
newVarXRefp->varp(newp->modVarp());
|
newVarXRefp->varp(newp->modVarp());
|
||||||
newVarXRefp->dtypep(newp->modVarp()->dtypep());
|
newVarXRefp->dtypep(newp->modVarp()->dtypep());
|
||||||
newp->exprp()->unlinkFrBack()->deleteTree();
|
newp->exprp()->unlinkFrBack()->deleteTree();
|
||||||
|
@ -464,7 +463,7 @@ private:
|
||||||
: static_cast<AstNode*>(new AstExtend (fl, rhsp)));
|
: static_cast<AstNode*>(new AstExtend (fl, rhsp)));
|
||||||
rhsp->dtypeFrom(cmpWidthp); // Need proper widthMin, which may differ from AstSel created above
|
rhsp->dtypeFrom(cmpWidthp); // Need proper widthMin, which may differ from AstSel created above
|
||||||
} else if (cmpWidthp->width() < rhsp->width()) {
|
} else if (cmpWidthp->width() < rhsp->width()) {
|
||||||
rhsp = new AstSel (fl, rhsp, 0, cmpWidthp->width());
|
rhsp = new AstSel(fl, rhsp, 0, cmpWidthp->width());
|
||||||
rhsp->dtypeFrom(cmpWidthp); // Need proper widthMin, which may differ from AstSel created above
|
rhsp->dtypeFrom(cmpWidthp); // Need proper widthMin, which may differ from AstSel created above
|
||||||
}
|
}
|
||||||
// else don't change dtype, as might be e.g. array of something
|
// else don't change dtype, as might be e.g. array of something
|
||||||
|
@ -517,7 +516,7 @@ public:
|
||||||
string newvarname = ((string)(pinVarp->isOutput() ? "__Vcellout" : "__Vcellinp")
|
string newvarname = ((string)(pinVarp->isOutput() ? "__Vcellout" : "__Vcellinp")
|
||||||
+(forTristate?"t":"") // Prevent name conflict if both tri & non-tri add signals
|
+(forTristate?"t":"") // Prevent name conflict if both tri & non-tri add signals
|
||||||
+"__"+cellp->name()+"__"+pinp->name());
|
+"__"+cellp->name()+"__"+pinp->name());
|
||||||
AstVar* newvarp = new AstVar (pinVarp->fileline(), AstVarType::MODULETEMP, newvarname, pinVarp);
|
AstVar* newvarp = new AstVar(pinVarp->fileline(), AstVarType::MODULETEMP, newvarname, pinVarp);
|
||||||
// Important to add statement next to cell, in case there is a generate with same named cell
|
// Important to add statement next to cell, in case there is a generate with same named cell
|
||||||
cellp->addNextHere(newvarp);
|
cellp->addNextHere(newvarp);
|
||||||
if (pinVarp->isInout()) {
|
if (pinVarp->isInout()) {
|
||||||
|
@ -527,16 +526,16 @@ public:
|
||||||
// See also V3Inst
|
// See also V3Inst
|
||||||
AstNode* rhsp = new AstVarRef(pinp->fileline(), newvarp, false);
|
AstNode* rhsp = new AstVarRef(pinp->fileline(), newvarp, false);
|
||||||
UINFO(5,"pinRecon width "<<pinVarp->width()<<" >? "<<rhsp->width()<<" >? "<<pinexprp->width()<<endl);
|
UINFO(5,"pinRecon width "<<pinVarp->width()<<" >? "<<rhsp->width()<<" >? "<<pinexprp->width()<<endl);
|
||||||
rhsp = extendOrSel (pinp->fileline(), rhsp, pinVarp);
|
rhsp = extendOrSel(pinp->fileline(), rhsp, pinVarp);
|
||||||
pinp->exprp(new AstVarRef (newvarp->fileline(), newvarp, true));
|
pinp->exprp(new AstVarRef(newvarp->fileline(), newvarp, true));
|
||||||
AstNode* rhsSelp = extendOrSel (pinp->fileline(), rhsp, pinexprp);
|
AstNode* rhsSelp = extendOrSel(pinp->fileline(), rhsp, pinexprp);
|
||||||
assignp = new AstAssignW (pinp->fileline(), pinexprp, rhsSelp);
|
assignp = new AstAssignW(pinp->fileline(), pinexprp, rhsSelp);
|
||||||
} else {
|
} else {
|
||||||
// V3 width should have range/extended to make the widths correct
|
// V3 width should have range/extended to make the widths correct
|
||||||
assignp = new AstAssignW (pinp->fileline(),
|
assignp = new AstAssignW(pinp->fileline(),
|
||||||
new AstVarRef(pinp->fileline(), newvarp, true),
|
new AstVarRef(pinp->fileline(), newvarp, true),
|
||||||
pinexprp);
|
pinexprp);
|
||||||
pinp->exprp(new AstVarRef (pinexprp->fileline(), newvarp, false));
|
pinp->exprp(new AstVarRef(pinexprp->fileline(), newvarp, false));
|
||||||
}
|
}
|
||||||
if (assignp) cellp->addNextHere(assignp);
|
if (assignp) cellp->addNextHere(assignp);
|
||||||
//if (debug()) { pinp->dumpTree(cout,"- out:"); }
|
//if (debug()) { pinp->dumpTree(cout,"- out:"); }
|
||||||
|
|
|
@ -66,12 +66,12 @@ public:
|
||||||
bool legal() const { return m_e != L_ERROR; }
|
bool legal() const { return m_e != L_ERROR; }
|
||||||
//
|
//
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
inline V3LangCode () : m_e(L_ERROR) {}
|
inline V3LangCode() : m_e(L_ERROR) {}
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
inline V3LangCode (en _e) : m_e(_e) {}
|
inline V3LangCode(en _e) : m_e(_e) {}
|
||||||
explicit V3LangCode (const char* textp);
|
explicit V3LangCode(const char* textp);
|
||||||
explicit inline V3LangCode (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline V3LangCode(int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en() const { return m_e; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
|
|
@ -79,7 +79,7 @@ class LifeVarEntry {
|
||||||
bool m_setBeforeUse; // First access was a set (and thus block above may have a set that can be deleted
|
bool m_setBeforeUse; // First access was a set (and thus block above may have a set that can be deleted
|
||||||
bool m_everSet; // Was ever assigned (and thus above block may not preserve constant propagation)
|
bool m_everSet; // Was ever assigned (and thus above block may not preserve constant propagation)
|
||||||
|
|
||||||
inline void init (bool setBeforeUse) {
|
inline void init(bool setBeforeUse) {
|
||||||
m_assignp = NULL;
|
m_assignp = NULL;
|
||||||
m_constp = NULL;
|
m_constp = NULL;
|
||||||
m_setBeforeUse = setBeforeUse;
|
m_setBeforeUse = setBeforeUse;
|
||||||
|
@ -185,7 +185,7 @@ public:
|
||||||
m_map.insert(make_pair(nodep,LifeVarEntry(LifeVarEntry::COMPLEXASSIGN())));
|
m_map.insert(make_pair(nodep,LifeVarEntry(LifeVarEntry::COMPLEXASSIGN())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void varUsageReplace (AstVarScope* nodep, AstVarRef* varrefp) {
|
void varUsageReplace(AstVarScope* nodep, AstVarRef* varrefp) {
|
||||||
// Variable rvalue. If it references a constant, we can simply replace it
|
// Variable rvalue. If it references a constant, we can simply replace it
|
||||||
LifeMap::iterator it = m_map.find(nodep);
|
LifeMap::iterator it = m_map.find(nodep);
|
||||||
if (it != m_map.end()) {
|
if (it != m_map.end()) {
|
||||||
|
@ -238,7 +238,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void dualBranch (LifeBlock* life1p, LifeBlock* life2p) {
|
void dualBranch(LifeBlock* life1p, LifeBlock* life2p) {
|
||||||
// Find any common sets on both branches of IF and propagate upwards
|
// Find any common sets on both branches of IF and propagate upwards
|
||||||
//life1p->lifeDump();
|
//life1p->lifeDump();
|
||||||
//life2p->lifeDump();
|
//life2p->lifeDump();
|
||||||
|
@ -340,8 +340,8 @@ private:
|
||||||
// Condition is part of PREVIOUS block
|
// Condition is part of PREVIOUS block
|
||||||
iterateAndNextNull(nodep->condp());
|
iterateAndNextNull(nodep->condp());
|
||||||
LifeBlock* prevLifep = m_lifep;
|
LifeBlock* prevLifep = m_lifep;
|
||||||
LifeBlock* ifLifep = new LifeBlock (prevLifep, m_statep);
|
LifeBlock* ifLifep = new LifeBlock(prevLifep, m_statep);
|
||||||
LifeBlock* elseLifep = new LifeBlock (prevLifep, m_statep);
|
LifeBlock* elseLifep = new LifeBlock(prevLifep, m_statep);
|
||||||
{
|
{
|
||||||
m_lifep = ifLifep;
|
m_lifep = ifLifep;
|
||||||
iterateAndNextNull(nodep->ifsp());
|
iterateAndNextNull(nodep->ifsp());
|
||||||
|
@ -354,7 +354,7 @@ private:
|
||||||
}
|
}
|
||||||
UINFO(4," join "<<endl);
|
UINFO(4," join "<<endl);
|
||||||
// Find sets on both flows
|
// Find sets on both flows
|
||||||
m_lifep->dualBranch (ifLifep, elseLifep);
|
m_lifep->dualBranch(ifLifep, elseLifep);
|
||||||
// For the next assignments, clear any variables that were read or written in the block
|
// For the next assignments, clear any variables that were read or written in the block
|
||||||
ifLifep->lifeToAbove();
|
ifLifep->lifeToAbove();
|
||||||
elseLifep->lifeToAbove();
|
elseLifep->lifeToAbove();
|
||||||
|
@ -371,8 +371,8 @@ private:
|
||||||
// it as a IF statement, and just don't allow elimination of
|
// it as a IF statement, and just don't allow elimination of
|
||||||
// variables across the body.
|
// variables across the body.
|
||||||
LifeBlock* prevLifep = m_lifep;
|
LifeBlock* prevLifep = m_lifep;
|
||||||
LifeBlock* condLifep = new LifeBlock (prevLifep, m_statep);
|
LifeBlock* condLifep = new LifeBlock(prevLifep, m_statep);
|
||||||
LifeBlock* bodyLifep = new LifeBlock (prevLifep, m_statep);
|
LifeBlock* bodyLifep = new LifeBlock(prevLifep, m_statep);
|
||||||
{
|
{
|
||||||
m_lifep = condLifep;
|
m_lifep = condLifep;
|
||||||
iterateAndNextNull(nodep->precondsp());
|
iterateAndNextNull(nodep->precondsp());
|
||||||
|
@ -397,7 +397,7 @@ private:
|
||||||
// It's worse though as an IF(..., JUMPGO) may change the control flow.
|
// 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.
|
// Just don't optimize blocks with labels; they're rare - so far.
|
||||||
LifeBlock* prevLifep = m_lifep;
|
LifeBlock* prevLifep = m_lifep;
|
||||||
LifeBlock* bodyLifep = new LifeBlock (prevLifep, m_statep);
|
LifeBlock* bodyLifep = new LifeBlock(prevLifep, m_statep);
|
||||||
bool prev_noopt = m_noopt;
|
bool prev_noopt = m_noopt;
|
||||||
{
|
{
|
||||||
m_lifep = bodyLifep;
|
m_lifep = bodyLifep;
|
||||||
|
@ -452,7 +452,7 @@ public:
|
||||||
m_noopt = false;
|
m_noopt = false;
|
||||||
m_tracingCall = false;
|
m_tracingCall = false;
|
||||||
{
|
{
|
||||||
m_lifep = new LifeBlock (NULL, m_statep);
|
m_lifep = new LifeBlock(NULL, m_statep);
|
||||||
iterate(nodep);
|
iterate(nodep);
|
||||||
if (m_lifep) { delete m_lifep; m_lifep=NULL; }
|
if (m_lifep) { delete m_lifep; m_lifep=NULL; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1149,10 +1149,10 @@ private:
|
||||||
<<" attach-to "<<cellp
|
<<" attach-to "<<cellp
|
||||||
<<" <= "<<exprp<<endl);
|
<<" <= "<<exprp<<endl);
|
||||||
// Don't need to check the name of the defparam exists. V3Param does.
|
// Don't need to check the name of the defparam exists. V3Param does.
|
||||||
AstPin* pinp = new AstPin (nodep->fileline(),
|
AstPin* pinp = new AstPin(nodep->fileline(),
|
||||||
-1, // Pin# not relevant
|
-1, // Pin# not relevant
|
||||||
nodep->name(),
|
nodep->name(),
|
||||||
exprp);
|
exprp);
|
||||||
cellp->addParamsp(pinp);
|
cellp->addParamsp(pinp);
|
||||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
|
@ -1508,7 +1508,7 @@ private:
|
||||||
int debug() { return LinkDotState::debug(); }
|
int debug() { return LinkDotState::debug(); }
|
||||||
|
|
||||||
// METHODS - Variables
|
// METHODS - Variables
|
||||||
void createImplicitVar (VSymEnt* lookupSymp, AstVarRef* nodep, AstNodeModule* modp, VSymEnt* moduleSymp, bool noWarn) {
|
void createImplicitVar(VSymEnt* lookupSymp, AstVarRef* nodep, AstNodeModule* modp, VSymEnt* moduleSymp, bool noWarn) {
|
||||||
// Create implicit after warning
|
// Create implicit after warning
|
||||||
if (!nodep->varp()) {
|
if (!nodep->varp()) {
|
||||||
if (!noWarn) {
|
if (!noWarn) {
|
||||||
|
@ -1518,8 +1518,8 @@ private:
|
||||||
nodep->v3warn(IMPLICIT,"Signal definition not found, creating implicitly: "<<nodep->prettyName());
|
nodep->v3warn(IMPLICIT,"Signal definition not found, creating implicitly: "<<nodep->prettyName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AstVar* newp = new AstVar (nodep->fileline(), AstVarType::WIRE,
|
AstVar* newp = new AstVar(nodep->fileline(), AstVarType::WIRE,
|
||||||
nodep->name(), VFlagLogicPacked(), 1);
|
nodep->name(), VFlagLogicPacked(), 1);
|
||||||
newp->trace(modp->modTrace());
|
newp->trace(modp->modTrace());
|
||||||
nodep->varp(newp);
|
nodep->varp(newp);
|
||||||
modp->addStmtp(newp);
|
modp->addStmtp(newp);
|
||||||
|
@ -1936,7 +1936,7 @@ private:
|
||||||
AstVarRef* newp = new AstVarRef(nodep->fileline(), nodep->name(), false);
|
AstVarRef* newp = new AstVarRef(nodep->fileline(), nodep->name(), false);
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||||
createImplicitVar (m_curSymp, newp, m_modp, m_modSymp, err);
|
createImplicitVar(m_curSymp, newp, m_modp, m_modSymp, err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
// Levelizing class functions
|
// Levelizing class functions
|
||||||
|
|
||||||
struct CmpLevel {
|
struct CmpLevel {
|
||||||
inline bool operator () (const AstNodeModule* lhsp, const AstNodeModule* rhsp) const {
|
inline bool operator() (const AstNodeModule* lhsp, const AstNodeModule* rhsp) const {
|
||||||
return lhsp->level() < rhsp->level();
|
return lhsp->level() < rhsp->level();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -179,13 +179,13 @@ private:
|
||||||
else if (m_valueModp) {
|
else if (m_valueModp) {
|
||||||
nodep->addNextHere
|
nodep->addNextHere
|
||||||
(new AstInitial
|
(new AstInitial
|
||||||
(fl, new AstAssign (fl, new AstVarRef(fl, nodep->name(), true),
|
(fl, new AstAssign(fl, new AstVarRef(fl, nodep->name(), true),
|
||||||
nodep->valuep()->unlinkFrBack())));
|
nodep->valuep()->unlinkFrBack())));
|
||||||
} // 3. Under blocks, it's an initial value to be under an assign
|
} // 3. Under blocks, it's an initial value to be under an assign
|
||||||
else {
|
else {
|
||||||
nodep->addNextHere
|
nodep->addNextHere
|
||||||
(new AstAssign (fl, new AstVarRef(fl, nodep->name(), true),
|
(new AstAssign(fl, new AstVarRef(fl, nodep->name(), true),
|
||||||
nodep->valuep()->unlinkFrBack()));
|
nodep->valuep()->unlinkFrBack()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nodep->isIfaceRef() && !nodep->isIfaceParent()) {
|
if (nodep->isIfaceRef() && !nodep->isIfaceParent()) {
|
||||||
|
|
|
@ -136,8 +136,8 @@ private:
|
||||||
&& !VN_IS(sensp, Const)) {
|
&& !VN_IS(sensp, Const)) {
|
||||||
// Make a new temp wire
|
// Make a new temp wire
|
||||||
string newvarname = "__Vsenitemexpr"+cvtToStr(++m_senitemCvtNum);
|
string newvarname = "__Vsenitemexpr"+cvtToStr(++m_senitemCvtNum);
|
||||||
AstVar* newvarp = new AstVar (sensp->fileline(), AstVarType::MODULETEMP, newvarname,
|
AstVar* newvarp = new AstVar(sensp->fileline(), AstVarType::MODULETEMP, newvarname,
|
||||||
VFlagLogicPacked(), 1);
|
VFlagLogicPacked(), 1);
|
||||||
// We can't just add under the module, because we may be inside a generate, begin, etc.
|
// We can't just add under the module, because we may be inside a generate, begin, etc.
|
||||||
// We know a SenItem should be under a SenTree/Always etc, we we'll just hunt upwards
|
// We know a SenItem should be under a SenTree/Always etc, we we'll just hunt upwards
|
||||||
AstNode* addwherep = nodep; // Add to this element's next
|
AstNode* addwherep = nodep; // Add to this element's next
|
||||||
|
@ -151,7 +151,7 @@ private:
|
||||||
}
|
}
|
||||||
addwherep->addNext(newvarp);
|
addwherep->addNext(newvarp);
|
||||||
|
|
||||||
sensp->replaceWith(new AstVarRef (sensp->fileline(), newvarp, false));
|
sensp->replaceWith(new AstVarRef(sensp->fileline(), newvarp, false));
|
||||||
AstAssignW* assignp = new AstAssignW
|
AstAssignW* assignp = new AstAssignW
|
||||||
(sensp->fileline(),
|
(sensp->fileline(),
|
||||||
new AstVarRef(sensp->fileline(), newvarp, true),
|
new AstVarRef(sensp->fileline(), newvarp, true),
|
||||||
|
|
|
@ -76,7 +76,7 @@ public:
|
||||||
}
|
}
|
||||||
T nextp() const { return m_nextp; }
|
T nextp() const { return m_nextp; }
|
||||||
// METHODS
|
// METHODS
|
||||||
void pushBack (V3List<T>& listr, T newp) {
|
void pushBack(V3List<T>& listr, T newp) {
|
||||||
// "this" must be a element inside of *newp
|
// "this" must be a element inside of *newp
|
||||||
// cppcheck-suppress thisSubtraction
|
// cppcheck-suppress thisSubtraction
|
||||||
size_t offset = (size_t)(vluint8_t*)(this) - (size_t)(vluint8_t*)(newp);
|
size_t offset = (size_t)(vluint8_t*)(this) - (size_t)(vluint8_t*)(newp);
|
||||||
|
@ -86,7 +86,7 @@ public:
|
||||||
if (m_prevp) baseToListEnt(m_prevp,offset)->m_nextp = newp;
|
if (m_prevp) baseToListEnt(m_prevp,offset)->m_nextp = newp;
|
||||||
listr.m_tailp = newp;
|
listr.m_tailp = newp;
|
||||||
}
|
}
|
||||||
void pushFront (V3List<T>& listr, T newp) {
|
void pushFront(V3List<T>& listr, T newp) {
|
||||||
// "this" must be a element inside of *newp
|
// "this" must be a element inside of *newp
|
||||||
// cppcheck-suppress thisSubtraction
|
// cppcheck-suppress thisSubtraction
|
||||||
size_t offset = (size_t)(vluint8_t*)(this) - (size_t)(vluint8_t*)(newp);
|
size_t offset = (size_t)(vluint8_t*)(this) - (size_t)(vluint8_t*)(newp);
|
||||||
|
@ -97,7 +97,7 @@ public:
|
||||||
if (!listr.m_tailp) listr.m_tailp = newp;
|
if (!listr.m_tailp) listr.m_tailp = newp;
|
||||||
}
|
}
|
||||||
// Unlink from side
|
// Unlink from side
|
||||||
void unlink (V3List<T>& listr, T oldp) {
|
void unlink(V3List<T>& listr, T oldp) {
|
||||||
// "this" must be a element inside of *oldp
|
// "this" must be a element inside of *oldp
|
||||||
// cppcheck-suppress thisSubtraction
|
// cppcheck-suppress thisSubtraction
|
||||||
size_t offset = (size_t)(vluint8_t*)(this) - (size_t)(vluint8_t*)(oldp);
|
size_t offset = (size_t)(vluint8_t*)(this) - (size_t)(vluint8_t*)(oldp);
|
||||||
|
|
208
src/V3Number.cpp
208
src/V3Number.cpp
|
@ -51,7 +51,7 @@ V3Number::V3Number(VerilogStringLiteral, FileLine* fileline, const string& str)
|
||||||
opCleanThis(true);
|
opCleanThis(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number::V3Number (FileLine* fileline, const char* sourcep) {
|
V3Number::V3Number(FileLine* fileline, const char* sourcep) {
|
||||||
init(fileline, 0);
|
init(fileline, 0);
|
||||||
const char* value_startp = sourcep;
|
const char* value_startp = sourcep;
|
||||||
for (const char* cp=sourcep; *cp; cp++) {
|
for (const char* cp=sourcep; *cp; cp++) {
|
||||||
|
@ -823,7 +823,7 @@ uint32_t V3Number::mostSetBitP1() const {
|
||||||
}
|
}
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
V3Number& V3Number::opBitsNonX (const V3Number& lhs) { // 0/1->1, X/Z->0
|
V3Number& V3Number::opBitsNonX(const V3Number& lhs) { // 0/1->1, X/Z->0
|
||||||
// op i, L(lhs) bit return
|
// op i, L(lhs) bit return
|
||||||
setZero();
|
setZero();
|
||||||
for(int bit=0; bit<this->width(); bit++) {
|
for(int bit=0; bit<this->width(); bit++) {
|
||||||
|
@ -831,7 +831,7 @@ V3Number& V3Number::opBitsNonX (const V3Number& lhs) { // 0/1->1, X/Z->0
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opBitsOne (const V3Number& lhs) { // 1->1, 0/X/Z->0
|
V3Number& V3Number::opBitsOne(const V3Number& lhs) { // 1->1, 0/X/Z->0
|
||||||
// op i, L(lhs) bit return
|
// op i, L(lhs) bit return
|
||||||
setZero();
|
setZero();
|
||||||
for(int bit=0; bit<this->width(); bit++) {
|
for(int bit=0; bit<this->width(); bit++) {
|
||||||
|
@ -839,7 +839,7 @@ V3Number& V3Number::opBitsOne (const V3Number& lhs) { // 1->1, 0/X/Z->0
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opBitsXZ (const V3Number& lhs) { // 0/1->1, X/Z->0
|
V3Number& V3Number::opBitsXZ(const V3Number& lhs) { // 0/1->1, X/Z->0
|
||||||
// op i, L(lhs) bit return
|
// op i, L(lhs) bit return
|
||||||
setZero();
|
setZero();
|
||||||
for(int bit=0; bit<this->width(); bit++) {
|
for(int bit=0; bit<this->width(); bit++) {
|
||||||
|
@ -847,7 +847,7 @@ V3Number& V3Number::opBitsXZ (const V3Number& lhs) { // 0/1->1, X/Z->0
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opBitsZ (const V3Number& lhs) { // 0/1->1, X/Z->0
|
V3Number& V3Number::opBitsZ(const V3Number& lhs) { // 0/1->1, X/Z->0
|
||||||
// op i, L(lhs) bit return
|
// op i, L(lhs) bit return
|
||||||
setZero();
|
setZero();
|
||||||
for(int bit=0; bit<this->width(); bit++) {
|
for(int bit=0; bit<this->width(); bit++) {
|
||||||
|
@ -855,7 +855,7 @@ V3Number& V3Number::opBitsZ (const V3Number& lhs) { // 0/1->1, X/Z->0
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opBitsNonZ (const V3Number& lhs) { // 0/1->1, X/Z->0
|
V3Number& V3Number::opBitsNonZ(const V3Number& lhs) { // 0/1->1, X/Z->0
|
||||||
// op i, L(lhs) bit return
|
// op i, L(lhs) bit return
|
||||||
setZero();
|
setZero();
|
||||||
for(int bit=0; bit<this->width(); bit++) {
|
for(int bit=0; bit<this->width(); bit++) {
|
||||||
|
@ -867,7 +867,7 @@ V3Number& V3Number::opBitsNonZ (const V3Number& lhs) { // 0/1->1, X/Z->0
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// Operators - Simple per-bit logical ops
|
// Operators - Simple per-bit logical ops
|
||||||
|
|
||||||
V3Number& V3Number::opRedOr (const V3Number& lhs) {
|
V3Number& V3Number::opRedOr(const V3Number& lhs) {
|
||||||
// op i, 1 bit return
|
// op i, 1 bit return
|
||||||
char outc = 0;
|
char outc = 0;
|
||||||
for(int bit=0; bit<lhs.width(); bit++) {
|
for(int bit=0; bit<lhs.width(); bit++) {
|
||||||
|
@ -878,7 +878,7 @@ V3Number& V3Number::opRedOr (const V3Number& lhs) {
|
||||||
return setSingleBits(outc);
|
return setSingleBits(outc);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opRedAnd (const V3Number& lhs) {
|
V3Number& V3Number::opRedAnd(const V3Number& lhs) {
|
||||||
// op i, 1 bit return
|
// op i, 1 bit return
|
||||||
char outc = 1;
|
char outc = 1;
|
||||||
for(int bit=0; bit<lhs.width(); bit++) {
|
for(int bit=0; bit<lhs.width(); bit++) {
|
||||||
|
@ -889,7 +889,7 @@ V3Number& V3Number::opRedAnd (const V3Number& lhs) {
|
||||||
return setSingleBits(outc);
|
return setSingleBits(outc);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opRedXor (const V3Number& lhs) {
|
V3Number& V3Number::opRedXor(const V3Number& lhs) {
|
||||||
// op i, 1 bit return
|
// op i, 1 bit return
|
||||||
char outc = 0;
|
char outc = 0;
|
||||||
for(int bit=0; bit<lhs.width(); bit++) {
|
for(int bit=0; bit<lhs.width(); bit++) {
|
||||||
|
@ -900,7 +900,7 @@ V3Number& V3Number::opRedXor (const V3Number& lhs) {
|
||||||
return setSingleBits(outc);
|
return setSingleBits(outc);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opRedXnor (const V3Number& lhs) {
|
V3Number& V3Number::opRedXnor(const V3Number& lhs) {
|
||||||
// op i, 1 bit return
|
// op i, 1 bit return
|
||||||
char outc = 1;
|
char outc = 1;
|
||||||
for(int bit=0; bit<lhs.width(); bit++) {
|
for(int bit=0; bit<lhs.width(); bit++) {
|
||||||
|
@ -911,25 +911,25 @@ V3Number& V3Number::opRedXnor (const V3Number& lhs) {
|
||||||
return setSingleBits(outc);
|
return setSingleBits(outc);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opCountOnes (const V3Number& lhs) {
|
V3Number& V3Number::opCountOnes(const V3Number& lhs) {
|
||||||
if (lhs.isFourState()) return setAllBitsX();
|
if (lhs.isFourState()) return setAllBitsX();
|
||||||
setZero();
|
setZero();
|
||||||
m_value[0] = lhs.countOnes();
|
m_value[0] = lhs.countOnes();
|
||||||
opCleanThis();
|
opCleanThis();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opIsUnknown (const V3Number& lhs) {
|
V3Number& V3Number::opIsUnknown(const V3Number& lhs) {
|
||||||
return setSingleBits(lhs.isUnknown());
|
return setSingleBits(lhs.isUnknown());
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opOneHot (const V3Number& lhs) {
|
V3Number& V3Number::opOneHot(const V3Number& lhs) {
|
||||||
if (lhs.isFourState()) return setAllBitsX();
|
if (lhs.isFourState()) return setAllBitsX();
|
||||||
return setSingleBits(lhs.countOnes()==1);
|
return setSingleBits(lhs.countOnes()==1);
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opOneHot0 (const V3Number& lhs) {
|
V3Number& V3Number::opOneHot0(const V3Number& lhs) {
|
||||||
if (lhs.isFourState()) return setAllBitsX();
|
if (lhs.isFourState()) return setAllBitsX();
|
||||||
return setSingleBits(lhs.countOnes()<=1);
|
return setSingleBits(lhs.countOnes()<=1);
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opCLog2 (const V3Number& lhs) {
|
V3Number& V3Number::opCLog2(const V3Number& lhs) {
|
||||||
if (lhs.isFourState()) return setAllBitsX();
|
if (lhs.isFourState()) return setAllBitsX();
|
||||||
// IE if 4, this algorithm didn't pre-subtract 1, so we need to post-correct now
|
// IE if 4, this algorithm didn't pre-subtract 1, so we need to post-correct now
|
||||||
int adjust = (lhs.countOnes()==1) ? 0 : 1;
|
int adjust = (lhs.countOnes()==1) ? 0 : 1;
|
||||||
|
@ -943,7 +943,7 @@ V3Number& V3Number::opCLog2 (const V3Number& lhs) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opLogNot (const V3Number& lhs) {
|
V3Number& V3Number::opLogNot(const V3Number& lhs) {
|
||||||
// op i, 1 bit return
|
// op i, 1 bit return
|
||||||
char outc = 1;
|
char outc = 1;
|
||||||
for(int bit=0; bit<lhs.width(); bit++) {
|
for(int bit=0; bit<lhs.width(); bit++) {
|
||||||
|
@ -955,7 +955,7 @@ V3Number& V3Number::opLogNot (const V3Number& lhs) {
|
||||||
return setSingleBits(outc);
|
return setSingleBits(outc);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opNot (const V3Number& lhs) {
|
V3Number& V3Number::opNot(const V3Number& lhs) {
|
||||||
// op i, L(lhs) bit return
|
// op i, L(lhs) bit return
|
||||||
setZero();
|
setZero();
|
||||||
for(int bit=0; bit<this->width(); bit++) {
|
for(int bit=0; bit<this->width(); bit++) {
|
||||||
|
@ -965,7 +965,7 @@ V3Number& V3Number::opNot (const V3Number& lhs) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opAnd (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opAnd(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// i op j, max(L(lhs),L(rhs)) bit return, careful need to X/Z extend.
|
// i op j, max(L(lhs),L(rhs)) bit return, careful need to X/Z extend.
|
||||||
setZero();
|
setZero();
|
||||||
for(int bit=0; bit<this->width(); bit++) {
|
for(int bit=0; bit<this->width(); bit++) {
|
||||||
|
@ -976,7 +976,7 @@ V3Number& V3Number::opAnd (const V3Number& lhs, const V3Number& rhs) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opOr (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opOr(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// i op j, max(L(lhs),L(rhs)) bit return, careful need to X/Z extend.
|
// i op j, max(L(lhs),L(rhs)) bit return, careful need to X/Z extend.
|
||||||
setZero();
|
setZero();
|
||||||
for(int bit=0; bit<this->width(); bit++) {
|
for(int bit=0; bit<this->width(); bit++) {
|
||||||
|
@ -987,13 +987,13 @@ V3Number& V3Number::opOr (const V3Number& lhs, const V3Number& rhs) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opChangeXor (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opChangeXor(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// 32 bit result
|
// 32 bit result
|
||||||
opEq(lhs,rhs);
|
opEq(lhs,rhs);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opXor (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opXor(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// i op j, max(L(lhs),L(rhs)) bit return, careful need to X/Z extend.
|
// i op j, max(L(lhs),L(rhs)) bit return, careful need to X/Z extend.
|
||||||
setZero();
|
setZero();
|
||||||
for(int bit=0; bit<this->width(); bit++) {
|
for(int bit=0; bit<this->width(); bit++) {
|
||||||
|
@ -1005,7 +1005,7 @@ V3Number& V3Number::opXor (const V3Number& lhs, const V3Number& rhs) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opXnor (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opXnor(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// i op j, max(L(lhs),L(rhs)) bit return, careful need to X/Z extend.
|
// i op j, max(L(lhs),L(rhs)) bit return, careful need to X/Z extend.
|
||||||
setZero();
|
setZero();
|
||||||
for(int bit=0; bit<this->width(); bit++) {
|
for(int bit=0; bit<this->width(); bit++) {
|
||||||
|
@ -1017,7 +1017,7 @@ V3Number& V3Number::opXnor (const V3Number& lhs, const V3Number& rhs) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opConcat (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opConcat(const V3Number& lhs, const V3Number& rhs) {
|
||||||
setZero();
|
setZero();
|
||||||
// See also error in V3Width
|
// See also error in V3Width
|
||||||
if (!lhs.sized() || !rhs.sized()) {
|
if (!lhs.sized() || !rhs.sized()) {
|
||||||
|
@ -1035,19 +1035,19 @@ V3Number& V3Number::opConcat (const V3Number& lhs, const V3Number& rhs) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opLenN (const V3Number& lhs) {
|
V3Number& V3Number::opLenN(const V3Number& lhs) {
|
||||||
setQuad(lhs.toString().length());
|
setQuad(lhs.toString().length());
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opRepl (const V3Number& lhs, const V3Number& rhs) { // rhs is # of times to replicate
|
V3Number& V3Number::opRepl(const V3Number& lhs, const V3Number& rhs) { // rhs is # of times to replicate
|
||||||
// Hopefully the using routine has a error check too.
|
// Hopefully the using routine has a error check too.
|
||||||
// See also error in V3Width
|
// See also error in V3Width
|
||||||
if (!lhs.sized()) m_fileline->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in replications.");
|
if (!lhs.sized()) m_fileline->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in replications.");
|
||||||
return opRepl(lhs, rhs.toUInt());
|
return opRepl(lhs, rhs.toUInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opRepl (const V3Number& lhs, uint32_t rhsval) { // rhs is # of times to replicate
|
V3Number& V3Number::opRepl(const V3Number& lhs, uint32_t rhsval) { // rhs is # of times to replicate
|
||||||
// i op repl, L(i)*value(rhs) bit return
|
// i op repl, L(i)*value(rhs) bit return
|
||||||
setZero();
|
setZero();
|
||||||
if (rhsval>8192) m_fileline->v3warn(WIDTHCONCAT,"More than a 8k bit replication is probably wrong: "<<rhsval);
|
if (rhsval>8192) m_fileline->v3warn(WIDTHCONCAT,"More than a 8k bit replication is probably wrong: "<<rhsval);
|
||||||
|
@ -1061,7 +1061,7 @@ V3Number& V3Number::opRepl (const V3Number& lhs, uint32_t rhsval) { // rhs is #
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opStreamL (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opStreamL(const V3Number& lhs, const V3Number& rhs) {
|
||||||
setZero();
|
setZero();
|
||||||
// See also error in V3Width
|
// See also error in V3Width
|
||||||
if (!lhs.sized()) {
|
if (!lhs.sized()) {
|
||||||
|
@ -1078,7 +1078,7 @@ V3Number& V3Number::opStreamL (const V3Number& lhs, const V3Number& rhs) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opLogAnd (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opLogAnd(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation
|
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation
|
||||||
char loutc = 0;
|
char loutc = 0;
|
||||||
char routc = 0;
|
char routc = 0;
|
||||||
|
@ -1096,7 +1096,7 @@ V3Number& V3Number::opLogAnd (const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setSingleBits(outc);
|
return setSingleBits(outc);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opLogOr (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opLogOr(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
|
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
|
||||||
char outc = 0;
|
char outc = 0;
|
||||||
for(int bit=0; bit<lhs.width(); bit++) {
|
for(int bit=0; bit<lhs.width(); bit++) {
|
||||||
|
@ -1111,19 +1111,19 @@ last:
|
||||||
return setSingleBits(outc);
|
return setSingleBits(outc);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opLogIf (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opLogIf(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to
|
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to
|
||||||
// X/Z extend. Use opLogNot and opLogOr to do this for us.
|
// X/Z extend. Use opLogNot and opLogOr to do this for us.
|
||||||
return opLogOr(opLogNot(lhs), rhs);
|
return opLogOr(opLogNot(lhs), rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opLogIff (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opLogIff(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to
|
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to
|
||||||
// X/Z extend. Use opLogNot and opLogXor to do this for us.
|
// X/Z extend. Use opLogNot and opLogXor to do this for us.
|
||||||
return opLogNot(opXor(lhs, rhs));
|
return opLogNot(opXor(lhs, rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opEq (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opEq(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
|
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
|
||||||
char outc = 1;
|
char outc = 1;
|
||||||
for (int bit=0; bit < std::max(lhs.width(),rhs.width()); bit++) {
|
for (int bit=0; bit < std::max(lhs.width(),rhs.width()); bit++) {
|
||||||
|
@ -1136,7 +1136,7 @@ last:
|
||||||
return setSingleBits(outc);
|
return setSingleBits(outc);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opNeq (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opNeq(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
|
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
|
||||||
char outc = 0;
|
char outc = 0;
|
||||||
for (int bit=0; bit < std::max(lhs.width(),rhs.width()); bit++) {
|
for (int bit=0; bit < std::max(lhs.width(),rhs.width()); bit++) {
|
||||||
|
@ -1149,7 +1149,7 @@ last:
|
||||||
return setSingleBits(outc);
|
return setSingleBits(outc);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool V3Number::isCaseEq (const V3Number& rhs) const {
|
bool V3Number::isCaseEq(const V3Number& rhs) const {
|
||||||
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
|
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
|
||||||
if (this->width() != rhs.width()) return false;
|
if (this->width() != rhs.width()) return false;
|
||||||
for (int bit=0; bit < std::max(this->width(),rhs.width()); bit++) {
|
for (int bit=0; bit < std::max(this->width(),rhs.width()); bit++) {
|
||||||
|
@ -1158,11 +1158,11 @@ bool V3Number::isCaseEq (const V3Number& rhs) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opCaseEq (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opCaseEq(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setSingleBits(lhs.isCaseEq(rhs) ? 1:0);
|
return setSingleBits(lhs.isCaseEq(rhs) ? 1:0);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opCaseNeq (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opCaseNeq(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
|
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
|
||||||
char outc = 0;
|
char outc = 0;
|
||||||
for (int bit=0; bit < std::max(lhs.width(),rhs.width()); bit++) {
|
for (int bit=0; bit < std::max(lhs.width(),rhs.width()); bit++) {
|
||||||
|
@ -1172,7 +1172,7 @@ last:
|
||||||
return setSingleBits(outc);
|
return setSingleBits(outc);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opWildEq (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opWildEq(const V3Number& lhs, const V3Number& rhs) {
|
||||||
char outc = 1;
|
char outc = 1;
|
||||||
for (int bit=0; bit < std::max(lhs.width(),rhs.width()); bit++) {
|
for (int bit=0; bit < std::max(lhs.width(),rhs.width()); bit++) {
|
||||||
if (!rhs.bitIsXZ(bit)
|
if (!rhs.bitIsXZ(bit)
|
||||||
|
@ -1183,7 +1183,7 @@ last:
|
||||||
return setSingleBits(outc);
|
return setSingleBits(outc);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opWildNeq (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opWildNeq(const V3Number& lhs, const V3Number& rhs) {
|
||||||
char outc = 0;
|
char outc = 0;
|
||||||
for (int bit=0; bit < std::max(lhs.width(),rhs.width()); bit++) {
|
for (int bit=0; bit < std::max(lhs.width(),rhs.width()); bit++) {
|
||||||
if (!rhs.bitIsXZ(bit)
|
if (!rhs.bitIsXZ(bit)
|
||||||
|
@ -1194,7 +1194,7 @@ last:
|
||||||
return setSingleBits(outc);
|
return setSingleBits(outc);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opGt (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opGt(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
|
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
|
||||||
char outc = 0;
|
char outc = 0;
|
||||||
for (int bit=0; bit < std::max(lhs.width(),rhs.width()); bit++) {
|
for (int bit=0; bit < std::max(lhs.width(),rhs.width()); bit++) {
|
||||||
|
@ -1206,7 +1206,7 @@ V3Number& V3Number::opGt (const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setSingleBits(outc);
|
return setSingleBits(outc);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opGtS (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opGtS(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
|
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
|
||||||
char outc = 0;
|
char outc = 0;
|
||||||
{
|
{
|
||||||
|
@ -1228,34 +1228,34 @@ V3Number& V3Number::opGtS (const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setSingleBits(outc);
|
return setSingleBits(outc);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opGte (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opGte(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
|
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
|
||||||
V3Number& eq = opEq (lhs,rhs);
|
V3Number& eq = opEq(lhs,rhs);
|
||||||
if (eq.isNeqZero()) return eq; // Return true
|
if (eq.isNeqZero()) return eq; // Return true
|
||||||
return opGt (lhs,rhs);
|
return opGt(lhs,rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opGteS (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opGteS(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
|
// i op j, 1 bit return, max(L(lhs),L(rhs)) calculation, careful need to X/Z extend.
|
||||||
V3Number& eq = opEq (lhs,rhs);
|
V3Number& eq = opEq(lhs,rhs);
|
||||||
if (eq.isNeqZero()) return eq; // Return true
|
if (eq.isNeqZero()) return eq; // Return true
|
||||||
return opGtS (lhs,rhs);
|
return opGtS(lhs,rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opLt (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opLt(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return opGt(rhs,lhs);
|
return opGt(rhs,lhs);
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opLte (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opLte(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return opGte(rhs,lhs);
|
return opGte(rhs,lhs);
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opLtS (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opLtS(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return opGtS(rhs,lhs);
|
return opGtS(rhs,lhs);
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opLteS (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opLteS(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return opGteS(rhs,lhs);
|
return opGteS(rhs,lhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opRotR (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opRotR(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// L(lhs) bit return
|
// L(lhs) bit return
|
||||||
if (rhs.isFourState()) return setAllBitsX();
|
if (rhs.isFourState()) return setAllBitsX();
|
||||||
setZero();
|
setZero();
|
||||||
|
@ -1266,7 +1266,7 @@ V3Number& V3Number::opRotR (const V3Number& lhs, const V3Number& rhs) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opRotL (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opRotL(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// L(lhs) bit return
|
// L(lhs) bit return
|
||||||
if (rhs.isFourState()) return setAllBitsX();
|
if (rhs.isFourState()) return setAllBitsX();
|
||||||
setZero();
|
setZero();
|
||||||
|
@ -1279,7 +1279,7 @@ V3Number& V3Number::opRotL (const V3Number& lhs, const V3Number& rhs) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opShiftR (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opShiftR(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// L(lhs) bit return
|
// L(lhs) bit return
|
||||||
if (rhs.isFourState()) return setAllBitsX();
|
if (rhs.isFourState()) return setAllBitsX();
|
||||||
setZero();
|
setZero();
|
||||||
|
@ -1295,7 +1295,7 @@ V3Number& V3Number::opShiftR (const V3Number& lhs, const V3Number& rhs) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opShiftRS (const V3Number& lhs, const V3Number& rhs, uint32_t lbits) {
|
V3Number& V3Number::opShiftRS(const V3Number& lhs, const V3Number& rhs, uint32_t lbits) {
|
||||||
// L(lhs) bit return
|
// L(lhs) bit return
|
||||||
// The spec says a unsigned >>> still acts as a normal >>.
|
// The spec says a unsigned >>> still acts as a normal >>.
|
||||||
// We presume it is signed; as that's V3Width's job to convert to opShiftR
|
// We presume it is signed; as that's V3Width's job to convert to opShiftR
|
||||||
|
@ -1321,7 +1321,7 @@ V3Number& V3Number::opShiftRS (const V3Number& lhs, const V3Number& rhs, uint32_
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opShiftL (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opShiftL(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// L(lhs) bit return
|
// L(lhs) bit return
|
||||||
if (rhs.isFourState()) return setAllBitsX();
|
if (rhs.isFourState()) return setAllBitsX();
|
||||||
setZero();
|
setZero();
|
||||||
|
@ -1340,7 +1340,7 @@ V3Number& V3Number::opShiftL (const V3Number& lhs, const V3Number& rhs) {
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// Ops - Arithmetic
|
// Ops - Arithmetic
|
||||||
|
|
||||||
V3Number& V3Number::opAbsS (const V3Number& lhs) {
|
V3Number& V3Number::opAbsS(const V3Number& lhs) {
|
||||||
// op i, L(lhs) bit return
|
// op i, L(lhs) bit return
|
||||||
if (lhs.isFourState()) return setAllBitsX();
|
if (lhs.isFourState()) return setAllBitsX();
|
||||||
if (lhs.isNegative()) {
|
if (lhs.isNegative()) {
|
||||||
|
@ -1349,7 +1349,7 @@ V3Number& V3Number::opAbsS (const V3Number& lhs) {
|
||||||
return opAssign(lhs);
|
return opAssign(lhs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opNegate (const V3Number& lhs) {
|
V3Number& V3Number::opNegate(const V3Number& lhs) {
|
||||||
// op i, L(lhs) bit return
|
// op i, L(lhs) bit return
|
||||||
if (lhs.isFourState()) return setAllBitsX();
|
if (lhs.isFourState()) return setAllBitsX();
|
||||||
V3Number notlhs (lhs.m_fileline, width());
|
V3Number notlhs (lhs.m_fileline, width());
|
||||||
|
@ -1358,7 +1358,7 @@ V3Number& V3Number::opNegate (const V3Number& lhs) {
|
||||||
opAdd(notlhs,one);
|
opAdd(notlhs,one);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opAdd (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opAdd(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return
|
// i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return
|
||||||
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
||||||
setZero();
|
setZero();
|
||||||
|
@ -1373,14 +1373,14 @@ V3Number& V3Number::opAdd (const V3Number& lhs, const V3Number& rhs) {
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opSub (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opSub(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return
|
// i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return
|
||||||
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
||||||
V3Number negrhs (rhs.m_fileline, rhs.width());
|
V3Number negrhs (rhs.m_fileline, rhs.width());
|
||||||
negrhs.opNegate(rhs);
|
negrhs.opNegate(rhs);
|
||||||
return opAdd(lhs, negrhs);
|
return opAdd(lhs, negrhs);
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opMul (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opMul(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return
|
// i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return
|
||||||
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
||||||
setZero();
|
setZero();
|
||||||
|
@ -1402,7 +1402,7 @@ V3Number& V3Number::opMul (const V3Number& lhs, const V3Number& rhs) {
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opMulS (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opMulS(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// Signed multiply
|
// Signed multiply
|
||||||
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
||||||
V3Number lhsNoSign = lhs; if (lhs.isNegative()) lhsNoSign.opNegate(lhs);
|
V3Number lhsNoSign = lhs; if (lhs.isNegative()) lhsNoSign.opNegate(lhs);
|
||||||
|
@ -1416,7 +1416,7 @@ V3Number& V3Number::opMulS (const V3Number& lhs, const V3Number& rhs) {
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opDiv (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opDiv(const V3Number& lhs, const V3Number& rhs) {
|
||||||
UINFO(9, "opdiv "<<lhs<<" "<<rhs<<endl);
|
UINFO(9, "opdiv "<<lhs<<" "<<rhs<<endl);
|
||||||
// i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return
|
// i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return
|
||||||
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
||||||
|
@ -1429,7 +1429,7 @@ V3Number& V3Number::opDiv (const V3Number& lhs, const V3Number& rhs) {
|
||||||
return opModDivGuts(lhs,rhs,false);
|
return opModDivGuts(lhs,rhs,false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opDivS (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opDivS(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// Signed divide
|
// Signed divide
|
||||||
//UINFO(9, ">>divs-start "<<lhs<<" "<<rhs<<endl);
|
//UINFO(9, ">>divs-start "<<lhs<<" "<<rhs<<endl);
|
||||||
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
||||||
|
@ -1447,7 +1447,7 @@ V3Number& V3Number::opDivS (const V3Number& lhs, const V3Number& rhs) {
|
||||||
UINFO(9, " <divs-out "<<lhs<<" "<<rhs<<" ="<<*this<<endl);
|
UINFO(9, " <divs-out "<<lhs<<" "<<rhs<<" ="<<*this<<endl);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opModDiv (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opModDiv(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return
|
// i op j, max(L(lhs),L(rhs)) bit return, if any 4-state, 4-state return
|
||||||
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
||||||
if (rhs.isEqZero()) return setAllBitsXRemoved();
|
if (rhs.isEqZero()) return setAllBitsXRemoved();
|
||||||
|
@ -1459,7 +1459,7 @@ V3Number& V3Number::opModDiv (const V3Number& lhs, const V3Number& rhs) {
|
||||||
return opModDivGuts(lhs,rhs,true);
|
return opModDivGuts(lhs,rhs,true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opModDivS (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opModDivS(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// Signed moddiv
|
// Signed moddiv
|
||||||
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
||||||
if (rhs.isEqZero()) return setAllBitsXRemoved();
|
if (rhs.isEqZero()) return setAllBitsXRemoved();
|
||||||
|
@ -1592,7 +1592,7 @@ V3Number& V3Number::opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opPow (const V3Number& lhs, const V3Number& rhs, bool lsign, bool rsign) {
|
V3Number& V3Number::opPow(const V3Number& lhs, const V3Number& rhs, bool lsign, bool rsign) {
|
||||||
// L(i) bit return, if any 4-state, 4-state return
|
// L(i) bit return, if any 4-state, 4-state return
|
||||||
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
||||||
if (rhs.isEqZero()) return setQuad(1); // Overrides lhs 0 -> return 0
|
if (rhs.isEqZero()) return setQuad(1); // Overrides lhs 0 -> return 0
|
||||||
|
@ -1623,17 +1623,17 @@ V3Number& V3Number::opPow (const V3Number& lhs, const V3Number& rhs, bool lsign,
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opPowSU (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opPowSU(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return opPow(lhs,rhs,true,false);
|
return opPow(lhs,rhs,true,false);
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opPowSS (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opPowSS(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return opPow(lhs,rhs,true,true);
|
return opPow(lhs,rhs,true,true);
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opPowUS (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opPowUS(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return opPow(lhs,rhs,false,true);
|
return opPow(lhs,rhs,false,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opBufIf1 (const V3Number& ens, const V3Number& if1s) {
|
V3Number& V3Number::opBufIf1(const V3Number& ens, const V3Number& if1s) {
|
||||||
setZero();
|
setZero();
|
||||||
for(int bit=0; bit<this->width(); bit++) {
|
for(int bit=0; bit<this->width(); bit++) {
|
||||||
if (ens.bitIs1(bit)) { setBit(bit, if1s.bitIs(bit)); }
|
if (ens.bitIs1(bit)) { setBit(bit, if1s.bitIs(bit)); }
|
||||||
|
@ -1642,7 +1642,7 @@ V3Number& V3Number::opBufIf1 (const V3Number& ens, const V3Number& if1s) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opAssign (const V3Number& lhs) {
|
V3Number& V3Number::opAssign(const V3Number& lhs) {
|
||||||
// Note may be a width change during the assign
|
// Note may be a width change during the assign
|
||||||
setZero();
|
setZero();
|
||||||
for(int bit=0; bit<this->width(); bit++) {
|
for(int bit=0; bit<this->width(); bit++) {
|
||||||
|
@ -1651,7 +1651,7 @@ V3Number& V3Number::opAssign (const V3Number& lhs) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opExtendS (const V3Number& lhs, uint32_t lbits) {
|
V3Number& V3Number::opExtendS(const V3Number& lhs, uint32_t lbits) {
|
||||||
// Note may be a width change during the sign extension
|
// Note may be a width change during the sign extension
|
||||||
setZero();
|
setZero();
|
||||||
for(int bit=0; bit<this->width(); bit++) {
|
for(int bit=0; bit<this->width(); bit++) {
|
||||||
|
@ -1660,7 +1660,7 @@ V3Number& V3Number::opExtendS (const V3Number& lhs, uint32_t lbits) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opClean (const V3Number& lhs, uint32_t bits) {
|
V3Number& V3Number::opClean(const V3Number& lhs, uint32_t bits) {
|
||||||
return opSel(lhs, bits-1, 0);
|
return opSel(lhs, bits-1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1676,12 +1676,12 @@ void V3Number::opCleanThis(bool warnOnTruncation) {
|
||||||
m_valueX[words()-1] = newValueXMsb;
|
m_valueX[words()-1] = newValueXMsb;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opSel (const V3Number& lhs, const V3Number& msb, const V3Number& lsb) {
|
V3Number& V3Number::opSel(const V3Number& lhs, const V3Number& msb, const V3Number& lsb) {
|
||||||
if (lsb.isFourState() || msb.isFourState()) return setAllBitsX();
|
if (lsb.isFourState() || msb.isFourState()) return setAllBitsX();
|
||||||
return opSel(lhs, msb.toUInt(), lsb.toUInt());
|
return opSel(lhs, msb.toUInt(), lsb.toUInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opSel (const V3Number& lhs, uint32_t msbval, uint32_t lsbval) {
|
V3Number& V3Number::opSel(const V3Number& lhs, uint32_t msbval, uint32_t lsbval) {
|
||||||
setZero();
|
setZero();
|
||||||
int ibit=lsbval;
|
int ibit=lsbval;
|
||||||
for(int bit=0; bit<this->width(); bit++) {
|
for(int bit=0; bit<this->width(); bit++) {
|
||||||
|
@ -1697,11 +1697,11 @@ V3Number& V3Number::opSel (const V3Number& lhs, uint32_t msbval, uint32_t lsbval
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opSelInto (const V3Number& lhs, const V3Number& lsb, int width) {
|
V3Number& V3Number::opSelInto(const V3Number& lhs, const V3Number& lsb, int width) {
|
||||||
return opSelInto(lhs, lsb.toSInt(), width);
|
return opSelInto(lhs, lsb.toSInt(), width);
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opSelInto (const V3Number& lhs, int lsbval, int width) {
|
V3Number& V3Number::opSelInto(const V3Number& lhs, int lsbval, int width) {
|
||||||
// this[lsbval+width-1 : lsbval] = lhs; Other bits of this are not affected
|
// this[lsbval+width-1 : lsbval] = lhs; Other bits of this are not affected
|
||||||
int ibit=0;
|
int ibit=0;
|
||||||
for(int bit=lsbval; bit<lsbval+width; bit++) {
|
for(int bit=lsbval; bit<lsbval+width; bit++) {
|
||||||
|
@ -1715,7 +1715,7 @@ V3Number& V3Number::opSelInto (const V3Number& lhs, int lsbval, int width) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
V3Number& V3Number::opCond (const V3Number& lhs, const V3Number& if1s, const V3Number& if0s) {
|
V3Number& V3Number::opCond(const V3Number& lhs, const V3Number& if1s, const V3Number& if0s) {
|
||||||
V3Number lhstrue (lhs.m_fileline); lhstrue.opRedOr(lhs);
|
V3Number lhstrue (lhs.m_fileline); lhstrue.opRedOr(lhs);
|
||||||
if (lhstrue.bitIs0(0)) {
|
if (lhstrue.bitIs0(0)) {
|
||||||
this->opAssign(if0s);
|
this->opAssign(if0s);
|
||||||
|
@ -1737,20 +1737,20 @@ V3Number& V3Number::opCond (const V3Number& lhs, const V3Number& if1s, const V3
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// Ops - Floating point
|
// Ops - Floating point
|
||||||
|
|
||||||
V3Number& V3Number::opIToRD (const V3Number& lhs) {
|
V3Number& V3Number::opIToRD(const V3Number& lhs) {
|
||||||
return setDouble(lhs.toSInt());
|
return setDouble(lhs.toSInt());
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opRToIS (const V3Number& lhs) {
|
V3Number& V3Number::opRToIS(const V3Number& lhs) {
|
||||||
double v = VL_TRUNC(lhs.toDouble());
|
double v = VL_TRUNC(lhs.toDouble());
|
||||||
vlsint32_t i = (vlsint32_t)v; // C converts from double to vlsint32
|
vlsint32_t i = (vlsint32_t)v; // C converts from double to vlsint32
|
||||||
return setLongS(i);
|
return setLongS(i);
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opRToIRoundS (const V3Number& lhs) {
|
V3Number& V3Number::opRToIRoundS(const V3Number& lhs) {
|
||||||
double v = VL_ROUND(lhs.toDouble());
|
double v = VL_ROUND(lhs.toDouble());
|
||||||
vlsint32_t i = (vlsint32_t)v; // C converts from double to vlsint32
|
vlsint32_t i = (vlsint32_t)v; // C converts from double to vlsint32
|
||||||
return setLongS(i);
|
return setLongS(i);
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opRealToBits (const V3Number& lhs) {
|
V3Number& V3Number::opRealToBits(const V3Number& lhs) {
|
||||||
// Conveniently our internal format is identical so we can copy bits...
|
// Conveniently our internal format is identical so we can copy bits...
|
||||||
if (lhs.width()!=64 || this->width()!=64) {
|
if (lhs.width()!=64 || this->width()!=64) {
|
||||||
m_fileline->v3fatalSrc("Real operation on wrong sized number");
|
m_fileline->v3fatalSrc("Real operation on wrong sized number");
|
||||||
|
@ -1759,7 +1759,7 @@ V3Number& V3Number::opRealToBits (const V3Number& lhs) {
|
||||||
m_double = false;
|
m_double = false;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opBitsToRealD (const V3Number& lhs) {
|
V3Number& V3Number::opBitsToRealD(const V3Number& lhs) {
|
||||||
// Conveniently our internal format is identical so we can copy bits...
|
// Conveniently our internal format is identical so we can copy bits...
|
||||||
if (lhs.width()!=64 || this->width()!=64) {
|
if (lhs.width()!=64 || this->width()!=64) {
|
||||||
m_fileline->v3fatalSrc("Real operation on wrong sized number");
|
m_fileline->v3fatalSrc("Real operation on wrong sized number");
|
||||||
|
@ -1768,78 +1768,78 @@ V3Number& V3Number::opBitsToRealD (const V3Number& lhs) {
|
||||||
m_double = true;
|
m_double = true;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opNegateD (const V3Number& lhs) {
|
V3Number& V3Number::opNegateD(const V3Number& lhs) {
|
||||||
return setDouble(- lhs.toDouble());
|
return setDouble(- lhs.toDouble());
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opAddD (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opAddD(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setDouble(lhs.toDouble() + rhs.toDouble());
|
return setDouble(lhs.toDouble() + rhs.toDouble());
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opSubD (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opSubD(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setDouble(lhs.toDouble() - rhs.toDouble());
|
return setDouble(lhs.toDouble() - rhs.toDouble());
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opMulD (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opMulD(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setDouble(lhs.toDouble() * rhs.toDouble());
|
return setDouble(lhs.toDouble() * rhs.toDouble());
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opDivD (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opDivD(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// On exceptions, we just generate 'inf' through floating point
|
// On exceptions, we just generate 'inf' through floating point
|
||||||
// IEEE says it's implementation defined what happens
|
// IEEE says it's implementation defined what happens
|
||||||
return setDouble(lhs.toDouble() / rhs.toDouble());
|
return setDouble(lhs.toDouble() / rhs.toDouble());
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opPowD (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opPowD(const V3Number& lhs, const V3Number& rhs) {
|
||||||
// On exceptions, we just generate 'inf' through floating point
|
// On exceptions, we just generate 'inf' through floating point
|
||||||
// IEEE says it's implementation defined what happens
|
// IEEE says it's implementation defined what happens
|
||||||
return setDouble(pow(lhs.toDouble(), rhs.toDouble()));
|
return setDouble(pow(lhs.toDouble(), rhs.toDouble()));
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opEqD (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opEqD(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setSingleBits(lhs.toDouble() == rhs.toDouble());
|
return setSingleBits(lhs.toDouble() == rhs.toDouble());
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opNeqD (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opNeqD(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setSingleBits(lhs.toDouble() != rhs.toDouble());
|
return setSingleBits(lhs.toDouble() != rhs.toDouble());
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opGtD (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opGtD(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setSingleBits(lhs.toDouble() > rhs.toDouble());
|
return setSingleBits(lhs.toDouble() > rhs.toDouble());
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opGteD (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opGteD(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setSingleBits(lhs.toDouble() >= rhs.toDouble());
|
return setSingleBits(lhs.toDouble() >= rhs.toDouble());
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opLtD (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opLtD(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setSingleBits(lhs.toDouble() < rhs.toDouble());
|
return setSingleBits(lhs.toDouble() < rhs.toDouble());
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opLteD (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opLteD(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setSingleBits(lhs.toDouble() <= rhs.toDouble());
|
return setSingleBits(lhs.toDouble() <= rhs.toDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// Ops - String
|
// Ops - String
|
||||||
|
|
||||||
V3Number& V3Number::opConcatN (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opConcatN(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setString(lhs.toString() + rhs.toString());
|
return setString(lhs.toString() + rhs.toString());
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opReplN (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opReplN(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return opReplN(lhs, rhs.toUInt());
|
return opReplN(lhs, rhs.toUInt());
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opReplN (const V3Number& lhs, uint32_t rhsval) {
|
V3Number& V3Number::opReplN(const V3Number& lhs, uint32_t rhsval) {
|
||||||
string out; out.reserve(lhs.toString().length() * rhsval);
|
string out; out.reserve(lhs.toString().length() * rhsval);
|
||||||
for (unsigned times=0; times<rhsval; times++) {
|
for (unsigned times=0; times<rhsval; times++) {
|
||||||
out += lhs.toString();
|
out += lhs.toString();
|
||||||
}
|
}
|
||||||
return setString(out);
|
return setString(out);
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opEqN (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opEqN(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setSingleBits(lhs.toString() == rhs.toString());
|
return setSingleBits(lhs.toString() == rhs.toString());
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opNeqN (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opNeqN(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setSingleBits(lhs.toString() != rhs.toString());
|
return setSingleBits(lhs.toString() != rhs.toString());
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opGtN (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opGtN(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setSingleBits(lhs.toString() > rhs.toString());
|
return setSingleBits(lhs.toString() > rhs.toString());
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opGteN (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opGteN(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setSingleBits(lhs.toString() >= rhs.toString());
|
return setSingleBits(lhs.toString() >= rhs.toString());
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opLtN (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opLtN(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setSingleBits(lhs.toString() < rhs.toString());
|
return setSingleBits(lhs.toString() < rhs.toString());
|
||||||
}
|
}
|
||||||
V3Number& V3Number::opLteN (const V3Number& lhs, const V3Number& rhs) {
|
V3Number& V3Number::opLteN(const V3Number& lhs, const V3Number& rhs) {
|
||||||
return setSingleBits(lhs.toString() <= rhs.toString());
|
return setSingleBits(lhs.toString() <= rhs.toString());
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ public:
|
||||||
V3Number& setLong(uint32_t value);
|
V3Number& setLong(uint32_t value);
|
||||||
V3Number& setLongS(vlsint32_t value);
|
V3Number& setLongS(vlsint32_t value);
|
||||||
V3Number& setDouble(double value);
|
V3Number& setDouble(double value);
|
||||||
void setBit (int bit, char value) { // Note must be pre-zeroed!
|
void setBit(int bit, char value) { // Note must be pre-zeroed!
|
||||||
if (bit>=m_width) return;
|
if (bit>=m_width) return;
|
||||||
uint32_t mask = (1UL<<(bit&31));
|
uint32_t mask = (1UL<<(bit&31));
|
||||||
if (value=='0' || value==0) {
|
if (value=='0' || value==0) {
|
||||||
|
@ -72,14 +72,14 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
char bitIs (int bit) const {
|
char bitIs(int bit) const {
|
||||||
if (bit>=m_width || bit<0) {
|
if (bit>=m_width || bit<0) {
|
||||||
// We never sign extend
|
// We never sign extend
|
||||||
return '0';
|
return '0';
|
||||||
}
|
}
|
||||||
return ( "01zx"[(((m_value[bit/32] & (1UL<<(bit&31)))?1:0)
|
return ( "01zx"[(((m_value[bit/32] & (1UL<<(bit&31)))?1:0)
|
||||||
| ((m_valueX[bit/32] & (1UL<<(bit&31)))?2:0))] ); }
|
| ((m_valueX[bit/32] & (1UL<<(bit&31)))?2:0))] ); }
|
||||||
char bitIsExtend (int bit, int lbits) const {
|
char bitIsExtend(int bit, int lbits) const {
|
||||||
// lbits usually = width, but for C optimizations width=32_bits, lbits = 32_or_less
|
// lbits usually = width, but for C optimizations width=32_bits, lbits = 32_or_less
|
||||||
if (bit<0) return '0';
|
if (bit<0) return '0';
|
||||||
UASSERT(lbits<=m_width, "Extend of wrong size");
|
UASSERT(lbits<=m_width, "Extend of wrong size");
|
||||||
|
@ -91,19 +91,19 @@ private:
|
||||||
}
|
}
|
||||||
return ( "01zx"[(((m_value[bit/32] & (1UL<<(bit&31)))?1:0)
|
return ( "01zx"[(((m_value[bit/32] & (1UL<<(bit&31)))?1:0)
|
||||||
| ((m_valueX[bit/32] & (1UL<<(bit&31)))?2:0))] ); }
|
| ((m_valueX[bit/32] & (1UL<<(bit&31)))?2:0))] ); }
|
||||||
bool bitIs0 (int bit) const {
|
bool bitIs0(int bit) const {
|
||||||
if (bit<0) return false;
|
if (bit<0) return false;
|
||||||
if (bit>=m_width) return !bitIsXZ(m_width-1);
|
if (bit>=m_width) return !bitIsXZ(m_width-1);
|
||||||
return ( (m_value[bit/32] & (1UL<<(bit&31)))==0 && !(m_valueX[bit/32] & (1UL<<(bit&31))) ); }
|
return ( (m_value[bit/32] & (1UL<<(bit&31)))==0 && !(m_valueX[bit/32] & (1UL<<(bit&31))) ); }
|
||||||
bool bitIs1 (int bit) const {
|
bool bitIs1(int bit) const {
|
||||||
if (bit<0) return false;
|
if (bit<0) return false;
|
||||||
if (bit>=m_width) return false;
|
if (bit>=m_width) return false;
|
||||||
return ( (m_value[bit/32] & (1UL<<(bit&31))) && !(m_valueX[bit/32] & (1UL<<(bit&31))) ); }
|
return ( (m_value[bit/32] & (1UL<<(bit&31))) && !(m_valueX[bit/32] & (1UL<<(bit&31))) ); }
|
||||||
bool bitIs1Extend (int bit) const {
|
bool bitIs1Extend(int bit) const {
|
||||||
if (bit<0) return false;
|
if (bit<0) return false;
|
||||||
if (bit>=m_width) return bitIs1Extend(m_width-1);
|
if (bit>=m_width) return bitIs1Extend(m_width-1);
|
||||||
return ( (m_value[bit/32] & (1UL<<(bit&31))) && !(m_valueX[bit/32] & (1UL<<(bit&31))) ); }
|
return ( (m_value[bit/32] & (1UL<<(bit&31))) && !(m_valueX[bit/32] & (1UL<<(bit&31))) ); }
|
||||||
bool bitIsX (int bit) const {
|
bool bitIsX(int bit) const {
|
||||||
if (bit<0) return false;
|
if (bit<0) return false;
|
||||||
if (bit>=m_width) return bitIsZ(m_width-1);
|
if (bit>=m_width) return bitIsZ(m_width-1);
|
||||||
return ( (m_value[bit/32] & (1UL<<(bit&31))) && (m_valueX[bit/32] & (1UL<<(bit&31))) ); }
|
return ( (m_value[bit/32] & (1UL<<(bit&31))) && (m_valueX[bit/32] & (1UL<<(bit&31))) ); }
|
||||||
|
@ -112,7 +112,7 @@ private:
|
||||||
if (bit>=m_width) return bitIsXZ(m_width-1);
|
if (bit>=m_width) return bitIsXZ(m_width-1);
|
||||||
return ( (m_valueX[bit/32] & (1UL<<(bit&31))));
|
return ( (m_valueX[bit/32] & (1UL<<(bit&31))));
|
||||||
}
|
}
|
||||||
bool bitIsZ (int bit) const {
|
bool bitIsZ(int bit) const {
|
||||||
if (bit<0) return false;
|
if (bit<0) return false;
|
||||||
if (bit>=m_width) return bitIsZ(m_width-1);
|
if (bit>=m_width) return bitIsZ(m_width-1);
|
||||||
return ( (~m_value[bit/32] & (1UL<<(bit&31))) && (m_valueX[bit/32] & (1UL<<(bit&31))) ); }
|
return ( (~m_value[bit/32] & (1UL<<(bit&31))) && (m_valueX[bit/32] & (1UL<<(bit&31))) ); }
|
||||||
|
|
|
@ -37,8 +37,8 @@ void test(const string& lhss, const string& op, const string& rhss, const string
|
||||||
char* r1 = strdup(rhss.c_str());
|
char* r1 = strdup(rhss.c_str());
|
||||||
char* e1 = strdup(exps.c_str());
|
char* e1 = strdup(exps.c_str());
|
||||||
|
|
||||||
V3Number lhnum (new FileLine ("ck",__LINE__), l1);
|
V3Number lhnum (new FileLine("ck",__LINE__), l1);
|
||||||
V3Number rhnum (new FileLine ("ck",__LINE__), r1);
|
V3Number rhnum (new FileLine("ck",__LINE__), r1);
|
||||||
V3Number expnum (new FileLine("ck",__LINE__), e1);
|
V3Number expnum (new FileLine("ck",__LINE__), e1);
|
||||||
|
|
||||||
V3Number gotnum (new FileLine("ck",__LINE__), expnum.width());
|
V3Number gotnum (new FileLine("ck",__LINE__), expnum.width());
|
||||||
|
|
|
@ -245,7 +245,7 @@ string V3Options::allArgsString() {
|
||||||
//######################################################################
|
//######################################################################
|
||||||
// V3LangCode class functions
|
// V3LangCode class functions
|
||||||
|
|
||||||
V3LangCode::V3LangCode (const char* textp) {
|
V3LangCode::V3LangCode(const char* textp) {
|
||||||
// Return code for given string, or ERROR, which is a bad code
|
// Return code for given string, or ERROR, which is a bad code
|
||||||
for (int codei=V3LangCode::L_ERROR; codei<V3LangCode::_ENUM_END; ++codei) {
|
for (int codei=V3LangCode::L_ERROR; codei<V3LangCode::_ENUM_END; ++codei) {
|
||||||
V3LangCode code = (V3LangCode)codei;
|
V3LangCode code = (V3LangCode)codei;
|
||||||
|
@ -286,7 +286,7 @@ void V3Options::fileNfsFlush(const string& filename) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string V3Options::fileExists (const string& filename) {
|
string V3Options::fileExists(const string& filename) {
|
||||||
// Surprisingly, for VCS and other simulators, this process
|
// Surprisingly, for VCS and other simulators, this process
|
||||||
// is quite slow; presumably because of re-reading each directory
|
// is quite slow; presumably because of re-reading each directory
|
||||||
// many times. So we read a whole dir at once and cache it
|
// many times. So we read a whole dir at once and cache it
|
||||||
|
@ -317,7 +317,7 @@ string V3Options::fileExists (const string& filename) {
|
||||||
return ""; // Not found
|
return ""; // Not found
|
||||||
}
|
}
|
||||||
// Check if it is a directory, ignore if so
|
// Check if it is a directory, ignore if so
|
||||||
string filenameOut = V3Os::filenameFromDirBase (dir, basename);
|
string filenameOut = V3Os::filenameFromDirBase(dir, basename);
|
||||||
if (!fileStatNormal(filenameOut)) return ""; // Directory
|
if (!fileStatNormal(filenameOut)) return ""; // Directory
|
||||||
return filenameOut;
|
return filenameOut;
|
||||||
}
|
}
|
||||||
|
@ -335,8 +335,8 @@ string V3Options::filePathCheckOneDir(const string& modname, const string& dirna
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
string V3Options::filePath (FileLine* fl, const string& modname, const string& lastpath,
|
string V3Options::filePath(FileLine* fl, const string& modname, const string& lastpath,
|
||||||
const string& errmsg) { // Error prefix or "" to suppress error
|
const string& errmsg) { // Error prefix or "" to suppress error
|
||||||
// Find a filename to read the specified module name,
|
// Find a filename to read the specified module name,
|
||||||
// using the incdir and libext's.
|
// using the incdir and libext's.
|
||||||
// Return "" if not found.
|
// Return "" if not found.
|
||||||
|
@ -533,7 +533,7 @@ void V3Options::throwSigsegv() {
|
||||||
//######################################################################
|
//######################################################################
|
||||||
// V3 Options utilities
|
// V3 Options utilities
|
||||||
|
|
||||||
string V3Options::argString (int argc, char** argv) {
|
string V3Options::argString(int argc, char** argv) {
|
||||||
// Return list of arguments as simple string
|
// Return list of arguments as simple string
|
||||||
string opts;
|
string opts;
|
||||||
for (int i=0; i<argc; ++i) {
|
for (int i=0; i<argc; ++i) {
|
||||||
|
@ -546,10 +546,10 @@ string V3Options::argString (int argc, char** argv) {
|
||||||
//######################################################################
|
//######################################################################
|
||||||
// V3 Options Parsing
|
// V3 Options Parsing
|
||||||
|
|
||||||
void V3Options::parseOpts (FileLine* fl, int argc, char** argv) {
|
void V3Options::parseOpts(FileLine* fl, int argc, char** argv) {
|
||||||
// Parse all options
|
// Parse all options
|
||||||
// Inital entry point from Verilator.cpp
|
// Inital entry point from Verilator.cpp
|
||||||
parseOptsList (fl, ".", argc, argv);
|
parseOptsList(fl, ".", argc, argv);
|
||||||
|
|
||||||
// Default certain options and error check
|
// Default certain options and error check
|
||||||
// Detailed error, since this is what we often get when run with minimal arguments
|
// Detailed error, since this is what we often get when run with minimal arguments
|
||||||
|
@ -599,10 +599,10 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||||
if (argv[i][0]=='+') {
|
if (argv[i][0]=='+') {
|
||||||
char *sw = argv[i];
|
char *sw = argv[i];
|
||||||
if ( !strncmp (sw, "+define+", 8)) {
|
if ( !strncmp (sw, "+define+", 8)) {
|
||||||
addDefine (string (sw+strlen("+define+")), true);
|
addDefine(string(sw+strlen("+define+")), true);
|
||||||
}
|
}
|
||||||
else if ( !strncmp (sw, "+incdir+", 8)) {
|
else if ( !strncmp (sw, "+incdir+", 8)) {
|
||||||
addIncDirUser (parseFileArg(optdir, string (sw+strlen("+incdir+"))));
|
addIncDirUser(parseFileArg(optdir, string(sw+strlen("+incdir+"))));
|
||||||
}
|
}
|
||||||
else if (parseLangExt(sw, "+systemverilogext+", V3LangCode::L1800_2017)
|
else if (parseLangExt(sw, "+systemverilogext+", V3LangCode::L1800_2017)
|
||||||
|| parseLangExt(sw, "+verilog1995ext+", V3LangCode::L1364_1995)
|
|| parseLangExt(sw, "+verilog1995ext+", V3LangCode::L1364_1995)
|
||||||
|
@ -621,17 +621,17 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||||
string exts = string(sw+strlen("+libext+"));
|
string exts = string(sw+strlen("+libext+"));
|
||||||
string::size_type pos;
|
string::size_type pos;
|
||||||
while ((pos=exts.find("+")) != string::npos) {
|
while ((pos=exts.find("+")) != string::npos) {
|
||||||
addLibExtV (exts.substr(0,pos));
|
addLibExtV(exts.substr(0,pos));
|
||||||
exts = exts.substr(pos+1);
|
exts = exts.substr(pos+1);
|
||||||
}
|
}
|
||||||
addLibExtV (exts);
|
addLibExtV(exts);
|
||||||
}
|
}
|
||||||
else if ( !strcmp (sw, "+librescan")) { // NOP
|
else if ( !strcmp (sw, "+librescan")) { // NOP
|
||||||
}
|
}
|
||||||
else if ( !strcmp (sw, "+notimingchecks")) { // NOP
|
else if ( !strcmp (sw, "+notimingchecks")) { // NOP
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fl->v3fatal ("Invalid Option: "<<argv[i]);
|
fl->v3fatal("Invalid Option: "<<argv[i]);
|
||||||
}
|
}
|
||||||
shift;
|
shift;
|
||||||
} // + options
|
} // + options
|
||||||
|
@ -762,7 +762,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||||
m_convergeLimit = atoi(argv[i]);
|
m_convergeLimit = atoi(argv[i]);
|
||||||
}
|
}
|
||||||
else if ( !strncmp (sw, "-D", 2)) {
|
else if ( !strncmp (sw, "-D", 2)) {
|
||||||
addDefine (string (sw+strlen("-D")), false);
|
addDefine(string(sw+strlen("-D")), false);
|
||||||
}
|
}
|
||||||
else if ( !strcmp (sw, "-debug") ) {
|
else if ( !strcmp (sw, "-debug") ) {
|
||||||
setDebugMode(3);
|
setDebugMode(3);
|
||||||
|
@ -791,10 +791,10 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||||
}
|
}
|
||||||
else if ( !strcmp (sw, "-FI") && (i+1)<argc ) {
|
else if ( !strcmp (sw, "-FI") && (i+1)<argc ) {
|
||||||
shift;
|
shift;
|
||||||
addForceInc(parseFileArg(optdir, string (argv[i])));
|
addForceInc(parseFileArg(optdir, string(argv[i])));
|
||||||
}
|
}
|
||||||
else if ( !strncmp (sw, "-G", strlen("-G"))) {
|
else if ( !strncmp (sw, "-G", strlen("-G"))) {
|
||||||
addParameter(string (sw+strlen("-G")), false);
|
addParameter(string(sw+strlen("-G")), false);
|
||||||
}
|
}
|
||||||
else if ( !strcmp (sw, "-gate-stmts") && (i+1)<argc ) {
|
else if ( !strcmp (sw, "-gate-stmts") && (i+1)<argc ) {
|
||||||
shift;
|
shift;
|
||||||
|
@ -806,7 +806,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
else if ( !strncmp (sw, "-I", 2)) {
|
else if ( !strncmp (sw, "-I", 2)) {
|
||||||
addIncDirUser(parseFileArg(optdir, string (sw+strlen("-I"))));
|
addIncDirUser(parseFileArg(optdir, string(sw+strlen("-I"))));
|
||||||
}
|
}
|
||||||
else if ( !strcmp (sw, "-if-depth") && (i+1)<argc ) {
|
else if ( !strcmp (sw, "-if-depth") && (i+1)<argc ) {
|
||||||
shift;
|
shift;
|
||||||
|
@ -842,7 +842,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||||
}
|
}
|
||||||
else if ( !strcmp (sw, "-Mdir") && (i+1)<argc ) {
|
else if ( !strcmp (sw, "-Mdir") && (i+1)<argc ) {
|
||||||
shift; m_makeDir = argv[i];
|
shift; m_makeDir = argv[i];
|
||||||
addIncDirFallback (m_makeDir); // Need to find generated files there too
|
addIncDirFallback(m_makeDir); // Need to find generated files there too
|
||||||
}
|
}
|
||||||
else if ( !strcmp (sw, "-o") && (i+1)<argc ) {
|
else if ( !strcmp (sw, "-o") && (i+1)<argc ) {
|
||||||
shift; m_exeName = argv[i];
|
shift; m_exeName = argv[i];
|
||||||
|
@ -876,7 +876,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||||
m_traceMaxWidth = atoi(argv[i]);
|
m_traceMaxWidth = atoi(argv[i]);
|
||||||
}
|
}
|
||||||
else if ( !strncmp (sw, "-U", 2)) {
|
else if ( !strncmp (sw, "-U", 2)) {
|
||||||
V3PreShell::undef (string (sw+strlen("-U")));
|
V3PreShell::undef(string(sw+strlen("-U")));
|
||||||
}
|
}
|
||||||
else if ( !strcmp (sw, "-unroll-count") ) { // Undocumented optimization tweak
|
else if ( !strcmp (sw, "-unroll-count") ) { // Undocumented optimization tweak
|
||||||
shift;
|
shift;
|
||||||
|
@ -1058,10 +1058,10 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( !strcmp (sw, "-y") && (i+1)<argc ) {
|
else if ( !strcmp (sw, "-y") && (i+1)<argc ) {
|
||||||
shift; addIncDirUser (parseFileArg(optdir,string (argv[i])));
|
shift; addIncDirUser(parseFileArg(optdir,string(argv[i])));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fl->v3fatal ("Invalid Option: "<<argv[i]);
|
fl->v3fatal("Invalid Option: "<<argv[i]);
|
||||||
}
|
}
|
||||||
shift;
|
shift;
|
||||||
} // - options
|
} // - options
|
||||||
|
@ -1178,9 +1178,9 @@ string V3Options::parseFileArg(const string& optdir, const string& relfilename)
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
//! Utility to see if we have a language extension argument and if so add it.
|
//! Utility to see if we have a language extension argument and if so add it.
|
||||||
bool V3Options::parseLangExt (const char* swp, //!< argument text
|
bool V3Options::parseLangExt(const char* swp, //!< argument text
|
||||||
const char* langswp, //!< option to match
|
const char* langswp, //!< option to match
|
||||||
const V3LangCode& lc) { //!< language code
|
const V3LangCode& lc) { //!< language code
|
||||||
int len = strlen(langswp);
|
int len = strlen(langswp);
|
||||||
if (!strncmp(swp, langswp, len)) {
|
if (!strncmp(swp, langswp, len)) {
|
||||||
addLangExt(swp + len, lc);
|
addLangExt(swp + len, lc);
|
||||||
|
|
|
@ -353,8 +353,8 @@ class V3Options {
|
||||||
string allArgsString(); ///< Return all passed arguments as simple string
|
string allArgsString(); ///< Return all passed arguments as simple string
|
||||||
void bin(const string& flag) { m_bin = flag; }
|
void bin(const string& flag) { m_bin = flag; }
|
||||||
void parseOpts(FileLine* fl, int argc, char** argv);
|
void parseOpts(FileLine* fl, int argc, char** argv);
|
||||||
void parseOptsList (FileLine* fl, const string& optdir, int argc, char** argv);
|
void parseOptsList(FileLine* fl, const string& optdir, int argc, char** argv);
|
||||||
void parseOptsFile (FileLine* fl, const string& filename, bool rel);
|
void parseOptsFile(FileLine* fl, const string& filename, bool rel);
|
||||||
|
|
||||||
// METHODS (environment)
|
// METHODS (environment)
|
||||||
// Most of these may be built into the executable with --enable-defenv,
|
// Most of these may be built into the executable with --enable-defenv,
|
||||||
|
@ -369,12 +369,12 @@ class V3Options {
|
||||||
static string getenvVERILATOR_ROOT();
|
static string getenvVERILATOR_ROOT();
|
||||||
|
|
||||||
// METHODS (file utilities using these options)
|
// METHODS (file utilities using these options)
|
||||||
string fileExists (const string& filename);
|
string fileExists(const string& filename);
|
||||||
string filePath(FileLine* fl, const string& modname, const string& lastpath, const string& errmsg);
|
string filePath(FileLine* fl, const string& modname, const string& lastpath, const string& errmsg);
|
||||||
void filePathLookedMsg(FileLine* fl, const string& modname);
|
void filePathLookedMsg(FileLine* fl, const string& modname);
|
||||||
V3LangCode fileLanguage(const string &filename);
|
V3LangCode fileLanguage(const string &filename);
|
||||||
static bool fileStatDir (const string& filename);
|
static bool fileStatDir(const string& filename);
|
||||||
static bool fileStatNormal (const string& filename);
|
static bool fileStatNormal(const string& filename);
|
||||||
static void fileNfsFlush(const string& filename);
|
static void fileNfsFlush(const string& filename);
|
||||||
|
|
||||||
// METHODS (other OS)
|
// METHODS (other OS)
|
||||||
|
|
|
@ -876,14 +876,14 @@ private:
|
||||||
m_graph.userClearVertices();
|
m_graph.userClearVertices();
|
||||||
AstNode::user3ClearTree();
|
AstNode::user3ClearTree();
|
||||||
m_unoptflatVars.clear();
|
m_unoptflatVars.clear();
|
||||||
reportLoopVarsIterate (vertexp, vertexp->color());
|
reportLoopVarsIterate(vertexp, vertexp->color());
|
||||||
AstNode::user3ClearTree();
|
AstNode::user3ClearTree();
|
||||||
m_graph.userClearVertices();
|
m_graph.userClearVertices();
|
||||||
// May be very large vector, so only report the "most important"
|
// May be very large vector, so only report the "most important"
|
||||||
// elements. Up to 10 of the widest
|
// elements. Up to 10 of the widest
|
||||||
std::cerr<<V3Error::msgPrefix()
|
std::cerr<<V3Error::msgPrefix()
|
||||||
<<" Widest candidate vars to split:"<<endl;
|
<<" Widest candidate vars to split:"<<endl;
|
||||||
std::stable_sort (m_unoptflatVars.begin(), m_unoptflatVars.end(), OrderVarWidthCmp());
|
std::stable_sort(m_unoptflatVars.begin(), m_unoptflatVars.end(), OrderVarWidthCmp());
|
||||||
int lim = m_unoptflatVars.size() < 10 ? m_unoptflatVars.size() : 10;
|
int lim = m_unoptflatVars.size() < 10 ? m_unoptflatVars.size() : 10;
|
||||||
for (int i = 0; i < lim; i++) {
|
for (int i = 0; i < lim; i++) {
|
||||||
OrderVarStdVertex* vsvertexp = m_unoptflatVars[i];
|
OrderVarStdVertex* vsvertexp = m_unoptflatVars[i];
|
||||||
|
@ -896,8 +896,8 @@ private:
|
||||||
// Up to 10 of the most fanned out
|
// Up to 10 of the most fanned out
|
||||||
std::cerr<<V3Error::msgPrefix()
|
std::cerr<<V3Error::msgPrefix()
|
||||||
<<" Most fanned out candidate vars to split:"<<endl;
|
<<" Most fanned out candidate vars to split:"<<endl;
|
||||||
std::stable_sort (m_unoptflatVars.begin(), m_unoptflatVars.end(),
|
std::stable_sort(m_unoptflatVars.begin(), m_unoptflatVars.end(),
|
||||||
OrderVarFanoutCmp());
|
OrderVarFanoutCmp());
|
||||||
lim = m_unoptflatVars.size() < 10 ? m_unoptflatVars.size() : 10;
|
lim = m_unoptflatVars.size() < 10 ? m_unoptflatVars.size() : 10;
|
||||||
for (int i = 0; i < lim; i++) {
|
for (int i = 0; i < lim; i++) {
|
||||||
OrderVarStdVertex* vsvertexp = m_unoptflatVars[i];
|
OrderVarStdVertex* vsvertexp = m_unoptflatVars[i];
|
||||||
|
@ -965,17 +965,17 @@ private:
|
||||||
m_finder.main(m_topScopep);
|
m_finder.main(m_topScopep);
|
||||||
// ProcessDomainsIterate will use these when it needs to move
|
// ProcessDomainsIterate will use these when it needs to move
|
||||||
// something to a combodomain. This saves a ton of find() operations.
|
// something to a combodomain. This saves a ton of find() operations.
|
||||||
AstSenTree* combp = new AstSenTree (nodep->fileline(), // Gets cloned() so ok if goes out of scope
|
AstSenTree* combp = new AstSenTree(nodep->fileline(), // Gets cloned() so ok if goes out of scope
|
||||||
new AstSenItem(nodep->fileline(), AstSenItem::Combo()));
|
new AstSenItem(nodep->fileline(), AstSenItem::Combo()));
|
||||||
m_comboDomainp = m_finder.getSenTree(nodep->fileline(), combp);
|
m_comboDomainp = m_finder.getSenTree(nodep->fileline(), combp);
|
||||||
pushDeletep(combp); // Cleanup when done
|
pushDeletep(combp); // Cleanup when done
|
||||||
AstSenTree* settlep = new AstSenTree (nodep->fileline(), // Gets cloned() so ok if goes out of scope
|
AstSenTree* settlep = new AstSenTree(nodep->fileline(), // Gets cloned() so ok if goes out of scope
|
||||||
new AstSenItem(nodep->fileline(), AstSenItem::Settle()));
|
new AstSenItem(nodep->fileline(), AstSenItem::Settle()));
|
||||||
m_settleDomainp = m_finder.getSenTree(nodep->fileline(), settlep);
|
m_settleDomainp = m_finder.getSenTree(nodep->fileline(), settlep);
|
||||||
pushDeletep(settlep); // Cleanup when done
|
pushDeletep(settlep); // Cleanup when done
|
||||||
// Fake AstSenTree we set domainp to indicate needs deletion
|
// Fake AstSenTree we set domainp to indicate needs deletion
|
||||||
m_deleteDomainp = new AstSenTree (nodep->fileline(),
|
m_deleteDomainp = new AstSenTree(nodep->fileline(),
|
||||||
new AstSenItem(nodep->fileline(), AstSenItem::Settle()));
|
new AstSenItem(nodep->fileline(), AstSenItem::Settle()));
|
||||||
pushDeletep(m_deleteDomainp); // Cleanup when done
|
pushDeletep(m_deleteDomainp); // Cleanup when done
|
||||||
UINFO(5," DeleteDomain = "<<m_deleteDomainp<<endl);
|
UINFO(5," DeleteDomain = "<<m_deleteDomainp<<endl);
|
||||||
// Base vertices
|
// Base vertices
|
||||||
|
|
|
@ -96,11 +96,11 @@ struct OrderVEdgeType {
|
||||||
return names[m_e];
|
return names[m_e];
|
||||||
}
|
}
|
||||||
enum en m_e;
|
enum en m_e;
|
||||||
inline OrderVEdgeType () : m_e(VERTEX_UNKNOWN) {}
|
inline OrderVEdgeType() : m_e(VERTEX_UNKNOWN) {}
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
inline OrderVEdgeType (en _e) : m_e(_e) {}
|
inline OrderVEdgeType(en _e) : m_e(_e) {}
|
||||||
explicit inline OrderVEdgeType (int _e) : m_e(static_cast<en>(_e)) {}
|
explicit inline OrderVEdgeType(int _e) : m_e(static_cast<en>(_e)) {}
|
||||||
operator en () const { return m_e; }
|
operator en() const { return m_e; }
|
||||||
};
|
};
|
||||||
inline bool operator== (OrderVEdgeType lhs, OrderVEdgeType rhs) { return (lhs.m_e == rhs.m_e); }
|
inline bool operator== (OrderVEdgeType lhs, OrderVEdgeType rhs) { return (lhs.m_e == rhs.m_e); }
|
||||||
inline bool operator== (OrderVEdgeType lhs, OrderVEdgeType::en rhs) { return (lhs.m_e == rhs); }
|
inline bool operator== (OrderVEdgeType lhs, OrderVEdgeType::en rhs) { return (lhs.m_e == rhs); }
|
||||||
|
@ -222,7 +222,7 @@ public:
|
||||||
: OrderEitherVertex(graphp, scopep, NULL), m_varScp(varScp)
|
: OrderEitherVertex(graphp, scopep, NULL), m_varScp(varScp)
|
||||||
, m_isClock(false), m_isDelayed(false) {}
|
, m_isClock(false), m_isDelayed(false) {}
|
||||||
virtual ~OrderVarVertex() {}
|
virtual ~OrderVarVertex() {}
|
||||||
virtual OrderVarVertex* clone (V3Graph* graphp) const = 0;
|
virtual OrderVarVertex* clone(V3Graph* graphp) const = 0;
|
||||||
virtual OrderVEdgeType type() const = 0;
|
virtual OrderVEdgeType type() const = 0;
|
||||||
virtual FileLine* fileline() const { return varScp()->fileline(); }
|
virtual FileLine* fileline() const { return varScp()->fileline(); }
|
||||||
// ACCESSORS
|
// ACCESSORS
|
||||||
|
@ -430,7 +430,7 @@ public:
|
||||||
: V3GraphEdge(graphp, fromp, top, weight, cutable) {}
|
: V3GraphEdge(graphp, fromp, top, weight, cutable) {}
|
||||||
virtual ~OrderEdge() {}
|
virtual ~OrderEdge() {}
|
||||||
virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_STD; }
|
virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_STD; }
|
||||||
virtual OrderEdge* clone (V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const {
|
virtual OrderEdge* clone(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const {
|
||||||
return new OrderEdge(graphp, fromp, top, *this);
|
return new OrderEdge(graphp, fromp, top, *this);
|
||||||
}
|
}
|
||||||
// When ordering combo blocks with stronglyConnected, follow edges not involving pre/pos variables
|
// When ordering combo blocks with stronglyConnected, follow edges not involving pre/pos variables
|
||||||
|
|
12
src/V3Os.cpp
12
src/V3Os.cpp
|
@ -71,13 +71,13 @@ void V3Os::setenvStr(const string& envvar, const string& value, const string& wh
|
||||||
//######################################################################
|
//######################################################################
|
||||||
// Generic filename utilities
|
// Generic filename utilities
|
||||||
|
|
||||||
string V3Os::filenameFromDirBase (const string& dir, const string& basename) {
|
string V3Os::filenameFromDirBase(const string& dir, const string& basename) {
|
||||||
// Don't return ./{filename} because if filename was absolute, that makes it relative
|
// Don't return ./{filename} because if filename was absolute, that makes it relative
|
||||||
if (dir == ".") return basename;
|
if (dir == ".") return basename;
|
||||||
else return dir+"/"+basename;
|
else return dir+"/"+basename;
|
||||||
}
|
}
|
||||||
|
|
||||||
string V3Os::filenameDir (const string& filename) {
|
string V3Os::filenameDir(const string& filename) {
|
||||||
string::size_type pos;
|
string::size_type pos;
|
||||||
if ((pos = filename.rfind("/")) != string::npos) {
|
if ((pos = filename.rfind("/")) != string::npos) {
|
||||||
return filename.substr(0,pos);
|
return filename.substr(0,pos);
|
||||||
|
@ -86,7 +86,7 @@ string V3Os::filenameDir (const string& filename) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string V3Os::filenameNonDir (const string& filename) {
|
string V3Os::filenameNonDir(const string& filename) {
|
||||||
string::size_type pos;
|
string::size_type pos;
|
||||||
if ((pos = filename.rfind("/")) != string::npos) {
|
if ((pos = filename.rfind("/")) != string::npos) {
|
||||||
return filename.substr(pos+1);
|
return filename.substr(pos+1);
|
||||||
|
@ -95,7 +95,7 @@ string V3Os::filenameNonDir (const string& filename) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string V3Os::filenameNonExt (const string& filename) {
|
string V3Os::filenameNonExt(const string& filename) {
|
||||||
string base = filenameNonDir(filename);
|
string base = filenameNonDir(filename);
|
||||||
string::size_type pos;
|
string::size_type pos;
|
||||||
if ((pos = base.find(".")) != string::npos) {
|
if ((pos = base.find(".")) != string::npos) {
|
||||||
|
@ -104,7 +104,7 @@ string V3Os::filenameNonExt (const string& filename) {
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
string V3Os::filenameSubstitute (const string& filename) {
|
string V3Os::filenameSubstitute(const string& filename) {
|
||||||
string out;
|
string out;
|
||||||
enum { NONE, PAREN, CURLY } brackets = NONE;
|
enum { NONE, PAREN, CURLY } brackets = NONE;
|
||||||
for (string::size_type pos = 0; pos < filename.length(); ++pos) {
|
for (string::size_type pos = 0; pos < filename.length(); ++pos) {
|
||||||
|
@ -181,7 +181,7 @@ void V3Os::unlinkRegexp(const string& dir, const string& regexp) {
|
||||||
while (struct dirent* direntp = readdir(dirp)) {
|
while (struct dirent* direntp = readdir(dirp)) {
|
||||||
if (VString::wildmatch(direntp->d_name, regexp.c_str())) {
|
if (VString::wildmatch(direntp->d_name, regexp.c_str())) {
|
||||||
string fullname = dir + "/" + string(direntp->d_name);
|
string fullname = dir + "/" + string(direntp->d_name);
|
||||||
unlink (fullname.c_str());
|
unlink(fullname.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
closedir(dirp);
|
closedir(dirp);
|
||||||
|
|
14
src/V3Os.h
14
src/V3Os.h
|
@ -35,15 +35,15 @@ public:
|
||||||
static void setenvStr(const string& envvar, const string& value, const string& why);
|
static void setenvStr(const string& envvar, const string& value, const string& why);
|
||||||
|
|
||||||
// METHODS (generic filename utilities)
|
// METHODS (generic filename utilities)
|
||||||
static string filenameFromDirBase (const string& dir, const string& basename);
|
static string filenameFromDirBase(const string& dir, const string& basename);
|
||||||
static string filenameNonDir (const string& filename); ///< Return non-directory part of filename
|
static string filenameNonDir(const string& filename); ///< Return non-directory part of filename
|
||||||
static string filenameNonExt (const string& filename); ///< Return non-extensioned (no .) part of filename
|
static string filenameNonExt(const string& filename); ///< Return non-extensioned (no .) part of filename
|
||||||
static string filenameNonDirExt (const string& filename) { ///< Return basename of filename
|
static string filenameNonDirExt(const string& filename) { ///< Return basename of filename
|
||||||
return filenameNonExt(filenameNonDir(filename)); }
|
return filenameNonExt(filenameNonDir(filename)); }
|
||||||
static string filenameDir (const string& filename); ///< Return directory part of filename
|
static string filenameDir(const string& filename); ///< Return directory part of filename
|
||||||
static string filenameSubstitute (const string& filename); ///< Return filename with env vars removed
|
static string filenameSubstitute(const string& filename); ///< Return filename with env vars removed
|
||||||
static string filenameRealPath(const string& fn); ///< Return realpath of filename
|
static string filenameRealPath(const string& fn); ///< Return realpath of filename
|
||||||
static bool filenameIsRel (const string& filename); ///< True if relative
|
static bool filenameIsRel(const string& filename); ///< True if relative
|
||||||
|
|
||||||
// METHODS (directory utilities)
|
// METHODS (directory utilities)
|
||||||
static void createDir(const string& dirname);
|
static void createDir(const string& dirname);
|
||||||
|
|
|
@ -104,7 +104,7 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
|
||||||
// from the V3LangCode to the various Lex BEGIN states. The language
|
// from the V3LangCode to the various Lex BEGIN states. The language
|
||||||
// of this source file is updated here, in case there have been any
|
// of this source file is updated here, in case there have been any
|
||||||
// intervening +<lang>ext+ options since it was first ecountered.
|
// intervening +<lang>ext+ options since it was first ecountered.
|
||||||
FileLine *modfileline = new FileLine (modfilename, 0);
|
FileLine *modfileline = new FileLine(modfilename, 0);
|
||||||
modfileline->language(v3Global.opt.fileLanguage(modfilename));
|
modfileline->language(v3Global.opt.fileLanguage(modfilename));
|
||||||
ppPushText((string)"`begin_keywords \""+modfileline->language().ascii()+"\"\n");
|
ppPushText((string)"`begin_keywords \""+modfileline->language().ascii()+"\"\n");
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
|
||||||
|
|
||||||
// Parse it
|
// Parse it
|
||||||
if (!v3Global.opt.preprocOnly()) {
|
if (!v3Global.opt.preprocOnly()) {
|
||||||
lexFile (modfilename);
|
lexFile(modfilename);
|
||||||
} else {
|
} else {
|
||||||
m_ppBuffers.clear();
|
m_ppBuffers.clear();
|
||||||
}
|
}
|
||||||
|
@ -175,7 +175,7 @@ void V3ParseImp::lexFile(const string& modname) {
|
||||||
// V3Parse functions
|
// V3Parse functions
|
||||||
|
|
||||||
V3Parse::V3Parse(AstNetlist* rootp, V3InFilter* filterp, V3ParseSym* symp) {
|
V3Parse::V3Parse(AstNetlist* rootp, V3InFilter* filterp, V3ParseSym* symp) {
|
||||||
m_impp = new V3ParseImp (rootp, filterp, symp);
|
m_impp = new V3ParseImp(rootp, filterp, symp);
|
||||||
}
|
}
|
||||||
V3Parse::~V3Parse() {
|
V3Parse::~V3Parse() {
|
||||||
delete m_impp; m_impp = NULL;
|
delete m_impp; m_impp = NULL;
|
||||||
|
|
|
@ -139,7 +139,7 @@ public:
|
||||||
int yylexThis();
|
int yylexThis();
|
||||||
static bool optFuture(const string& flag) { return v3Global.opt.isFuture(flag); }
|
static bool optFuture(const string& flag) { return v3Global.opt.isFuture(flag); }
|
||||||
|
|
||||||
void ppline (const char* text);
|
void ppline(const char* text);
|
||||||
void linenoInc() { fileline()->linenoInc(); }
|
void linenoInc() { fileline()->linenoInc(); }
|
||||||
void verilatorCmtLint(const char* text, bool on);
|
void verilatorCmtLint(const char* text, bool on);
|
||||||
void verilatorCmtLintSave();
|
void verilatorCmtLintSave();
|
||||||
|
@ -164,23 +164,23 @@ public:
|
||||||
// and called as READP->newString(...) etc.
|
// and called as READP->newString(...) etc.
|
||||||
string* newString(const string& text) {
|
string* newString(const string& text) {
|
||||||
// Allocate a string, remembering it so we can reclaim storage at lex end
|
// Allocate a string, remembering it so we can reclaim storage at lex end
|
||||||
string* strp = new string (text);
|
string* strp = new string(text);
|
||||||
m_stringps.push_back(strp);
|
m_stringps.push_back(strp);
|
||||||
return strp;
|
return strp;
|
||||||
}
|
}
|
||||||
string* newString(const char* text) {
|
string* newString(const char* text) {
|
||||||
// Allocate a string, remembering it so we can reclaim storage at lex end
|
// Allocate a string, remembering it so we can reclaim storage at lex end
|
||||||
string* strp = new string (text);
|
string* strp = new string(text);
|
||||||
m_stringps.push_back(strp);
|
m_stringps.push_back(strp);
|
||||||
return strp;
|
return strp;
|
||||||
}
|
}
|
||||||
string* newString(const char* text, size_t length) {
|
string* newString(const char* text, size_t length) {
|
||||||
string* strp = new string (text, length);
|
string* strp = new string(text, length);
|
||||||
m_stringps.push_back(strp);
|
m_stringps.push_back(strp);
|
||||||
return strp;
|
return strp;
|
||||||
}
|
}
|
||||||
V3Number* newNumber(FileLine* fl, const char* text) {
|
V3Number* newNumber(FileLine* fl, const char* text) {
|
||||||
V3Number* nump = new V3Number (fl, text);
|
V3Number* nump = new V3Number(fl, text);
|
||||||
m_numberps.push_back(nump);
|
m_numberps.push_back(nump);
|
||||||
return nump;
|
return nump;
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ public:
|
||||||
if (m_sympStack.empty()) { nodep->v3fatalSrc("symbol stack underflow"); return; }
|
if (m_sympStack.empty()) { nodep->v3fatalSrc("symbol stack underflow"); return; }
|
||||||
m_symCurrentp = m_sympStack.back();
|
m_symCurrentp = m_sympStack.back();
|
||||||
}
|
}
|
||||||
void showUpward () {
|
void showUpward() {
|
||||||
UINFO(1,"ParseSym Stack:\n");
|
UINFO(1,"ParseSym Stack:\n");
|
||||||
for (SymStack::reverse_iterator it=m_sympStack.rbegin(); it!=m_sympStack.rend(); ++it) {
|
for (SymStack::reverse_iterator it=m_sympStack.rbegin(); it!=m_sympStack.rend(); ++it) {
|
||||||
VSymEnt* symp = *it;
|
VSymEnt* symp = *it;
|
||||||
|
@ -127,7 +127,7 @@ public:
|
||||||
void dump(std::ostream& os, const string& indent="") {
|
void dump(std::ostream& os, const string& indent="") {
|
||||||
m_syms.dump(os,indent);
|
m_syms.dump(os,indent);
|
||||||
}
|
}
|
||||||
AstNode* findEntUpward (const string& name) {
|
AstNode* findEntUpward(const string& name) {
|
||||||
// Lookup the given string as an identifier, return type of the id, scanning upward
|
// Lookup the given string as an identifier, return type of the id, scanning upward
|
||||||
VSymEnt* foundp = symCurrentp()->findIdFallback(name);
|
VSymEnt* foundp = symCurrentp()->findIdFallback(name);
|
||||||
if (foundp) return foundp->nodep();
|
if (foundp) return foundp->nodep();
|
||||||
|
|
|
@ -112,9 +112,9 @@ extern char* yyourtext();
|
||||||
extern size_t yyourleng();
|
extern size_t yyourleng();
|
||||||
extern void yyourtext(const char* textp, size_t size); // Must call with static
|
extern void yyourtext(const char* textp, size_t size); // Must call with static
|
||||||
|
|
||||||
YY_BUFFER_STATE yy_create_buffer ( FILE *file, int size );
|
YY_BUFFER_STATE yy_create_buffer(FILE *file, int size);
|
||||||
void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer );
|
void yy_switch_to_buffer(YY_BUFFER_STATE new_buffer);
|
||||||
void yy_delete_buffer( YY_BUFFER_STATE b );
|
void yy_delete_buffer(YY_BUFFER_STATE b);
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
|
|
|
@ -238,10 +238,10 @@ public:
|
||||||
// METHODS, callbacks
|
// METHODS, callbacks
|
||||||
virtual void comment(const string& cmt); // Comment detected (if keepComments==2)
|
virtual void comment(const string& cmt); // Comment detected (if keepComments==2)
|
||||||
virtual void include(const string& filename); // Request a include file be processed
|
virtual void include(const string& filename); // Request a include file be processed
|
||||||
virtual void undef (const string& name);
|
virtual void undef(const string& name);
|
||||||
virtual void undefineall();
|
virtual void undefineall();
|
||||||
virtual void define (FileLine* fl, const string& name, const string& value,
|
virtual void define(FileLine* fl, const string& name, const string& value,
|
||||||
const string& params, bool cmdline);
|
const string& params, bool cmdline);
|
||||||
virtual string removeDefines(const string& text); // Remove defines in a text string
|
virtual string removeDefines(const string& text); // Remove defines in a text string
|
||||||
|
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
|
@ -268,7 +268,7 @@ public:
|
||||||
m_preprocp = this; // Silly, but to make code more similar to Verilog-Perl
|
m_preprocp = this; // Silly, but to make code more similar to Verilog-Perl
|
||||||
m_finFilelinep = filelinep->create(1);
|
m_finFilelinep = filelinep->create(1);
|
||||||
// Create lexer
|
// Create lexer
|
||||||
m_lexp = new V3PreLex (this, filelinep);
|
m_lexp = new V3PreLex(this, filelinep);
|
||||||
m_lexp->m_keepComments = m_preprocp->keepComments();
|
m_lexp->m_keepComments = m_preprocp->keepComments();
|
||||||
m_lexp->m_keepWhitespace = m_preprocp->keepWhitespace();
|
m_lexp->m_keepWhitespace = m_preprocp->keepWhitespace();
|
||||||
m_lexp->m_pedantic = m_preprocp->pedantic();
|
m_lexp->m_pedantic = m_preprocp->pedantic();
|
||||||
|
@ -361,7 +361,7 @@ string V3PreProcImp::removeDefines(const string& sym) {
|
||||||
|
|
||||||
void V3PreProcImp::include(const string& filename) {
|
void V3PreProcImp::include(const string& filename) {
|
||||||
// Include seen. Ask the preprocessor shell to call back around to us
|
// Include seen. Ask the preprocessor shell to call back around to us
|
||||||
V3PreShell::preprocInclude (fileline(), filename);
|
V3PreShell::preprocInclude(fileline(), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool V3PreProcImp::commentTokenMatch(string& cmdr, const char* strg) {
|
bool V3PreProcImp::commentTokenMatch(string& cmdr, const char* strg) {
|
||||||
|
@ -432,10 +432,10 @@ void V3PreProcImp::comment(const string& text) {
|
||||||
if (v3Global.opt.assertOn()) {
|
if (v3Global.opt.assertOn()) {
|
||||||
// one_hot, one_cold, (full_case, parallel_case)
|
// one_hot, one_cold, (full_case, parallel_case)
|
||||||
if (commentTokenMatch(cmd/*ref*/, "full_case")) {
|
if (commentTokenMatch(cmd/*ref*/, "full_case")) {
|
||||||
insertUnreadback ("/*verilator full_case*/");
|
insertUnreadback("/*verilator full_case*/");
|
||||||
}
|
}
|
||||||
if (commentTokenMatch(cmd/*ref*/, "parallel_case")) {
|
if (commentTokenMatch(cmd/*ref*/, "parallel_case")) {
|
||||||
insertUnreadback ("/*verilator parallel_case*/");
|
insertUnreadback("/*verilator parallel_case*/");
|
||||||
}
|
}
|
||||||
//if (commentTokenMatch(cmd/*ref*/, "one_hot")) {
|
//if (commentTokenMatch(cmd/*ref*/, "one_hot")) {
|
||||||
// insertUnreadback ("/*verilator one_hot*/ "+cmd+";");
|
// insertUnreadback ("/*verilator one_hot*/ "+cmd+";");
|
||||||
|
@ -451,9 +451,9 @@ void V3PreProcImp::comment(const string& text) {
|
||||||
while (isspace(cmd[0])) cmd = cmd.substr(1);
|
while (isspace(cmd[0])) cmd = cmd.substr(1);
|
||||||
if ((pos=cmd.find("*/")) != string::npos)
|
if ((pos=cmd.find("*/")) != string::npos)
|
||||||
cmd.replace(pos, 2, "");
|
cmd.replace(pos, 2, "");
|
||||||
insertUnreadback ("/*verilator public_flat_rw*/ "+cmd+" /**/");
|
insertUnreadback("/*verilator public_flat_rw*/ "+cmd+" /**/");
|
||||||
} else {
|
} else {
|
||||||
insertUnreadback ("/*verilator "+cmd+"*/");
|
insertUnreadback("/*verilator "+cmd+"*/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -851,14 +851,14 @@ int V3PreProcImp::getRawToken() {
|
||||||
|
|
||||||
void V3PreProcImp::debugToken(int tok, const char* cmtp) {
|
void V3PreProcImp::debugToken(int tok, const char* cmtp) {
|
||||||
if (debug()>=5) {
|
if (debug()>=5) {
|
||||||
string buf = string (yyourtext(), yyourleng());
|
string buf = string(yyourtext(), yyourleng());
|
||||||
string::size_type pos;
|
string::size_type pos;
|
||||||
while ((pos=buf.find("\n")) != string::npos) { buf.replace(pos, 1, "\\n"); }
|
while ((pos=buf.find("\n")) != string::npos) { buf.replace(pos, 1, "\\n"); }
|
||||||
while ((pos=buf.find("\r")) != string::npos) { buf.replace(pos, 1, "\\r"); }
|
while ((pos=buf.find("\r")) != string::npos) { buf.replace(pos, 1, "\\r"); }
|
||||||
fprintf (stderr, "%d: %s %s %s(%d) dr%d: <%d>%-10s: %s\n",
|
fprintf(stderr, "%d: %s %s %s(%d) dr%d: <%d>%-10s: %s\n",
|
||||||
m_lexp->m_tokFilelinep->lineno(), cmtp, m_off?"of":"on",
|
m_lexp->m_tokFilelinep->lineno(), cmtp, m_off?"of":"on",
|
||||||
procStateName(state()), (int)m_states.size(), (int)m_defRefs.size(),
|
procStateName(state()), (int)m_states.size(), (int)m_defRefs.size(),
|
||||||
m_lexp->currentStartState(), tokenName(tok), buf.c_str());
|
m_lexp->currentStartState(), tokenName(tok), buf.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -880,13 +880,13 @@ int V3PreProcImp::getStateToken() {
|
||||||
if (m_lexp->m_keepComments == KEEPCMT_SUB) {
|
if (m_lexp->m_keepComments == KEEPCMT_SUB) {
|
||||||
string rtn; rtn.assign(yyourtext(),yyourleng());
|
string rtn; rtn.assign(yyourtext(),yyourleng());
|
||||||
comment(rtn);
|
comment(rtn);
|
||||||
// Need to insure "foo/**/bar" becomes two tokens
|
// Need to ensure "foo/**/bar" becomes two tokens
|
||||||
insertUnreadback (" ");
|
insertUnreadback(" ");
|
||||||
} else if (m_lexp->m_keepComments) {
|
} else if (m_lexp->m_keepComments) {
|
||||||
return (tok);
|
return (tok);
|
||||||
} else {
|
} else {
|
||||||
// Need to insure "foo/**/bar" becomes two tokens
|
// Need to ensure "foo/**/bar" becomes two tokens
|
||||||
insertUnreadback (" ");
|
insertUnreadback(" ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We're off or processed the comment specially. If there are newlines
|
// We're off or processed the comment specially. If there are newlines
|
||||||
|
@ -1399,14 +1399,14 @@ int V3PreProcImp::getFinalToken(string& buf) {
|
||||||
if (!m_finAhead) {
|
if (!m_finAhead) {
|
||||||
m_finAhead = true;
|
m_finAhead = true;
|
||||||
m_finToken = getStateToken();
|
m_finToken = getStateToken();
|
||||||
m_finBuf = string (yyourtext(), yyourleng());
|
m_finBuf = string(yyourtext(), yyourleng());
|
||||||
}
|
}
|
||||||
int tok = m_finToken;
|
int tok = m_finToken;
|
||||||
buf = m_finBuf;
|
buf = m_finBuf;
|
||||||
if (0 && debug()>=5) {
|
if (0 && debug()>=5) {
|
||||||
string bufcln = V3PreLex::cleanDbgStrg(buf);
|
string bufcln = V3PreLex::cleanDbgStrg(buf);
|
||||||
fprintf (stderr,"%d: FIN: %-10s: %s\n",
|
fprintf(stderr,"%d: FIN: %-10s: %s\n",
|
||||||
m_lexp->m_tokFilelinep->lineno(), tokenName(tok), bufcln.c_str());
|
m_lexp->m_tokFilelinep->lineno(), tokenName(tok), bufcln.c_str());
|
||||||
}
|
}
|
||||||
// Track `line
|
// Track `line
|
||||||
const char* bufp = buf.c_str();
|
const char* bufp = buf.c_str();
|
||||||
|
@ -1461,8 +1461,8 @@ string V3PreProcImp::getline() {
|
||||||
int tok = getFinalToken(buf/*ref*/);
|
int tok = getFinalToken(buf/*ref*/);
|
||||||
if (debug()>=5) {
|
if (debug()>=5) {
|
||||||
string bufcln = V3PreLex::cleanDbgStrg(buf);
|
string bufcln = V3PreLex::cleanDbgStrg(buf);
|
||||||
fprintf (stderr,"%d: GETFETC: %-10s: %s\n",
|
fprintf(stderr,"%d: GETFETC: %-10s: %s\n",
|
||||||
m_lexp->m_tokFilelinep->lineno(), tokenName(tok), bufcln.c_str());
|
m_lexp->m_tokFilelinep->lineno(), tokenName(tok), bufcln.c_str());
|
||||||
}
|
}
|
||||||
if (tok==VP_EOF) {
|
if (tok==VP_EOF) {
|
||||||
// Add a final newline, if the user forgot the final \n.
|
// Add a final newline, if the user forgot the final \n.
|
||||||
|
@ -1482,8 +1482,8 @@ string V3PreProcImp::getline() {
|
||||||
m_lineChars = m_lineChars.erase(0,len); // Remove returned characters
|
m_lineChars = m_lineChars.erase(0,len); // Remove returned characters
|
||||||
if (debug()>=4) {
|
if (debug()>=4) {
|
||||||
string lncln = V3PreLex::cleanDbgStrg(theLine);
|
string lncln = V3PreLex::cleanDbgStrg(theLine);
|
||||||
fprintf (stderr,"%d: GETLINE: %s\n",
|
fprintf(stderr,"%d: GETLINE: %s\n",
|
||||||
m_lexp->m_tokFilelinep->lineno(), lncln.c_str());
|
m_lexp->m_tokFilelinep->lineno(), lncln.c_str());
|
||||||
}
|
}
|
||||||
return theLine;
|
return theLine;
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,8 +94,8 @@ protected:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool preproc (FileLine* fl, const string& modname, V3InFilter* filterp, V3ParseImp* parsep,
|
bool preproc(FileLine* fl, const string& modname, V3InFilter* filterp, V3ParseImp* parsep,
|
||||||
const string& errmsg) { // "" for no error
|
const string& errmsg) { // "" for no error
|
||||||
debug(true); // Recheck if debug on - first check was before command line passed
|
debug(true); // Recheck if debug on - first check was before command line passed
|
||||||
|
|
||||||
// Preprocess the given module, putting output in vppFilename
|
// Preprocess the given module, putting output in vppFilename
|
||||||
|
@ -113,24 +113,24 @@ protected:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void preprocInclude (FileLine* fl, const string& modname) {
|
void preprocInclude(FileLine* fl, const string& modname) {
|
||||||
if (modname[0]=='/' || modname[0]=='\\') {
|
if (modname[0]=='/' || modname[0]=='\\') {
|
||||||
fl->v3warn(INCABSPATH,"Suggest `include with absolute path be made relative, and use +include: "<<modname);
|
fl->v3warn(INCABSPATH,"Suggest `include with absolute path be made relative, and use +include: "<<modname);
|
||||||
}
|
}
|
||||||
preprocOpen(fl, s_filterp, modname, V3Os::filenameDir(fl->filename()), "Cannot find include file: ");
|
preprocOpen(fl, s_filterp, modname, V3Os::filenameDir(fl->filename()), "Cannot find include file: ");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool preprocOpen (FileLine* fl, V3InFilter* filterp, const string& modname, const string& lastpath,
|
bool preprocOpen(FileLine* fl, V3InFilter* filterp, const string& modname, const string& lastpath,
|
||||||
const string& errmsg) { // Error message or "" to suppress
|
const string& errmsg) { // Error message or "" to suppress
|
||||||
// Returns true if successful
|
// Returns true if successful
|
||||||
// Try a pure name in case user has a bogus `filename they don't expect
|
// Try a pure name in case user has a bogus `filename they don't expect
|
||||||
string filename = v3Global.opt.filePath (fl, modname, lastpath, errmsg);
|
string filename = v3Global.opt.filePath(fl, modname, lastpath, errmsg);
|
||||||
if (filename=="") {
|
if (filename=="") {
|
||||||
// Allow user to put `defined names on the command line instead of filenames,
|
// Allow user to put `defined names on the command line instead of filenames,
|
||||||
// then convert them properly.
|
// then convert them properly.
|
||||||
string ppmodname = s_preprocp->removeDefines (modname);
|
string ppmodname = s_preprocp->removeDefines(modname);
|
||||||
|
|
||||||
filename = v3Global.opt.filePath (fl, ppmodname, lastpath, errmsg);
|
filename = v3Global.opt.filePath(fl, ppmodname, lastpath, errmsg);
|
||||||
}
|
}
|
||||||
if (filename=="") return false; // Not found
|
if (filename=="") return false; // Not found
|
||||||
|
|
||||||
|
|
|
@ -152,8 +152,8 @@ private:
|
||||||
|
|
||||||
AstVar* getBlockTemp(AstNode* nodep) {
|
AstVar* getBlockTemp(AstNode* nodep) {
|
||||||
string newvarname = ((string)"__Vtemp"+cvtToStr(m_modp->varNumGetInc()));
|
string newvarname = ((string)"__Vtemp"+cvtToStr(m_modp->varNumGetInc()));
|
||||||
AstVar* varp = new AstVar (nodep->fileline(), AstVarType::STMTTEMP, newvarname,
|
AstVar* varp = new AstVar(nodep->fileline(), AstVarType::STMTTEMP, newvarname,
|
||||||
nodep->dtypep());
|
nodep->dtypep());
|
||||||
m_funcp->addInitsp(varp);
|
m_funcp->addInitsp(varp);
|
||||||
return varp;
|
return varp;
|
||||||
}
|
}
|
||||||
|
@ -185,12 +185,12 @@ private:
|
||||||
AstVar* varp = getBlockTemp(nodep);
|
AstVar* varp = getBlockTemp(nodep);
|
||||||
if (noSubst) varp->noSubst(true); // Do not remove varrefs to this in V3Const
|
if (noSubst) varp->noSubst(true); // Do not remove varrefs to this in V3Const
|
||||||
// Replace node tree with reference to var
|
// Replace node tree with reference to var
|
||||||
AstVarRef* newp = new AstVarRef (nodep->fileline(), varp, false);
|
AstVarRef* newp = new AstVarRef(nodep->fileline(), varp, false);
|
||||||
linker.relink(newp);
|
linker.relink(newp);
|
||||||
// Put assignment before the referencing statement
|
// Put assignment before the referencing statement
|
||||||
AstAssign* assp = new AstAssign (nodep->fileline(),
|
AstAssign* assp = new AstAssign(nodep->fileline(),
|
||||||
new AstVarRef(nodep->fileline(), varp, true),
|
new AstVarRef(nodep->fileline(), varp, true),
|
||||||
nodep);
|
nodep);
|
||||||
insertBeforeStmt(assp);
|
insertBeforeStmt(assp);
|
||||||
if (debug()>8) assp->dumpTree(cout,"deepou:");
|
if (debug()>8) assp->dumpTree(cout,"deepou:");
|
||||||
nodep->user1(true); // Don't add another assignment
|
nodep->user1(true); // Don't add another assignment
|
||||||
|
@ -255,7 +255,7 @@ private:
|
||||||
m_inTracep = NULL;
|
m_inTracep = NULL;
|
||||||
m_stmtp = NULL;
|
m_stmtp = NULL;
|
||||||
}
|
}
|
||||||
void visitShift (AstNodeBiop* nodep) {
|
void visitShift(AstNodeBiop* nodep) {
|
||||||
// Shifts of > 32/64 bits in C++ will wrap-around and generate non-0s
|
// Shifts of > 32/64 bits in C++ will wrap-around and generate non-0s
|
||||||
if (!nodep->user2SetOnce()) {
|
if (!nodep->user2SetOnce()) {
|
||||||
UINFO(4," ShiftFix "<<nodep<<endl);
|
UINFO(4," ShiftFix "<<nodep<<endl);
|
||||||
|
@ -275,28 +275,28 @@ private:
|
||||||
// Then over shifting gives the sign bit, not all zeros
|
// Then over shifting gives the sign bit, not all zeros
|
||||||
// Note *NOT* clean output -- just like normal shift!
|
// Note *NOT* clean output -- just like normal shift!
|
||||||
// Create equivalent of VL_SIGNONES_(node_width)
|
// Create equivalent of VL_SIGNONES_(node_width)
|
||||||
constzerop = new AstNegate (nodep->fileline(),
|
constzerop = new AstNegate(nodep->fileline(),
|
||||||
new AstShiftR(nodep->fileline(),
|
new AstShiftR(nodep->fileline(),
|
||||||
nodep->lhsp()->cloneTree(false),
|
nodep->lhsp()->cloneTree(false),
|
||||||
new AstConst(nodep->fileline(),
|
new AstConst(nodep->fileline(),
|
||||||
m1value),
|
m1value),
|
||||||
nodep->width()));
|
nodep->width()));
|
||||||
} else {
|
} else {
|
||||||
V3Number zeronum (nodep->fileline(), nodep->width(), 0);
|
V3Number zeronum (nodep->fileline(), nodep->width(), 0);
|
||||||
constzerop = new AstConst(nodep->fileline(), zeronum);
|
constzerop = new AstConst(nodep->fileline(), zeronum);
|
||||||
}
|
}
|
||||||
constzerop->dtypeFrom (nodep); // unsigned
|
constzerop->dtypeFrom(nodep); // unsigned
|
||||||
|
|
||||||
V3Number widthnum (nodep->fileline(), nodep->rhsp()->widthMin(), m1value);
|
V3Number widthnum (nodep->fileline(), nodep->rhsp()->widthMin(), m1value);
|
||||||
AstNode* constwidthp = new AstConst(nodep->fileline(), widthnum);
|
AstNode* constwidthp = new AstConst(nodep->fileline(), widthnum);
|
||||||
constwidthp->dtypeFrom (nodep->rhsp()); // unsigned
|
constwidthp->dtypeFrom(nodep->rhsp()); // unsigned
|
||||||
AstCond* newp =
|
AstCond* newp =
|
||||||
new AstCond (nodep->fileline(),
|
new AstCond(nodep->fileline(),
|
||||||
new AstGte (nodep->fileline(),
|
new AstGte(nodep->fileline(),
|
||||||
constwidthp,
|
constwidthp,
|
||||||
nodep->rhsp()->cloneTree(false)),
|
nodep->rhsp()->cloneTree(false)),
|
||||||
nodep,
|
nodep,
|
||||||
constzerop);
|
constzerop);
|
||||||
replaceHandle.relink(newp);
|
replaceHandle.relink(newp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,7 +215,7 @@ private:
|
||||||
nump->setLong(value); // We do support more than 32 bit numbers, just valuep=0 in that case
|
nump->setLong(value); // We do support more than 32 bit numbers, just valuep=0 in that case
|
||||||
} else {
|
} else {
|
||||||
//UINFO(7,"Num New "<<nodep->width()<<endl);
|
//UINFO(7,"Num New "<<nodep->width()<<endl);
|
||||||
nump = new V3Number (nodep->fileline(), nodep->width(), value);
|
nump = new V3Number(nodep->fileline(), nodep->width(), value);
|
||||||
m_numAllps.push_back(nump);
|
m_numAllps.push_back(nump);
|
||||||
}
|
}
|
||||||
nump->isDouble(nodep->isDouble());
|
nump->isDouble(nodep->isDouble());
|
||||||
|
@ -567,9 +567,9 @@ private:
|
||||||
assignOutNumber(nodep, vscp, &outnum);
|
assignOutNumber(nodep, vscp, &outnum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void handleAssignSelRecurse (AstNodeAssign* nodep, AstSel* selp,
|
void handleAssignSelRecurse(AstNodeAssign* nodep, AstSel* selp,
|
||||||
AstVarRef*& outVarrefpRef, V3Number& lsbRef,
|
AstVarRef*& outVarrefpRef, V3Number& lsbRef,
|
||||||
int depth) {
|
int depth) {
|
||||||
// Recurse down to find final variable being set (outVarrefp), with value to write on nodep->rhsp()
|
// Recurse down to find final variable being set (outVarrefp), with value to write on nodep->rhsp()
|
||||||
checkNodeInfo(selp);
|
checkNodeInfo(selp);
|
||||||
iterateAndNextNull(selp->lsbp()); // Bit index
|
iterateAndNextNull(selp->lsbp()); // Bit index
|
||||||
|
@ -942,19 +942,19 @@ public:
|
||||||
// Move all allocated numbers to the free pool
|
// Move all allocated numbers to the free pool
|
||||||
m_numFreeps = m_numAllps;
|
m_numFreeps = m_numAllps;
|
||||||
}
|
}
|
||||||
void mainTableCheck (AstNode* nodep) {
|
void mainTableCheck(AstNode* nodep) {
|
||||||
setMode(true/*scoped*/,true/*checking*/, false/*params*/);
|
setMode(true/*scoped*/,true/*checking*/, false/*params*/);
|
||||||
mainGuts(nodep);
|
mainGuts(nodep);
|
||||||
}
|
}
|
||||||
void mainTableEmulate (AstNode* nodep) {
|
void mainTableEmulate(AstNode* nodep) {
|
||||||
setMode(true/*scoped*/,false/*checking*/, false/*params*/);
|
setMode(true/*scoped*/,false/*checking*/, false/*params*/);
|
||||||
mainGuts(nodep);
|
mainGuts(nodep);
|
||||||
}
|
}
|
||||||
void mainCheckTree (AstNode* nodep) {
|
void mainCheckTree(AstNode* nodep) {
|
||||||
setMode(false/*scoped*/,true/*checking*/, false/*params*/);
|
setMode(false/*scoped*/,true/*checking*/, false/*params*/);
|
||||||
mainGuts(nodep);
|
mainGuts(nodep);
|
||||||
}
|
}
|
||||||
void mainParamEmulate (AstNode* nodep) {
|
void mainParamEmulate(AstNode* nodep) {
|
||||||
setMode(false/*scoped*/,false/*checking*/, true/*params*/);
|
setMode(false/*scoped*/,false/*checking*/, true/*params*/);
|
||||||
mainGuts(nodep);
|
mainGuts(nodep);
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,8 @@ public:
|
||||||
~V3Double0() {}
|
~V3Double0() {}
|
||||||
|
|
||||||
// Implicit conversion operators:
|
// Implicit conversion operators:
|
||||||
inline explicit V3Double0 (const vluint64_t v) : m_d(v) { }
|
inline explicit V3Double0(const vluint64_t v) : m_d(v) { }
|
||||||
inline operator double () const { return m_d; }
|
inline operator double() const { return m_d; }
|
||||||
|
|
||||||
// Explicit operators:
|
// Explicit operators:
|
||||||
inline V3Double0& operator++() { ++m_d; return *this; } // prefix
|
inline V3Double0& operator++() { ++m_d; return *this; } // prefix
|
||||||
|
|
|
@ -99,7 +99,7 @@ class VName {
|
||||||
static size_t s_minLength; // Length to preserve if over maxLength
|
static size_t s_minLength; // Length to preserve if over maxLength
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
explicit VName (const string& name) : m_name(name) {}
|
explicit VName(const string& name) : m_name(name) {}
|
||||||
~VName() {}
|
~VName() {}
|
||||||
// METHODS
|
// METHODS
|
||||||
void name(const string& name) { m_name = name; m_hashed = ""; }
|
void name(const string& name) { m_name = name; m_hashed = ""; }
|
||||||
|
|
|
@ -82,7 +82,7 @@ class SubstVarEntry {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
explicit SubstVarEntry (AstVar* varp) { // Construction for when a var is used
|
explicit SubstVarEntry(AstVar* varp) { // Construction for when a var is used
|
||||||
m_varp = varp;
|
m_varp = varp;
|
||||||
m_whole.m_use = false;
|
m_whole.m_use = false;
|
||||||
m_wordAssign = false;
|
m_wordAssign = false;
|
||||||
|
@ -104,12 +104,12 @@ private:
|
||||||
else return m_words[word].m_assignp;
|
else return m_words[word].m_assignp;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
void assignWhole (int step, AstNodeAssign* assp) {
|
void assignWhole(int step, AstNodeAssign* assp) {
|
||||||
if (m_whole.m_assignp) m_whole.m_complex = true;
|
if (m_whole.m_assignp) m_whole.m_complex = true;
|
||||||
m_whole.m_assignp = assp;
|
m_whole.m_assignp = assp;
|
||||||
m_whole.m_step = step;
|
m_whole.m_step = step;
|
||||||
}
|
}
|
||||||
void assignWord (int step, int word, AstNodeAssign* assp) {
|
void assignWord(int step, int word, AstNodeAssign* assp) {
|
||||||
if (!wordNumOk(word) || getWordAssignp(word) || m_words[word].m_complex) m_whole.m_complex = true;
|
if (!wordNumOk(word) || getWordAssignp(word) || m_words[word].m_complex) m_whole.m_complex = true;
|
||||||
m_wordAssign = true;
|
m_wordAssign = true;
|
||||||
if (wordNumOk(word)) {
|
if (wordNumOk(word)) {
|
||||||
|
@ -117,7 +117,7 @@ public:
|
||||||
m_words[word].m_step = step;
|
m_words[word].m_step = step;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void assignWordComplex (int step, int word) {
|
void assignWordComplex(int step, int word) {
|
||||||
if (!wordNumOk(word) || getWordAssignp(word) || m_words[word].m_complex) m_whole.m_complex = true;
|
if (!wordNumOk(word) || getWordAssignp(word) || m_words[word].m_complex) m_whole.m_complex = true;
|
||||||
m_words[word].m_complex = true;
|
m_words[word].m_complex = true;
|
||||||
}
|
}
|
||||||
|
@ -157,18 +157,18 @@ public:
|
||||||
int getWordStep(int word) const {
|
int getWordStep(int word) const {
|
||||||
if (!wordNumOk(word)) return 0; else return m_words[word].m_step;
|
if (!wordNumOk(word)) return 0; else return m_words[word].m_step;
|
||||||
}
|
}
|
||||||
void deleteAssign (AstNodeAssign* nodep) {
|
void deleteAssign(AstNodeAssign* nodep) {
|
||||||
UINFO(5, "Delete "<<nodep<<endl);
|
UINFO(5, "Delete "<<nodep<<endl);
|
||||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
void deleteUnusedAssign() {
|
void deleteUnusedAssign() {
|
||||||
// If there are unused assignments in this var, kill them
|
// If there are unused assignments in this var, kill them
|
||||||
if (!m_whole.m_use && !m_wordUse && m_whole.m_assignp) {
|
if (!m_whole.m_use && !m_wordUse && m_whole.m_assignp) {
|
||||||
deleteAssign (m_whole.m_assignp); m_whole.m_assignp=NULL;
|
deleteAssign(m_whole.m_assignp); m_whole.m_assignp=NULL;
|
||||||
}
|
}
|
||||||
for (unsigned i=0; i<m_words.size(); i++) {
|
for (unsigned i=0; i<m_words.size(); i++) {
|
||||||
if (!m_whole.m_use && !m_words[i].m_use && m_words[i].m_assignp && !m_words[i].m_complex) {
|
if (!m_whole.m_use && !m_words[i].m_use && m_words[i].m_assignp && !m_words[i].m_complex) {
|
||||||
deleteAssign (m_words[i].m_assignp); m_words[i].m_assignp=NULL;
|
deleteAssign(m_words[i].m_assignp); m_words[i].m_assignp=NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,7 +192,7 @@ private:
|
||||||
}
|
}
|
||||||
// VISITORS
|
// VISITORS
|
||||||
virtual void visit(AstVarRef* nodep) {
|
virtual void visit(AstVarRef* nodep) {
|
||||||
SubstVarEntry* entryp = findEntryp (nodep);
|
SubstVarEntry* entryp = findEntryp(nodep);
|
||||||
if (entryp) {
|
if (entryp) {
|
||||||
// Don't sweat it. We assign a new temp variable for every new assignment,
|
// Don't sweat it. We assign a new temp variable for every new assignment,
|
||||||
// so there's no way we'd ever replace a old value.
|
// so there's no way we'd ever replace a old value.
|
||||||
|
@ -245,7 +245,7 @@ private:
|
||||||
// METHODS
|
// METHODS
|
||||||
SubstVarEntry* getEntryp(AstVarRef* nodep) {
|
SubstVarEntry* getEntryp(AstVarRef* nodep) {
|
||||||
if (!nodep->varp()->user1p()) {
|
if (!nodep->varp()->user1p()) {
|
||||||
SubstVarEntry* entryp = new SubstVarEntry (nodep->varp());
|
SubstVarEntry* entryp = new SubstVarEntry(nodep->varp());
|
||||||
m_entryps.push_back(entryp);
|
m_entryps.push_back(entryp);
|
||||||
nodep->varp()->user1p(entryp);
|
nodep->varp()->user1p(entryp);
|
||||||
return entryp;
|
return entryp;
|
||||||
|
@ -302,7 +302,7 @@ private:
|
||||||
if (debug()>5) nodep->dumpTree(cout," substw_old: ");
|
if (debug()>5) nodep->dumpTree(cout," substw_old: ");
|
||||||
AstNode* newp = substp->cloneTree(true);
|
AstNode* newp = substp->cloneTree(true);
|
||||||
if (!nodep->isQuad() && newp->isQuad()) {
|
if (!nodep->isQuad() && newp->isQuad()) {
|
||||||
newp = new AstCCast (newp->fileline(), newp, nodep);
|
newp = new AstCCast(newp->fileline(), newp, nodep);
|
||||||
}
|
}
|
||||||
if (debug()>5) newp->dumpTree(cout," w_new: ");
|
if (debug()>5) newp->dumpTree(cout," w_new: ");
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
|
@ -344,7 +344,7 @@ private:
|
||||||
UINFO(9, " ASSIGNstep u2="<<nodep->varp()->user2()<<" "<<nodep<<endl);
|
UINFO(9, " ASSIGNstep u2="<<nodep->varp()->user2()<<" "<<nodep<<endl);
|
||||||
}
|
}
|
||||||
if (isSubstVar(nodep->varp())) {
|
if (isSubstVar(nodep->varp())) {
|
||||||
SubstVarEntry* entryp = getEntryp (nodep);
|
SubstVarEntry* entryp = getEntryp(nodep);
|
||||||
if (nodep->lvalue()) {
|
if (nodep->lvalue()) {
|
||||||
UINFO(8," ASSIGNcpx "<<nodep<<endl);
|
UINFO(8," ASSIGNcpx "<<nodep<<endl);
|
||||||
entryp->assignComplex(m_assignStep);
|
entryp->assignComplex(m_assignStep);
|
||||||
|
|
|
@ -175,29 +175,29 @@ private:
|
||||||
++m_statTablesCre;
|
++m_statTablesCre;
|
||||||
|
|
||||||
// Index into our table
|
// Index into our table
|
||||||
AstVar* indexVarp = new AstVar (nodep->fileline(), AstVarType::BLOCKTEMP,
|
AstVar* indexVarp = new AstVar(nodep->fileline(), AstVarType::BLOCKTEMP,
|
||||||
"__Vtableidx" + cvtToStr(m_modTables),
|
"__Vtableidx" + cvtToStr(m_modTables),
|
||||||
VFlagBitPacked(), m_inWidth);
|
VFlagBitPacked(), m_inWidth);
|
||||||
m_modp->addStmtp(indexVarp);
|
m_modp->addStmtp(indexVarp);
|
||||||
AstVarScope* indexVscp = new AstVarScope (indexVarp->fileline(), m_scopep, indexVarp);
|
AstVarScope* indexVscp = new AstVarScope(indexVarp->fileline(), m_scopep, indexVarp);
|
||||||
m_scopep->addVarp(indexVscp);
|
m_scopep->addVarp(indexVscp);
|
||||||
|
|
||||||
// Change it variable
|
// Change it variable
|
||||||
FileLine* fl = nodep->fileline();
|
FileLine* fl = nodep->fileline();
|
||||||
AstNodeArrayDType* dtypep
|
AstNodeArrayDType* dtypep
|
||||||
= new AstUnpackArrayDType (fl,
|
= new AstUnpackArrayDType(fl,
|
||||||
nodep->findBitDType(m_outVarps.size(),
|
nodep->findBitDType(m_outVarps.size(),
|
||||||
m_outVarps.size(), AstNumeric::UNSIGNED),
|
m_outVarps.size(), AstNumeric::UNSIGNED),
|
||||||
new AstRange (fl, VL_MASK_I(m_inWidth), 0));
|
new AstRange(fl, VL_MASK_I(m_inWidth), 0));
|
||||||
v3Global.rootp()->typeTablep()->addTypesp(dtypep);
|
v3Global.rootp()->typeTablep()->addTypesp(dtypep);
|
||||||
AstVar* chgVarp
|
AstVar* chgVarp
|
||||||
= new AstVar (fl, AstVarType::MODULETEMP,
|
= new AstVar(fl, AstVarType::MODULETEMP,
|
||||||
"__Vtablechg" + cvtToStr(m_modTables),
|
"__Vtablechg" + cvtToStr(m_modTables),
|
||||||
dtypep);
|
dtypep);
|
||||||
chgVarp->isConst(true);
|
chgVarp->isConst(true);
|
||||||
chgVarp->valuep(new AstInitArray (nodep->fileline(), dtypep, NULL));
|
chgVarp->valuep(new AstInitArray(nodep->fileline(), dtypep, NULL));
|
||||||
m_modp->addStmtp(chgVarp);
|
m_modp->addStmtp(chgVarp);
|
||||||
AstVarScope* chgVscp = new AstVarScope (chgVarp->fileline(), m_scopep, chgVarp);
|
AstVarScope* chgVscp = new AstVarScope(chgVarp->fileline(), m_scopep, chgVarp);
|
||||||
m_scopep->addVarp(chgVscp);
|
m_scopep->addVarp(chgVscp);
|
||||||
|
|
||||||
createTableVars(nodep);
|
createTableVars(nodep);
|
||||||
|
@ -233,16 +233,16 @@ private:
|
||||||
AstVar* outvarp = outvscp->varp();
|
AstVar* outvarp = outvscp->varp();
|
||||||
FileLine* fl = nodep->fileline();
|
FileLine* fl = nodep->fileline();
|
||||||
AstNodeArrayDType* dtypep
|
AstNodeArrayDType* dtypep
|
||||||
= new AstUnpackArrayDType (fl, outvarp->dtypep(),
|
= new AstUnpackArrayDType(fl, outvarp->dtypep(),
|
||||||
new AstRange (fl, VL_MASK_I(m_inWidth), 0));
|
new AstRange(fl, VL_MASK_I(m_inWidth), 0));
|
||||||
v3Global.rootp()->typeTablep()->addTypesp(dtypep);
|
v3Global.rootp()->typeTablep()->addTypesp(dtypep);
|
||||||
AstVar* tablevarp
|
AstVar* tablevarp
|
||||||
= new AstVar (fl, AstVarType::MODULETEMP,
|
= new AstVar(fl, AstVarType::MODULETEMP,
|
||||||
"__Vtable" + cvtToStr(m_modTables) +"_"+outvarp->name(),
|
"__Vtable" + cvtToStr(m_modTables) +"_"+outvarp->name(),
|
||||||
dtypep);
|
dtypep);
|
||||||
tablevarp->isConst(true);
|
tablevarp->isConst(true);
|
||||||
tablevarp->isStatic(true);
|
tablevarp->isStatic(true);
|
||||||
tablevarp->valuep(new AstInitArray (nodep->fileline(), dtypep, NULL));
|
tablevarp->valuep(new AstInitArray(nodep->fileline(), dtypep, NULL));
|
||||||
m_modp->addStmtp(tablevarp);
|
m_modp->addStmtp(tablevarp);
|
||||||
AstVarScope* tablevscp = new AstVarScope(tablevarp->fileline(), m_scopep, tablevarp);
|
AstVarScope* tablevscp = new AstVarScope(tablevarp->fileline(), m_scopep, tablevarp);
|
||||||
m_scopep->addVarp(tablevscp);
|
m_scopep->addVarp(tablevscp);
|
||||||
|
@ -256,15 +256,15 @@ private:
|
||||||
AstNode* concatp = NULL;
|
AstNode* concatp = NULL;
|
||||||
for (std::deque<AstVarScope*>::iterator it = m_inVarps.begin(); it!=m_inVarps.end(); ++it) {
|
for (std::deque<AstVarScope*>::iterator it = m_inVarps.begin(); it!=m_inVarps.end(); ++it) {
|
||||||
AstVarScope* invscp = *it;
|
AstVarScope* invscp = *it;
|
||||||
AstVarRef* refp = new AstVarRef (nodep->fileline(), invscp, false);
|
AstVarRef* refp = new AstVarRef(nodep->fileline(), invscp, false);
|
||||||
if (concatp) {
|
if (concatp) {
|
||||||
concatp = new AstConcat (nodep->fileline(), refp, concatp);
|
concatp = new AstConcat(nodep->fileline(), refp, concatp);
|
||||||
} else concatp = refp;
|
} else concatp = refp;
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode* stmtsp = new AstAssign
|
AstNode* stmtsp = new AstAssign
|
||||||
(nodep->fileline(),
|
(nodep->fileline(),
|
||||||
new AstVarRef (nodep->fileline(), indexVscp, true),
|
new AstVarRef(nodep->fileline(), indexVscp, true),
|
||||||
concatp);
|
concatp);
|
||||||
return stmtsp;
|
return stmtsp;
|
||||||
}
|
}
|
||||||
|
@ -317,14 +317,14 @@ private:
|
||||||
UINFO(8," Output "<<outvscp->name()<<" never set\n");
|
UINFO(8," Output "<<outvscp->name()<<" never set\n");
|
||||||
m_outNotSet[outnum] = true;
|
m_outNotSet[outnum] = true;
|
||||||
// Value in table is arbitrary, but we need something
|
// Value in table is arbitrary, but we need something
|
||||||
setp = new AstConst (outvscp->fileline(),
|
setp = new AstConst(outvscp->fileline(),
|
||||||
V3Number(outvscp->fileline(), outvscp->width(), 0));
|
V3Number(outvscp->fileline(), outvscp->width(), 0));
|
||||||
} else {
|
} else {
|
||||||
UINFO(8," Output "<<outvscp->name()<<" = "<<*outnump<<endl);
|
UINFO(8," Output "<<outvscp->name()<<" = "<<*outnump<<endl);
|
||||||
// m_tableVarps[inValue] = num;
|
// m_tableVarps[inValue] = num;
|
||||||
// Mark changed bit, too
|
// Mark changed bit, too
|
||||||
outputChgMask.setBit(outnum, 1);
|
outputChgMask.setBit(outnum, 1);
|
||||||
setp = new AstConst (outnump->fileline(), *outnump);
|
setp = new AstConst(outnump->fileline(), *outnump);
|
||||||
}
|
}
|
||||||
// Note InitArray requires us to have the values in inValue order
|
// Note InitArray requires us to have the values in inValue order
|
||||||
VN_CAST(m_tableVarps[outnum]->varp()->valuep(), InitArray)->addValuep(setp);
|
VN_CAST(m_tableVarps[outnum]->varp()->valuep(), InitArray)->addValuep(setp);
|
||||||
|
@ -334,7 +334,7 @@ private:
|
||||||
{ // Set changed table
|
{ // Set changed table
|
||||||
if (inValue != inValueNextInitArray++)
|
if (inValue != inValueNextInitArray++)
|
||||||
nodep->v3fatalSrc("InitArray requires us to have the values in inValue order");
|
nodep->v3fatalSrc("InitArray requires us to have the values in inValue order");
|
||||||
AstNode* setp = new AstConst (nodep->fileline(), outputChgMask);
|
AstNode* setp = new AstConst(nodep->fileline(), outputChgMask);
|
||||||
VN_CAST(chgVscp->varp()->valuep(), InitArray)->addValuep(setp);
|
VN_CAST(chgVscp->varp()->valuep(), InitArray)->addValuep(setp);
|
||||||
}
|
}
|
||||||
} // each value
|
} // each value
|
||||||
|
@ -377,21 +377,21 @@ private:
|
||||||
new AstVarRef(nodep->fileline(), m_tableVarps[outnum], false),
|
new AstVarRef(nodep->fileline(), m_tableVarps[outnum], false),
|
||||||
new AstVarRef(nodep->fileline(), indexVscp, false));
|
new AstVarRef(nodep->fileline(), indexVscp, false));
|
||||||
AstNode* outasnp = (m_assignDly
|
AstNode* outasnp = (m_assignDly
|
||||||
? (AstNode*)(new AstAssignDly (nodep->fileline(), alhsp, arhsp))
|
? (AstNode*)(new AstAssignDly(nodep->fileline(), alhsp, arhsp))
|
||||||
: (AstNode*)(new AstAssign (nodep->fileline(), alhsp, arhsp)));
|
: (AstNode*)(new AstAssign(nodep->fileline(), alhsp, arhsp)));
|
||||||
AstNode* outsetp = outasnp;
|
AstNode* outsetp = outasnp;
|
||||||
|
|
||||||
// Is the value set in only some branches of the table?
|
// Is the value set in only some branches of the table?
|
||||||
if (m_outNotSet[outnum]) {
|
if (m_outNotSet[outnum]) {
|
||||||
V3Number outputChgMask (nodep->fileline(), m_outVarps.size(), 0);
|
V3Number outputChgMask (nodep->fileline(), m_outVarps.size(), 0);
|
||||||
outputChgMask.setBit(outnum,1);
|
outputChgMask.setBit(outnum,1);
|
||||||
outsetp = new AstIf (nodep->fileline(),
|
outsetp = new AstIf(nodep->fileline(),
|
||||||
new AstAnd(nodep->fileline(),
|
new AstAnd(nodep->fileline(),
|
||||||
new AstArraySel(nodep->fileline(),
|
new AstArraySel(nodep->fileline(),
|
||||||
new AstVarRef(nodep->fileline(), chgVscp, false),
|
new AstVarRef(nodep->fileline(), chgVscp, false),
|
||||||
new AstVarRef(nodep->fileline(), indexVscp, false)),
|
new AstVarRef(nodep->fileline(), indexVscp, false)),
|
||||||
new AstConst(nodep->fileline(), outputChgMask)),
|
new AstConst(nodep->fileline(), outputChgMask)),
|
||||||
outsetp, NULL);
|
outsetp, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
stmtsp->addNext(outsetp);
|
stmtsp->addNext(outsetp);
|
||||||
|
|
|
@ -196,7 +196,7 @@ private:
|
||||||
}
|
}
|
||||||
// We make multiple edges if a task is called multiple times from another task.
|
// We make multiple edges if a task is called multiple times from another task.
|
||||||
if (!nodep->taskp()) nodep->v3fatalSrc("Unlinked task");
|
if (!nodep->taskp()) nodep->v3fatalSrc("Unlinked task");
|
||||||
new TaskEdge (&m_callGraph, m_curVxp, getFTaskVertex(nodep->taskp()));
|
new TaskEdge(&m_callGraph, m_curVxp, getFTaskVertex(nodep->taskp()));
|
||||||
}
|
}
|
||||||
virtual void visit(AstNodeFTask* nodep) {
|
virtual void visit(AstNodeFTask* nodep) {
|
||||||
UINFO(9," TASK "<<nodep<<endl);
|
UINFO(9," TASK "<<nodep<<endl);
|
||||||
|
@ -322,8 +322,8 @@ private:
|
||||||
VL_DEBUG_FUNC; // Declare debug()
|
VL_DEBUG_FUNC; // Declare debug()
|
||||||
|
|
||||||
AstVarScope* createFuncVar(AstCFunc* funcp, const string& name, AstVar* examplep) {
|
AstVarScope* createFuncVar(AstCFunc* funcp, const string& name, AstVar* examplep) {
|
||||||
AstVar* newvarp = new AstVar (funcp->fileline(), AstVarType::BLOCKTEMP, name,
|
AstVar* newvarp = new AstVar(funcp->fileline(), AstVarType::BLOCKTEMP, name,
|
||||||
examplep);
|
examplep);
|
||||||
newvarp->funcLocal(true);
|
newvarp->funcLocal(true);
|
||||||
funcp->addInitsp(newvarp);
|
funcp->addInitsp(newvarp);
|
||||||
AstVarScope* newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp);
|
AstVarScope* newvscp = new AstVarScope(funcp->fileline(), m_scopep, newvarp);
|
||||||
|
@ -331,8 +331,8 @@ private:
|
||||||
return newvscp;
|
return newvscp;
|
||||||
}
|
}
|
||||||
AstVarScope* createInputVar(AstCFunc* funcp, const string& name, AstBasicDTypeKwd kwd) {
|
AstVarScope* createInputVar(AstCFunc* funcp, const string& name, AstBasicDTypeKwd kwd) {
|
||||||
AstVar* newvarp = new AstVar (funcp->fileline(), AstVarType::BLOCKTEMP, name,
|
AstVar* newvarp = new AstVar(funcp->fileline(), AstVarType::BLOCKTEMP, name,
|
||||||
funcp->findBasicDType(kwd));
|
funcp->findBasicDType(kwd));
|
||||||
newvarp->funcLocal(true);
|
newvarp->funcLocal(true);
|
||||||
newvarp->combineType(AstVarType::INPUT);
|
newvarp->combineType(AstVarType::INPUT);
|
||||||
funcp->addArgsp(newvarp);
|
funcp->addArgsp(newvarp);
|
||||||
|
@ -345,12 +345,12 @@ private:
|
||||||
// It shouldn't matter, as they are only local variables.
|
// It shouldn't matter, as they are only local variables.
|
||||||
// We choose to do it under whichever called this function, which results
|
// We choose to do it under whichever called this function, which results
|
||||||
// in more cache locality.
|
// in more cache locality.
|
||||||
AstVar* newvarp = new AstVar (invarp->fileline(), AstVarType::BLOCKTEMP,
|
AstVar* newvarp = new AstVar(invarp->fileline(), AstVarType::BLOCKTEMP,
|
||||||
name, invarp);
|
name, invarp);
|
||||||
newvarp->funcLocal(false);
|
newvarp->funcLocal(false);
|
||||||
newvarp->propagateAttrFrom(invarp);
|
newvarp->propagateAttrFrom(invarp);
|
||||||
m_modp->addStmtp(newvarp);
|
m_modp->addStmtp(newvarp);
|
||||||
AstVarScope* newvscp = new AstVarScope (newvarp->fileline(), m_scopep, newvarp);
|
AstVarScope* newvscp = new AstVarScope(newvarp->fileline(), m_scopep, newvarp);
|
||||||
m_scopep->addVarp(newvscp);
|
m_scopep->addVarp(newvscp);
|
||||||
return newvscp;
|
return newvscp;
|
||||||
}
|
}
|
||||||
|
@ -405,22 +405,22 @@ private:
|
||||||
|
|
||||||
// Even if it's referencing a varref, we still make a temporary
|
// Even if it's referencing a varref, we still make a temporary
|
||||||
// Else task(x,x,x) might produce incorrect results
|
// Else task(x,x,x) might produce incorrect results
|
||||||
AstVarScope* outvscp = createVarScope (portp, namePrefix+"__"+portp->shortName());
|
AstVarScope* outvscp = createVarScope(portp, namePrefix+"__"+portp->shortName());
|
||||||
portp->user2p(outvscp);
|
portp->user2p(outvscp);
|
||||||
AstAssign* assp = new AstAssign (pinp->fileline(),
|
AstAssign* assp = new AstAssign(pinp->fileline(),
|
||||||
pinp,
|
pinp,
|
||||||
new AstVarRef(outvscp->fileline(), outvscp, false));
|
new AstVarRef(outvscp->fileline(), outvscp, false));
|
||||||
assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); // Ok if in <= block
|
assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); // Ok if in <= block
|
||||||
// Put assignment BEHIND of all other statements
|
// Put assignment BEHIND of all other statements
|
||||||
beginp->addNext(assp);
|
beginp->addNext(assp);
|
||||||
}
|
}
|
||||||
else if (portp->isInput()) {
|
else if (portp->isInput()) {
|
||||||
// Make input variable
|
// Make input variable
|
||||||
AstVarScope* inVscp = createVarScope (portp, namePrefix+"__"+portp->shortName());
|
AstVarScope* inVscp = createVarScope(portp, namePrefix+"__"+portp->shortName());
|
||||||
portp->user2p(inVscp);
|
portp->user2p(inVscp);
|
||||||
AstAssign* assp = new AstAssign (pinp->fileline(),
|
AstAssign* assp = new AstAssign(pinp->fileline(),
|
||||||
new AstVarRef(inVscp->fileline(), inVscp, true),
|
new AstVarRef(inVscp->fileline(), inVscp, true),
|
||||||
pinp);
|
pinp);
|
||||||
assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); // Ok if in <= block
|
assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); // Ok if in <= block
|
||||||
// Put assignment in FRONT of all other statements
|
// Put assignment in FRONT of all other statements
|
||||||
if (AstNode* afterp = beginp->nextp()) {
|
if (AstNode* afterp = beginp->nextp()) {
|
||||||
|
@ -441,7 +441,7 @@ private:
|
||||||
if (!portp->user2p()) {
|
if (!portp->user2p()) {
|
||||||
// Move it to a new localized variable
|
// Move it to a new localized variable
|
||||||
portp->unlinkFrBack(); pushDeletep(portp); // Remove it from the clone (not original)
|
portp->unlinkFrBack(); pushDeletep(portp); // Remove it from the clone (not original)
|
||||||
AstVarScope* localVscp = createVarScope (portp, namePrefix+"__"+portp->shortName());
|
AstVarScope* localVscp = createVarScope(portp, namePrefix+"__"+portp->shortName());
|
||||||
portp->user2p(localVscp);
|
portp->user2p(localVscp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -507,12 +507,12 @@ private:
|
||||||
|
|
||||||
// Even if it's referencing a varref, we still make a temporary
|
// Even if it's referencing a varref, we still make a temporary
|
||||||
// Else task(x,x,x) might produce incorrect results
|
// Else task(x,x,x) might produce incorrect results
|
||||||
AstVarScope* outvscp = createVarScope (portp, namePrefix+"__"+portp->shortName());
|
AstVarScope* outvscp = createVarScope(portp, namePrefix+"__"+portp->shortName());
|
||||||
portp->user2p(outvscp);
|
portp->user2p(outvscp);
|
||||||
pinp->replaceWith(new AstVarRef(outvscp->fileline(), outvscp, true));
|
pinp->replaceWith(new AstVarRef(outvscp->fileline(), outvscp, true));
|
||||||
AstAssign* assp = new AstAssign (pinp->fileline(),
|
AstAssign* assp = new AstAssign(pinp->fileline(),
|
||||||
pinp,
|
pinp,
|
||||||
new AstVarRef(outvscp->fileline(), outvscp, false));
|
new AstVarRef(outvscp->fileline(), outvscp, false));
|
||||||
assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); // Ok if in <= block
|
assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); // Ok if in <= block
|
||||||
// Put assignment BEHIND of all other statements
|
// Put assignment BEHIND of all other statements
|
||||||
beginp->addNext(assp);
|
beginp->addNext(assp);
|
||||||
|
@ -720,7 +720,7 @@ private:
|
||||||
// SAME CODE BELOW
|
// SAME CODE BELOW
|
||||||
args+= ", ";
|
args+= ", ";
|
||||||
if (args != "") { argnodesp = argnodesp->addNext(new AstText(portp->fileline(), args, true)); args=""; }
|
if (args != "") { argnodesp = argnodesp->addNext(new AstText(portp->fileline(), args, true)); args=""; }
|
||||||
AstVarScope* outvscp = createFuncVar (dpip, portp->name()+"__Vcvt", portp);
|
AstVarScope* outvscp = createFuncVar(dpip, portp->name()+"__Vcvt", portp);
|
||||||
AstVarRef* refp = new AstVarRef(portp->fileline(), outvscp, portp->isOutput());
|
AstVarRef* refp = new AstVarRef(portp->fileline(), outvscp, portp->isOutput());
|
||||||
argnodesp = argnodesp->addNextNull(refp);
|
argnodesp = argnodesp->addNextNull(refp);
|
||||||
|
|
||||||
|
@ -736,7 +736,7 @@ private:
|
||||||
// SAME CODE ABOVE
|
// SAME CODE ABOVE
|
||||||
args+= ", ";
|
args+= ", ";
|
||||||
if (args != "") { argnodesp = argnodesp->addNext(new AstText(portp->fileline(), args, true)); args=""; }
|
if (args != "") { argnodesp = argnodesp->addNext(new AstText(portp->fileline(), args, true)); args=""; }
|
||||||
AstVarScope* outvscp = createFuncVar (dpip, portp->name()+"__Vcvt", portp);
|
AstVarScope* outvscp = createFuncVar(dpip, portp->name()+"__Vcvt", portp);
|
||||||
AstVarRef* refp = new AstVarRef(portp->fileline(), outvscp, portp->isOutput());
|
AstVarRef* refp = new AstVarRef(portp->fileline(), outvscp, portp->isOutput());
|
||||||
argnodesp = argnodesp->addNextNull(refp);
|
argnodesp = argnodesp->addNextNull(refp);
|
||||||
}
|
}
|
||||||
|
@ -783,11 +783,11 @@ private:
|
||||||
: nodep->dpiTask() ? "int"
|
: nodep->dpiTask() ? "int"
|
||||||
: ""));
|
: ""));
|
||||||
dpip->dontCombine(true);
|
dpip->dontCombine(true);
|
||||||
dpip->entryPoint (false);
|
dpip->entryPoint(false);
|
||||||
dpip->funcPublic (true);
|
dpip->funcPublic(true);
|
||||||
dpip->isStatic (false);
|
dpip->isStatic(false);
|
||||||
dpip->pure (nodep->pure());
|
dpip->pure(nodep->pure());
|
||||||
dpip->dpiImport (true);
|
dpip->dpiImport(true);
|
||||||
// Add DPI reference to top, since it's a global function
|
// Add DPI reference to top, since it's a global function
|
||||||
m_topScopep->scopep()->addActivep(dpip);
|
m_topScopep->scopep()->addActivep(dpip);
|
||||||
makePortList(nodep, rtnvarp, dpip);
|
makePortList(nodep, rtnvarp, dpip);
|
||||||
|
@ -958,7 +958,7 @@ private:
|
||||||
|
|
||||||
AstVarScope* rtnvscp = NULL;
|
AstVarScope* rtnvscp = NULL;
|
||||||
if (rtnvarp) {
|
if (rtnvarp) {
|
||||||
rtnvscp = new AstVarScope (rtnvarp->fileline(), m_scopep, rtnvarp);
|
rtnvscp = new AstVarScope(rtnvarp->fileline(), m_scopep, rtnvarp);
|
||||||
m_scopep->addVarp(rtnvscp);
|
m_scopep->addVarp(rtnvscp);
|
||||||
rtnvarp->user2p(rtnvscp);
|
rtnvarp->user2p(rtnvscp);
|
||||||
}
|
}
|
||||||
|
@ -978,12 +978,12 @@ private:
|
||||||
: ""));
|
: ""));
|
||||||
// It's ok to combine imports because this is just a wrapper; duplicate wrappers can get merged.
|
// It's ok to combine imports because this is just a wrapper; duplicate wrappers can get merged.
|
||||||
cfuncp->dontCombine(!nodep->dpiImport());
|
cfuncp->dontCombine(!nodep->dpiImport());
|
||||||
cfuncp->entryPoint (!nodep->dpiImport());
|
cfuncp->entryPoint(!nodep->dpiImport());
|
||||||
cfuncp->funcPublic (nodep->taskPublic());
|
cfuncp->funcPublic(nodep->taskPublic());
|
||||||
cfuncp->dpiExport (nodep->dpiExport());
|
cfuncp->dpiExport(nodep->dpiExport());
|
||||||
cfuncp->dpiImportWrapper(nodep->dpiImport());
|
cfuncp->dpiImportWrapper(nodep->dpiImport());
|
||||||
cfuncp->isStatic (!(nodep->dpiImport()||nodep->taskPublic()));
|
cfuncp->isStatic(!(nodep->dpiImport()||nodep->taskPublic()));
|
||||||
cfuncp->pure (nodep->pure());
|
cfuncp->pure(nodep->pure());
|
||||||
//cfuncp->dpiImport // Not set in the wrapper - the called function has it set
|
//cfuncp->dpiImport // Not set in the wrapper - the called function has it set
|
||||||
if (cfuncp->dpiExport()) cfuncp->cname (nodep->cname());
|
if (cfuncp->dpiExport()) cfuncp->cname (nodep->cname());
|
||||||
|
|
||||||
|
@ -1001,9 +1001,9 @@ private:
|
||||||
}
|
}
|
||||||
if (nodep->dpiContext()) {
|
if (nodep->dpiContext()) {
|
||||||
// First three args go to dpiContext call
|
// First three args go to dpiContext call
|
||||||
createInputVar (cfuncp, "__Vscopep", AstBasicDTypeKwd::SCOPEPTR);
|
createInputVar(cfuncp, "__Vscopep", AstBasicDTypeKwd::SCOPEPTR);
|
||||||
createInputVar (cfuncp, "__Vfilenamep", AstBasicDTypeKwd::CHARPTR);
|
createInputVar(cfuncp, "__Vfilenamep", AstBasicDTypeKwd::CHARPTR);
|
||||||
createInputVar (cfuncp, "__Vlineno", AstBasicDTypeKwd::INT);
|
createInputVar(cfuncp, "__Vlineno", AstBasicDTypeKwd::INT);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nodep->dpiImport()) {
|
if (!nodep->dpiImport()) {
|
||||||
|
@ -1030,7 +1030,7 @@ private:
|
||||||
// "Normal" variable, mark inside function
|
// "Normal" variable, mark inside function
|
||||||
portp->funcLocal(true);
|
portp->funcLocal(true);
|
||||||
}
|
}
|
||||||
AstVarScope* newvscp = new AstVarScope (portp->fileline(), m_scopep, portp);
|
AstVarScope* newvscp = new AstVarScope(portp->fileline(), m_scopep, portp);
|
||||||
m_scopep->addVarp(newvscp);
|
m_scopep->addVarp(newvscp);
|
||||||
portp->user2p(newvscp);
|
portp->user2p(newvscp);
|
||||||
}
|
}
|
||||||
|
@ -1155,7 +1155,7 @@ private:
|
||||||
AstNode* visitp = NULL;
|
AstNode* visitp = NULL;
|
||||||
if (VN_IS(nodep, FuncRef)) {
|
if (VN_IS(nodep, FuncRef)) {
|
||||||
if (!nodep->taskp()->isFunction()) nodep->v3fatalSrc("func reference to non-function");
|
if (!nodep->taskp()->isFunction()) nodep->v3fatalSrc("func reference to non-function");
|
||||||
AstVarRef* outrefp = new AstVarRef (nodep->fileline(), outvscp, false);
|
AstVarRef* outrefp = new AstVarRef(nodep->fileline(), outvscp, false);
|
||||||
nodep->replaceWith(outrefp);
|
nodep->replaceWith(outrefp);
|
||||||
// Insert new statements
|
// Insert new statements
|
||||||
visitp = insertBeforeStmt(nodep, beginp);
|
visitp = insertBeforeStmt(nodep, beginp);
|
||||||
|
|
|
@ -488,7 +488,7 @@ private:
|
||||||
if (condp) condp = new AstOr (fl, condp, selp);
|
if (condp) condp = new AstOr (fl, condp, selp);
|
||||||
else condp = selp;
|
else condp = selp;
|
||||||
}
|
}
|
||||||
AstIf* ifp = new AstIf (fl, condp, NULL, NULL);
|
AstIf* ifp = new AstIf(fl, condp, NULL, NULL);
|
||||||
ifp->branchPred(AstBranchPred::BP_UNLIKELY);
|
ifp->branchPred(AstBranchPred::BP_UNLIKELY);
|
||||||
m_chgFuncp->addStmtsp(ifp);
|
m_chgFuncp->addStmtsp(ifp);
|
||||||
lastactp = &actset;
|
lastactp = &actset;
|
||||||
|
@ -647,7 +647,7 @@ private:
|
||||||
UINFO(8," SubCCALL "<<ccallp<<endl);
|
UINFO(8," SubCCALL "<<ccallp<<endl);
|
||||||
V3GraphVertex* ccallFuncVtxp = getCFuncVertexp(ccallp->funcp());
|
V3GraphVertex* ccallFuncVtxp = getCFuncVertexp(ccallp->funcp());
|
||||||
activityVtxp->slow(ccallp->funcp()->slow());
|
activityVtxp->slow(ccallp->funcp()->slow());
|
||||||
new V3GraphEdge (&m_graph, activityVtxp, ccallFuncVtxp, 1);
|
new V3GraphEdge(&m_graph, activityVtxp, ccallFuncVtxp, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -669,7 +669,7 @@ private:
|
||||||
// Need a non-null place to remember to later add a statement; make one
|
// Need a non-null place to remember to later add a statement; make one
|
||||||
if (!nodep->stmtsp()) nodep->addStmtsp(new AstComment(nodep->fileline(), "Tracing activity check"));
|
if (!nodep->stmtsp()) nodep->addStmtsp(new AstComment(nodep->fileline(), "Tracing activity check"));
|
||||||
V3GraphVertex* activityVtxp = getActivityVertexp(nodep->stmtsp(), nodep->slow());
|
V3GraphVertex* activityVtxp = getActivityVertexp(nodep->stmtsp(), nodep->slow());
|
||||||
new V3GraphEdge (&m_graph, activityVtxp, funcVtxp, 1);
|
new V3GraphEdge(&m_graph, activityVtxp, funcVtxp, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_funcp = nodep;
|
m_funcp = nodep;
|
||||||
|
@ -756,7 +756,7 @@ public:
|
||||||
void V3Trace::traceAll(AstNetlist* nodep) {
|
void V3Trace::traceAll(AstNetlist* nodep) {
|
||||||
UINFO(2,__FUNCTION__<<": "<<endl);
|
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||||
{
|
{
|
||||||
TraceVisitor visitor (nodep);
|
TraceVisitor visitor(nodep);
|
||||||
} // Destruct before checking
|
} // Destruct before checking
|
||||||
V3Global::dumpCheckGlobalTree("trace", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
V3Global::dumpCheckGlobalTree("trace", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
|
||||||
}
|
}
|
||||||
|
|
|
@ -939,11 +939,11 @@ class TristateVisitor : public TristateBaseVisitor {
|
||||||
V3Number oneIfEn = VN_CAST(constp->user1p(), Const)->num(); // visit(AstConst) already split into en/ones
|
V3Number oneIfEn = VN_CAST(constp->user1p(), Const)->num(); // visit(AstConst) already split into en/ones
|
||||||
V3Number oneIfEnOne = constp->num();
|
V3Number oneIfEnOne = constp->num();
|
||||||
AstVar* envarp = getCreateEnVarp(varrefp->varp());
|
AstVar* envarp = getCreateEnVarp(varrefp->varp());
|
||||||
AstNode* newp = new AstLogAnd (fl, new AstEq (fl, new AstConst(fl, oneIfEn),
|
AstNode* newp = new AstLogAnd(fl, new AstEq(fl, new AstConst(fl, oneIfEn),
|
||||||
new AstVarRef(fl, envarp, false)),
|
new AstVarRef(fl, envarp, false)),
|
||||||
// Keep the caseeq if there are X's present
|
// Keep the caseeq if there are X's present
|
||||||
new AstEqCase(fl, new AstConst(fl, oneIfEnOne),
|
new AstEqCase(fl, new AstConst(fl, oneIfEnOne),
|
||||||
varrefp));
|
varrefp));
|
||||||
if (neq) newp = new AstLogNot(fl, newp);
|
if (neq) newp = new AstLogNot(fl, newp);
|
||||||
UINFO(9," newceq "<<newp<<endl);
|
UINFO(9," newceq "<<newp<<endl);
|
||||||
if (debug()>=9) nodep->dumpTree(cout,"-caseeq-old: ");
|
if (debug()>=9) nodep->dumpTree(cout,"-caseeq-old: ");
|
||||||
|
|
|
@ -56,7 +56,7 @@ class UndrivenVarEntry {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
explicit UndrivenVarEntry (AstVar* varp) { // Construction for when a var is used
|
explicit UndrivenVarEntry(AstVar* varp) { // Construction for when a var is used
|
||||||
UINFO(9, "create "<<varp<<endl);
|
UINFO(9, "create "<<varp<<endl);
|
||||||
m_varp = varp;
|
m_varp = varp;
|
||||||
m_usedWhole = false;
|
m_usedWhole = false;
|
||||||
|
@ -113,7 +113,7 @@ public:
|
||||||
UINFO(9, "set d[*] "<<m_varp->name()<<endl);
|
UINFO(9, "set d[*] "<<m_varp->name()<<endl);
|
||||||
m_drivenWhole = true;
|
m_drivenWhole = true;
|
||||||
}
|
}
|
||||||
void usedBit (int bit, int width) {
|
void usedBit(int bit, int width) {
|
||||||
UINFO(9, "set u["<<(bit+width-1)<<":"<<bit<<"] "<<m_varp->name()<<endl);
|
UINFO(9, "set u["<<(bit+width-1)<<":"<<bit<<"] "<<m_varp->name()<<endl);
|
||||||
for (int i=0; i<width; i++) {
|
for (int i=0; i<width; i++) {
|
||||||
if (bitNumOk(bit+i)) {
|
if (bitNumOk(bit+i)) {
|
||||||
|
@ -121,7 +121,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void drivenBit (int bit, int width) {
|
void drivenBit(int bit, int width) {
|
||||||
UINFO(9, "set d["<<(bit+width-1)<<":"<<bit<<"] "<<m_varp->name()<<endl);
|
UINFO(9, "set d["<<(bit+width-1)<<":"<<bit<<"] "<<m_varp->name()<<endl);
|
||||||
for (int i=0; i<width; i++) {
|
for (int i=0; i<width; i++) {
|
||||||
if (bitNumOk(bit+i)) {
|
if (bitNumOk(bit+i)) {
|
||||||
|
@ -129,7 +129,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool isUsedNotDrivenBit (int bit, int width) const {
|
bool isUsedNotDrivenBit(int bit, int width) const {
|
||||||
for (int i=0; i<width; i++) {
|
for (int i=0; i<width; i++) {
|
||||||
if (bitNumOk(bit+i)
|
if (bitNumOk(bit+i)
|
||||||
&& (m_usedWhole || m_flags[(bit+i)*FLAGS_PER_BIT + FLAG_USED])
|
&& (m_usedWhole || m_flags[(bit+i)*FLAGS_PER_BIT + FLAG_USED])
|
||||||
|
@ -137,7 +137,7 @@ public:
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool isUsedNotDrivenAny () const {
|
bool isUsedNotDrivenAny() const {
|
||||||
return isUsedNotDrivenBit(0, m_flags.size()/FLAGS_PER_BIT);
|
return isUsedNotDrivenBit(0, m_flags.size()/FLAGS_PER_BIT);
|
||||||
}
|
}
|
||||||
bool unusedMatch(AstVar* nodep) {
|
bool unusedMatch(AstVar* nodep) {
|
||||||
|
@ -241,7 +241,7 @@ private:
|
||||||
|
|
||||||
UndrivenVarEntry* getEntryp(AstVar* nodep, int which_user) {
|
UndrivenVarEntry* getEntryp(AstVar* nodep, int which_user) {
|
||||||
if (!(which_user==1 ? nodep->user1p() : nodep->user2p())) {
|
if (!(which_user==1 ? nodep->user1p() : nodep->user2p())) {
|
||||||
UndrivenVarEntry* entryp = new UndrivenVarEntry (nodep);
|
UndrivenVarEntry* entryp = new UndrivenVarEntry(nodep);
|
||||||
//UINFO(9," Associate u="<<which_user<<" "<<(void*)this<<" "<<nodep->name()<<endl);
|
//UINFO(9," Associate u="<<which_user<<" "<<(void*)this<<" "<<nodep->name()<<endl);
|
||||||
m_entryps[which_user].push_back(entryp);
|
m_entryps[which_user].push_back(entryp);
|
||||||
if (which_user==1) nodep->user1p(entryp);
|
if (which_user==1) nodep->user1p(entryp);
|
||||||
|
@ -270,7 +270,7 @@ private:
|
||||||
for (int usr=1; usr<(m_alwaysp?3:2); ++usr) {
|
for (int usr=1; usr<(m_alwaysp?3:2); ++usr) {
|
||||||
// For assigns and non-combo always, do just usr==1, to look for module-wide undriven etc
|
// For assigns and non-combo always, do just usr==1, to look for module-wide undriven etc
|
||||||
// For non-combo always, run both usr==1 for above, and also usr==2 for always-only checks
|
// For non-combo always, run both usr==1 for above, and also usr==2 for always-only checks
|
||||||
UndrivenVarEntry* entryp = getEntryp (nodep, usr);
|
UndrivenVarEntry* entryp = getEntryp(nodep, usr);
|
||||||
if (nodep->isInput()
|
if (nodep->isInput()
|
||||||
|| nodep->isSigPublic() || nodep->isSigUserRWPublic()
|
|| nodep->isSigPublic() || nodep->isSigUserRWPublic()
|
||||||
|| (m_taskp && (m_taskp->dpiImport() || m_taskp->dpiExport()))) {
|
|| (m_taskp && (m_taskp->dpiImport() || m_taskp->dpiExport()))) {
|
||||||
|
@ -299,7 +299,7 @@ private:
|
||||||
AstConst* constp = VN_CAST(nodep->lsbp(), Const);
|
AstConst* constp = VN_CAST(nodep->lsbp(), Const);
|
||||||
if (varrefp && constp && !constp->num().isFourState()) {
|
if (varrefp && constp && !constp->num().isFourState()) {
|
||||||
for (int usr=1; usr<(m_alwaysp?3:2); ++usr) {
|
for (int usr=1; usr<(m_alwaysp?3:2); ++usr) {
|
||||||
UndrivenVarEntry* entryp = getEntryp (varrefp->varp(), usr);
|
UndrivenVarEntry* entryp = getEntryp(varrefp->varp(), usr);
|
||||||
int lsb = constp->toUInt();
|
int lsb = constp->toUInt();
|
||||||
if (m_inBBox || varrefp->lvalue()) {
|
if (m_inBBox || varrefp->lvalue()) {
|
||||||
// Don't warn if already driven earlier as "a=0; if(a) a=1;" is fine.
|
// Don't warn if already driven earlier as "a=0; if(a) a=1;" is fine.
|
||||||
|
@ -319,7 +319,7 @@ private:
|
||||||
virtual void visit(AstNodeVarRef* nodep) {
|
virtual void visit(AstNodeVarRef* nodep) {
|
||||||
// Any variable
|
// Any variable
|
||||||
for (int usr=1; usr<(m_alwaysp?3:2); ++usr) {
|
for (int usr=1; usr<(m_alwaysp?3:2); ++usr) {
|
||||||
UndrivenVarEntry* entryp = getEntryp (nodep->varp(), usr);
|
UndrivenVarEntry* entryp = getEntryp(nodep->varp(), usr);
|
||||||
bool fdrv = nodep->lvalue() && nodep->varp()->attrFileDescr(); // FD's are also being read from
|
bool fdrv = nodep->lvalue() && nodep->varp()->attrFileDescr(); // FD's are also being read from
|
||||||
if (m_inBBox || nodep->lvalue()) {
|
if (m_inBBox || nodep->lvalue()) {
|
||||||
if (usr==2 && m_alwaysp && entryp->isUsedNotDrivenAny()) {
|
if (usr==2 && m_alwaysp && entryp->isUsedNotDrivenAny()) {
|
||||||
|
|
|
@ -113,9 +113,8 @@ private:
|
||||||
if (needDly) prep->v3fatalSrc("Should have already converted to non-delay");
|
if (needDly) prep->v3fatalSrc("Should have already converted to non-delay");
|
||||||
AstNRelinker replaceHandle;
|
AstNRelinker replaceHandle;
|
||||||
AstNode* earliercondp = ifp->condp()->unlinkFrBack(&replaceHandle);
|
AstNode* earliercondp = ifp->condp()->unlinkFrBack(&replaceHandle);
|
||||||
AstNode* newp = new AstLogAnd (condp->fileline(),
|
AstNode* newp = new AstLogAnd(condp->fileline(),
|
||||||
condp,
|
condp, earliercondp);
|
||||||
earliercondp);
|
|
||||||
UINFO(4, "Edit BOUNDLVALUE "<<newp<<endl);
|
UINFO(4, "Edit BOUNDLVALUE "<<newp<<endl);
|
||||||
replaceHandle.relink(newp);
|
replaceHandle.relink(newp);
|
||||||
}
|
}
|
||||||
|
@ -133,8 +132,8 @@ private:
|
||||||
(new AstAssignDly(fl, prep,
|
(new AstAssignDly(fl, prep,
|
||||||
new AstVarRef(fl, varp, false)))
|
new AstVarRef(fl, varp, false)))
|
||||||
: static_cast<AstNode*>
|
: static_cast<AstNode*>
|
||||||
(new AstAssign (fl, prep,
|
(new AstAssign(fl, prep,
|
||||||
new AstVarRef(fl, varp, false)))),
|
new AstVarRef(fl, varp, false)))),
|
||||||
NULL);
|
NULL);
|
||||||
newp->branchPred(AstBranchPred::BP_LIKELY);
|
newp->branchPred(AstBranchPred::BP_LIKELY);
|
||||||
if (debug()>=9) newp->dumpTree(cout," _new: ");
|
if (debug()>=9) newp->dumpTree(cout," _new: ");
|
||||||
|
@ -188,13 +187,13 @@ private:
|
||||||
if (((VN_IS(lhsp, Const) && VN_CAST(lhsp, Const)->num().isFourState())
|
if (((VN_IS(lhsp, Const) && VN_CAST(lhsp, Const)->num().isFourState())
|
||||||
|| (VN_IS(rhsp, Const) && VN_CAST(rhsp, Const)->num().isFourState()))) {
|
|| (VN_IS(rhsp, Const) && VN_CAST(rhsp, Const)->num().isFourState()))) {
|
||||||
V3Number num(nodep->fileline(), 1, (VN_IS(nodep, EqCase) ? 0:1));
|
V3Number num(nodep->fileline(), 1, (VN_IS(nodep, EqCase) ? 0:1));
|
||||||
newp = new AstConst (nodep->fileline(), num);
|
newp = new AstConst(nodep->fileline(), num);
|
||||||
lhsp->deleteTree(); VL_DANGLING(lhsp);
|
lhsp->deleteTree(); VL_DANGLING(lhsp);
|
||||||
rhsp->deleteTree(); VL_DANGLING(rhsp);
|
rhsp->deleteTree(); VL_DANGLING(rhsp);
|
||||||
} else {
|
} else {
|
||||||
if (VN_IS(nodep, EqCase))
|
if (VN_IS(nodep, EqCase))
|
||||||
newp = new AstEq (nodep->fileline(), lhsp, rhsp);
|
newp = new AstEq(nodep->fileline(), lhsp, rhsp);
|
||||||
else newp = new AstNeq (nodep->fileline(), lhsp, rhsp);
|
else newp = new AstNeq(nodep->fileline(), lhsp, rhsp);
|
||||||
}
|
}
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||||
|
@ -217,19 +216,19 @@ private:
|
||||||
if (!VN_IS(rhsp, Const)) {
|
if (!VN_IS(rhsp, Const)) {
|
||||||
nodep->v3error("Unsupported: RHS of ==? or !=? must be constant to be synthesizable"); // Says spec.
|
nodep->v3error("Unsupported: RHS of ==? or !=? must be constant to be synthesizable"); // Says spec.
|
||||||
// Replace with anything that won't cause more errors
|
// Replace with anything that won't cause more errors
|
||||||
newp = new AstEq (nodep->fileline(), lhsp, rhsp);
|
newp = new AstEq(nodep->fileline(), lhsp, rhsp);
|
||||||
} else {
|
} else {
|
||||||
// X or Z's become mask, ala case statements.
|
// X or Z's become mask, ala case statements.
|
||||||
V3Number nummask (rhsp->fileline(), rhsp->width());
|
V3Number nummask (rhsp->fileline(), rhsp->width());
|
||||||
nummask.opBitsNonX(VN_CAST(rhsp, Const)->num());
|
nummask.opBitsNonX(VN_CAST(rhsp, Const)->num());
|
||||||
V3Number numval (rhsp->fileline(), rhsp->width());
|
V3Number numval (rhsp->fileline(), rhsp->width());
|
||||||
numval.opBitsOne (VN_CAST(rhsp, Const)->num());
|
numval.opBitsOne(VN_CAST(rhsp, Const)->num());
|
||||||
AstNode* and1p = new AstAnd(nodep->fileline(), lhsp,
|
AstNode* and1p = new AstAnd(nodep->fileline(), lhsp,
|
||||||
new AstConst(nodep->fileline(), nummask));
|
new AstConst(nodep->fileline(), nummask));
|
||||||
AstNode* and2p = new AstConst(nodep->fileline(), numval);
|
AstNode* and2p = new AstConst(nodep->fileline(), numval);
|
||||||
if (VN_IS(nodep, EqWild))
|
if (VN_IS(nodep, EqWild))
|
||||||
newp = new AstEq (nodep->fileline(), and1p, and2p);
|
newp = new AstEq(nodep->fileline(), and1p, and2p);
|
||||||
else newp = new AstNeq (nodep->fileline(), and1p, and2p);
|
else newp = new AstNeq(nodep->fileline(), and1p, and2p);
|
||||||
rhsp->deleteTree(); VL_DANGLING(rhsp);
|
rhsp->deleteTree(); VL_DANGLING(rhsp);
|
||||||
}
|
}
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
|
@ -256,7 +255,7 @@ private:
|
||||||
// Ahh, we're two state, so this is easy
|
// Ahh, we're two state, so this is easy
|
||||||
UINFO(4," ISUNKNOWN->0 "<<nodep<<endl);
|
UINFO(4," ISUNKNOWN->0 "<<nodep<<endl);
|
||||||
V3Number zero (nodep->fileline(), 1, 0);
|
V3Number zero (nodep->fileline(), 1, 0);
|
||||||
AstConst* newp = new AstConst (nodep->fileline(), zero);
|
AstConst* newp = new AstConst(nodep->fileline(), zero);
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||||
}
|
}
|
||||||
|
@ -291,8 +290,8 @@ private:
|
||||||
string newvarname = ((string)"__Vxrand"
|
string newvarname = ((string)"__Vxrand"
|
||||||
+cvtToStr(m_modp->varNumGetInc()));
|
+cvtToStr(m_modp->varNumGetInc()));
|
||||||
AstVar* newvarp
|
AstVar* newvarp
|
||||||
= new AstVar (nodep->fileline(), AstVarType::XTEMP, newvarname,
|
= new AstVar(nodep->fileline(), AstVarType::XTEMP, newvarname,
|
||||||
VFlagLogicPacked(), nodep->width());
|
VFlagLogicPacked(), nodep->width());
|
||||||
++m_statUnkVars;
|
++m_statUnkVars;
|
||||||
AstNRelinker replaceHandle;
|
AstNRelinker replaceHandle;
|
||||||
nodep->unlinkFrBack(&replaceHandle);
|
nodep->unlinkFrBack(&replaceHandle);
|
||||||
|
@ -340,9 +339,9 @@ private:
|
||||||
V3Number maxmsbnum (nodep->fileline(), nodep->lsbp()->width(), maxmsb);
|
V3Number maxmsbnum (nodep->fileline(), nodep->lsbp()->width(), maxmsb);
|
||||||
|
|
||||||
// If (maxmsb >= selected), we're in bound
|
// If (maxmsb >= selected), we're in bound
|
||||||
AstNode* condp = new AstGte (nodep->fileline(),
|
AstNode* condp = new AstGte(nodep->fileline(),
|
||||||
new AstConst(nodep->fileline(), maxmsbnum),
|
new AstConst(nodep->fileline(), maxmsbnum),
|
||||||
nodep->lsbp()->cloneTree(false));
|
nodep->lsbp()->cloneTree(false));
|
||||||
// See if the condition is constant true (e.g. always in bound due to constant select)
|
// See if the condition is constant true (e.g. always in bound due to constant select)
|
||||||
// Note below has null backp(); the Edit function knows how to deal with that.
|
// Note below has null backp(); the Edit function knows how to deal with that.
|
||||||
condp = V3Const::constifyEdit(condp);
|
condp = V3Const::constifyEdit(condp);
|
||||||
|
@ -356,10 +355,10 @@ private:
|
||||||
nodep->unlinkFrBack(&replaceHandle);
|
nodep->unlinkFrBack(&replaceHandle);
|
||||||
V3Number xnum (nodep->fileline(), nodep->width());
|
V3Number xnum (nodep->fileline(), nodep->width());
|
||||||
xnum.setAllBitsX();
|
xnum.setAllBitsX();
|
||||||
AstNode* newp = new AstCondBound (nodep->fileline(),
|
AstNode* newp = new AstCondBound(nodep->fileline(),
|
||||||
condp,
|
condp,
|
||||||
nodep,
|
nodep,
|
||||||
new AstConst(nodep->fileline(), xnum));
|
new AstConst(nodep->fileline(), xnum));
|
||||||
if (debug()>=9) newp->dumpTree(cout," _new: ");
|
if (debug()>=9) newp->dumpTree(cout," _new: ");
|
||||||
// Link in conditional
|
// Link in conditional
|
||||||
replaceHandle.relink(newp);
|
replaceHandle.relink(newp);
|
||||||
|
@ -402,9 +401,9 @@ private:
|
||||||
V3Number widthnum (nodep->fileline(), nodep->bitp()->width(), declElements-1);
|
V3Number widthnum (nodep->fileline(), nodep->bitp()->width(), declElements-1);
|
||||||
|
|
||||||
// See if the condition is constant true
|
// See if the condition is constant true
|
||||||
AstNode* condp = new AstGte (nodep->fileline(),
|
AstNode* condp = new AstGte(nodep->fileline(),
|
||||||
new AstConst(nodep->fileline(), widthnum),
|
new AstConst(nodep->fileline(), widthnum),
|
||||||
nodep->bitp()->cloneTree(false));
|
nodep->bitp()->cloneTree(false));
|
||||||
// Note below has null backp(); the Edit function knows how to deal with that.
|
// Note below has null backp(); the Edit function knows how to deal with that.
|
||||||
condp = V3Const::constifyEdit(condp);
|
condp = V3Const::constifyEdit(condp);
|
||||||
if (condp->isOne()) {
|
if (condp->isOne()) {
|
||||||
|
@ -422,10 +421,9 @@ private:
|
||||||
} else {
|
} else {
|
||||||
xnum.setAllBitsX();
|
xnum.setAllBitsX();
|
||||||
}
|
}
|
||||||
AstNode* newp = new AstCondBound (nodep->fileline(),
|
AstNode* newp = new AstCondBound(nodep->fileline(),
|
||||||
condp,
|
condp, nodep,
|
||||||
nodep,
|
new AstConst(nodep->fileline(), xnum));
|
||||||
new AstConst(nodep->fileline(), xnum));
|
|
||||||
if (debug()>=9) newp->dumpTree(cout," _new: ");
|
if (debug()>=9) newp->dumpTree(cout," _new: ");
|
||||||
// Link in conditional, can blow away temp xor
|
// Link in conditional, can blow away temp xor
|
||||||
replaceHandle.relink(newp);
|
replaceHandle.relink(newp);
|
||||||
|
@ -437,10 +435,9 @@ private:
|
||||||
AstNRelinker replaceHandle;
|
AstNRelinker replaceHandle;
|
||||||
AstNode* bitp = nodep->bitp()->unlinkFrBack(&replaceHandle);
|
AstNode* bitp = nodep->bitp()->unlinkFrBack(&replaceHandle);
|
||||||
V3Number zeronum (nodep->fileline(), bitp->width(), 0);
|
V3Number zeronum (nodep->fileline(), bitp->width(), 0);
|
||||||
AstNode* newp = new AstCondBound (bitp->fileline(),
|
AstNode* newp = new AstCondBound(bitp->fileline(),
|
||||||
condp,
|
condp, bitp,
|
||||||
bitp,
|
new AstConst(bitp->fileline(), zeronum));
|
||||||
new AstConst(bitp->fileline(), zeronum));
|
|
||||||
// Added X's, tristate them too
|
// Added X's, tristate them too
|
||||||
if (debug()>=9) newp->dumpTree(cout," _new: ");
|
if (debug()>=9) newp->dumpTree(cout," _new: ");
|
||||||
replaceHandle.relink(newp);
|
replaceHandle.relink(newp);
|
||||||
|
|
|
@ -405,8 +405,8 @@ private:
|
||||||
}
|
}
|
||||||
if (nodep->lhsp()->isString()
|
if (nodep->lhsp()->isString()
|
||||||
|| nodep->rhsp()->isString()) {
|
|| nodep->rhsp()->isString()) {
|
||||||
AstNode* newp = new AstConcatN (nodep->fileline(),nodep->lhsp()->unlinkFrBack(),
|
AstNode* newp = new AstConcatN(nodep->fileline(),nodep->lhsp()->unlinkFrBack(),
|
||||||
nodep->rhsp()->unlinkFrBack());
|
nodep->rhsp()->unlinkFrBack());
|
||||||
nodep->replaceWith(newp);
|
nodep->replaceWith(newp);
|
||||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||||
return;
|
return;
|
||||||
|
@ -846,14 +846,14 @@ private:
|
||||||
iterateCheck(nodep,"LHS",nodep->lhsp(),SELF,FINAL,nodep->dtypep(),EXTEND_EXP);
|
iterateCheck(nodep,"LHS",nodep->lhsp(),SELF,FINAL,nodep->dtypep(),EXTEND_EXP);
|
||||||
AstNode* newp = NULL; // No change
|
AstNode* newp = NULL; // No change
|
||||||
if (nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()) {
|
if (nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()) {
|
||||||
newp = new AstPowSS (nodep->fileline(), nodep->lhsp()->unlinkFrBack(),
|
newp = new AstPowSS(nodep->fileline(), nodep->lhsp()->unlinkFrBack(),
|
||||||
nodep->rhsp()->unlinkFrBack());
|
nodep->rhsp()->unlinkFrBack());
|
||||||
} else if (nodep->lhsp()->isSigned() && !nodep->rhsp()->isSigned()) {
|
} else if (nodep->lhsp()->isSigned() && !nodep->rhsp()->isSigned()) {
|
||||||
newp = new AstPowSU (nodep->fileline(), nodep->lhsp()->unlinkFrBack(),
|
newp = new AstPowSU(nodep->fileline(), nodep->lhsp()->unlinkFrBack(),
|
||||||
nodep->rhsp()->unlinkFrBack());
|
nodep->rhsp()->unlinkFrBack());
|
||||||
} else if (!nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()) {
|
} else if (!nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned()) {
|
||||||
newp = new AstPowUS (nodep->fileline(), nodep->lhsp()->unlinkFrBack(),
|
newp = new AstPowUS(nodep->fileline(), nodep->lhsp()->unlinkFrBack(),
|
||||||
nodep->rhsp()->unlinkFrBack());
|
nodep->rhsp()->unlinkFrBack());
|
||||||
}
|
}
|
||||||
if (newp) {
|
if (newp) {
|
||||||
newp->dtypeFrom(nodep);
|
newp->dtypeFrom(nodep);
|
||||||
|
@ -2967,7 +2967,7 @@ private:
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// LOWER LEVEL WIDTH METHODS (none iterate)
|
// LOWER LEVEL WIDTH METHODS (none iterate)
|
||||||
|
|
||||||
bool widthBad (AstNode* nodep, AstNodeDType* expDTypep) {
|
bool widthBad(AstNode* nodep, AstNodeDType* expDTypep) {
|
||||||
int expWidth = expDTypep->width();
|
int expWidth = expDTypep->width();
|
||||||
int expWidthMin = expDTypep->widthMin();
|
int expWidthMin = expDTypep->widthMin();
|
||||||
if (!nodep->dtypep()) nodep->v3fatalSrc("Under node "<<nodep->prettyTypeName()
|
if (!nodep->dtypep()) nodep->v3fatalSrc("Under node "<<nodep->prettyTypeName()
|
||||||
|
@ -2983,7 +2983,7 @@ private:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fixWidthExtend (AstNode* nodep, AstNodeDType* expDTypep, ExtendRule extendRule) {
|
void fixWidthExtend(AstNode* nodep, AstNodeDType* expDTypep, ExtendRule extendRule) {
|
||||||
// Fix the width mismatch by extending or truncating bits
|
// Fix the width mismatch by extending or truncating bits
|
||||||
// *ONLY* call this from checkWidth()
|
// *ONLY* call this from checkWidth()
|
||||||
// Truncation is rarer, but can occur: parameter [3:0] FOO = 64'h12312;
|
// Truncation is rarer, but can occur: parameter [3:0] FOO = 64'h12312;
|
||||||
|
@ -3042,7 +3042,7 @@ private:
|
||||||
UINFO(4," _new: "<<nodep<<endl);
|
UINFO(4," _new: "<<nodep<<endl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fixWidthReduce (AstNode* nodep) {
|
void fixWidthReduce(AstNode* nodep) {
|
||||||
// Fix the width mismatch by adding a reduction OR operator
|
// Fix the width mismatch by adding a reduction OR operator
|
||||||
// IF (A(CONSTwide)) becomes IF (A(CONSTreduced))
|
// IF (A(CONSTwide)) becomes IF (A(CONSTreduced))
|
||||||
// IF (A(somewide)) becomes IF (A(REDOR(somewide)))
|
// IF (A(somewide)) becomes IF (A(REDOR(somewide)))
|
||||||
|
@ -3070,7 +3070,7 @@ private:
|
||||||
UINFO(4," _new: "<<nodep<<endl);
|
UINFO(4," _new: "<<nodep<<endl);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fixAutoExtend (AstNode*& nodepr, int expWidth) {
|
bool fixAutoExtend(AstNode*& nodepr, int expWidth) {
|
||||||
// For SystemVerilog '0,'1,'x,'z, autoextend and don't warn
|
// For SystemVerilog '0,'1,'x,'z, autoextend and don't warn
|
||||||
if (AstConst* constp = VN_CAST(nodepr, Const)) {
|
if (AstConst* constp = VN_CAST(nodepr, Const)) {
|
||||||
if (constp->num().autoExtend() && !constp->num().sized() && constp->width()==1) {
|
if (constp->num().autoExtend() && !constp->num().sized() && constp->width()==1) {
|
||||||
|
@ -3094,7 +3094,7 @@ private:
|
||||||
bool similarDTypeRecurse(AstNodeDType* node1p, AstNodeDType* node2p) {
|
bool similarDTypeRecurse(AstNodeDType* node1p, AstNodeDType* node2p) {
|
||||||
return node1p->skipRefp()->similarDType(node2p->skipRefp());
|
return node1p->skipRefp()->similarDType(node2p->skipRefp());
|
||||||
}
|
}
|
||||||
void iterateCheckFileDesc (AstNode* nodep, AstNode* underp, Stage stage) {
|
void iterateCheckFileDesc(AstNode* nodep, AstNode* underp, Stage stage) {
|
||||||
if (stage != BOTH) nodep->v3fatalSrc("Bad call");
|
if (stage != BOTH) nodep->v3fatalSrc("Bad call");
|
||||||
// underp may change as a result of replacement
|
// underp may change as a result of replacement
|
||||||
underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,PRELIM).p());
|
underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,PRELIM).p());
|
||||||
|
@ -3102,7 +3102,7 @@ private:
|
||||||
underp = iterateCheck(nodep,"file_descriptor",underp,SELF,FINAL,expDTypep,EXTEND_EXP);
|
underp = iterateCheck(nodep,"file_descriptor",underp,SELF,FINAL,expDTypep,EXTEND_EXP);
|
||||||
if (underp) {} // cppcheck
|
if (underp) {} // cppcheck
|
||||||
}
|
}
|
||||||
void iterateCheckReal (AstNode* nodep, const char* side, AstNode* underp, Stage stage) {
|
void iterateCheckReal(AstNode* nodep, const char* side, AstNode* underp, Stage stage) {
|
||||||
// Coerce child to real if not already. Child is self-determined
|
// Coerce child to real if not already. Child is self-determined
|
||||||
// e.g. nodep=ADDD, underp=ADD in ADDD(ADD(a,b), real-CONST)
|
// e.g. nodep=ADDD, underp=ADD in ADDD(ADD(a,b), real-CONST)
|
||||||
// Don't need separate PRELIM and FINAL(double) calls;
|
// Don't need separate PRELIM and FINAL(double) calls;
|
||||||
|
@ -3118,7 +3118,7 @@ private:
|
||||||
}
|
}
|
||||||
if (underp) {} // cppcheck
|
if (underp) {} // cppcheck
|
||||||
}
|
}
|
||||||
void iterateCheckString (AstNode* nodep, const char* side, AstNode* underp, Stage stage) {
|
void iterateCheckString(AstNode* nodep, const char* side, AstNode* underp, Stage stage) {
|
||||||
if (stage & PRELIM) {
|
if (stage & PRELIM) {
|
||||||
underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,PRELIM).p());
|
underp = userIterateSubtreeReturnEdits(underp, WidthVP(SELF,PRELIM).p());
|
||||||
}
|
}
|
||||||
|
@ -3128,8 +3128,8 @@ private:
|
||||||
}
|
}
|
||||||
if (underp) {} // cppcheck
|
if (underp) {} // cppcheck
|
||||||
}
|
}
|
||||||
void iterateCheckSizedSelf (AstNode* nodep, const char* side, AstNode* underp,
|
void iterateCheckSizedSelf(AstNode* nodep, const char* side, AstNode* underp,
|
||||||
Determ determ, Stage stage) {
|
Determ determ, Stage stage) {
|
||||||
// Coerce child to any sized-number data type; child is self-determined i.e. isolated from expected type.
|
// Coerce child to any sized-number data type; child is self-determined i.e. isolated from expected type.
|
||||||
// e.g. nodep=CONCAT, underp=lhs in CONCAT(lhs,rhs)
|
// e.g. nodep=CONCAT, underp=lhs in CONCAT(lhs,rhs)
|
||||||
if (determ != SELF) nodep->v3fatalSrc("Bad call");
|
if (determ != SELF) nodep->v3fatalSrc("Bad call");
|
||||||
|
@ -3154,7 +3154,7 @@ private:
|
||||||
if (rhsp) {} // cppcheck
|
if (rhsp) {} // cppcheck
|
||||||
}
|
}
|
||||||
|
|
||||||
void iterateCheckBool (AstNode* nodep, const char* side, AstNode* underp, Stage stage) {
|
void iterateCheckBool(AstNode* nodep, const char* side, AstNode* underp, Stage stage) {
|
||||||
if (stage != BOTH) nodep->v3fatalSrc("Bad call"); // Booleans always self-determined so do BOTH at once
|
if (stage != BOTH) nodep->v3fatalSrc("Bad call"); // Booleans always self-determined so do BOTH at once
|
||||||
// Underp is used in a self-determined but boolean context, reduce a multibit number to one bit
|
// Underp is used in a self-determined but boolean context, reduce a multibit number to one bit
|
||||||
// stage is always BOTH so not passed as argument
|
// stage is always BOTH so not passed as argument
|
||||||
|
@ -3193,10 +3193,10 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AstNode* iterateCheck (AstNode* nodep, const char* side, AstNode* underp,
|
AstNode* iterateCheck(AstNode* nodep, const char* side, AstNode* underp,
|
||||||
Determ determ, Stage stage, AstNodeDType* expDTypep,
|
Determ determ, Stage stage, AstNodeDType* expDTypep,
|
||||||
ExtendRule extendRule,
|
ExtendRule extendRule,
|
||||||
bool warnOn=true) {
|
bool warnOn=true) {
|
||||||
// Perform data type check on underp, which is underneath nodep used for error reporting
|
// Perform data type check on underp, which is underneath nodep used for error reporting
|
||||||
// Returns the new underp
|
// Returns the new underp
|
||||||
// Conversion to/from doubles and integers are before iterating.
|
// Conversion to/from doubles and integers are before iterating.
|
||||||
|
@ -3249,11 +3249,11 @@ private:
|
||||||
return underp;
|
return underp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void widthCheckSized (AstNode* nodep, const char* side,
|
void widthCheckSized(AstNode* nodep, const char* side,
|
||||||
AstNode* underp, // Node to be checked or have typecast added in front of
|
AstNode* underp, // Node to be checked or have typecast added in front of
|
||||||
AstNodeDType* expDTypep,
|
AstNodeDType* expDTypep,
|
||||||
ExtendRule extendRule,
|
ExtendRule extendRule,
|
||||||
bool warnOn=true) {
|
bool warnOn=true) {
|
||||||
// Issue warnings on sized number width mismatches, then do appropriate size extension
|
// Issue warnings on sized number width mismatches, then do appropriate size extension
|
||||||
// Generally iterateCheck is what is wanted instead of this
|
// Generally iterateCheck is what is wanted instead of this
|
||||||
//UINFO(9,"wchk "<<side<<endl<<" "<<nodep<<endl<<" "<<underp<<endl<<" e="<<expDTypep<<" i"<<warnOn<<endl);
|
//UINFO(9,"wchk "<<side<<endl<<" "<<nodep<<endl<<" "<<underp<<endl<<" e="<<expDTypep<<" i"<<warnOn<<endl);
|
||||||
|
@ -3617,11 +3617,11 @@ private:
|
||||||
AstNodeArrayDType* vardtypep = new AstUnpackArrayDType(nodep->fileline(),
|
AstNodeArrayDType* vardtypep = new AstUnpackArrayDType(nodep->fileline(),
|
||||||
nodep->findSigned32DType(),
|
nodep->findSigned32DType(),
|
||||||
new AstRange(nodep->fileline(), msbdim, 0));
|
new AstRange(nodep->fileline(), msbdim, 0));
|
||||||
AstInitArray* initp = new AstInitArray (nodep->fileline(), vardtypep, NULL);
|
AstInitArray* initp = new AstInitArray(nodep->fileline(), vardtypep, NULL);
|
||||||
v3Global.rootp()->typeTablep()->addTypesp(vardtypep);
|
v3Global.rootp()->typeTablep()->addTypesp(vardtypep);
|
||||||
AstVar* varp = new AstVar (nodep->fileline(), AstVarType::MODULETEMP,
|
AstVar* varp = new AstVar(nodep->fileline(), AstVarType::MODULETEMP,
|
||||||
"__Vdimtab_" + VString::downcase(attrType.ascii()) + cvtToStr(m_dtTables++),
|
"__Vdimtab_" + VString::downcase(attrType.ascii()) + cvtToStr(m_dtTables++),
|
||||||
vardtypep);
|
vardtypep);
|
||||||
varp->isConst(true);
|
varp->isConst(true);
|
||||||
varp->isStatic(true);
|
varp->isStatic(true);
|
||||||
varp->valuep(initp);
|
varp->valuep(initp);
|
||||||
|
@ -3652,11 +3652,11 @@ private:
|
||||||
AstNodeArrayDType* vardtypep = new AstUnpackArrayDType(nodep->fileline(),
|
AstNodeArrayDType* vardtypep = new AstUnpackArrayDType(nodep->fileline(),
|
||||||
basep,
|
basep,
|
||||||
new AstRange(nodep->fileline(), msbdim, 0));
|
new AstRange(nodep->fileline(), msbdim, 0));
|
||||||
AstInitArray* initp = new AstInitArray (nodep->fileline(), vardtypep, NULL);
|
AstInitArray* initp = new AstInitArray(nodep->fileline(), vardtypep, NULL);
|
||||||
v3Global.rootp()->typeTablep()->addTypesp(vardtypep);
|
v3Global.rootp()->typeTablep()->addTypesp(vardtypep);
|
||||||
AstVar* varp = new AstVar (nodep->fileline(), AstVarType::MODULETEMP,
|
AstVar* varp = new AstVar(nodep->fileline(), AstVarType::MODULETEMP,
|
||||||
"__Venumtab_" + VString::downcase(attrType.ascii()) + cvtToStr(m_dtTables++),
|
"__Venumtab_" + VString::downcase(attrType.ascii()) + cvtToStr(m_dtTables++),
|
||||||
vardtypep);
|
vardtypep);
|
||||||
varp->isConst(true);
|
varp->isConst(true);
|
||||||
varp->isStatic(true);
|
varp->isStatic(true);
|
||||||
varp->valuep(initp);
|
varp->valuep(initp);
|
||||||
|
@ -3894,7 +3894,7 @@ void V3Width::width(AstNetlist* nodep) {
|
||||||
|
|
||||||
//! Single node parameter propagation
|
//! Single node parameter propagation
|
||||||
//! Smaller step... Only do a single node for parameter propagation
|
//! Smaller step... Only do a single node for parameter propagation
|
||||||
AstNode* V3Width::widthParamsEdit (AstNode* nodep) {
|
AstNode* V3Width::widthParamsEdit(AstNode* nodep) {
|
||||||
UINFO(4,__FUNCTION__<<": "<<nodep<<endl);
|
UINFO(4,__FUNCTION__<<": "<<nodep<<endl);
|
||||||
// We should do it in bottom-up module order, but it works in any order.
|
// We should do it in bottom-up module order, but it works in any order.
|
||||||
WidthVisitor visitor (true, false);
|
WidthVisitor visitor (true, false);
|
||||||
|
|
|
@ -72,7 +72,7 @@ class WidthCommitVisitor : public AstNVisitor {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// METHODS
|
// METHODS
|
||||||
static AstConst* newIfConstCommitSize (AstConst* nodep) {
|
static AstConst* newIfConstCommitSize(AstConst* nodep) {
|
||||||
if (((nodep->dtypep()->width() != nodep->num().width())
|
if (((nodep->dtypep()->width() != nodep->num().width())
|
||||||
|| !nodep->num().sized())
|
|| !nodep->num().sized())
|
||||||
&& !nodep->num().isString()) { // Need to force the number from unsized to sized
|
&& !nodep->num().isString()) { // Need to force the number from unsized to sized
|
||||||
|
|
|
@ -207,10 +207,10 @@ private:
|
||||||
// SELBIT(array, index) -> ARRAYSEL(array, index)
|
// SELBIT(array, index) -> ARRAYSEL(array, index)
|
||||||
AstNode* subp = rhsp;
|
AstNode* subp = rhsp;
|
||||||
if (fromRange.lo()!=0 || fromRange.hi()<0) {
|
if (fromRange.lo()!=0 || fromRange.hi()<0) {
|
||||||
subp = newSubNeg (subp, fromRange.lo());
|
subp = newSubNeg(subp, fromRange.lo());
|
||||||
}
|
}
|
||||||
AstArraySel* newp = new AstArraySel (nodep->fileline(),
|
AstArraySel* newp = new AstArraySel(nodep->fileline(),
|
||||||
fromp, subp);
|
fromp, subp);
|
||||||
newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference
|
newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference
|
||||||
if (debug()>=9) newp->dumpTree(cout,"--SELBTn: ");
|
if (debug()>=9) newp->dumpTree(cout,"--SELBTn: ");
|
||||||
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
|
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
|
||||||
|
@ -229,12 +229,12 @@ private:
|
||||||
adtypep->v3fatalSrc("Array extraction with width miscomputed "
|
adtypep->v3fatalSrc("Array extraction with width miscomputed "
|
||||||
<<adtypep->width()<<"/"<<fromRange.elements());
|
<<adtypep->width()<<"/"<<fromRange.elements());
|
||||||
int elwidth = adtypep->width() / fromRange.elements();
|
int elwidth = adtypep->width() / fromRange.elements();
|
||||||
AstSel* newp = new AstSel (nodep->fileline(),
|
AstSel* newp = new AstSel(nodep->fileline(),
|
||||||
fromp,
|
fromp,
|
||||||
new AstMul(nodep->fileline(),
|
new AstMul(nodep->fileline(),
|
||||||
new AstConst(nodep->fileline(),AstConst::Unsized32(),elwidth),
|
new AstConst(nodep->fileline(),AstConst::Unsized32(),elwidth),
|
||||||
subp),
|
subp),
|
||||||
new AstConst (nodep->fileline(),AstConst::Unsized32(),elwidth));
|
new AstConst(nodep->fileline(),AstConst::Unsized32(),elwidth));
|
||||||
newp->declRange(fromRange);
|
newp->declRange(fromRange);
|
||||||
newp->declElWidth(elwidth);
|
newp->declElWidth(elwidth);
|
||||||
newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference
|
newp->dtypeFrom(adtypep->subDTypep()); // Need to strip off array reference
|
||||||
|
@ -243,11 +243,11 @@ private:
|
||||||
}
|
}
|
||||||
else if (VN_IS(ddtypep, BasicDType)) {
|
else if (VN_IS(ddtypep, BasicDType)) {
|
||||||
// SELBIT(range, index) -> SEL(array, index, 1)
|
// SELBIT(range, index) -> SEL(array, index, 1)
|
||||||
AstSel* newp = new AstSel (nodep->fileline(),
|
AstSel* newp = new AstSel(nodep->fileline(),
|
||||||
fromp,
|
fromp,
|
||||||
newSubLsbOf(rhsp, fromRange),
|
newSubLsbOf(rhsp, fromRange),
|
||||||
// Unsized so width from user
|
// Unsized so width from user
|
||||||
new AstConst (nodep->fileline(),AstConst::Unsized32(),1));
|
new AstConst(nodep->fileline(), AstConst::Unsized32(), 1));
|
||||||
newp->declRange(fromRange);
|
newp->declRange(fromRange);
|
||||||
UINFO(6," new "<<newp<<endl);
|
UINFO(6," new "<<newp<<endl);
|
||||||
if (debug()>=9) newp->dumpTree(cout,"--SELBTn: ");
|
if (debug()>=9) newp->dumpTree(cout,"--SELBTn: ");
|
||||||
|
@ -255,11 +255,11 @@ private:
|
||||||
}
|
}
|
||||||
else if (VN_IS(ddtypep, NodeClassDType)) { // It's packed, so a bit from the packed struct
|
else if (VN_IS(ddtypep, NodeClassDType)) { // It's packed, so a bit from the packed struct
|
||||||
// SELBIT(range, index) -> SEL(array, index, 1)
|
// SELBIT(range, index) -> SEL(array, index, 1)
|
||||||
AstSel* newp = new AstSel (nodep->fileline(),
|
AstSel* newp = new AstSel(nodep->fileline(),
|
||||||
fromp,
|
fromp,
|
||||||
newSubLsbOf(rhsp, fromRange),
|
newSubLsbOf(rhsp, fromRange),
|
||||||
// Unsized so width from user
|
// Unsized so width from user
|
||||||
new AstConst (nodep->fileline(),AstConst::Unsized32(),1));
|
new AstConst(nodep->fileline(), AstConst::Unsized32(), 1));
|
||||||
newp->declRange(fromRange);
|
newp->declRange(fromRange);
|
||||||
UINFO(6," new "<<newp<<endl);
|
UINFO(6," new "<<newp<<endl);
|
||||||
if (debug()>=9) newp->dumpTree(cout,"--SELBTn: ");
|
if (debug()>=9) newp->dumpTree(cout,"--SELBTn: ");
|
||||||
|
@ -323,11 +323,11 @@ private:
|
||||||
int x = msb; msb = lsb; lsb = x;
|
int x = msb; msb = lsb; lsb = x;
|
||||||
}
|
}
|
||||||
int elwidth = adtypep->width() / fromRange.elements();
|
int elwidth = adtypep->width() / fromRange.elements();
|
||||||
AstSel* newp = new AstSel (nodep->fileline(),
|
AstSel* newp = new AstSel(nodep->fileline(),
|
||||||
fromp,
|
fromp,
|
||||||
new AstMul(nodep->fileline(), newSubLsbOf(lsbp, fromRange),
|
new AstMul(nodep->fileline(), newSubLsbOf(lsbp, fromRange),
|
||||||
new AstConst(nodep->fileline(), AstConst::Unsized32(), elwidth)),
|
new AstConst(nodep->fileline(), AstConst::Unsized32(), elwidth)),
|
||||||
new AstConst(nodep->fileline(), AstConst::Unsized32(), (msb-lsb+1)*elwidth));
|
new AstConst(nodep->fileline(), AstConst::Unsized32(), (msb-lsb+1)*elwidth));
|
||||||
newp->declRange(fromRange);
|
newp->declRange(fromRange);
|
||||||
newp->declElWidth(elwidth);
|
newp->declElWidth(elwidth);
|
||||||
newp->dtypeFrom(sliceDType(adtypep, msb, lsb));
|
newp->dtypeFrom(sliceDType(adtypep, msb, lsb));
|
||||||
|
@ -344,12 +344,13 @@ private:
|
||||||
nodep->v3error("["<<msb<<":"<<lsb<<"] Range extract has backward bit ordering, perhaps you wanted ["<<lsb<<":"<<msb<<"]");
|
nodep->v3error("["<<msb<<":"<<lsb<<"] Range extract has backward bit ordering, perhaps you wanted ["<<lsb<<":"<<msb<<"]");
|
||||||
int x = msb; msb = lsb; lsb = x;
|
int x = msb; msb = lsb; lsb = x;
|
||||||
}
|
}
|
||||||
AstNode* widthp = new AstConst (msbp->fileline(), AstConst::Unsized32(), // Unsized so width from user
|
AstNode* widthp = new AstConst(msbp->fileline(),
|
||||||
msb +1-lsb);
|
AstConst::Unsized32(), // Unsized so width from user
|
||||||
AstSel* newp = new AstSel (nodep->fileline(),
|
msb +1-lsb);
|
||||||
fromp,
|
AstSel* newp = new AstSel(nodep->fileline(),
|
||||||
newSubLsbOf(lsbp, fromRange),
|
fromp,
|
||||||
widthp);
|
newSubLsbOf(lsbp, fromRange),
|
||||||
|
widthp);
|
||||||
newp->declRange(fromRange);
|
newp->declRange(fromRange);
|
||||||
UINFO(6," new "<<newp<<endl);
|
UINFO(6," new "<<newp<<endl);
|
||||||
//if (debug()>=9) newp->dumpTree(cout,"--SELEXnew: ");
|
//if (debug()>=9) newp->dumpTree(cout,"--SELEXnew: ");
|
||||||
|
@ -361,12 +362,13 @@ private:
|
||||||
nodep->v3error("["<<msb<<":"<<lsb<<"] Range extract has backward bit ordering, perhaps you wanted ["<<lsb<<":"<<msb<<"]");
|
nodep->v3error("["<<msb<<":"<<lsb<<"] Range extract has backward bit ordering, perhaps you wanted ["<<lsb<<":"<<msb<<"]");
|
||||||
int x = msb; msb = lsb; lsb = x;
|
int x = msb; msb = lsb; lsb = x;
|
||||||
}
|
}
|
||||||
AstNode* widthp = new AstConst (msbp->fileline(), AstConst::Unsized32(), // Unsized so width from user
|
AstNode* widthp = new AstConst(msbp->fileline(),
|
||||||
msb +1-lsb);
|
AstConst::Unsized32(), // Unsized so width from user
|
||||||
AstSel* newp = new AstSel (nodep->fileline(),
|
msb +1-lsb);
|
||||||
fromp,
|
AstSel* newp = new AstSel(nodep->fileline(),
|
||||||
newSubLsbOf(lsbp, fromRange),
|
fromp,
|
||||||
widthp);
|
newSubLsbOf(lsbp, fromRange),
|
||||||
|
widthp);
|
||||||
newp->declRange(fromRange);
|
newp->declRange(fromRange);
|
||||||
UINFO(6," new "<<newp<<endl);
|
UINFO(6," new "<<newp<<endl);
|
||||||
//if (debug()>=9) newp->dumpTree(cout,"--SELEXnew: ");
|
//if (debug()>=9) newp->dumpTree(cout,"--SELEXnew: ");
|
||||||
|
@ -412,7 +414,7 @@ private:
|
||||||
AstNode* newwidthp = widthp;
|
AstNode* newwidthp = widthp;
|
||||||
if (const AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) {
|
if (const AstPackArrayDType* adtypep = VN_CAST(ddtypep, PackArrayDType)) {
|
||||||
elwidth = adtypep->width() / fromRange.elements();
|
elwidth = adtypep->width() / fromRange.elements();
|
||||||
newwidthp = new AstConst (nodep->fileline(),AstConst::Unsized32(), width * elwidth);
|
newwidthp = new AstConst(nodep->fileline(),AstConst::Unsized32(), width * elwidth);
|
||||||
}
|
}
|
||||||
AstNode* newlsbp = NULL;
|
AstNode* newlsbp = NULL;
|
||||||
if (VN_IS(nodep, SelPlus)) {
|
if (VN_IS(nodep, SelPlus)) {
|
||||||
|
@ -434,10 +436,10 @@ private:
|
||||||
} else {
|
} else {
|
||||||
nodep->v3fatalSrc("Bad Case");
|
nodep->v3fatalSrc("Bad Case");
|
||||||
}
|
}
|
||||||
if (elwidth != 1) newlsbp = new AstMul (nodep->fileline(), newlsbp,
|
if (elwidth != 1) newlsbp = new AstMul(nodep->fileline(), newlsbp,
|
||||||
new AstConst (nodep->fileline(), elwidth));
|
new AstConst(nodep->fileline(), elwidth));
|
||||||
AstSel* newp = new AstSel (nodep->fileline(),
|
AstSel* newp = new AstSel(nodep->fileline(),
|
||||||
fromp, newlsbp, newwidthp);
|
fromp, newlsbp, newwidthp);
|
||||||
newp->declRange(fromRange);
|
newp->declRange(fromRange);
|
||||||
newp->declElWidth(elwidth);
|
newp->declElWidth(elwidth);
|
||||||
UINFO(6," new "<<newp<<endl);
|
UINFO(6," new "<<newp<<endl);
|
||||||
|
|
|
@ -155,7 +155,7 @@ void V3Global::dumpCheckGlobalTree(const string& stagename, int newNumber, bool
|
||||||
|
|
||||||
//######################################################################
|
//######################################################################
|
||||||
|
|
||||||
void process () {
|
void process() {
|
||||||
// Sort modules by level so later algorithms don't need to care
|
// Sort modules by level so later algorithms don't need to care
|
||||||
V3LinkLevel::modSortByLevel();
|
V3LinkLevel::modSortByLevel();
|
||||||
V3Error::abortIfErrors();
|
V3Error::abortIfErrors();
|
||||||
|
|
|
@ -112,7 +112,7 @@ void VlcOptions::parseOptsList(int argc, char** argv) {
|
||||||
m_writeFile = argv[i];
|
m_writeFile = argv[i];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v3fatal ("Invalid option: "<<argv[i]);
|
v3fatal("Invalid option: "<<argv[i]);
|
||||||
}
|
}
|
||||||
shift;
|
shift;
|
||||||
} // - options
|
} // - options
|
||||||
|
@ -121,7 +121,7 @@ void VlcOptions::parseOptsList(int argc, char** argv) {
|
||||||
shift;
|
shift;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v3fatal ("Invalid argument: "<<argv[i]);
|
v3fatal("Invalid argument: "<<argv[i]);
|
||||||
shift;
|
shift;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,7 @@ void VlcTop::writeCoverage(const string& filename) {
|
||||||
//********************************************************************
|
//********************************************************************
|
||||||
|
|
||||||
struct CmpComputrons {
|
struct CmpComputrons {
|
||||||
inline bool operator () (const VlcTest* lhsp, const VlcTest* rhsp) const {
|
inline bool operator() (const VlcTest* lhsp, const VlcTest* rhsp) const {
|
||||||
if (lhsp->computrons() != rhsp->computrons()) {
|
if (lhsp->computrons() != rhsp->computrons()) {
|
||||||
return lhsp->computrons() < rhsp->computrons();
|
return lhsp->computrons() < rhsp->computrons();
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ public:
|
||||||
TestVpiHandle() : m_handle(NULL), m_free(true) { }
|
TestVpiHandle() : m_handle(NULL), m_free(true) { }
|
||||||
TestVpiHandle(vpiHandle h) : m_handle(h), m_free(true) { }
|
TestVpiHandle(vpiHandle h) : m_handle(h), m_free(true) { }
|
||||||
~TestVpiHandle() { if (m_handle && m_free) { vpi_free_object(m_handle); m_handle=NULL; } } // icarus has yet to catch up with 1800-2009
|
~TestVpiHandle() { if (m_handle && m_free) { vpi_free_object(m_handle); m_handle=NULL; } } // icarus has yet to catch up with 1800-2009
|
||||||
operator vpiHandle () const { return m_handle; }
|
operator vpiHandle() const { return m_handle; }
|
||||||
inline TestVpiHandle& operator= (vpiHandle h) { m_handle = h; return *this; }
|
inline TestVpiHandle& operator= (vpiHandle h) { m_handle = h; return *this; }
|
||||||
TestVpiHandle& nofree() {
|
TestVpiHandle& nofree() {
|
||||||
m_free = false;
|
m_free = false;
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
unsigned int main_time = false;
|
unsigned int main_time = false;
|
||||||
|
|
||||||
double sc_time_stamp () {
|
double sc_time_stamp() {
|
||||||
return main_time;
|
return main_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,7 @@ void clockit(int clk1, int clk0) {
|
||||||
main_time++;
|
main_time++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main (int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
topp = new VM_PREFIX;
|
topp = new VM_PREFIX;
|
||||||
topp->check = 0;
|
topp->check = 0;
|
||||||
clockit(0,0);
|
clockit(0,0);
|
||||||
|
|
|
@ -23,7 +23,7 @@ execute(
|
||||||
# Check that the hierarchy doesn't include __PVT__
|
# Check that the hierarchy doesn't include __PVT__
|
||||||
# Otherwise our coverage reports would look really ugly
|
# Otherwise our coverage reports would look really ugly
|
||||||
if ($Self->{vlt_all}) {
|
if ($Self->{vlt_all}) {
|
||||||
file_grep ($Self->{coverage_filename}, qr/(top\.t\.sub.*.cyc_eq_5)/)
|
file_grep($Self->{coverage_filename}, qr/(top\.t\.sub.*.cyc_eq_5)/)
|
||||||
}
|
}
|
||||||
|
|
||||||
ok(1);
|
ok(1);
|
||||||
|
|
|
@ -33,9 +33,7 @@ using std::setw;
|
||||||
|
|
||||||
|
|
||||||
// Convenience function to check we didn't finish unexpectedly
|
// Convenience function to check we didn't finish unexpectedly
|
||||||
static void
|
static void checkFinish(const char *msg) {
|
||||||
checkFinish (const char *msg)
|
|
||||||
{
|
|
||||||
if (Verilated::gotFinish ()) {
|
if (Verilated::gotFinish ()) {
|
||||||
vl_fatal (__FILE__, __LINE__, "dut", msg);
|
vl_fatal (__FILE__, __LINE__, "dut", msg);
|
||||||
exit (1);
|
exit (1);
|
||||||
|
@ -45,12 +43,10 @@ checkFinish (const char *msg)
|
||||||
|
|
||||||
// Convenience function to log the value of a register in hex. Only in verbose
|
// Convenience function to log the value of a register in hex. Only in verbose
|
||||||
// mode.
|
// mode.
|
||||||
static void
|
static void logReg(int clk,
|
||||||
logReg (int clk,
|
const char *desc,
|
||||||
const char *desc,
|
int val,
|
||||||
int val,
|
const char *note) {
|
||||||
const char *note)
|
|
||||||
{
|
|
||||||
#ifdef TEST_VERBOSE
|
#ifdef TEST_VERBOSE
|
||||||
cout << "clk = " << clk << ", " << desc << " = " << val << note << endl;
|
cout << "clk = " << clk << ", " << desc << " = " << val << note << endl;
|
||||||
#endif
|
#endif
|
||||||
|
@ -59,12 +55,11 @@ logReg (int clk,
|
||||||
|
|
||||||
// Convenience function to log the value of a register in hex. Only in verbose
|
// Convenience function to log the value of a register in hex. Only in verbose
|
||||||
// mode.
|
// mode.
|
||||||
static void
|
static void logRegHex (int clk,
|
||||||
logRegHex (int clk,
|
const char *desc,
|
||||||
const char *desc,
|
int bitWidth,
|
||||||
int bitWidth,
|
int val,
|
||||||
int val,
|
const char *note)
|
||||||
const char *note)
|
|
||||||
{
|
{
|
||||||
#ifdef TEST_VERBOSE
|
#ifdef TEST_VERBOSE
|
||||||
cout << "clk = " << clk << ", " << desc << " = " << bitWidth << "\'h" << hex
|
cout << "clk = " << clk << ", " << desc << " = " << bitWidth << "\'h" << hex
|
||||||
|
@ -76,10 +71,8 @@ logRegHex (int clk,
|
||||||
|
|
||||||
|
|
||||||
// Convenience function to check we got an expected result. Silent on success.
|
// Convenience function to check we got an expected result. Silent on success.
|
||||||
static void
|
static void checkResult (bool p,
|
||||||
checkResult (bool p,
|
const char *msg_fail) {
|
||||||
const char *msg_fail)
|
|
||||||
{
|
|
||||||
if (!p) {
|
if (!p) {
|
||||||
vl_fatal (__FILE__, __LINE__, "dut", msg_fail);
|
vl_fatal (__FILE__, __LINE__, "dut", msg_fail);
|
||||||
}
|
}
|
||||||
|
@ -87,8 +80,7 @@ checkResult (bool p,
|
||||||
|
|
||||||
|
|
||||||
// Main function instantiates the model and steps through the test.
|
// Main function instantiates the model and steps through the test.
|
||||||
int main ()
|
int main () {
|
||||||
{
|
|
||||||
Vt_dpi_accessors *dut = new Vt_dpi_accessors ("dut");
|
Vt_dpi_accessors *dut = new Vt_dpi_accessors ("dut");
|
||||||
svSetScope (svGetScopeFromName ("dut.t"));
|
svSetScope (svGetScopeFromName ("dut.t"));
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#ifdef NEED_EXTERNS
|
#ifdef NEED_EXTERNS
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
extern void dpii_display_call (const char* c);
|
extern void dpii_display_call(const char* c);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ extern "C" {
|
||||||
extern long long dpix_f_longint(long long i);
|
extern long long dpix_f_longint(long long i);
|
||||||
extern void* dpix_f_chandle(void* i);
|
extern void* dpix_f_chandle(void* i);
|
||||||
|
|
||||||
extern int dpix_sub_inst (int i);
|
extern int dpix_sub_inst(int i);
|
||||||
|
|
||||||
extern void dpix_t_reg(svLogic i, svLogic* o);
|
extern void dpix_t_reg(svLogic i, svLogic* o);
|
||||||
extern void dpix_t_reg15(const svLogicVecVal* i, svLogicVecVal* o);
|
extern void dpix_t_reg15(const svLogicVecVal* i, svLogicVecVal* o);
|
||||||
|
@ -88,7 +88,7 @@ static int check_sub(const char* name, int i) {
|
||||||
#ifdef TEST_VERBOSE
|
#ifdef TEST_VERBOSE
|
||||||
printf("svGetScopeFromName(\"%s\") -> %p\n", name, scope);
|
printf("svGetScopeFromName(\"%s\") -> %p\n", name, scope);
|
||||||
#endif
|
#endif
|
||||||
CHECK_RESULT_NNULL (scope);
|
CHECK_RESULT_NNULL(scope);
|
||||||
svScope prev = svGetScope();
|
svScope prev = svGetScope();
|
||||||
svScope sout = svSetScope(scope);
|
svScope sout = svSetScope(scope);
|
||||||
CHECK_RESULT(svScope, sout, prev);
|
CHECK_RESULT(svScope, sout, prev);
|
||||||
|
@ -113,7 +113,7 @@ int dpix_run_tests() {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CADENCE // Unimplemented; how hard is it?
|
#ifndef CADENCE // Unimplemented; how hard is it?
|
||||||
printf ("svDpiVersion: %s\n",svDpiVersion());
|
printf("svDpiVersion: %s\n",svDpiVersion());
|
||||||
CHECK_RESULT (bool,
|
CHECK_RESULT (bool,
|
||||||
strcmp(svDpiVersion(), "1800-2005")==0
|
strcmp(svDpiVersion(), "1800-2005")==0
|
||||||
|| strcmp(svDpiVersion(), "P1800-2005")==0
|
|| strcmp(svDpiVersion(), "P1800-2005")==0
|
||||||
|
|
|
@ -33,7 +33,7 @@ extern "C" {
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
// Called from our Verilog code to run the tests
|
// Called from our Verilog code to run the tests
|
||||||
void dpi_genvarTest () {
|
void dpi_genvarTest() {
|
||||||
const char *scopeName = svGetNameFromScope(svGetScope());
|
const char *scopeName = svGetNameFromScope(svGetScope());
|
||||||
printf("scope name : %s\n", scopeName);
|
printf("scope name : %s\n", scopeName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,12 +81,12 @@ extern "C" {
|
||||||
extern void dpii_v_integer(const svLogicVecVal* i, svLogicVecVal* o);
|
extern void dpii_v_integer(const svLogicVecVal* i, svLogicVecVal* o);
|
||||||
extern void dpii_v_time(const svLogicVecVal* i, svLogicVecVal* o);
|
extern void dpii_v_time(const svLogicVecVal* i, svLogicVecVal* o);
|
||||||
|
|
||||||
extern int dpii_f_strlen (const char* i);
|
extern int dpii_f_strlen(const char* i);
|
||||||
|
|
||||||
extern void dpii_f_void ();
|
extern void dpii_f_void();
|
||||||
extern int dpii_t_void ();
|
extern int dpii_t_void();
|
||||||
extern int dpii_t_void_context ();
|
extern int dpii_t_void_context();
|
||||||
extern int dpii_t_int (int i, int *o);
|
extern int dpii_t_int(int i, int *o);
|
||||||
|
|
||||||
extern int dpii_fa_bit(int i);
|
extern int dpii_fa_bit(int i);
|
||||||
}
|
}
|
||||||
|
@ -112,18 +112,18 @@ const char* dpii_f_string (const char* i) { return i; }
|
||||||
double dpii_f_real (double i) { return i+1.5; }
|
double dpii_f_real (double i) { return i+1.5; }
|
||||||
float dpii_f_shortreal(float i) { return i+1.5f; }
|
float dpii_f_shortreal(float i) { return i+1.5f; }
|
||||||
|
|
||||||
void dpii_v_bit (unsigned char i, unsigned char *o) { *o = 1 & ~i; }
|
void dpii_v_bit(unsigned char i, unsigned char *o) { *o = 1 & ~i; }
|
||||||
void dpii_v_int (int i, int *o) { *o = ~i; }
|
void dpii_v_int(int i, int *o) { *o = ~i; }
|
||||||
void dpii_v_uint (unsigned int i, unsigned int *o) { *o = ~i; }
|
void dpii_v_uint(unsigned int i, unsigned int *o) { *o = ~i; }
|
||||||
void dpii_v_byte (char i, char *o) { *o = ~i; }
|
void dpii_v_byte(char i, char *o) { *o = ~i; }
|
||||||
void dpii_v_shortint (short int i, short int *o) { *o = ~i; }
|
void dpii_v_shortint(short int i, short int *o) { *o = ~i; }
|
||||||
void dpii_v_ushort (unsigned short i, unsigned short *o) { *o = ~i; }
|
void dpii_v_ushort(unsigned short i, unsigned short *o) { *o = ~i; }
|
||||||
void dpii_v_longint (long long i, long long *o) { *o = ~i; }
|
void dpii_v_longint(long long i, long long *o) { *o = ~i; }
|
||||||
void dpii_v_ulong (unsigned long long i, unsigned long long *o) { *o = ~i; }
|
void dpii_v_ulong(unsigned long long i, unsigned long long *o) { *o = ~i; }
|
||||||
void dpii_v_chandle (void* i, void* *o) { *o = i; }
|
void dpii_v_chandle(void* i, void* *o) { *o = i; }
|
||||||
void dpii_v_string (const char* i, const char** o) { *o = strdup(i); } // Leaks
|
void dpii_v_string(const char* i, const char** o) { *o = strdup(i); } // Leaks
|
||||||
void dpii_v_real (double i, double* o) { *o = i + 1.5; }
|
void dpii_v_real(double i, double* o) { *o = i + 1.5; }
|
||||||
void dpii_v_shortreal(float i, float* o) { *o = i + 1.5f; }
|
void dpii_v_shortreal(float i, float* o) { *o = i + 1.5f; }
|
||||||
|
|
||||||
void dpii_v_reg(unsigned char i, unsigned char* o) { *o = (~i)&1; }
|
void dpii_v_reg(unsigned char i, unsigned char* o) { *o = (~i)&1; }
|
||||||
void dpii_v_reg15(const svLogicVecVal* i, svLogicVecVal* o) {
|
void dpii_v_reg15(const svLogicVecVal* i, svLogicVecVal* o) {
|
||||||
|
@ -179,23 +179,23 @@ int dpii_f_strlen (const char* i) { return strlen(i); }
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
void dpii_f_void () {}
|
void dpii_f_void() {}
|
||||||
|
|
||||||
#ifdef VCS
|
#ifdef VCS
|
||||||
void dpii_t_void () {}
|
void dpii_t_void() {}
|
||||||
void dpii_t_void_context () {}
|
void dpii_t_void_context() {}
|
||||||
void dpii_t_int (int i, int *o) {
|
void dpii_t_int(int i, int *o) {
|
||||||
*o = i;
|
*o = i;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
int dpii_t_void () { return svIsDisabledState(); }
|
int dpii_t_void() { return svIsDisabledState(); }
|
||||||
int dpii_t_void_context () { return svIsDisabledState(); }
|
int dpii_t_void_context() { return svIsDisabledState(); }
|
||||||
int dpii_t_int (int i, int *o) {
|
int dpii_t_int(int i, int *o) {
|
||||||
*o = i;
|
*o = i;
|
||||||
return svIsDisabledState(); // Tasks generally need this
|
return svIsDisabledState(); // Tasks generally need this
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int dpii_fa_bit (int i) {
|
int dpii_fa_bit(int i) {
|
||||||
return ~i;
|
return ~i;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,11 +47,11 @@ extern "C" {
|
||||||
extern void dpii_open_pw_u2(int c, int p, int u, const svOpenArrayHandle i, const svOpenArrayHandle o);
|
extern void dpii_open_pw_u2(int c, int p, int u, const svOpenArrayHandle i, const svOpenArrayHandle o);
|
||||||
extern void dpii_open_pw_u3(int c, int p, int u, const svOpenArrayHandle i, const svOpenArrayHandle o);
|
extern void dpii_open_pw_u3(int c, int p, int u, const svOpenArrayHandle i, const svOpenArrayHandle o);
|
||||||
|
|
||||||
extern void dpii_open_bit (const svOpenArrayHandle i, const svOpenArrayHandle o);
|
extern void dpii_open_bit(const svOpenArrayHandle i, const svOpenArrayHandle o);
|
||||||
extern void dpii_open_byte (const svOpenArrayHandle i, const svOpenArrayHandle o);
|
extern void dpii_open_byte(const svOpenArrayHandle i, const svOpenArrayHandle o);
|
||||||
extern void dpii_open_int (const svOpenArrayHandle i, const svOpenArrayHandle o);
|
extern void dpii_open_int(const svOpenArrayHandle i, const svOpenArrayHandle o);
|
||||||
extern void dpii_open_integer (const svOpenArrayHandle i, const svOpenArrayHandle o);
|
extern void dpii_open_integer(const svOpenArrayHandle i, const svOpenArrayHandle o);
|
||||||
extern void dpii_open_logic (const svOpenArrayHandle i, const svOpenArrayHandle o);
|
extern void dpii_open_logic(const svOpenArrayHandle i, const svOpenArrayHandle o);
|
||||||
|
|
||||||
extern int dpii_failure();
|
extern int dpii_failure();
|
||||||
}
|
}
|
||||||
|
@ -222,11 +222,11 @@ void dpii_open_pw_u3(int c, int p, int u, const svOpenArrayHandle i, const svOpe
|
||||||
_dpii_all(c,p,u,i,o);
|
_dpii_all(c,p,u,i,o);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dpii_open_bit (const svOpenArrayHandle i, const svOpenArrayHandle o) { }
|
void dpii_open_bit(const svOpenArrayHandle i, const svOpenArrayHandle o) { }
|
||||||
void dpii_open_byte (const svOpenArrayHandle i, const svOpenArrayHandle o) { }
|
void dpii_open_byte(const svOpenArrayHandle i, const svOpenArrayHandle o) { }
|
||||||
void dpii_open_int (const svOpenArrayHandle i, const svOpenArrayHandle o) { }
|
void dpii_open_int(const svOpenArrayHandle i, const svOpenArrayHandle o) { }
|
||||||
void dpii_open_integer (const svOpenArrayHandle i, const svOpenArrayHandle o) { }
|
void dpii_open_integer(const svOpenArrayHandle i, const svOpenArrayHandle o) { }
|
||||||
void dpii_open_logic (const svOpenArrayHandle i, const svOpenArrayHandle o) { }
|
void dpii_open_logic(const svOpenArrayHandle i, const svOpenArrayHandle o) { }
|
||||||
|
|
||||||
int dpii_failed() {
|
int dpii_failed() {
|
||||||
return failure;
|
return failure;
|
||||||
|
|
|
@ -37,11 +37,11 @@
|
||||||
|
|
||||||
#ifdef NEED_EXTERNS
|
#ifdef NEED_EXTERNS
|
||||||
extern "C" {
|
extern "C" {
|
||||||
extern int dpii_clear ();
|
extern int dpii_clear();
|
||||||
extern int dpii_count (int idx);
|
extern int dpii_count(int idx);
|
||||||
extern unsigned char dpii_inc0 (int idx);
|
extern unsigned char dpii_inc0(int idx);
|
||||||
extern unsigned char dpii_inc1 (int idx);
|
extern unsigned char dpii_inc1(int idx);
|
||||||
extern unsigned char dpii_incx (int idx, unsigned char value);
|
extern unsigned char dpii_incx(int idx, unsigned char value);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -50,16 +50,16 @@ extern "C" {
|
||||||
#define COUNTERS 16
|
#define COUNTERS 16
|
||||||
static int global_count[COUNTERS];
|
static int global_count[COUNTERS];
|
||||||
|
|
||||||
int dpii_clear () {
|
int dpii_clear() {
|
||||||
for (int i=0; i<COUNTERS; ++i) global_count[i] = 0;
|
for (int i=0; i<COUNTERS; ++i) global_count[i] = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int dpii_count (int idx) {
|
int dpii_count(int idx) {
|
||||||
return (idx >= 0 && idx<COUNTERS) ? global_count[idx] : -1;
|
return (idx >= 0 && idx<COUNTERS) ? global_count[idx] : -1;
|
||||||
}
|
}
|
||||||
unsigned char dpii_incx (int idx, unsigned char value) {
|
unsigned char dpii_incx(int idx, unsigned char value) {
|
||||||
if (idx >= 0 && idx<COUNTERS) global_count[idx]++;
|
if (idx >= 0 && idx<COUNTERS) global_count[idx]++;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
unsigned char dpii_inc0 (int idx) { return dpii_incx(idx,0); }
|
unsigned char dpii_inc0(int idx) { return dpii_incx(idx,0); }
|
||||||
unsigned char dpii_inc1 (int idx) { return dpii_incx(idx,1); }
|
unsigned char dpii_inc1(int idx) { return dpii_incx(idx,1); }
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#ifdef NEED_EXTERNS
|
#ifdef NEED_EXTERNS
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
extern int dpii_string (const char* s);
|
extern int dpii_string(const char* s);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -31,8 +31,8 @@
|
||||||
#ifdef NEED_EXTERNS
|
#ifdef NEED_EXTERNS
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
extern void dpii_sys_task (int i);
|
extern void dpii_sys_task(int i);
|
||||||
extern int dpii_sys_func (int i);
|
extern int dpii_sys_func(int i);
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -22,24 +22,24 @@
|
||||||
|
|
||||||
#ifdef NEED_EXTERNS
|
#ifdef NEED_EXTERNS
|
||||||
extern "C" {
|
extern "C" {
|
||||||
extern void dpii_call (double in, double* outp);
|
extern void dpii_call(double in, double* outp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void dpii_call (double in, double* outp) {
|
void dpii_call(double in, double* outp) {
|
||||||
*outp = in + 0.1;
|
*outp = in + 0.1;
|
||||||
}
|
}
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
unsigned int main_time = 0;
|
unsigned int main_time = 0;
|
||||||
|
|
||||||
double sc_time_stamp () {
|
double sc_time_stamp() {
|
||||||
return main_time;
|
return main_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
VM_PREFIX* topp = NULL;
|
VM_PREFIX* topp = NULL;
|
||||||
|
|
||||||
int main (int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
topp = new VM_PREFIX;
|
topp = new VM_PREFIX;
|
||||||
|
|
||||||
Verilated::debug(0);
|
Verilated::debug(0);
|
||||||
|
|
|
@ -111,7 +111,7 @@ void mon_eval() {
|
||||||
|
|
||||||
unsigned int main_time = false;
|
unsigned int main_time = false;
|
||||||
|
|
||||||
double sc_time_stamp () {
|
double sc_time_stamp() {
|
||||||
return main_time;
|
return main_time;
|
||||||
}
|
}
|
||||||
int main(int argc, char **argv, char **env) {
|
int main(int argc, char **argv, char **env) {
|
||||||
|
@ -119,7 +119,7 @@ int main(int argc, char **argv, char **env) {
|
||||||
Verilated::commandArgs(argc, argv);
|
Verilated::commandArgs(argc, argv);
|
||||||
Verilated::debug(0);
|
Verilated::debug(0);
|
||||||
|
|
||||||
VM_PREFIX* topp = new VM_PREFIX (""); // Note null name - we're flattening it out
|
VM_PREFIX* topp = new VM_PREFIX(""); // Note null name - we're flattening it out
|
||||||
|
|
||||||
#ifdef VERILATOR
|
#ifdef VERILATOR
|
||||||
# ifdef TEST_VERBOSE
|
# ifdef TEST_VERBOSE
|
||||||
|
|
|
@ -85,15 +85,15 @@ void t_embed_child_eval() {
|
||||||
__modelp->eval();
|
__modelp->eval();
|
||||||
}
|
}
|
||||||
|
|
||||||
void t_embed_child_io_eval (unsigned char clk,
|
void t_embed_child_io_eval(unsigned char clk,
|
||||||
unsigned char bit_in,
|
unsigned char bit_in,
|
||||||
const svBitVecVal* vec_in,
|
const svBitVecVal* vec_in,
|
||||||
const svBitVecVal* wide_in,
|
const svBitVecVal* wide_in,
|
||||||
unsigned char is_ref,
|
unsigned char is_ref,
|
||||||
unsigned char* bit_out,
|
unsigned char* bit_out,
|
||||||
svBitVecVal* vec_out,
|
svBitVecVal* vec_out,
|
||||||
svBitVecVal* wide_out,
|
svBitVecVal* wide_out,
|
||||||
unsigned char* did_init_out) {
|
unsigned char* did_init_out) {
|
||||||
VL_DEBUG_IF(VL_PRINTF(" t_embed1_child_io_eval\n"); );
|
VL_DEBUG_IF(VL_PRINTF(" t_embed1_child_io_eval\n"); );
|
||||||
Vt_embed1_child* __modelp = __get_modelp();
|
Vt_embed1_child* __modelp = __get_modelp();
|
||||||
VL_DEBUG_IF(VL_PRINTF("[%0ld] in clk=%x b=%x V=%x R=%x\n",
|
VL_DEBUG_IF(VL_PRINTF("[%0ld] in clk=%x b=%x V=%x R=%x\n",
|
||||||
|
|
|
@ -53,7 +53,7 @@ execute(
|
||||||
check_finished => 1,
|
check_finished => 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/struct \{/);
|
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/struct \{/);
|
||||||
|
|
||||||
ok(1);
|
ok(1);
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#include "Vt_enum_public_p3.h"
|
#include "Vt_enum_public_p3.h"
|
||||||
#include "Vt_enum_public_p62.h"
|
#include "Vt_enum_public_p62.h"
|
||||||
|
|
||||||
int main (int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
Vt_enum_public *topp = new Vt_enum_public;
|
Vt_enum_public *topp = new Vt_enum_public;
|
||||||
|
|
||||||
Verilated::debug(0);
|
Verilated::debug(0);
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
unsigned int main_time = 0;
|
unsigned int main_time = 0;
|
||||||
|
|
||||||
double sc_time_stamp () {
|
double sc_time_stamp() {
|
||||||
return main_time;
|
return main_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,14 +23,14 @@ void myfunction() {
|
||||||
gotit = true;
|
gotit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main (int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
topp = new VM_PREFIX;
|
topp = new VM_PREFIX;
|
||||||
|
|
||||||
Verilated::debug(0);
|
Verilated::debug(0);
|
||||||
|
|
||||||
topp->eval();
|
topp->eval();
|
||||||
if (!gotit) {
|
if (!gotit) {
|
||||||
vl_fatal (__FILE__, __LINE__, "dut", "Never got call to myfunction");
|
vl_fatal(__FILE__, __LINE__, "dut", "Never got call to myfunction");
|
||||||
}
|
}
|
||||||
|
|
||||||
topp->final();
|
topp->final();
|
||||||
|
|
|
@ -17,7 +17,7 @@ execute(
|
||||||
check_finished => 1,
|
check_finished => 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
file_grep_not ("$Self->{obj_dir}/$Self->{VM_PREFIX}.cpp", qr/VL_RAND_RESET/);
|
file_grep_not("$Self->{obj_dir}/$Self->{VM_PREFIX}.cpp", qr/VL_RAND_RESET/);
|
||||||
|
|
||||||
ok(1);
|
ok(1);
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -17,7 +17,7 @@ execute(
|
||||||
check_finished => 1,
|
check_finished => 1,
|
||||||
);
|
);
|
||||||
|
|
||||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.cpp", qr/VL_RAND_RESET/);
|
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}.cpp", qr/VL_RAND_RESET/);
|
||||||
|
|
||||||
ok(1);
|
ok(1);
|
||||||
1;
|
1;
|
||||||
|
|
|
@ -19,12 +19,12 @@ execute(
|
||||||
|
|
||||||
# We expect all loops should be unrolled by verilator,
|
# We expect all loops should be unrolled by verilator,
|
||||||
# none of the loop variables should exist in the output:
|
# none of the loop variables should exist in the output:
|
||||||
file_grep_not ("$Self->{obj_dir}/$Self->{VM_PREFIX}.cpp", qr/index_/);
|
file_grep_not("$Self->{obj_dir}/$Self->{VM_PREFIX}.cpp", qr/index_/);
|
||||||
|
|
||||||
# Further, we expect that all logic within the loop should
|
# Further, we expect that all logic within the loop should
|
||||||
# have been evaluated inside the compiler. So there should be
|
# have been evaluated inside the compiler. So there should be
|
||||||
# no references to 'sum' in the .cpp.
|
# no references to 'sum' in the .cpp.
|
||||||
file_grep_not ("$Self->{obj_dir}/$Self->{VM_PREFIX}.cpp", qr/sum/);
|
file_grep_not("$Self->{obj_dir}/$Self->{VM_PREFIX}.cpp", qr/sum/);
|
||||||
|
|
||||||
ok(1);
|
ok(1);
|
||||||
1;
|
1;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue