clang-format many files. No functional change.

Use nodist/clang_formatter to reformat files that are now clean.
This commit is contained in:
Wilson Snyder 2020-04-13 22:51:35 -04:00
parent dc5c259069
commit 5c966ec510
91 changed files with 4413 additions and 4023 deletions

View File

@ -1,150 +0,0 @@
clang-format is used to standardize the indentation of the internal C++
code.
For the most part clang-format changes provide good consistency, the two
main exceptions being the indentation of preprocessor directives, and
tables of statements.
Reformatting is generally performed only before other large changes are to
be made to a file. The following files are not yet clang-format clean:
clang-format -i include/verilated.h
clang-format -i include/verilated_dpi.h
clang-format -i include/verilated_imp.h
clang-format -i include/verilated_unordered_set_map.h
clang-format -i include/verilatedos.h
clang-format -i include/verilated.cpp
clang-format -i include/verilated_cov.cpp
clang-format -i include/verilated_dpi.cpp
clang-format -i include/verilated_vpi.cpp
clang-format -i src/V3Ast.h
clang-format -i src/V3AstNodes.h
clang-format -i src/V3EmitCBase.h
clang-format -i src/V3Error.h
clang-format -i src/V3File.h
clang-format -i src/V3FileLine.h
clang-format -i src/V3Global.h
clang-format -i src/V3Graph.h
clang-format -i src/V3GraphDfa.h
clang-format -i src/V3GraphStream.h
clang-format -i src/V3Hashed.h
clang-format -i src/V3LanguageWords.h
clang-format -i src/V3LinkDot.h
clang-format -i src/V3List.h
clang-format -i src/V3Number.h
clang-format -i src/V3Options.h
clang-format -i src/V3OrderGraph.h
clang-format -i src/V3Os.h
clang-format -i src/V3ParseImp.h
clang-format -i src/V3ParseSym.h
clang-format -i src/V3Partition.h
clang-format -i src/V3PartitionGraph.h
clang-format -i src/V3PreLex.h
clang-format -i src/V3PreProc.h
clang-format -i src/V3Scoreboard.h
clang-format -i src/V3SenTree.h
clang-format -i src/V3Simulate.h
clang-format -i src/V3Stats.h
clang-format -i src/V3String.h
clang-format -i src/V3SymTable.h
clang-format -i src/V3TSP.h
clang-format -i src/V3Task.h
clang-format -i src/V3WidthCommit.h
clang-format -i src/V3Active.cpp
clang-format -i src/V3ActiveTop.cpp
clang-format -i src/V3Assert.cpp
clang-format -i src/V3AssertPre.cpp
clang-format -i src/V3Ast.cpp
clang-format -i src/V3AstNodes.cpp
clang-format -i src/V3Begin.cpp
clang-format -i src/V3Branch.cpp
clang-format -i src/V3Broken.cpp
clang-format -i src/V3CCtors.cpp
clang-format -i src/V3Case.cpp
clang-format -i src/V3Cast.cpp
clang-format -i src/V3Cdc.cpp
clang-format -i src/V3Changed.cpp
clang-format -i src/V3Clean.cpp
clang-format -i src/V3Clock.cpp
clang-format -i src/V3Combine.cpp
clang-format -i src/V3Const.cpp
clang-format -i src/V3Coverage.cpp
clang-format -i src/V3CoverageJoin.cpp
clang-format -i src/V3Dead.cpp
clang-format -i src/V3Delayed.cpp
clang-format -i src/V3Depth.cpp
clang-format -i src/V3DepthBlock.cpp
clang-format -i src/V3EmitC.cpp
clang-format -i src/V3EmitCInlines.cpp
clang-format -i src/V3EmitCMake.cpp
clang-format -i src/V3EmitCSyms.cpp
clang-format -i src/V3EmitMk.cpp
clang-format -i src/V3EmitV.cpp
clang-format -i src/V3EmitXml.cpp
clang-format -i src/V3Error.cpp
clang-format -i src/V3Expand.cpp
clang-format -i src/V3File.cpp
clang-format -i src/V3FileLine.cpp
clang-format -i src/V3Gate.cpp
clang-format -i src/V3GenClk.cpp
clang-format -i src/V3Graph.cpp
clang-format -i src/V3GraphAcyc.cpp
clang-format -i src/V3GraphAlg.cpp
clang-format -i src/V3GraphDfa.cpp
clang-format -i src/V3GraphPathChecker.cpp
clang-format -i src/V3GraphTest.cpp
clang-format -i src/V3Hashed.cpp
clang-format -i src/V3Inline.cpp
clang-format -i src/V3Inst.cpp
clang-format -i src/V3InstrCount.cpp
clang-format -i src/V3Life.cpp
clang-format -i src/V3LifePost.cpp
clang-format -i src/V3LinkCells.cpp
clang-format -i src/V3LinkDot.cpp
clang-format -i src/V3LinkJump.cpp
clang-format -i src/V3LinkLValue.cpp
clang-format -i src/V3LinkLevel.cpp
clang-format -i src/V3LinkParse.cpp
clang-format -i src/V3LinkResolve.cpp
clang-format -i src/V3Localize.cpp
clang-format -i src/V3Name.cpp
clang-format -i src/V3Number.cpp
clang-format -i src/V3Number_test.cpp
clang-format -i src/V3Options.cpp
clang-format -i src/V3Order.cpp
clang-format -i src/V3Os.cpp
clang-format -i src/V3Param.cpp
clang-format -i src/V3ParseGrammar.cpp
clang-format -i src/V3ParseImp.cpp
clang-format -i src/V3ParseLex.cpp
clang-format -i src/V3Partition.cpp
clang-format -i src/V3PreProc.cpp
clang-format -i src/V3PreShell.cpp
clang-format -i src/V3Premit.cpp
clang-format -i src/V3ProtectLib.cpp
clang-format -i src/V3Reloop.cpp
clang-format -i src/V3Scope.cpp
clang-format -i src/V3Scoreboard.cpp
clang-format -i src/V3Slice.cpp
clang-format -i src/V3Split.cpp
clang-format -i src/V3SplitAs.cpp
clang-format -i src/V3SplitVar.cpp
clang-format -i src/V3Stats.cpp
clang-format -i src/V3StatsReport.cpp
clang-format -i src/V3String.cpp
clang-format -i src/V3Subst.cpp
clang-format -i src/V3TSP.cpp
clang-format -i src/V3Table.cpp
clang-format -i src/V3Task.cpp
clang-format -i src/V3Trace.cpp
clang-format -i src/V3TraceDecl.cpp
clang-format -i src/V3Tristate.cpp
clang-format -i src/V3Undriven.cpp
clang-format -i src/V3Unknown.cpp
clang-format -i src/V3Unroll.cpp
clang-format -i src/V3Width.cpp
clang-format -i src/V3WidthSel.cpp
clang-format -i src/Verilator.cpp

View File

@ -17,9 +17,7 @@
#endif
vluint64_t main_time = 0;
double sc_time_stamp() {
return main_time;
}
double sc_time_stamp() { return main_time; }
int main(int argc, char** argv, char** env) {
if (0 && argc && argv && env) {}
@ -62,11 +60,15 @@ int main(int argc, char** argv, char** env) {
// Close trace if opened
#if VM_TRACE
if (tfp) { tfp->close(); tfp = NULL; }
if (tfp) {
tfp->close();
tfp = NULL;
}
#endif
// Destroy model
delete top; top = NULL;
delete top;
top = NULL;
// Fin
exit(0);

View File

@ -84,8 +84,8 @@ int main(int argc, char** argv, char** env) {
// Read outputs
VL_PRINTF("[%" VL_PRI64 "d] clk=%x rstl=%x iquad=%" VL_PRI64 "x"
" -> oquad=%" VL_PRI64 "x owide=%x_%08x_%08x\n",
main_time, top->clk, top->reset_l, top->in_quad,
top->out_quad, top->out_wide[2], top->out_wide[1], top->out_wide[0]);
main_time, top->clk, top->reset_l, top->in_quad, top->out_quad, top->out_wide[2],
top->out_wide[1], top->out_wide[0]);
}
// Final model cleanup
@ -98,7 +98,8 @@ int main(int argc, char** argv, char** env) {
#endif
// Destroy model
delete top; top = NULL;
delete top;
top = NULL;
// Fin
exit(0);

View File

@ -118,8 +118,7 @@ int sc_main(int argc, char* argv[]) {
#endif
// Apply inputs
if (sc_time_stamp() > sc_time(1, SC_NS)
&& sc_time_stamp() < sc_time(10, SC_NS)) {
if (sc_time_stamp() > sc_time(1, SC_NS) && sc_time_stamp() < sc_time(10, SC_NS)) {
reset_l = !1; // Assert reset
} else {
reset_l = !0; // Deassert reset
@ -138,7 +137,10 @@ int sc_main(int argc, char* argv[]) {
// Close trace if opened
#if VM_TRACE
if (tfp) { tfp->close(); tfp = NULL; }
if (tfp) {
tfp->close();
tfp = NULL;
}
#endif
// Coverage analysis (since test passed)
@ -148,7 +150,8 @@ int sc_main(int argc, char* argv[]) {
#endif
// Destroy model
delete top; top = NULL;
delete top;
top = NULL;
// Fin
return 0;

View File

@ -31,9 +31,11 @@
#include <cerrno>
#include <sys/stat.h> // mkdir
// clang-format off
#if defined(_WIN32) || defined(__MINGW32__)
# include <direct.h> // mkdir
#endif
// clang-format on
#define VL_VALUE_STRING_MAX_WIDTH 8192 ///< Max static char array for VL_VALUE_STRING
@ -114,7 +116,8 @@ void vl_stop_maybe(const char* filename, int linenum, const char* hier, bool may
Verilated::errorCountInc();
if (maybe && Verilated::errorCount() < Verilated::errorLimit()) {
VL_PRINTF( // Not VL_PRINTF_MT, already on main thread
"-Info: %s:%d: %s\n", filename, linenum, "Verilog $stop, ignored due to +verilator+error+limit");
"-Info: %s:%d: %s\n", filename, linenum,
"Verilog $stop, ignored due to +verilator+error+limit");
} else {
vl_stop(filename, linenum, hier);
}
@ -126,7 +129,7 @@ void vl_stop_maybe(const char* filename, int linenum, const char* hier, bool may
void VL_FINISH_MT(const char* filename, int linenum, const char* hier) VL_MT_SAFE {
#ifdef VL_THREADED
VerilatedThreadMsgQueue::post(VerilatedMsg([=](){
VerilatedThreadMsgQueue::post(VerilatedMsg([=]() { //
vl_finish(filename, linenum, hier);
}));
#else
@ -136,7 +139,7 @@ void VL_FINISH_MT(const char* filename, int linenum, const char* hier) VL_MT_SAF
void VL_STOP_MT(const char* filename, int linenum, const char* hier, bool maybe) VL_MT_SAFE {
#ifdef VL_THREADED
VerilatedThreadMsgQueue::post(VerilatedMsg([=](){
VerilatedThreadMsgQueue::post(VerilatedMsg([=]() { //
vl_stop_maybe(filename, linenum, hier, maybe);
}));
#else
@ -146,7 +149,7 @@ void VL_STOP_MT(const char* filename, int linenum, const char* hier, bool maybe)
void VL_FATAL_MT(const char* filename, int linenum, const char* hier, const char* msg) VL_MT_SAFE {
#ifdef VL_THREADED
VerilatedThreadMsgQueue::post(VerilatedMsg([=](){
VerilatedThreadMsgQueue::post(VerilatedMsg([=]() { //
vl_fatal(filename, linenum, hier, msg);
}));
#else
@ -163,9 +166,7 @@ std::string _vl_string_vprintf(const char* formatp, va_list ap) VL_MT_SAFE {
va_copy(aq, ap);
int len = VL_VSNPRINTF(NULL, 0, formatp, aq);
va_end(aq);
if (VL_UNLIKELY(len < 1)) {
return "";
}
if (VL_UNLIKELY(len < 1)) return "";
char* bufp = new char[len + 1];
VL_VSNPRINTF(bufp, len + 1, formatp, ap);
@ -203,7 +204,8 @@ void VL_DBG_MSGF(const char* formatp, ...) VL_MT_SAFE {
va_start(ap, formatp);
std::string out = _vl_string_vprintf(formatp, ap);
va_end(ap);
// printf("-imm-V{t%d,%" VL_PRI64 "d}%s", VL_THREAD_ID(), _vl_dbg_sequence_number(), out.c_str());
// printf("-imm-V{t%d,%" VL_PRI64 "d}%s", VL_THREAD_ID(), _vl_dbg_sequence_number(),
// out.c_str());
// Using VL_PRINTF not VL_PRINTF_MT so that we can call VL_DBG_MSGF
// from within the guts of the thread execution machinery (and it goes
@ -217,7 +219,7 @@ void VL_PRINTF_MT(const char* formatp, ...) VL_MT_SAFE {
va_start(ap, formatp);
std::string out = _vl_string_vprintf(formatp, ap);
va_end(ap);
VerilatedThreadMsgQueue::post(VerilatedMsg([=](){
VerilatedThreadMsgQueue::post(VerilatedMsg([=]() { //
VL_PRINTF("%s", out.c_str());
}));
}
@ -292,18 +294,13 @@ vluint64_t vl_rand64() VL_MT_SAFE {
// Xoroshiro128+ algorithm
vluint64_t result = t_state[0] + t_state[1];
t_state[1] ^= t_state[0];
t_state[0] = (((t_state[0] << 55) | (t_state[0] >> 9))
^ t_state[1] ^ (t_state[1] << 14));
t_state[0] = (((t_state[0] << 55) | (t_state[0] >> 9)) ^ t_state[1] ^ (t_state[1] << 14));
t_state[1] = (t_state[1] << 36) | (t_state[1] >> 28);
return result;
}
IData VL_RANDOM_I(int obits) VL_MT_SAFE {
return vl_rand64() & VL_MASK_I(obits);
}
QData VL_RANDOM_Q(int obits) VL_MT_SAFE {
return vl_rand64() & VL_MASK_Q(obits);
}
IData VL_RANDOM_I(int obits) VL_MT_SAFE { return vl_rand64() & VL_MASK_I(obits); }
QData VL_RANDOM_Q(int obits) VL_MT_SAFE { return vl_rand64() & VL_MASK_Q(obits); }
// VL_RANDOM_W currently unused as $random always 32 bits
WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp) VL_MT_SAFE {
for (int i = 0; i < VL_WORDS_I(obits); ++i) {
@ -355,9 +352,7 @@ WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE {
void _VL_DEBUG_PRINT_W(int lbits, WDataInP iwp) VL_MT_SAFE {
VL_PRINTF_MT(" Data: w%d: ", lbits);
for (int i = VL_WORDS_I(lbits) - 1; i >= 0; --i) {
VL_PRINTF_MT("%08x ", iwp[i]);
}
for (int i = VL_WORDS_I(lbits) - 1; i >= 0; --i) VL_PRINTF_MT("%08x ", iwp[i]);
VL_PRINTF_MT("\n");
}
@ -415,8 +410,11 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp,
vn[0] = rwp[0] << s;
// Copy and shift dividend by same amount; may set new upper word
if (s) un[uw] = lwp[uw-1] >> (32-s);
else un[uw] = 0;
if (s) {
un[uw] = lwp[uw - 1] >> (32 - s);
} else {
un[uw] = 0;
}
for (int i = uw - 1; i > 0; --i) {
un[i] = (lwp[i] << s) | (shift_mask & (lwp[i - 1] >> (32 - s)));
}
@ -475,8 +473,8 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp,
}
}
WDataOutP VL_POW_WWW(int obits, int, int rbits,
WDataOutP owp, WDataInP lwp, WDataInP rwp) VL_MT_SAFE {
WDataOutP VL_POW_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp,
WDataInP rwp) VL_MT_SAFE {
// obits==lbits, rbits can be different
owp[0] = 1;
for (int i = 1; i < VL_WORDS_I(obits); i++) owp[i] = 0;
@ -498,9 +496,10 @@ WDataOutP VL_POW_WWW(int obits, int, int rbits,
}
return owp;
}
WDataOutP VL_POW_WWQ(int obits, int lbits, int rbits,
WDataOutP owp, WDataInP lwp, QData rhs) VL_MT_SAFE {
WData rhsw[VL_WQ_WORDS_E]; VL_SET_WQ(rhsw, rhs);
WDataOutP VL_POW_WWQ(int obits, int lbits, int rbits, WDataOutP owp, WDataInP lwp,
QData rhs) VL_MT_SAFE {
WData rhsw[VL_WQ_WORDS_E];
VL_SET_WQ(rhsw, rhs);
return VL_POW_WWW(obits, lbits, rbits, owp, lwp, rhsw);
}
QData VL_POW_QQW(int, int, int rbits, QData lhs, WDataInP rwp) VL_MT_SAFE {
@ -522,35 +521,45 @@ WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, W
int words = VL_WORDS_I(obits);
VL_ZERO_W(obits, owp);
EData lor = 0; // 0=all zeros, ~0=all ones, else mix
for (int i=1; i < (words-1); ++i) {
lor |= lwp[i];
}
for (int i = 1; i < (words - 1); ++i) { lor |= lwp[i]; }
lor |= ((lwp[words - 1] == VL_MASK_E(rbits)) ? ~VL_EUL(0) : 0);
if (lor==0 && lwp[0]==0) { return owp; } // "X" so return 0
else if (lor==0 && lwp[0]==1) { owp[0] = 1; return owp; } // 1
else if (lsign && lor == ~VL_EUL(0) && lwp[0] == ~VL_EUL(0)) { // -1
if (rwp[0] & 1) { return VL_ALLONES_W(obits, owp); } // -1^odd=-1
else { owp[0] = 1; return owp; } // -1^even=1
if (lor == 0 && lwp[0] == 0) { // "X" so return 0
return owp;
} else if (lor == 0 && lwp[0] == 1) { // 1
owp[0] = 1;
return owp;
} else if (lsign && lor == ~VL_EUL(0) && lwp[0] == ~VL_EUL(0)) { // -1
if (rwp[0] & 1) { // -1^odd=-1
return VL_ALLONES_W(obits, owp);
} else { // -1^even=1
owp[0] = 1;
return owp;
}
}
return 0;
}
return VL_POW_WWW(obits, rbits, rbits, owp, lwp, rwp);
}
WDataOutP VL_POWSS_WWQ(int obits, int lbits, int rbits,
WDataOutP owp, WDataInP lwp, QData rhs,
WDataOutP VL_POWSS_WWQ(int obits, int lbits, int rbits, WDataOutP owp, WDataInP lwp, QData rhs,
bool lsign, bool rsign) VL_MT_SAFE {
WData rhsw[VL_WQ_WORDS_E]; VL_SET_WQ(rhsw, rhs);
WData rhsw[VL_WQ_WORDS_E];
VL_SET_WQ(rhsw, rhs);
return VL_POWSS_WWW(obits, lbits, rbits, owp, lwp, rhsw, lsign, rsign);
}
QData VL_POWSS_QQW(int obits, int, int rbits,
QData lhs, WDataInP rwp, bool lsign, bool rsign) VL_MT_SAFE {
QData VL_POWSS_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp, bool lsign,
bool rsign) VL_MT_SAFE {
// Skip check for rhs == 0, as short-circuit doesn't save time
if (rsign && VL_SIGN_W(rbits, rwp)) {
if (lhs == 0) return 0; // "X"
else if (lhs == 1) return 1;
else if (lsign && lhs == VL_MASK_Q(obits)) { // -1
if (rwp[0] & 1) return VL_MASK_Q(obits); // -1^odd=-1
else return 1; // -1^even=1
if (lhs == 0) {
return 0; // "X"
} else if (lhs == 1) {
return 1;
} else if (lsign && lhs == VL_MASK_Q(obits)) { // -1
if (rwp[0] & 1) {
return VL_MASK_Q(obits); // -1^odd=-1
} else {
return 1; // -1^even=1
}
}
return 0;
}
@ -570,7 +579,7 @@ std::string VL_DECIMAL_NW(int width, WDataInP lwp) VL_MT_SAFE {
WData tmp2[VL_VALUE_STRING_MAX_WIDTH / 4 + 2];
int from_bit = width - 1;
// Skip all leading zeros
for (; from_bit >= 0 && !(VL_BITRSHIFT_W(lwp, from_bit) & 1); --from_bit);
for (; from_bit >= 0 && !(VL_BITRSHIFT_W(lwp, from_bit) & 1); --from_bit) {}
// Double-dabble algorithm
for (; from_bit >= 0; --from_bit) {
// Any digits >= 5 need an add 3 (via tmp)
@ -634,8 +643,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
inPct = false;
char fmt = pos[0];
switch (fmt) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '0' ... '9':
inPct = true; // Get more digits
widthSet = true;
width = width * 10 + (fmt - '0');
@ -647,12 +655,15 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
case '.':
inPct = true; // Get more digits
break;
case '%':
case '%': //
output += '%';
break;
case 'N': { // "C" string with name of module, add . if needed
const char* cstrp = va_arg(ap, const char*);
if (VL_LIKELY(*cstrp)) { output += cstrp; output += '.'; }
if (VL_LIKELY(*cstrp)) {
output += cstrp;
output += '.';
}
break;
}
case 'S': { // "C" string
@ -688,7 +699,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
sprintf(tmp, fmt.c_str(), d);
output += tmp;
break;
}
} //
break;
} // switch
break;
@ -708,7 +719,9 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
ld = lwp[0];
}
int lsb = lbits - 1;
if (widthSet && width==0) while (lsb && !VL_BITISSET_W(lwp, lsb)) --lsb;
if (widthSet && width == 0) {
while (lsb && !VL_BITISSET_W(lwp, lsb)) --lsb;
}
switch (fmt) {
case 'c': {
IData charval = ld & 0xff;
@ -796,9 +809,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
break;
}
case 'b':
for (; lsb>=0; --lsb) {
output += (VL_BITRSHIFT_W(lwp, lsb) & 1) + '0';
}
for (; lsb >= 0; --lsb) output += (VL_BITRSHIFT_W(lwp, lsb) & 1) + '0';
break;
case 'o':
for (; lsb >= 0; --lsb) {
@ -806,8 +817,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
// Octal numbers may span more than one wide word,
// so we need to grab each bit separately and check for overrun
// Octal is rare, so we'll do it a slow simple way
output += ('0'
+ ((VL_BITISSETLIMIT_W(lwp, lbits, lsb+0)) ? 1 : 0)
output += ('0' + ((VL_BITISSETLIMIT_W(lwp, lbits, lsb + 0)) ? 1 : 0)
+ ((VL_BITISSETLIMIT_W(lwp, lbits, lsb + 1)) ? 2 : 0)
+ ((VL_BITISSETLIMIT_W(lwp, lbits, lsb + 2)) ? 4 : 0));
}
@ -833,8 +843,11 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
break;
case 'v': // Strength; assume always strong
for (lsb = lbits - 1; lsb >= 0; --lsb) {
if (VL_BITRSHIFT_W(lwp, lsb) & 1) output += "St1 ";
else output += "St0 ";
if (VL_BITRSHIFT_W(lwp, lsb) & 1) {
output += "St1 ";
} else {
output += "St0 ";
}
}
break;
case 'x':
@ -863,8 +876,11 @@ static inline bool _vl_vsss_eof(FILE* fp, int floc) VL_MT_SAFE {
}
}
static inline void _vl_vsss_advance(FILE* fp, int& floc) VL_MT_SAFE {
if (fp) fgetc(fp);
else floc -= 8;
if (fp) {
fgetc(fp);
} else {
floc -= 8;
}
}
static inline int _vl_vsss_peek(FILE* fp, int& floc, WDataInP fromp,
const std::string& fstr) VL_MT_SAFE {
@ -884,8 +900,8 @@ static inline int _vl_vsss_peek(FILE* fp, int& floc, WDataInP fromp,
}
}
}
static inline void _vl_vsss_skipspace(FILE* fp, int& floc,
WDataInP fromp, const std::string& fstr) VL_MT_SAFE {
static inline void _vl_vsss_skipspace(FILE* fp, int& floc, WDataInP fromp,
const std::string& fstr) VL_MT_SAFE {
while (true) {
int c = _vl_vsss_peek(fp, floc, fromp, fstr);
if (c == EOF || !isspace(c)) return;
@ -899,8 +915,7 @@ static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp, const std:
while (true) {
int c = _vl_vsss_peek(fp, floc, fromp, fstr);
if (c == EOF || isspace(c)) break;
if (acceptp // String - allow anything
&& NULL==strchr(acceptp, c)) break;
if (acceptp && NULL == strchr(acceptp, c)) break; // String - allow anything
if (acceptp) c = tolower(c); // Non-strings we'll simplify
*cp++ = c;
_vl_vsss_advance(fp, floc);
@ -908,19 +923,19 @@ static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp, const std:
*cp++ = '\0';
// VL_DBG_MSGF(" _read got='"<<tmpp<<"'\n");
}
static inline void _vl_vsss_setbit(WDataOutP owp, int obits, int lsb,
int nbits, IData ld) VL_MT_SAFE {
static inline void _vl_vsss_setbit(WDataOutP owp, int obits, int lsb, int nbits,
IData ld) VL_MT_SAFE {
for (; nbits && lsb < obits; nbits--, lsb++, ld >>= 1) {
VL_ASSIGNBIT_WI(0, lsb, owp, ld & 1);
}
}
static inline void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2,
const char* strp,
static inline void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const char* strp,
size_t posstart, size_t posend) VL_MT_SAFE {
// Read in base "2^^baseLog2" digits from strp[posstart..posend-1] into owp of size obits.
int lsb = 0;
for (int i = 0, pos = static_cast<int>(posend) - 1;
i < obits && pos >= static_cast<int>(posstart); --pos) {
// clang-format off
switch (tolower (strp[pos])) {
case 'x': case 'z': case '?': // FALLTHRU
case '0': lsb += baseLog2; break;
@ -941,6 +956,7 @@ static inline void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2,
case 'f': _vl_vsss_setbit(owp, obits, lsb, baseLog2, 15); lsb += baseLog2; break;
case '_': break;
}
// clang-format on
}
}
@ -957,7 +973,8 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
bool inPct = false;
const char* pos = formatp;
for (; *pos && !_vl_vsss_eof(fp, floc); ++pos) {
//VL_DBG_MSGF("_vlscan fmt='"<<pos[0]<<"' floc="<<floc<<" file='"<<_vl_vsss_peek(fp, floc, fromp, fstr)<<"'"<<endl);
// VL_DBG_MSGF("_vlscan fmt='"<<pos[0]<<"' floc="<<floc<<" file='"<<_vl_vsss_peek(fp, floc,
// fromp, fstr)<<"'"<<endl);
if (!inPct && pos[0] == '%') {
inPct = true;
} else if (!inPct && isspace(pos[0])) { // Format spaces
@ -967,7 +984,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
_vl_vsss_skipspace(fp, floc, fromp, fstr);
int c = _vl_vsss_peek(fp, floc, fromp, fstr);
if (c != pos[0]) goto done;
else _vl_vsss_advance(fp, floc);
_vl_vsss_advance(fp, floc);
} else { // Format character
// Skip loading spaces
inPct = false;
@ -976,24 +993,23 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
case '%': {
int c = _vl_vsss_peek(fp, floc, fromp, fstr);
if (c != '%') goto done;
else _vl_vsss_advance(fp, floc);
_vl_vsss_advance(fp, floc);
break;
}
default: {
// Deal with all read-and-scan somethings
// Note LSBs are preserved if there's an overflow
const int obits = va_arg(ap, int);
WData qowp[VL_WQ_WORDS_E]; VL_SET_WQ(qowp, VL_ULL(0));
WData qowp[VL_WQ_WORDS_E];
VL_SET_WQ(qowp, VL_ULL(0));
WDataOutP owp = qowp;
if (obits > VL_QUADSIZE) {
owp = va_arg(ap, WDataOutP);
}
if (obits > VL_QUADSIZE) owp = va_arg(ap, WDataOutP);
for (int i = 0; i < VL_WORDS_I(obits); ++i) owp[i] = 0;
switch (fmt) {
case 'c': {
int c = _vl_vsss_peek(fp, floc, fromp, fstr);
if (c == EOF) goto done;
else _vl_vsss_advance(fp, floc);
_vl_vsss_advance(fp, floc);
owp[0] = c;
break;
}
@ -1004,7 +1020,8 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
int lpos = (static_cast<int>(strlen(tmp))) - 1;
int lsb = 0;
for (int i = 0; i < obits && lpos >= 0; --lpos) {
_vl_vsss_setbit(owp, obits, lsb, 8, tmp[lpos]); lsb+=8;
_vl_vsss_setbit(owp, obits, lsb, 8, tmp[lpos]);
lsb += 8;
}
break;
}
@ -1024,7 +1041,10 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
_vl_vsss_read(fp, floc, fromp, fstr, tmp, "+-.0123456789eE");
if (!tmp[0]) goto done;
// cppcheck-suppress unusedStructMember // It's used
union { double r; vlsint64_t ld; } u;
union {
double r;
vlsint64_t ld;
} u;
u.r = strtod(tmp, NULL);
VL_SET_WQ(owp, u.ld);
break;
@ -1069,13 +1089,17 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
got++;
// Reload data if non-wide (if wide, we put it in the right place directly)
if (obits <= VL_BYTESIZE) {
CData* p = va_arg(ap, CData*); *p = owp[0];
CData* p = va_arg(ap, CData*);
*p = owp[0];
} else if (obits <= VL_SHORTSIZE) {
SData* p = va_arg(ap, SData*); *p = owp[0];
SData* p = va_arg(ap, SData*);
*p = owp[0];
} else if (obits <= VL_IDATASIZE) {
IData* p = va_arg(ap, IData*); *p = owp[0];
IData* p = va_arg(ap, IData*);
*p = owp[0];
} else if (obits <= VL_QUADSIZE) {
QData* p = va_arg(ap, QData*); *p = VL_SET_QW(owp);
QData* p = va_arg(ap, QData*);
*p = VL_SET_QW(owp);
}
}
} // switch
@ -1088,9 +1112,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
//===========================================================================
// File I/O
FILE* VL_CVT_I_FP(IData lhs) VL_MT_SAFE {
return VerilatedImp::fdToFp(lhs);
}
FILE* VL_CVT_I_FP(IData lhs) VL_MT_SAFE { return VerilatedImp::fdToFp(lhs); }
void _VL_VINT_TO_STRING(int obits, char* destoutp, WDataInP sourcep) VL_MT_SAFE {
// See also VL_DATA_TO_STRING_NW
@ -1106,8 +1128,9 @@ void _VL_VINT_TO_STRING(int obits, char* destoutp, WDataInP sourcep) VL_MT_SAFE
}
}
*destp = '\0'; // Terminate
// Drop trailing spaces
if (!start) while (isspace(*(destp-1)) && destp>destoutp) *--destp = '\0';
if (!start) { // Drop trailing spaces
while (isspace(*(destp - 1)) && destp > destoutp) *--destp = '\0';
}
}
void _VL_STRING_TO_VINT(int obits, void* destp, size_t srclen, const char* srcp) VL_MT_SAFE {
@ -1141,7 +1164,8 @@ IData VL_FGETS_IXI(int obits, void* destp, IData fpi) VL_MT_SAFE {
while (got < bytes) {
int c = getc(fp); // getc() is threadsafe
if (c == EOF) break;
*cp++ = c; got++;
*cp++ = c;
got++;
if (c == '\n') break;
}
@ -1165,7 +1189,8 @@ IData VL_FOPEN_NI(const std::string& filename, IData mode) VL_MT_SAFE {
}
IData VL_FOPEN_QI(QData filename, IData mode) VL_MT_SAFE {
// While threadsafe, each thread can only access different file handles
WData fnw[VL_WQ_WORDS_E]; VL_SET_WQ(fnw, filename);
WData fnw[VL_WQ_WORDS_E];
VL_SET_WQ(fnw, filename);
return VL_FOPEN_WI(VL_WQ_WORDS_E, fnw, mode);
}
IData VL_FOPEN_WI(int fnwords, WDataInP filenamep, IData mode) VL_MT_SAFE {
@ -1189,9 +1214,7 @@ void VL_FCLOSE_I(IData fdi) VL_MT_SAFE {
VerilatedImp::fdDelete(fdi);
}
void VL_FFLUSH_ALL() VL_MT_SAFE {
fflush(stdout);
}
void VL_FFLUSH_ALL() VL_MT_SAFE { fflush(stdout); }
void VL_SFORMAT_X(int obits, CData& destr, const char* formatp, ...) VL_MT_SAFE {
static VL_THREAD_LOCAL std::string output; // static only for speed
@ -1307,7 +1330,8 @@ IData VL_FSCANF_IX(IData fpi, const char* formatp, ...) VL_MT_SAFE {
}
IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...) VL_MT_SAFE {
WData fnw[VL_WQ_WORDS_E]; VL_SET_WI(fnw, ld);
WData fnw[VL_WQ_WORDS_E];
VL_SET_WI(fnw, ld);
va_list ap;
va_start(ap, formatp);
@ -1316,7 +1340,8 @@ IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...) VL_MT_SAFE {
return got;
}
IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...) VL_MT_SAFE {
WData fnw[VL_WQ_WORDS_E]; VL_SET_WQ(fnw, ld);
WData fnw[VL_WQ_WORDS_E];
VL_SET_WQ(fnw, ld);
va_list ap;
va_start(ap, formatp);
@ -1339,8 +1364,8 @@ IData VL_SSCANF_INX(int, const std::string& ld, const char* formatp, ...) VL_MT_
return got;
}
IData VL_FREAD_I(int width, int array_lsb, int array_size,
void* memp, IData fpi, IData start, IData count) VL_MT_SAFE {
IData VL_FREAD_I(int width, int array_lsb, int array_size, void* memp, IData fpi, IData start,
IData count) VL_MT_SAFE {
// While threadsafe, each thread can only access different file handles
FILE* fp = VL_CVT_I_FP(fpi);
if (VL_UNLIKELY(!fp)) return 0;
@ -1373,11 +1398,10 @@ IData VL_FREAD_I(int width, int array_lsb, int array_size,
} else if (width <= VL_QUADSIZE) {
QData* datap = &(reinterpret_cast<QData*>(memp))[entry];
if (shift == start_shift) { *datap = 0; }
*datap |= ((static_cast<QData>(c) << static_cast<QData>(shift))
& VL_MASK_Q(width));
*datap |= ((static_cast<QData>(c) << static_cast<QData>(shift)) & VL_MASK_Q(width));
} else {
WDataOutP datap = &(reinterpret_cast<WDataOutP>(memp))[entry * VL_WORDS_I(width)];
if (shift == start_shift) { VL_ZERO_RESET_W(width, datap); }
if (shift == start_shift) VL_ZERO_RESET_W(width, datap);
datap[VL_BITWORD_E(shift)] |= (static_cast<EData>(c) << VL_BITBIT_E(shift));
}
// Prep for next
@ -1393,7 +1417,8 @@ IData VL_FREAD_I(int width, int array_lsb, int array_size,
}
IData VL_SYSTEM_IQ(QData lhs) VL_MT_SAFE {
WData lhsw[VL_WQ_WORDS_E]; VL_SET_WQ(lhsw, lhs);
WData lhsw[VL_WQ_WORDS_E];
VL_SET_WQ(lhsw, lhs);
return VL_SYSTEM_IW(VL_WQ_WORDS_E, lhsw);
}
IData VL_SYSTEM_IW(int lhswords, WDataInP lhsp) VL_MT_SAFE {
@ -1405,8 +1430,7 @@ IData VL_SYSTEM_IW(int lhswords, WDataInP lhsp) VL_MT_SAFE {
IData VL_TESTPLUSARGS_I(const char* formatp) VL_MT_SAFE {
const std::string& match = VerilatedImp::argPlusMatch(formatp);
if (match.empty()) return 0;
else return 1;
return match.empty() ? 0 : 1;
}
IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rwp) VL_MT_SAFE {
@ -1444,19 +1468,15 @@ IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rwp) VL_M
sscanf(dp, "%30" VL_PRI64 "d", &lld);
VL_SET_WQ(rwp, lld);
break;
case 'b':
_vl_vsss_based(rwp, rbits, 1, dp, 0, strlen(dp));
break;
case 'o':
_vl_vsss_based(rwp, rbits, 3, dp, 0, strlen(dp));
break;
case 'b': _vl_vsss_based(rwp, rbits, 1, dp, 0, strlen(dp)); break;
case 'o': _vl_vsss_based(rwp, rbits, 3, dp, 0, strlen(dp)); break;
case 'h': // FALLTHRU
case 'x':
_vl_vsss_based(rwp, rbits, 4, dp, 0, strlen(dp));
break;
case 'x': _vl_vsss_based(rwp, rbits, 4, dp, 0, strlen(dp)); break;
case 's': // string/no conversion
for (int i=0, lsb=0, posp=static_cast<int>(strlen(dp))-1; i<rbits && posp>=0; --posp) {
_vl_vsss_setbit(rwp, rbits, lsb, 8, dp[posp]); lsb+=8;
for (int i = 0, lsb = 0, posp = static_cast<int>(strlen(dp)) - 1; i < rbits && posp >= 0;
--posp) {
_vl_vsss_setbit(rwp, rbits, lsb, 8, dp[posp]);
lsb += 8;
}
break;
case 'e': {
@ -1498,7 +1518,7 @@ IData VL_VALUEPLUSARGS_INN(int, const std::string& ld, std::string& rdr) VL_MT_S
prefix += *posp;
inPct = false;
break;
default:
default: //
done = true;
break;
}
@ -1524,34 +1544,22 @@ const char* vl_mc_scan_plusargs(const char* prefixp) VL_MT_SAFE {
//===========================================================================
// Heavy string functions
std::string VL_TO_STRING(CData lhs) {
return VL_SFORMATF_NX("'h%0x", 8, lhs);
}
std::string VL_TO_STRING(SData lhs) {
return VL_SFORMATF_NX("'h%0x", 16, lhs);
}
std::string VL_TO_STRING(IData lhs) {
return VL_SFORMATF_NX("'h%0x", 32, lhs);
}
std::string VL_TO_STRING(QData lhs) {
return VL_SFORMATF_NX("'h%0x", 64, lhs);
}
std::string VL_TO_STRING(CData lhs) { return VL_SFORMATF_NX("'h%0x", 8, lhs); }
std::string VL_TO_STRING(SData lhs) { return VL_SFORMATF_NX("'h%0x", 16, lhs); }
std::string VL_TO_STRING(IData lhs) { return VL_SFORMATF_NX("'h%0x", 32, lhs); }
std::string VL_TO_STRING(QData lhs) { return VL_SFORMATF_NX("'h%0x", 64, lhs); }
std::string VL_TO_STRING_W(int words, WDataInP obj) {
return VL_SFORMATF_NX("'h%0x", words * VL_EDATASIZE, obj);
}
std::string VL_TOLOWER_NN(const std::string& ld) VL_MT_SAFE {
std::string out = ld;
for (std::string::iterator it = out.begin(); it != out.end(); ++it) {
*it = tolower(*it);
}
for (std::string::iterator it = out.begin(); it != out.end(); ++it) *it = tolower(*it);
return out;
}
std::string VL_TOUPPER_NN(const std::string& ld) VL_MT_SAFE {
std::string out = ld;
for (std::string::iterator it = out.begin(); it != out.end(); ++it) {
*it = toupper(*it);
}
for (std::string::iterator it = out.begin(); it != out.end(); ++it) *it = toupper(*it);
return out;
}
@ -1667,7 +1675,10 @@ VlReadMem::VlReadMem(bool hex, int bits, const std::string& filename, QData star
}
}
VlReadMem::~VlReadMem() {
if (m_fp) { fclose(m_fp); m_fp = NULL; }
if (m_fp) {
fclose(m_fp);
m_fp = NULL;
}
}
bool VlReadMem::get(QData& addrr, std::string& valuer) {
if (VL_UNLIKELY(!m_fp)) return false;
@ -1697,7 +1708,8 @@ bool VlReadMem::get(QData& addrr, std::string& valuer) {
}
// Parse line
if (c == '\n') {
++m_linenum; ignore_to_eol = false;
++m_linenum;
ignore_to_eol = false;
reading_addr = false;
} else if (c == '\t' || c == ' ' || c == '\r' || c == '\f') {
reading_addr = false;
@ -1707,15 +1719,22 @@ bool VlReadMem::get(QData& addrr, std::string& valuer) {
ignore_to_cmt = false;
reading_addr = false;
} else if (!ignore_to_eol && !ignore_to_cmt) {
if (lastc == '/' && c == '*') { ignore_to_cmt = true; }
else if (lastc == '/' && c == '/') { ignore_to_eol = true; }
else if (c == '/') {} // Part of /* or //
else if (c == '#') { ignore_to_eol = true; }
else if (c == '@') { reading_addr = true; m_addr = 0; }
if (lastc == '/' && c == '*') {
ignore_to_cmt = true;
} else if (lastc == '/' && c == '/') {
ignore_to_eol = true;
} else if (c == '/') { // Part of /* or //
} else if (c == '#') {
ignore_to_eol = true;
} else if (c == '@') {
reading_addr = true;
m_addr = 0;
}
// Check for hex or binary digits as file format requests
else if (isxdigit(c) || (!reading_addr && (c == 'x' || c == 'X'))) {
c = tolower(c);
int value = (c >= 'a' ? (c == 'x' ? VL_RAND_RESET_I(4) : (c-'a'+10)) : (c-'0'));
int value
= (c >= 'a' ? (c == 'x' ? VL_RAND_RESET_I(4) : (c - 'a' + 10)) : (c - '0'));
if (reading_addr) {
// Decode @ addresses
m_addr = (m_addr << 4) + value;
@ -1768,7 +1787,7 @@ void VlReadMem::setData(void* valuep, const std::string& rhs) {
& VL_MASK_Q(m_bits);
} else {
WDataOutP datap = reinterpret_cast<WDataOutP>(valuep);
if (!innum) { VL_ZERO_RESET_W(m_bits, datap); }
if (!innum) VL_ZERO_RESET_W(m_bits, datap);
_VL_SHIFTL_INPLACE_W(m_bits, datap, static_cast<IData>(shift));
datap[0] |= value;
}
@ -1798,7 +1817,10 @@ VlWriteMem::VlWriteMem(bool hex, int bits, const std::string& filename, QData st
}
}
VlWriteMem::~VlWriteMem() {
if (m_fp) { fclose(m_fp); m_fp = NULL; }
if (m_fp) {
fclose(m_fp);
m_fp = NULL;
}
}
void VlWriteMem::print(QData addr, bool addrstamp, const void* valuep) {
if (VL_UNLIKELY(!m_fp)) return;
@ -1886,8 +1908,8 @@ void VL_READMEM_N(bool hex, // Hex format, else binary
QData* datap = &(reinterpret_cast<QData*>(memp))[entry];
rmem.setData(datap, value);
} else {
WDataOutP datap = &(reinterpret_cast<WDataOutP>(memp))
[ entry*VL_WORDS_I(bits) ];
WDataOutP datap
= &(reinterpret_cast<WDataOutP>(memp))[entry * VL_WORDS_I(bits)];
rmem.setData(datap, value);
}
}
@ -1945,7 +1967,10 @@ int VL_TIME_STR_CONVERT(const char* strp) {
int scale = 0;
if (!strp) return 0;
if (*strp++ != '1') return 0;
while (*strp == '0') { scale++; strp++; }
while (*strp == '0') {
scale++;
strp++;
}
switch (*strp++) {
case 's': break;
case 'm': scale -= 3; break;
@ -1966,13 +1991,15 @@ int VL_TIME_STR_CONVERT(const char* strp) {
Verilated::ThreadLocal::ThreadLocal()
:
#ifdef VL_THREADED
t_mtaskId(0),
t_endOfEvalReqd(0),
t_mtaskId(0)
, t_endOfEvalReqd(0)
,
#endif
t_dpiScopep(NULL), t_dpiFilename(0), t_dpiLineno(0) {
}
Verilated::ThreadLocal::~ThreadLocal() {
t_dpiScopep(NULL)
, t_dpiFilename(0)
, t_dpiLineno(0) {
}
Verilated::ThreadLocal::~ThreadLocal() {}
void Verilated::debug(int level) VL_MT_SAFE {
VerilatedLockGuard lock(m_mutex);
@ -2038,7 +2065,6 @@ void Verilated::profThreadsFilenamep(const char* flagp) VL_MT_SAFE {
s_ns.s_profThreadsFilenamep = strdup(flagp);
}
const char* Verilated::catName(const char* n1, const char* n2, const char* delimiter) VL_MT_SAFE {
// Returns new'ed data
// Used by symbol table creation to make module names
@ -2058,9 +2084,10 @@ const char* Verilated::catName(const char* n1, const char* n2, const char* delim
void Verilated::flushCb(VerilatedVoidCb cb) VL_MT_SAFE {
VerilatedLockGuard lock(m_mutex);
if (s_flushCb == cb) {} // Ok - don't duplicate
else if (!s_flushCb) { s_flushCb=cb; }
else { // LCOV_EXCL_LINE
if (s_flushCb == cb) { // Ok - don't duplicate
} else if (!s_flushCb) {
s_flushCb = cb;
} else { // LCOV_EXCL_LINE
// Someday we may allow multiple callbacks ala atexit(), but until then
VL_FATAL_MT("unknown", 0, "", // LCOV_EXCL_LINE
"Verilated::flushCb called twice with different callbacks");
@ -2074,12 +2101,8 @@ void Verilated::flushCall() VL_MT_SAFE {
fflush(stdout);
}
const char* Verilated::productName() VL_PURE {
return VERILATOR_PRODUCT;
}
const char* Verilated::productVersion() VL_PURE {
return VERILATOR_VERSION;
}
const char* Verilated::productName() VL_PURE { return VERILATOR_PRODUCT; }
const char* Verilated::productVersion() VL_PURE { return VERILATOR_VERSION; }
void Verilated::commandArgs(int argc, const char** argv) VL_MT_SAFE {
VerilatedLockGuard lock(s_args.m_argMutex);
@ -2105,8 +2128,7 @@ void Verilated::nullPointerError(const char* filename, int linenum) VL_MT_SAFE {
void Verilated::overWidthError(const char* signame) VL_MT_SAFE {
// Slowpath - Called only when signal sets too high of a bit
std::string msg = (std::string("Testbench C set input '")
+ signame
std::string msg = (std::string("Testbench C set input '") + signame
+ "' to value that overflows what the signal's width can fit");
VL_FATAL_MT("unknown", 0, "", msg.c_str());
VL_UNREACHABLE
@ -2127,13 +2149,9 @@ void Verilated::quiesce() VL_MT_SAFE {
#endif
}
void Verilated::internalsDump() VL_MT_SAFE {
VerilatedImp::internalsDump();
}
void Verilated::internalsDump() VL_MT_SAFE { VerilatedImp::internalsDump(); }
void Verilated::scopesDump() VL_MT_SAFE {
VerilatedImp::scopesDump();
}
void Verilated::scopesDump() VL_MT_SAFE { VerilatedImp::scopesDump(); }
const VerilatedScope* Verilated::scopeFind(const char* namep) VL_MT_SAFE {
return VerilatedImp::scopeFind(namep);
@ -2176,8 +2194,7 @@ void VerilatedImp::internalsDump() VL_MT_SAFE {
userDump();
}
void VerilatedImp::versionDump() VL_MT_SAFE {
VL_PRINTF_MT(" Version: %s %s\n",
Verilated::productName(), Verilated::productVersion());
VL_PRINTF_MT(" Version: %s %s\n", Verilated::productName(), Verilated::productVersion());
}
void VerilatedImp::commandArgs(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex) {
@ -2202,53 +2219,42 @@ void VerilatedImp::commandArgVl(const std::string& arg) {
std::string value;
if (arg == "+verilator+debug") {
Verilated::debug(4);
}
else if (commandArgVlValue(arg, "+verilator+debugi+", value/*ref*/)) {
} else if (commandArgVlValue(arg, "+verilator+debugi+", value /*ref*/)) {
Verilated::debug(atoi(value.c_str()));
}
else if (commandArgVlValue(arg, "+verilator+error+limit+", value/*ref*/)) {
} else if (commandArgVlValue(arg, "+verilator+error+limit+", value /*ref*/)) {
Verilated::errorLimit(atoi(value.c_str()));
}
else if (arg == "+verilator+help") {
} else if (arg == "+verilator+help") {
versionDump();
VL_PRINTF_MT("For help, please see 'verilator --help'\n");
VL_FATAL_MT("COMMAND_LINE", 0, "", "Exiting due to command line argument (not an error)");
}
else if (commandArgVlValue(arg, "+verilator+prof+threads+start+", value/*ref*/)) {
VL_FATAL_MT("COMMAND_LINE", 0, "",
"Exiting due to command line argument (not an error)");
} else if (commandArgVlValue(arg, "+verilator+prof+threads+start+", value /*ref*/)) {
Verilated::profThreadsStart(atoll(value.c_str()));
}
else if (commandArgVlValue(arg, "+verilator+prof+threads+window+", value/*ref*/)) {
} else if (commandArgVlValue(arg, "+verilator+prof+threads+window+", value /*ref*/)) {
Verilated::profThreadsWindow(atol(value.c_str()));
}
else if (commandArgVlValue(arg, "+verilator+prof+threads+file+", value/*ref*/)) {
} else if (commandArgVlValue(arg, "+verilator+prof+threads+file+", value /*ref*/)) {
Verilated::profThreadsFilenamep(value.c_str());
}
else if (commandArgVlValue(arg, "+verilator+rand+reset+", value/*ref*/)) {
} else if (commandArgVlValue(arg, "+verilator+rand+reset+", value /*ref*/)) {
Verilated::randReset(atoi(value.c_str()));
}
else if (commandArgVlValue(arg, "+verilator+seed+", value/*ref*/)) {
} else if (commandArgVlValue(arg, "+verilator+seed+", value /*ref*/)) {
Verilated::randSeed(atoi(value.c_str()));
}
else if (arg == "+verilator+noassert") {
} else if (arg == "+verilator+noassert") {
Verilated::assertOn(false);
}
else if (arg == "+verilator+V") {
} else if (arg == "+verilator+V") {
versionDump(); // Someday more info too
VL_FATAL_MT("COMMAND_LINE", 0, "",
"Exiting due to command line argument (not an error)");
}
else if (arg == "+verilator+version") {
} else if (arg == "+verilator+version") {
versionDump();
VL_FATAL_MT("COMMAND_LINE", 0, "",
"Exiting due to command line argument (not an error)");
}
else {
} else {
VL_PRINTF_MT("%%Warning: Unknown +verilator runtime argument: '%s'\n", arg.c_str());
}
}
}
bool VerilatedImp::commandArgVlValue(const std::string& arg,
const std::string& prefix, std::string& valuer) {
bool VerilatedImp::commandArgVlValue(const std::string& arg, const std::string& prefix,
std::string& valuer) {
size_t len = prefix.length();
if (0 == strncmp(prefix.c_str(), arg.c_str(), len)) {
valuer = arg.substr(len);
@ -2276,8 +2282,7 @@ VerilatedSyms::~VerilatedSyms() {
// VerilatedModule:: Methods
VerilatedModule::VerilatedModule(const char* namep)
: m_namep(strdup(namep)) {
}
: m_namep(strdup(namep)) {}
VerilatedModule::~VerilatedModule() {
// Memory cleanup - not called during normal operation
@ -2305,9 +2310,7 @@ vluint32_t VerilatedVarProps::entSize() const {
size_t VerilatedVarProps::totalSize() const {
size_t size = entSize();
for (int dim=1; dim<=dims(); ++dim) {
size *= m_unpacked[dim].elements();
}
for (int dim = 1; dim <= dims(); ++dim) size *= m_unpacked[dim].elements();
return size;
}
@ -2345,9 +2348,8 @@ VerilatedScope::~VerilatedScope() {
m_funcnumMax = 0; // Force callback table to empty
}
void VerilatedScope::configure(VerilatedSyms* symsp, const char* prefixp,
const char* suffixp, const char* identifier,
const Type type) VL_MT_UNSAFE {
void VerilatedScope::configure(VerilatedSyms* symsp, const char* prefixp, const char* suffixp,
const char* identifier, const Type type) VL_MT_UNSAFE {
// Slowpath - called once/scope at construction
// We don't want the space and reference-count access overhead of strings.
m_symsp = symsp;
@ -2406,9 +2408,9 @@ void VerilatedScope::varInsert(int finalize, const char* namep, void* datap,
} else {
// We could have a linked list of ranges, but really this whole thing needs
// to be generalized to support structs and unions, etc.
VL_FATAL_MT(__FILE__, __LINE__, "",
(std::string("Unsupported multi-dimensional public varInsert: ")
+ namep).c_str());
VL_FATAL_MT(
__FILE__, __LINE__, "",
(std::string("Unsupported multi-dimensional public varInsert: ") + namep).c_str());
}
}
va_end(ap);
@ -2420,9 +2422,7 @@ void VerilatedScope::varInsert(int finalize, const char* namep, void* datap,
VerilatedVar* VerilatedScope::varFind(const char* namep) const VL_MT_SAFE_POSTINIT {
if (VL_LIKELY(m_varsp)) {
VerilatedVarNameMap::iterator it = m_varsp->find(namep);
if (VL_LIKELY(it != m_varsp->end())) {
return &(it->second);
}
if (VL_LIKELY(it != m_varsp->end())) return &(it->second);
}
return NULL;
}
@ -2438,8 +2438,7 @@ void* VerilatedScope::exportFindNullError(int funcnum) VL_MT_SAFE {
void* VerilatedScope::exportFindError(int funcnum) const {
// Slowpath - Called only when find has failed
std::string msg = (std::string("Testbench C called '")
+VerilatedImp::exportName(funcnum)
std::string msg = (std::string("Testbench C called '") + VerilatedImp::exportName(funcnum)
+ "' but this DPI export function exists only in other scopes, not scope '"
+ name() + "'");
VL_FATAL_MT("unknown", 0, "", msg.c_str());
@ -2450,13 +2449,12 @@ void VerilatedScope::scopeDump() const {
VL_PRINTF_MT(" SCOPE %p: %s\n", this, name());
for (int i = 0; i < m_funcnumMax; ++i) {
if (m_callbacksp && m_callbacksp[i]) {
VL_PRINTF_MT(" DPI-EXPORT %p: %s\n",
m_callbacksp[i], VerilatedImp::exportName(i));
VL_PRINTF_MT(" DPI-EXPORT %p: %s\n", m_callbacksp[i],
VerilatedImp::exportName(i));
}
}
if (VerilatedVarNameMap* varsp = this->varsp()) {
for (VerilatedVarNameMap::const_iterator it = varsp->begin();
it != varsp->end(); ++it) {
for (VerilatedVarNameMap::const_iterator it = varsp->begin(); it != varsp->end(); ++it) {
VL_PRINTF_MT(" VAR %p: %s\n", &(it->second), it->first);
}
}
@ -2471,7 +2469,8 @@ void VerilatedHierarchy::add(VerilatedScope* fromp, VerilatedScope* top) {
#if defined(VL_THREADED) && defined(VL_DEBUG)
void VerilatedAssertOneThread::fatal_different() VL_MT_SAFE {
VL_FATAL_MT(__FILE__, __LINE__, "", "Routine called that is single threaded, but called from"
VL_FATAL_MT(__FILE__, __LINE__, "",
"Routine called that is single threaded, but called from"
" a different thread then the expected constructing thread");
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,6 @@
///
//*************************************************************************
///**** Product and Version name
// Autoconf substitutes this with the strings from AC_INIT.

View File

@ -74,7 +74,10 @@ public:
virtual void zero() const VL_OVERRIDE { *m_countp = 0; }
// CONSTRUCTORS
// cppcheck-suppress noExplicitConstructor
explicit VerilatedCoverItemSpec(T* countp) : m_countp(countp) { *m_countp = 0; }
explicit VerilatedCoverItemSpec(T* countp)
: m_countp(countp) {
*m_countp = 0;
}
virtual ~VerilatedCoverItemSpec() VL_OVERRIDE {}
};
@ -93,9 +96,9 @@ private:
private:
// MEMBERS
VerilatedMutex m_mutex; ///< Protects all members, when VL_THREADED. Wrapper deals with setting it.
ValueIndexMap m_valueIndexes VL_GUARDED_BY(m_mutex); ///< For each key/value a unique arbitrary index value
IndexValueMap m_indexValues VL_GUARDED_BY(m_mutex); ///< For each key/value a unique arbitrary index value
VerilatedMutex m_mutex; ///< Protects all members
ValueIndexMap m_valueIndexes VL_GUARDED_BY(m_mutex); ///< Unique arbitrary value for values
IndexValueMap m_indexValues VL_GUARDED_BY(m_mutex); ///< Unique arbitrary value for keys
ItemList m_items VL_GUARDED_BY(m_mutex); ///< List of all items
VerilatedCovImpItem* m_insertp VL_GUARDED_BY(m_mutex); ///< Item about to insert
@ -109,6 +112,7 @@ private:
m_insertLineno = 0;
}
VL_UNCOPYABLE(VerilatedCovImp);
public:
~VerilatedCovImp() { clearGuts(); }
static VerilatedCovImp& imp() VL_MT_SAFE {
@ -122,7 +126,8 @@ private:
static int nextIndex = KEY_UNDEF + 1;
ValueIndexMap::iterator iter = m_valueIndexes.find(value);
if (iter != m_valueIndexes.end()) return iter->second;
nextIndex++; assert(nextIndex>0);
nextIndex++;
assert(nextIndex > 0); // Didn't rollover
m_valueIndexes.insert(std::make_pair(value, nextIndex));
m_indexValues.insert(std::make_pair(nextIndex, value));
return nextIndex;
@ -132,7 +137,8 @@ private:
std::string rtn;
for (const char* pos = text.c_str(); *pos; ++pos) {
if (!isprint(*pos) || *pos == '%' || *pos == '"') {
char hex[10]; sprintf(hex, "%%%02X", pos[0]);
char hex[10];
sprintf(hex, "%%%02X", pos[0]);
rtn += hex;
} else {
rtn += *pos;
@ -149,7 +155,8 @@ private:
if (key.length() == 2 && isdigit(key[1])) return false;
return true;
}
static std::string keyValueFormatter(const std::string& key, const std::string& value) VL_PURE {
static std::string keyValueFormatter(const std::string& key,
const std::string& value) VL_PURE {
std::string name;
if (key.length() == 1 && isalpha(key[0])) {
name += std::string("\001") + key;
@ -173,7 +180,10 @@ private:
// Scan forward to first mismatch
const char* apre = a;
const char* bpre = b;
while (*apre == *bpre) { apre++; bpre++; }
while (*apre == *bpre) {
apre++;
bpre++;
}
// We used to backup and split on only .'s but it seems better to be verbose
// and not assume . is the separator
@ -182,18 +192,22 @@ private:
// Scan backward to last mismatch
const char* apost = a + strlen(a) - 1;
const char* bpost = b + strlen(b) - 1;
while (*apost == *bpost
&& apost>apre && bpost>bpre) { apost--; bpost--; }
while (*apost == *bpost && apost > apre && bpost > bpre) {
apost--;
bpost--;
}
// Forward to . so we have a whole word
std::string suffix = *bpost ? std::string(bpost + 1) : "";
std::string out = prefix + "*" + suffix;
//cout << "\nch pre="<<prefix<<" s="<<suffix<<"\nch a="<<old<<"\nch b="<<add<<"\nch o="<<out<<endl;
// cout << "\nch pre="<<prefix<<" s="<<suffix<<"\nch a="<<old<<"\nch b="<<add
// <<"\ncho="<<out<<endl;
return out;
}
bool itemMatchesString(VerilatedCovImpItem* itemp, const std::string& match) VL_REQUIRES(m_mutex) {
bool itemMatchesString(VerilatedCovImpItem* itemp, const std::string& match)
VL_REQUIRES(m_mutex) {
for (int i = 0; i < MAX_KEYS; ++i) {
if (itemp->m_keys[i] != KEY_UNDEF) {
// We don't compare keys, only values
@ -207,14 +221,20 @@ private:
}
static void selftest() VL_MT_SAFE {
// Little selftest
if (combineHier("a.b.c","a.b.c") !="a.b.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier("a.b.c","a.b") !="a.b*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier("a.x.c","a.y.c") !="a.*.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier("a.z.z.z.c","a.b.c") !="a.*.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier("z","a") !="*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier("q.a","q.b") !="q.*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier("q.za","q.zb") !="q.z*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
if (combineHier("1.2.3.a","9.8.7.a") !="*.a") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
#define VL_CST_CHECK(got, exp) \
do { \
if ((got) != (exp)) VL_FATAL_MT(__FILE__, __LINE__, "", "%Error: selftest\n"); \
} while (0)
VL_CST_CHECK(combineHier("a.b.c", "a.b.c"), "a.b.c");
VL_CST_CHECK(combineHier("a.b.c", "a.b"), "a.b*");
VL_CST_CHECK(combineHier("a.x.c", "a.y.c"), "a.*.c");
VL_CST_CHECK(combineHier("a.z.z.z.c", "a.b.c"), "a.*.c");
VL_CST_CHECK(combineHier("z", "a"), "*");
VL_CST_CHECK(combineHier("q.a", "q.b"), "q.*");
VL_CST_CHECK(combineHier("q.za", "q.zb"), "q.z*");
VL_CST_CHECK(combineHier("1.2.3.a", "9.8.7.a"), "*.a");
#undef VL_CST_CHECK
}
void clearGuts() VL_REQUIRES(m_mutex) {
for (ItemList::const_iterator it = m_items.begin(); it != m_items.end(); ++it) {
@ -268,28 +288,28 @@ public:
m_insertFilenamep = filenamep;
m_insertLineno = lineno;
}
void insertp(const char* ckeyps[MAX_KEYS],
const char* valps[MAX_KEYS]) VL_EXCLUDES(m_mutex) {
void insertp(const char* ckeyps[MAX_KEYS], const char* valps[MAX_KEYS]) VL_EXCLUDES(m_mutex) {
VerilatedLockGuard lock(m_mutex);
assert(m_insertp);
// First two key/vals are filename
ckeyps[0]="filename"; valps[0]=m_insertFilenamep;
ckeyps[0] = "filename";
valps[0] = m_insertFilenamep;
std::string linestr = vlCovCvtToStr(m_insertLineno);
ckeyps[1]="lineno"; valps[1]=linestr.c_str();
ckeyps[1] = "lineno";
valps[1] = linestr.c_str();
// Default page if not specified
const char* fnstartp = m_insertFilenamep;
while (const char* foundp = strchr(fnstartp, '/')) fnstartp = foundp + 1;
const char* fnendp = fnstartp;
while (*fnendp && *fnendp!='.') fnendp++;
for (; *fnendp && *fnendp != '.'; fnendp++) {}
std::string page_default = "sp_user/" + std::string(fnstartp, fnendp - fnstartp);
ckeyps[2]="page"; valps[2]=page_default.c_str();
ckeyps[2] = "page";
valps[2] = page_default.c_str();
// Keys -> strings
std::string keys[MAX_KEYS];
for (int i = 0; i < MAX_KEYS; ++i) {
if (ckeyps[i] && ckeyps[i][0]) {
keys[i] = ckeyps[i];
}
if (ckeyps[i] && ckeyps[i][0]) { keys[i] = ckeyps[i]; }
}
// Ignore empty keys
for (int i = 0; i < MAX_KEYS; ++i) {
@ -400,15 +420,11 @@ public:
//=============================================================================
// VerilatedCov
void VerilatedCov::clear() VL_MT_SAFE {
VerilatedCovImp::imp().clear();
}
void VerilatedCov::clear() VL_MT_SAFE { VerilatedCovImp::imp().clear(); }
void VerilatedCov::clearNonMatch(const char* matchp) VL_MT_SAFE {
VerilatedCovImp::imp().clearNonMatch(matchp);
}
void VerilatedCov::zero() VL_MT_SAFE {
VerilatedCovImp::imp().zero();
}
void VerilatedCov::zero() VL_MT_SAFE { VerilatedCovImp::imp().zero(); }
void VerilatedCov::write(const char* filenamep) VL_MT_SAFE {
VerilatedCovImp::imp().write(filenamep);
}
@ -426,9 +442,10 @@ void VerilatedCov::_insertf(const char* filename, int lineno) VL_MT_SAFE {
#define A(n) const char *key##n, const char *valp##n // Argument list
#define C(n) key##n, valp##n // Calling 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),
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 {
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(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]
= {NULL, NULL, NULL, // filename,lineno,page
key0, key1, key2, key3, key4, key5, key6, key7, key8, key9,
@ -443,27 +460,27 @@ 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!)
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),
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));
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), 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));
}
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 {
_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),
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), 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), 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));
}
// Backward compatibility for Verilator
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 {
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 {
std::string val2str = vlCovCvtToStr(val2);
std::string val3str = vlCovCvtToStr(val3);
_insertp(C(0),C(1),
key2,val2str.c_str(), key3,val3str.c_str(), key4, val4.c_str(),
C(5),C(6),N(7),N(8),N(9),
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));
_insertp(C(0), C(1), key2, val2str.c_str(), key3, val3str.c_str(), key4, val4.c_str(), C(5),
C(6), N(7), N(8), N(9), 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));
}
#undef A
#undef C

View File

@ -28,17 +28,17 @@
//=============================================================================
/// Conditionally compile coverage code
// clang-format off
#ifdef VM_COVERAGE
# define VL_IF_COVER(stmts) \
do { \
stmts; \
} while (false)
do { stmts; } while (false)
#else
# define VL_IF_COVER(stmts) \
do { \
if (false) { stmts; } \
} while (false)
#endif
// clang-format on
//=============================================================================
/// Insert a item for coverage analysis.
@ -69,15 +69,16 @@
/// }
#define VL_COVER_INSERT(countp, ...) \
VL_IF_COVER(VerilatedCov::_inserti(countp); \
VerilatedCov::_insertf(__FILE__, __LINE__); \
VL_IF_COVER(VerilatedCov::_inserti(countp); VerilatedCov::_insertf(__FILE__, __LINE__); \
VerilatedCov::_insertp("hier", name(), __VA_ARGS__))
//=============================================================================
/// Convert VL_COVER_INSERT value arguments to strings
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();
}
//=============================================================================
@ -89,6 +90,7 @@ template< class T> std::string vlCovCvtToStr(const T& t) VL_PURE {
class VerilatedCov {
VL_UNCOPYABLE(VerilatedCov);
public:
// GLOBAL METHODS
/// Return default filename
@ -112,14 +114,14 @@ public:
#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
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)
,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)
,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));
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));
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(20), D(21),
D(22), D(23), D(24), D(25), D(26), D(27), D(28), D(29));
// Backward compatibility for Verilator
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));
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));
#undef K
#undef A

View File

@ -28,6 +28,7 @@
#define VLCOVGEN_ITEM(string_parsed_by_vlcovgen)
// clang-format off
VLCOVGEN_ITEM("name=>'col0_name', short=>'C0', group=>1, default=>undef, descr=>'The column title for the header line of this column'")
VLCOVGEN_ITEM("name=>'col1_name', short=>'C1', group=>1, default=>undef, ")
VLCOVGEN_ITEM("name=>'col2_name', short=>'C2', group=>1, default=>undef, ")
@ -59,6 +60,7 @@ VLCOVGEN_ITEM("name=>'row1', short=>'r1', group=>0, default=>undef, ")
VLCOVGEN_ITEM("name=>'row2', short=>'r2', group=>0, default=>undef, ")
VLCOVGEN_ITEM("name=>'row3', short=>'r3', group=>0, default=>undef, ")
VLCOVGEN_ITEM("name=>'weight', short=>'w', group=>0, default=>undef, descr=>'For totaling items, weight of this item'")
// clang-format on
// VLCOVGEN_CIK_AUTO_EDIT_BEGIN
#define VL_CIK_COL0 "c0"

View File

@ -42,28 +42,24 @@
VL_FATAL_MT(__FILE__, __LINE__, "", \
(std::string("%%Error: Unsupported DPI function: ") + VL_FUNC).c_str())
#define _VL_SVDPI_WARN(...) \
VL_PRINTF_MT(__VA_ARGS__)
#define _VL_SVDPI_WARN(...) VL_PRINTF_MT(__VA_ARGS__)
// Function requires a "context" in the import declaration
#define _VL_SVDPI_CONTEXT_WARN() \
_VL_SVDPI_WARN("%%Warning: DPI C Function called by Verilog DPI import with missing 'context' keyword.\n");
_VL_SVDPI_WARN("%%Warning: DPI C Function called by Verilog DPI import with missing " \
"'context' keyword.\n");
//======================================================================
//======================================================================
//======================================================================
// DPI ROUTINES
const char* svDpiVersion() {
return "1800-2005";
}
const char* svDpiVersion() { return "1800-2005"; }
//======================================================================
// Bit-select utility functions.
svBit svGetBitselBit(const svBitVecVal* sp, int bit) {
return VL_BITRSHIFT_W(sp,bit) & 1;
}
svBit svGetBitselBit(const svBitVecVal* sp, int bit) { return VL_BITRSHIFT_W(sp, bit) & 1; }
svLogic svGetBitselLogic(const svLogicVecVal* sp, int bit) {
// Not VL_BITRSHIFT_W as sp is a different structure type
// Verilator doesn't support X/Z so only aval
@ -71,16 +67,12 @@ svLogic svGetBitselLogic(const svLogicVecVal* sp, int bit) {
| (((sp[VL_BITWORD_I(bit)].bval >> VL_BITBIT_I(bit)) & 1) << 1));
}
void svPutBitselBit(svBitVecVal* dp, int bit, svBit s) {
VL_ASSIGNBIT_WI(32, bit, dp, s);
}
void svPutBitselBit(svBitVecVal* dp, int bit, svBit s) { VL_ASSIGNBIT_WI(32, bit, dp, s); }
void svPutBitselLogic(svLogicVecVal* dp, int bit, svLogic s) {
// Verilator doesn't support X/Z so only aval
dp[VL_BITWORD_I(bit)].aval
= ((dp[VL_BITWORD_I(bit)].aval & ~(VL_UL(1)<<VL_BITBIT_I(bit)))
dp[VL_BITWORD_I(bit)].aval = ((dp[VL_BITWORD_I(bit)].aval & ~(VL_UL(1) << VL_BITBIT_I(bit)))
| ((s & 1) << VL_BITBIT_I(bit)));
dp[VL_BITWORD_I(bit)].bval
= ((dp[VL_BITWORD_I(bit)].bval & ~(VL_UL(1)<<VL_BITBIT_I(bit)))
dp[VL_BITWORD_I(bit)].bval = ((dp[VL_BITWORD_I(bit)].bval & ~(VL_UL(1) << VL_BITBIT_I(bit)))
| ((s & 2) >> 1 << VL_BITBIT_I(bit)));
}
@ -140,8 +132,7 @@ void svPutPartselBit(svBitVecVal* dp, const svBitVecVal s, int lbit, int width)
if (hoffset == VL_SIZEBITS_I && loffset == 0) {
// Fast and common case, word based insertion
dp[VL_BITWORD_I(lbit)] = s;
}
else {
} else {
int hword = VL_BITWORD_I(hbit);
int lword = VL_BITWORD_I(lbit);
if (hword == lword) { // know < 32 bits because above checks it
@ -165,8 +156,7 @@ void svPutPartselLogic(svLogicVecVal* dp, const svLogicVecVal s, int lbit, int w
// Fast and common case, word based insertion
dp[VL_BITWORD_I(lbit)].aval = s.aval;
dp[VL_BITWORD_I(lbit)].bval = s.bval;
}
else {
} else {
int hword = VL_BITWORD_I(hbit);
int lword = VL_BITWORD_I(lbit);
if (hword == lword) { // know < 32 bits because above checks it
@ -204,27 +194,14 @@ static inline const VerilatedDpiOpenVar* _vl_openhandle_varp(const svOpenArrayHa
//======================================================================
// Open array querying functions
int svLeft(const svOpenArrayHandle h, int d) {
return _vl_openhandle_varp(h)->left(d);
}
int svRight(const svOpenArrayHandle h, int d) {
return _vl_openhandle_varp(h)->right(d);
}
int svLow(const svOpenArrayHandle h, int d) {
return _vl_openhandle_varp(h)->low(d);
}
int svHigh(const svOpenArrayHandle h, int d) {
return _vl_openhandle_varp(h)->high(d);
}
int svIncrement(const svOpenArrayHandle h, int d) {
return _vl_openhandle_varp(h)->increment(d);
}
int svSize(const svOpenArrayHandle h, int d) {
return _vl_openhandle_varp(h)->elements(d);
}
int svDimensions(const svOpenArrayHandle h) {
return _vl_openhandle_varp(h)->udims();
}
int svLeft(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->left(d); }
int svRight(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->right(d); }
int svLow(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->low(d); }
int svHigh(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->high(d); }
int svIncrement(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->increment(d); }
int svSize(const svOpenArrayHandle h, int d) { return _vl_openhandle_varp(h)->elements(d); }
int svDimensions(const svOpenArrayHandle h) { return _vl_openhandle_varp(h)->udims(); }
/// Return pointer to open array data, or NULL if not in IEEE standard C layout
void* svGetArrayPtr(const svOpenArrayHandle h) {
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(h);
@ -242,8 +219,8 @@ int svSizeOfArray(const svOpenArrayHandle h) {
//======================================================================
// Open array access internals
static void* _vl_sv_adjusted_datap(const VerilatedDpiOpenVar* varp,
int nargs, int indx1, int indx2, int indx3) {
static void* _vl_sv_adjusted_datap(const VerilatedDpiOpenVar* varp, int nargs, int indx1,
int indx2, int indx3) {
void* datap = varp->datap();
if (VL_UNLIKELY(nargs != varp->udims())) {
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function called on"
@ -254,7 +231,8 @@ static void* _vl_sv_adjusted_datap(const VerilatedDpiOpenVar* varp,
if (nargs >= 1) {
datap = varp->datapAdjustIndex(datap, 1, indx1);
if (VL_UNLIKELY(!datap)) {
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function index 1 out of bounds; %d outside [%d:%d].\n",
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function index 1 "
"out of bounds; %d outside [%d:%d].\n",
indx1, varp->left(1), varp->right(1));
return NULL;
}
@ -262,7 +240,8 @@ static void* _vl_sv_adjusted_datap(const VerilatedDpiOpenVar* varp,
if (nargs >= 2) {
datap = varp->datapAdjustIndex(datap, 2, indx2);
if (VL_UNLIKELY(!datap)) {
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function index 2 out of bounds; %d outside [%d:%d].\n",
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function index 2 "
"out of bounds; %d outside [%d:%d].\n",
indx2, varp->left(2), varp->right(2));
return NULL;
}
@ -270,7 +249,8 @@ static void* _vl_sv_adjusted_datap(const VerilatedDpiOpenVar* varp,
if (nargs >= 3) {
datap = varp->datapAdjustIndex(datap, 3, indx3);
if (VL_UNLIKELY(!datap)) {
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function index 3 out of bounds; %d outside [%d:%d].\n",
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function index 3 "
"out of bounds; %d outside [%d:%d].\n",
indx1, varp->left(3), varp->right(3));
return NULL;
}
@ -280,7 +260,8 @@ static void* _vl_sv_adjusted_datap(const VerilatedDpiOpenVar* varp,
static int _vl_sv_adjusted_bit(const VerilatedDpiOpenVar* varp, int indx) {
if (VL_UNLIKELY(indx < varp->low(0) || indx > varp->high(0))) {
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function packed index out of bounds; %d outside [%d:%d].\n",
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function packed index out of bounds; %d "
"outside [%d:%d].\n",
indx, varp->left(0), varp->right(0));
return 0;
}
@ -288,8 +269,8 @@ static int _vl_sv_adjusted_bit(const VerilatedDpiOpenVar* varp, int indx) {
}
/// Return pointer to simulator open array element, or NULL if outside range
static void* _vl_svGetArrElemPtr(const svOpenArrayHandle h,
int nargs, int indx1, int indx2, int indx3) VL_MT_SAFE {
static void* _vl_svGetArrElemPtr(const svOpenArrayHandle h, int nargs, int indx1, int indx2,
int indx3) VL_MT_SAFE {
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(h);
if (VL_UNLIKELY(!varp->isDpiStdLayout())) return NULL;
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
@ -297,8 +278,8 @@ static void* _vl_svGetArrElemPtr(const svOpenArrayHandle h,
}
/// Copy to user bit array from simulator open array
static void _vl_svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s,
int nargs, int indx1, int indx2, int indx3) VL_MT_SAFE {
static void _vl_svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s, int nargs,
int indx1, int indx2, int indx3) VL_MT_SAFE {
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
if (VL_UNLIKELY(!datap)) return;
@ -307,8 +288,10 @@ static void _vl_svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s,
case VLVT_UINT16: d[0] = *(reinterpret_cast<SData*>(datap)); return;
case VLVT_UINT32: d[0] = *(reinterpret_cast<IData*>(datap)); return;
case VLVT_UINT64: {
WData lwp[2]; VL_SET_WQ(lwp, *(reinterpret_cast<QData*>(datap)));
d[0] = lwp[0]; d[1] = lwp[1];
WData lwp[2];
VL_SET_WQ(lwp, *(reinterpret_cast<QData*>(datap)));
d[0] = lwp[0];
d[1] = lwp[1];
break;
}
case VLVT_WDATA: {
@ -323,25 +306,38 @@ static void _vl_svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s,
}
}
/// Copy to user logic array from simulator open array
static void _vl_svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s,
int nargs, int indx1, int indx2, int indx3) VL_MT_SAFE {
static void _vl_svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s, int nargs,
int indx1, int indx2, int indx3) VL_MT_SAFE {
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
if (VL_UNLIKELY(!datap)) return;
switch (varp->vltype()) {
case VLVT_UINT8: d[0].aval = *(reinterpret_cast<CData*>(datap)); d[0].bval=0; return;
case VLVT_UINT16: d[0].aval = *(reinterpret_cast<SData*>(datap)); d[0].bval=0; return;
case VLVT_UINT32: d[0].aval = *(reinterpret_cast<IData*>(datap)); d[0].bval=0; return;
case VLVT_UINT8:
d[0].aval = *(reinterpret_cast<CData*>(datap));
d[0].bval = 0;
return;
case VLVT_UINT16:
d[0].aval = *(reinterpret_cast<SData*>(datap));
d[0].bval = 0;
return;
case VLVT_UINT32:
d[0].aval = *(reinterpret_cast<IData*>(datap));
d[0].bval = 0;
return;
case VLVT_UINT64: {
WData lwp[2]; VL_SET_WQ(lwp, *(reinterpret_cast<QData*>(datap)));
d[0].aval = lwp[0]; d[0].bval=0;
d[1].aval = lwp[1]; d[0].bval=0;
WData lwp[2];
VL_SET_WQ(lwp, *(reinterpret_cast<QData*>(datap)));
d[0].aval = lwp[0];
d[0].bval = 0;
d[1].aval = lwp[1];
d[0].bval = 0;
break;
}
case VLVT_WDATA: {
WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
for (int i = 0; i < VL_WORDS_I(varp->packed().elements()); ++i) {
d[i].aval = wdatap[i]; d[i].bval = 0;
d[i].aval = wdatap[i];
d[i].bval = 0;
}
return;
}
@ -353,8 +349,8 @@ static void _vl_svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandl
}
/// Copy to simulator open array from from user bit array
static void _vl_svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s,
int nargs, int indx1, int indx2, int indx3) VL_MT_SAFE {
static void _vl_svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s, int nargs,
int indx1, int indx2, int indx3) VL_MT_SAFE {
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
if (VL_UNLIKELY(!datap)) return;
@ -384,31 +380,32 @@ static void _vl_svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogic
case VLVT_UINT8: *(reinterpret_cast<CData*>(datap)) = s[0].aval; return;
case VLVT_UINT16: *(reinterpret_cast<SData*>(datap)) = s[0].aval; return;
case VLVT_UINT32: *(reinterpret_cast<IData*>(datap)) = s[0].aval; return;
case VLVT_UINT64: *(reinterpret_cast<QData*>(datap)) = _VL_SET_QII(s[1].aval, s[0].aval); break;
case VLVT_UINT64:
*(reinterpret_cast<QData*>(datap)) = _VL_SET_QII(s[1].aval, s[0].aval);
break;
case VLVT_WDATA: {
WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
for (int i = 0; i < VL_WORDS_I(varp->packed().elements()); ++i) wdatap[i] = s[i].aval;
return;
}
default:
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype());
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
varp->vltype());
return;
}
}
/// Return bit from simulator open array
static svBit _vl_svGetBitArrElem(const svOpenArrayHandle s,
int nargs, int indx1, int indx2, int indx3, int indx4) VL_MT_SAFE {
static svBit _vl_svGetBitArrElem(const svOpenArrayHandle s, int nargs, int indx1, int indx2,
int indx3, int indx4) VL_MT_SAFE {
// One extra index supported, as need bit number
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
void* datap;
int lsb;
if (varp->packed().elements()) {
datap = _vl_sv_adjusted_datap(varp, nargs - 1, indx1, indx2, indx3);
lsb = _vl_sv_adjusted_bit(varp, ((nargs==1) ? indx1
: (nargs==2) ? indx2
: (nargs==3) ? indx3
: indx4));
lsb = _vl_sv_adjusted_bit(
varp, ((nargs == 1) ? indx1 : (nargs == 2) ? indx2 : (nargs == 3) ? indx3 : indx4));
} else {
datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
lsb = 0;
@ -418,19 +415,21 @@ static svBit _vl_svGetBitArrElem(const svOpenArrayHandle s,
case VLVT_UINT8: return (*(reinterpret_cast<CData*>(datap)) >> lsb) & 1;
case VLVT_UINT16: return (*(reinterpret_cast<SData*>(datap)) >> lsb) & 1;
case VLVT_UINT32: return (*(reinterpret_cast<IData*>(datap)) >> lsb) & 1;
case VLVT_UINT64: return (*(reinterpret_cast<QData*>(datap)) >> static_cast<QData>(lsb)) & VL_ULL(1);
case VLVT_UINT64:
return (*(reinterpret_cast<QData*>(datap)) >> static_cast<QData>(lsb)) & VL_ULL(1);
case VLVT_WDATA: {
WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
return VL_BITRSHIFT_W(wdatap, lsb) & 1;
}
default:
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype());
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
varp->vltype());
return 0;
}
}
/// Update simulator open array from bit
static void _vl_svPutBitArrElem(const svOpenArrayHandle d, svBit value,
int nargs, int indx1, int indx2, int indx3, int indx4) VL_MT_SAFE {
static void _vl_svPutBitArrElem(const svOpenArrayHandle d, svBit value, int nargs, int indx1,
int indx2, int indx3, int indx4) VL_MT_SAFE {
// One extra index supported, as need bit number
value &= 1; // Make sure clean
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
@ -438,10 +437,8 @@ static void _vl_svPutBitArrElem(const svOpenArrayHandle d, svBit value,
int lsb;
if (varp->packed().elements()) {
datap = _vl_sv_adjusted_datap(varp, nargs - 1, indx1, indx2, indx3);
lsb = _vl_sv_adjusted_bit(varp, ((nargs==1) ? indx1
: (nargs==2) ? indx2
: (nargs==3) ? indx3
: indx4));
lsb = _vl_sv_adjusted_bit(
varp, ((nargs == 1) ? indx1 : (nargs == 2) ? indx2 : (nargs == 3) ? indx3 : indx4));
} else {
datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
lsb = 0;
@ -454,7 +451,8 @@ static void _vl_svPutBitArrElem(const svOpenArrayHandle d, svBit value,
case VLVT_UINT64: VL_ASSIGNBIT_QI(-1, lsb, *(reinterpret_cast<QData*>(datap)), value); return;
case VLVT_WDATA: VL_ASSIGNBIT_WI(-1, lsb, (reinterpret_cast<WDataOutP>(datap)), value); return;
default:
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype());
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
varp->vltype());
return;
}
}
@ -470,10 +468,17 @@ void* svGetArrElemPtr(const svOpenArrayHandle h, int indx1, ...) {
// va_arg is a macro, so need temporaries as used below
switch (varp->udims()) {
case 1: datap = _vl_svGetArrElemPtr(h, 1, indx1, 0, 0); break;
case 2: { int indx2=va_arg(ap,int);
datap = _vl_svGetArrElemPtr(h, 2, indx1, indx2, 0); break; }
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
datap = _vl_svGetArrElemPtr(h, 3, indx1, indx2, indx3); break; }
case 2: {
int indx2 = va_arg(ap, int);
datap = _vl_svGetArrElemPtr(h, 2, indx1, indx2, 0);
break;
}
case 3: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
datap = _vl_svGetArrElemPtr(h, 3, indx1, indx2, indx3);
break;
}
default: datap = _vl_svGetArrElemPtr(h, -1, 0, 0, 0); break; // Will error
}
va_end(ap);
@ -489,116 +494,134 @@ void* svGetArrElemPtr3(const svOpenArrayHandle h, int indx1, int indx2, int indx
return _vl_svGetArrElemPtr(h, 3, indx1, indx2, indx3);
}
void svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s,
int indx1, ...) {
void svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, ...) {
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
va_list ap;
va_start(ap, indx1);
switch (varp->udims()) {
case 1: _vl_svPutBitArrElemVecVal(d, s, 1, indx1, 0, 0); break;
case 2: { int indx2=va_arg(ap,int);
_vl_svPutBitArrElemVecVal(d, s, 2, indx1, indx2, 0); break; }
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
_vl_svPutBitArrElemVecVal(d, s, 3, indx1, indx2, indx3); break; }
case 2: {
int indx2 = va_arg(ap, int);
_vl_svPutBitArrElemVecVal(d, s, 2, indx1, indx2, 0);
break;
}
case 3: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
_vl_svPutBitArrElemVecVal(d, s, 3, indx1, indx2, indx3);
break;
}
default: _vl_svPutBitArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error
}
va_end(ap);
}
void svPutBitArrElem1VecVal(const svOpenArrayHandle d, const svBitVecVal* s,
int indx1) {
void svPutBitArrElem1VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1) {
_vl_svPutBitArrElemVecVal(d, s, 1, indx1, 0, 0);
}
void svPutBitArrElem2VecVal(const svOpenArrayHandle d, const svBitVecVal* s,
int indx1, int indx2) {
void svPutBitArrElem2VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1,
int indx2) {
_vl_svPutBitArrElemVecVal(d, s, 2, indx1, indx2, 0);
}
void svPutBitArrElem3VecVal(const svOpenArrayHandle d, const svBitVecVal* s,
int indx1, int indx2, int indx3) {
void svPutBitArrElem3VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, int indx2,
int indx3) {
_vl_svPutBitArrElemVecVal(d, s, 3, indx1, indx2, indx3);
}
void svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
int indx1, ...) {
void svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1, ...) {
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
va_list ap;
va_start(ap, indx1);
switch (varp->udims()) {
case 1: _vl_svPutLogicArrElemVecVal(d, s, 1, indx1, 0, 0); break;
case 2: { int indx2=va_arg(ap,int);
_vl_svPutLogicArrElemVecVal(d, s, 2, indx1, indx2, 0); break; }
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
_vl_svPutLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3); break; }
case 2: {
int indx2 = va_arg(ap, int);
_vl_svPutLogicArrElemVecVal(d, s, 2, indx1, indx2, 0);
break;
}
case 3: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
_vl_svPutLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3);
break;
}
default: _vl_svPutLogicArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error
}
va_end(ap);
}
void svPutLogicArrElem1VecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
int indx1) {
void svPutLogicArrElem1VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1) {
_vl_svPutLogicArrElemVecVal(d, s, 1, indx1, 0, 0);
}
void svPutLogicArrElem2VecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
int indx1, int indx2) {
void svPutLogicArrElem2VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1,
int indx2) {
_vl_svPutLogicArrElemVecVal(d, s, 2, indx1, indx2, 0);
}
void svPutLogicArrElem3VecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
int indx1, int indx2, int indx3) {
void svPutLogicArrElem3VecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1,
int indx2, int indx3) {
_vl_svPutLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3);
}
//======================================================================
// From simulator storage into user space
void svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s,
int indx1, ...) {
void svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, ...) {
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
va_list ap;
va_start(ap, indx1);
switch (varp->udims()) {
case 1: _vl_svGetBitArrElemVecVal(d, s, 1, indx1, 0, 0); break;
case 2: { int indx2=va_arg(ap,int);
_vl_svGetBitArrElemVecVal(d, s, 2, indx1, indx2, 0); break; }
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
_vl_svGetBitArrElemVecVal(d, s, 3, indx1, indx2, indx3); break; }
case 2: {
int indx2 = va_arg(ap, int);
_vl_svGetBitArrElemVecVal(d, s, 2, indx1, indx2, 0);
break;
}
case 3: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
_vl_svGetBitArrElemVecVal(d, s, 3, indx1, indx2, indx3);
break;
}
default: _vl_svGetBitArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error
}
va_end(ap);
}
void svGetBitArrElem1VecVal(svBitVecVal* d, const svOpenArrayHandle s,
int indx1) {
void svGetBitArrElem1VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1) {
_vl_svGetBitArrElemVecVal(d, s, 1, indx1, 0, 0);
}
void svGetBitArrElem2VecVal(svBitVecVal* d, const svOpenArrayHandle s,
int indx1, int indx2) {
void svGetBitArrElem2VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, int indx2) {
_vl_svGetBitArrElemVecVal(d, s, 2, indx1, indx2, 0);
}
void svGetBitArrElem3VecVal(svBitVecVal* d, const svOpenArrayHandle s,
int indx1, int indx2, int indx3) {
void svGetBitArrElem3VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, int indx2,
int indx3) {
_vl_svGetBitArrElemVecVal(d, s, 3, indx1, indx2, indx3);
}
void svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s,
int indx1, ...) {
void svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, ...) {
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
va_list ap;
va_start(ap, indx1);
switch (varp->udims()) {
case 1: _vl_svGetLogicArrElemVecVal(d, s, 1, indx1, 0, 0); break;
case 2: { int indx2=va_arg(ap,int);
_vl_svGetLogicArrElemVecVal(d, s, 2, indx1, indx2, 0); break; }
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
_vl_svGetLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3); break; }
case 2: {
int indx2 = va_arg(ap, int);
_vl_svGetLogicArrElemVecVal(d, s, 2, indx1, indx2, 0);
break;
}
case 3: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
_vl_svGetLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3);
break;
}
default: _vl_svGetLogicArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error
}
va_end(ap);
}
void svGetLogicArrElem1VecVal(svLogicVecVal* d, const svOpenArrayHandle s,
int indx1) {
void svGetLogicArrElem1VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1) {
_vl_svGetLogicArrElemVecVal(d, s, 1, indx1, 0, 0);
}
void svGetLogicArrElem2VecVal(svLogicVecVal* d, const svOpenArrayHandle s,
int indx1, int indx2) {
void svGetLogicArrElem2VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, int indx2) {
_vl_svGetLogicArrElemVecVal(d, s, 2, indx1, indx2, 0);
}
void svGetLogicArrElem3VecVal(svLogicVecVal* d, const svOpenArrayHandle s,
int indx1, int indx2, int indx3) {
void svGetLogicArrElem3VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, int indx2,
int indx3) {
_vl_svGetLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3);
}
@ -609,12 +632,24 @@ svBit svGetBitArrElem(const svOpenArrayHandle s, int indx1, ...) {
va_start(ap, indx1);
switch (varp->udims()) {
case 1: out = _vl_svGetBitArrElem(s, 1, indx1, 0, 0, 0); break;
case 2: { int indx2=va_arg(ap,int);
out = _vl_svGetBitArrElem(s, 2, indx1, indx2, 0, 0); break; }
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
out = _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0); break; }
case 4: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); int indx4=va_arg(ap,int);
out = _vl_svGetBitArrElem(s, 4, indx1, indx2, indx3, indx4); break; }
case 2: {
int indx2 = va_arg(ap, int);
out = _vl_svGetBitArrElem(s, 2, indx1, indx2, 0, 0);
break;
}
case 3: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
out = _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0);
break;
}
case 4: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
int indx4 = va_arg(ap, int);
out = _vl_svGetBitArrElem(s, 4, indx1, indx2, indx3, indx4);
break;
}
default: out = _vl_svGetBitArrElem(s, -1, 0, 0, 0, 0); break; // Will error
}
va_end(ap);
@ -637,12 +672,24 @@ svLogic svGetLogicArrElem(const svOpenArrayHandle s, int indx1, ...) {
va_start(ap, indx1);
switch (varp->udims()) {
case 1: out = _vl_svGetBitArrElem(s, 1, indx1, 0, 0, 0); break;
case 2: { int indx2=va_arg(ap,int);
out = _vl_svGetBitArrElem(s, 2, indx1, indx2, 0, 0); break; }
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
out = _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0); break; }
case 4: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); int indx4=va_arg(ap,int);
out = _vl_svGetBitArrElem(s, 4, indx1, indx2, indx3, indx4); break; }
case 2: {
int indx2 = va_arg(ap, int);
out = _vl_svGetBitArrElem(s, 2, indx1, indx2, 0, 0);
break;
}
case 3: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
out = _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0);
break;
}
case 4: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
int indx4 = va_arg(ap, int);
out = _vl_svGetBitArrElem(s, 4, indx1, indx2, indx3, indx4);
break;
}
default: out = _vl_svGetBitArrElem(s, -1, 0, 0, 0, 0); break; // Will error
}
va_end(ap);
@ -667,12 +714,24 @@ void svPutBitArrElem(const svOpenArrayHandle d, svBit value, int indx1, ...) {
va_start(ap, indx1);
switch (varp->udims()) {
case 1: _vl_svPutBitArrElem(d, value, 1, indx1, 0, 0, 0); break;
case 2: { int indx2=va_arg(ap,int);
_vl_svPutBitArrElem(d, value, 2, indx1, indx2, 0, 0); break; }
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
_vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0); break; }
case 4: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); int indx4=va_arg(ap,int);
_vl_svPutBitArrElem(d, value, 4, indx1, indx2, indx3, indx4); break; }
case 2: {
int indx2 = va_arg(ap, int);
_vl_svPutBitArrElem(d, value, 2, indx1, indx2, 0, 0);
break;
}
case 3: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
_vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0);
break;
}
case 4: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
int indx4 = va_arg(ap, int);
_vl_svPutBitArrElem(d, value, 4, indx1, indx2, indx3, indx4);
break;
}
default: _vl_svPutBitArrElem(d, value, -1, 0, 0, 0, 0); break; // Will error
}
va_end(ap);
@ -693,12 +752,24 @@ void svPutLogicArrElem(const svOpenArrayHandle d, svLogic value, int indx1, ...)
va_start(ap, indx1);
switch (varp->udims()) {
case 1: _vl_svPutBitArrElem(d, value, 1, indx1, 0, 0, 0); break;
case 2: { int indx2=va_arg(ap,int);
_vl_svPutBitArrElem(d, value, 2, indx1, indx2, 0, 0); break; }
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
_vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0); break; }
case 4: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); int indx4=va_arg(ap,int);
_vl_svPutBitArrElem(d, value, 4, indx1, indx2, indx3, indx4); break; }
case 2: {
int indx2 = va_arg(ap, int);
_vl_svPutBitArrElem(d, value, 2, indx1, indx2, 0, 0);
break;
}
case 3: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
_vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0);
break;
}
case 4: {
int indx2 = va_arg(ap, int);
int indx3 = va_arg(ap, int);
int indx4 = va_arg(ap, int);
_vl_svPutBitArrElem(d, value, 4, indx1, indx2, indx3, indx4);
break;
}
default: _vl_svPutBitArrElem(d, value, -1, 0, 0, 0, 0); break; // Will error
}
va_end(ap);
@ -707,13 +778,12 @@ void svPutLogicArrElem1(const svOpenArrayHandle d, svLogic value, int indx1) {
// Verilator doesn't support X/Z so can just call Bit version
svPutBitArrElem1(d, value, indx1);
}
void svPutLogicArrElem2(const svOpenArrayHandle d, svLogic value,
int indx1, int indx2) {
void svPutLogicArrElem2(const svOpenArrayHandle d, svLogic value, int indx1, int indx2) {
// Verilator doesn't support X/Z so can just call Bit version
svPutBitArrElem2(d, value, indx1, indx2);
}
void svPutLogicArrElem3(const svOpenArrayHandle d, svLogic value,
int indx1, int indx2, int indx3) {
void svPutLogicArrElem3(const svOpenArrayHandle d, svLogic value, int indx1, int indx2,
int indx3) {
// Verilator doesn't support X/Z so can just call Bit version
svPutBitArrElem3(d, value, indx1, indx2, indx3);
}
@ -722,7 +792,10 @@ void svPutLogicArrElem3(const svOpenArrayHandle d, svLogic value,
// Functions for working with DPI context
svScope svGetScope() {
if (VL_UNLIKELY(!Verilated::dpiInContext())) { _VL_SVDPI_CONTEXT_WARN(); return NULL; }
if (VL_UNLIKELY(!Verilated::dpiInContext())) {
_VL_SVDPI_CONTEXT_WARN();
return NULL;
}
// NOLINTNEXTLINE(google-readability-casting)
return (svScope)(Verilated::dpiScope());
}
@ -755,7 +828,10 @@ void* svGetUserData(const svScope scope, void* userKey) {
}
int svGetCallerInfo(const char** fileNamepp, int* lineNumberp) {
if (VL_UNLIKELY(!Verilated::dpiInContext())) { _VL_SVDPI_CONTEXT_WARN(); return false; }
if (VL_UNLIKELY(!Verilated::dpiInContext())) {
_VL_SVDPI_CONTEXT_WARN();
return false;
}
if (VL_LIKELY(fileNamepp)) *fileNamepp = Verilated::dpiFilenamep(); // thread local
if (VL_LIKELY(lineNumberp)) *lineNumberp = Verilated::dpiLineno(); // thread local
return true;

View File

@ -35,29 +35,21 @@
/// Convert svBitVecVal to Verilator internal data
static inline void VL_SET_W_SVBV(int obits, WDataOutP owp, const svBitVecVal* lwp) VL_MT_SAFE {
int words = VL_WORDS_I(obits);
for (int i = 0; i < words - 1; ++i) {
owp[i] = lwp[i];
}
for (int i = 0; i < words - 1; ++i) owp[i] = lwp[i];
owp[words - 1] = lwp[words - 1] & VL_MASK_I(obits);
}
static inline QData VL_SET_Q_SVBV(const svBitVecVal* lwp) VL_MT_SAFE {
return _VL_SET_QII(lwp[1], lwp[0]);
}
static inline IData VL_SET_I_SVBV(const svBitVecVal* lwp) VL_MT_SAFE {
return lwp[0];
}
static inline IData VL_SET_I_SVBV(const svBitVecVal* lwp) VL_MT_SAFE { return lwp[0]; }
/// Convert Verilator internal data to svBitVecVal
static inline void VL_SET_SVBV_W(int obits, svBitVecVal* owp, WDataInP lwp) VL_MT_SAFE {
int words = VL_WORDS_I(obits);
for (int i = 0; i < words - 1; ++i) {
owp[i] = lwp[i];
}
for (int i = 0; i < words - 1; ++i) owp[i] = lwp[i];
owp[words - 1] = lwp[words - 1] & VL_MASK_I(obits);
}
static inline void VL_SET_SVBV_I(int, svBitVecVal* owp, IData ld) VL_MT_SAFE {
owp[0] = ld;
}
static inline void VL_SET_SVBV_I(int, svBitVecVal* owp, IData ld) VL_MT_SAFE { owp[0] = ld; }
static inline void VL_SET_SVBV_Q(int, svBitVecVal* owp, QData ld) VL_MT_SAFE {
VL_SET_WQ(owp, ld);
}
@ -66,28 +58,20 @@ static inline void VL_SET_SVBV_Q(int, svBitVecVal* owp, QData ld) VL_MT_SAFE {
/// Note these functions ignore X/Z in svLogicVecVal
static inline void VL_SET_W_SVLV(int obits, WDataOutP owp, const svLogicVecVal* lwp) VL_MT_SAFE {
int words = VL_WORDS_I(obits);
for (int i = 0; i < words - 1; ++i) {
owp[i] = lwp[i].aval;
}
for (int i = 0; i < words - 1; ++i) owp[i] = lwp[i].aval;
owp[words - 1] = lwp[words - 1].aval & VL_MASK_I(obits);
}
static inline QData VL_SET_Q_SVLV(const svLogicVecVal* lwp) VL_MT_SAFE {
return _VL_SET_QII(lwp[1].aval, lwp[0].aval);
}
static inline IData VL_SET_I_SVLV(const svLogicVecVal* lwp) VL_MT_SAFE {
return lwp[0].aval;
}
static inline IData VL_SET_I_SVLV(const svLogicVecVal* lwp) VL_MT_SAFE { return lwp[0].aval; }
/// Convert Verilator internal data to svLogicVecVal
/// Note these functions never create X/Z in svLogicVecVal
static inline void VL_SET_SVLV_W(int obits, svLogicVecVal* owp, WDataInP lwp) VL_MT_SAFE {
int words = VL_WORDS_I(obits);
for (int i = 0; i < words; ++i) {
owp[i].bval = 0;
}
for (int i = 0; i < words - 1; ++i) {
owp[i].aval = lwp[i];
}
for (int i = 0; i < words; ++i) owp[i].bval = 0;
for (int i = 0; i < words - 1; ++i) owp[i].aval = lwp[i];
owp[words - 1].aval = lwp[words - 1] & VL_MASK_I(obits);
}
static inline void VL_SET_SVLV_I(int, svLogicVecVal* owp, IData ld) VL_MT_SAFE {

View File

@ -379,11 +379,13 @@ template <class T_Value> std::string VL_TO_STRING(const VlQueue<T_Value>& obj) {
// be protected by other means
//
// clang-format off
#if (defined(_MSC_VER) && _MSC_VER >= 1900) || (__cplusplus >= 201103L)
# define VlClassRef std::shared_ptr
#else
# define VlClassRef VlClassRef__SystemVerilog_class_support_requires_a_C11_or_newer_compiler
#endif
// clang-format on
template <class T> // T typically of type VlClassRef<x>
inline T VL_NULL_CHECK(T t, const char* filename, int linenum) {
@ -412,9 +414,7 @@ inline std::string VL_CONCATN_NNN(const std::string& lhs, const std::string& rhs
inline std::string VL_REPLICATEN_NNQ(int, int, int, const std::string& lhs, IData rep) VL_PURE {
std::string out;
out.reserve(lhs.length() * rep);
for (unsigned times = 0; times < rep; ++times) {
out += lhs;
}
for (unsigned times = 0; times < rep; ++times) out += lhs;
return out;
}
inline std::string VL_REPLICATEN_NNI(int obits, int lbits, int rbits, const std::string& lhs,

View File

@ -19,6 +19,7 @@
#ifndef _VERILATED_IMP_H_
#define _VERILATED_IMP_H_ 1 ///< Header Guard
// clang-format off
#if !defined(_VERILATED_CPP_) && !defined(_VERILATED_DPI_CPP_) && !defined(_VERILATED_VPI_CPP_)
# error "verilated_imp.h only to be included by verilated*.cpp internals"
#endif
@ -35,6 +36,7 @@
# include <functional>
# include <queue>
#endif
// clang-format on
class VerilatedScope;
@ -48,8 +50,10 @@ public:
// TYPES
struct Cmp {
bool operator()(const VerilatedMsg& a, const VerilatedMsg& b) const {
return a.mtaskId() < b.mtaskId(); }
return a.mtaskId() < b.mtaskId();
}
};
private:
// MEMBERS
vluint32_t m_mtaskId; ///< MTask that did enqueue
@ -86,6 +90,7 @@ public:
private:
VL_UNCOPYABLE(VerilatedEvalMsgQueue);
public:
// METHODS
//// Add message to queue (called by producer)
@ -122,6 +127,7 @@ public:
/// Each thread has a local queue to build up messages until the end of the eval() call
class VerilatedThreadMsgQueue {
std::queue<VerilatedMsg> m_queue;
public:
// CONSTRUCTORS
VerilatedThreadMsgQueue() {}
@ -129,6 +135,7 @@ public:
// The only call of this with a non-empty queue is a fatal error.
// So this does not flush the queue, as the destination queue is not known to this class.
}
private:
VL_UNCOPYABLE(VerilatedThreadMsgQueue);
// METHODS
@ -136,6 +143,7 @@ private:
static VL_THREAD_LOCAL VerilatedThreadMsgQueue t_s;
return t_s;
}
public:
/// Add message to queue, called by producer
static void post(const VerilatedMsg& msg) VL_MT_SAFE {
@ -177,27 +185,32 @@ class VerilatedImp {
// Nothing here is save-restored; users expected to re-register appropriately
VerilatedMutex m_argMutex; ///< Protect m_argVec, m_argVecLoaded
ArgVec m_argVec VL_GUARDED_BY(m_argMutex); ///< Argument list (NOT save-restored, may want different results)
/// Argument list (NOT save-restored, may want different results)
ArgVec m_argVec VL_GUARDED_BY(m_argMutex);
bool m_argVecLoaded VL_GUARDED_BY(m_argMutex); ///< Ever loaded argument list
VerilatedMutex m_userMapMutex; ///< Protect m_userMap
UserMap m_userMap VL_GUARDED_BY(m_userMapMutex); ///< Map of <(scope,userkey), userData>
VerilatedMutex m_nameMutex; ///< Protect m_nameMap
VerilatedScopeNameMap m_nameMap VL_GUARDED_BY(m_nameMutex); ///< Map of <scope_name, scope pointer>
/// Map of <scope_name, scope pointer>
VerilatedScopeNameMap m_nameMap VL_GUARDED_BY(m_nameMutex);
VerilatedMutex m_hierMapMutex; ///< Protect m_hierMap
VerilatedHierarchyMap m_hierMap VL_GUARDED_BY(m_hierMapMutex); ///< Map the represents scope hierarchy
/// Map the represents scope hierarchy
VerilatedHierarchyMap m_hierMap VL_GUARDED_BY(m_hierMapMutex);
// Slow - somewhat static:
VerilatedMutex m_exportMutex; ///< Protect m_nameMap
ExportNameMap m_exportMap VL_GUARDED_BY(m_exportMutex); ///< Map of <export_func_proto, func number>
/// Map of <export_func_proto, func number>
ExportNameMap m_exportMap VL_GUARDED_BY(m_exportMutex);
int m_exportNext VL_GUARDED_BY(m_exportMutex); ///< Next export funcnum
// File I/O
VerilatedMutex m_fdMutex; ///< Protect m_fdps, m_fdFree
std::vector<FILE*> m_fdps VL_GUARDED_BY(m_fdMutex); ///< File descriptors
std::deque<IData> m_fdFree VL_GUARDED_BY(m_fdMutex); ///< List of free descriptors (SLOW - FOPEN/CLOSE only)
/// List of free descriptors (SLOW - FOPEN/CLOSE only)
std::deque<IData> m_fdFree VL_GUARDED_BY(m_fdMutex);
public: // But only for verilated*.cpp
// CONSTRUCTORS
@ -210,8 +223,10 @@ public: // But only for verilated*.cpp
m_fdps[2] = stderr;
}
~VerilatedImp() {}
private:
VL_UNCOPYABLE(VerilatedImp);
public:
// METHODS - debug
static void internalsDump() VL_MT_SAFE;
@ -238,11 +253,12 @@ public:
}
return "";
}
private:
static void commandArgsAddGuts(int argc, const char** argv) VL_REQUIRES(s_s.m_argMutex);
static void commandArgVl(const std::string& arg);
static bool commandArgVlValue(const std::string& arg,
const std::string& prefix, std::string& valuer);
static bool commandArgVlValue(const std::string& arg, const std::string& prefix,
std::string& valuer);
public:
// METHODS - user scope tracking
@ -252,16 +268,19 @@ public:
static inline void userInsert(const void* scopep, void* userKey, void* userData) VL_MT_SAFE {
VerilatedLockGuard lock(s_s.m_userMapMutex);
UserMap::iterator it = s_s.m_userMap.find(std::make_pair(scopep, userKey));
if (it != s_s.m_userMap.end()) it->second = userData;
// When we support VL_THREADs, we need a lock around this insert, as it's runtime
else s_s.m_userMap.insert(it, std::make_pair(std::make_pair(scopep, userKey), userData));
if (it != s_s.m_userMap.end()) {
it->second = userData;
} else {
s_s.m_userMap.insert(it, std::make_pair(std::make_pair(scopep, userKey), userData));
}
}
static inline void* userFind(const void* scopep, void* userKey) VL_MT_SAFE {
VerilatedLockGuard lock(s_s.m_userMapMutex);
UserMap::const_iterator it = s_s.m_userMap.find(std::make_pair(scopep, userKey));
if (VL_LIKELY(it != s_s.m_userMap.end())) return it->second;
else return NULL;
if (VL_UNLIKELY(it == s_s.m_userMap.end())) return NULL;
return it->second;
}
private:
/// Symbol table destruction cleans up the entries for each scope.
static void userEraseScope(const VerilatedScope* scopep) VL_MT_SAFE {
@ -279,9 +298,12 @@ private:
VerilatedLockGuard lock(s_s.m_userMapMutex); // Avoid it changing in middle of dump
bool first = true;
for (UserMap::const_iterator it = s_s.m_userMap.begin(); it != s_s.m_userMap.end(); ++it) {
if (first) { VL_PRINTF_MT(" userDump:\n"); first=false; }
VL_PRINTF_MT(" DPI_USER_DATA scope %p key %p: %p\n",
it->first.first, it->first.second, it->second);
if (first) {
VL_PRINTF_MT(" userDump:\n");
first = false;
}
VL_PRINTF_MT(" DPI_USER_DATA scope %p key %p: %p\n", it->first.first,
it->first.second, it->second);
}
}
@ -299,8 +321,8 @@ public: // But only for verilated*.cpp
VerilatedLockGuard lock(s_s.m_nameMutex);
// If too slow, can assume this is only VL_MT_SAFE_POSINIT
VerilatedScopeNameMap::const_iterator it = s_s.m_nameMap.find(namep);
if (VL_LIKELY(it != s_s.m_nameMap.end())) return it->second;
else return NULL;
if (VL_UNLIKELY(it == s_s.m_nameMap.end())) return NULL;
return it->second;
}
static void scopeErase(const VerilatedScope* scopep) VL_MT_SAFE {
// Slow ok - called once/scope at destruction
@ -379,7 +401,10 @@ public: // But only for verilated*.cpp
bool first = true;
for (ExportNameMap::const_iterator it = s_s.m_exportMap.begin();
it != s_s.m_exportMap.end(); ++it) {
if (first) { VL_PRINTF_MT(" exportDump:\n"); first=false; }
if (first) {
VL_PRINTF_MT(" exportDump:\n");
first = false;
}
VL_PRINTF_MT(" DPI_EXPORT_NAME %05d: %s\n", it->second, it->first);
}
}
@ -396,9 +421,12 @@ public: // But only for verilated*.cpp
// Need to create more space in m_fdps and m_fdFree
size_t start = s_s.m_fdps.size();
s_s.m_fdps.resize(start * 2);
for (size_t i=start; i<start*2; ++i) s_s.m_fdFree.push_back(static_cast<IData>(i));
for (size_t i = start; i < start * 2; ++i) {
s_s.m_fdFree.push_back(static_cast<IData>(i));
}
IData idx = s_s.m_fdFree.back(); s_s.m_fdFree.pop_back();
}
IData idx = s_s.m_fdFree.back();
s_s.m_fdFree.pop_back();
s_s.m_fdps[idx] = fp;
return (idx | (1UL << 31)); // bit 31 indicates not MCD
}

View File

@ -23,6 +23,7 @@
#include <cerrno>
#include <fcntl.h>
// clang-format off
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
# include <io.h>
#else
@ -38,6 +39,7 @@
#ifndef O_CLOEXEC
# define O_CLOEXEC 0
#endif
// clang-format on
// CONSTANTS
static const char* const VLTSAVE_HEADER_STR
@ -54,9 +56,7 @@ bool VerilatedDeserialize::readDiffers(const void* __restrict datap,
bufferCheck();
const vluint8_t* __restrict dp = static_cast<const vluint8_t* __restrict>(datap);
vluint8_t miss = 0;
while (size--) {
miss |= (*dp++ ^ *m_cp++);
}
while (size--) miss |= (*dp++ ^ *m_cp++);
return (miss != 0);
}
@ -232,9 +232,7 @@ void VerilatedRestore::fill() VL_MT_UNSAFE_ONE {
} else { // got==0, EOF
// Fill buffer from here to end with NULLs so reader's don't
// need to check eof each character.
while (m_endp < m_bufp + bufferSize()) {
*m_endp++ = '\0';
}
while (m_endp < m_bufp + bufferSize()) *m_endp++ = '\0';
break;
}
}

View File

@ -132,7 +132,7 @@ public:
size_t blk = size;
if (blk > bufferInsertSize()) blk = bufferInsertSize();
const vluint8_t* __restrict maxp = dp + blk;
for (; dp < maxp; *dp++ = *m_cp++);
for (; dp < maxp; *dp++ = *m_cp++) {}
size -= blk;
}
return *this; // For function chaining
@ -257,8 +257,8 @@ VerilatedSerialize& operator<<(VerilatedSerialize& os, VlAssocArray<T_Key, T_Val
os << rhs.atDefault();
vluint32_t len = rhs.size();
os << len;
for (typename VlAssocArray<T_Key, T_Value>::const_iterator it = rhs.begin();
it != rhs.end(); ++it) {
for (typename VlAssocArray<T_Key, T_Value>::const_iterator it = rhs.begin(); it != rhs.end();
++it) {
T_Key index = it->first; // Copy to get around const_iterator
T_Value value = it->second;
os << index << value;

View File

@ -41,8 +41,12 @@ class VerilatedRange {
protected:
friend class VerilatedVarProps;
friend class VerilatedScope;
VerilatedRange() : m_left(0), m_right(0) {}
VerilatedRange(int left, int right) : m_left(left), m_right(right) {}
VerilatedRange()
: m_left(0)
, m_right(0) {}
VerilatedRange(int left, int right)
: m_left(left)
, m_right(right) {}
void init(int left, int right) {
m_left = left;
m_right = right;
@ -78,63 +82,89 @@ class VerilatedVarProps {
// CONSTRUCTORS
protected:
friend class VerilatedScope;
VerilatedVarProps(VerilatedVarType vltype, VerilatedVarFlags vlflags,
int pdims, int udims)
: m_magic(MAGIC), m_vltype(vltype), m_vlflags(vlflags), m_pdims(pdims), m_udims(udims) {}
VerilatedVarProps(VerilatedVarType vltype, VerilatedVarFlags vlflags, int pdims, int udims)
: m_magic(MAGIC)
, m_vltype(vltype)
, m_vlflags(vlflags)
, m_pdims(pdims)
, m_udims(udims) {}
public:
class Unpacked {};
// Without packed
VerilatedVarProps(VerilatedVarType vltype, int vlflags)
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(0) {}
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Unpacked, int u0l, int u0r)
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(1) {
: m_magic(MAGIC)
, m_vltype(vltype)
, m_vlflags(VerilatedVarFlags(vlflags))
, m_pdims(0)
, m_udims(0) {}
VerilatedVarProps(VerilatedVarType vltype, int vlflags, Unpacked, int u0l, int u0r)
: m_magic(MAGIC)
, m_vltype(vltype)
, m_vlflags(VerilatedVarFlags(vlflags))
, m_pdims(0)
, m_udims(1) {
m_unpacked[0].init(u0l, u0r);
}
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Unpacked, int u0l, int u0r, int u1l, int u1r)
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(2) {
VerilatedVarProps(VerilatedVarType vltype, int vlflags, Unpacked, int u0l, int u0r, int u1l,
int u1r)
: m_magic(MAGIC)
, m_vltype(vltype)
, m_vlflags(VerilatedVarFlags(vlflags))
, m_pdims(0)
, m_udims(2) {
m_unpacked[0].init(u0l, u0r);
m_unpacked[1].init(u1l, u1r);
}
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Unpacked, int u0l, int u0r, int u1l, int u1r, int u2l, int u2r)
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(3) {
VerilatedVarProps(VerilatedVarType vltype, int vlflags, Unpacked, int u0l, int u0r, int u1l,
int u1r, int u2l, int u2r)
: m_magic(MAGIC)
, m_vltype(vltype)
, m_vlflags(VerilatedVarFlags(vlflags))
, m_pdims(0)
, m_udims(3) {
m_unpacked[0].init(u0l, u0r);
m_unpacked[1].init(u1l, u1r);
m_unpacked[2].init(u2l, u2r);
}
// With packed
class Packed {};
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Packed, int pl, int pr)
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(1), m_udims(0), m_packed(pl,pr) {}
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Packed, int pl, int pr,
Unpacked, int u0l, int u0r)
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(1), m_udims(1), m_packed(pl,pr) {
VerilatedVarProps(VerilatedVarType vltype, int vlflags, Packed, int pl, int pr)
: m_magic(MAGIC)
, m_vltype(vltype)
, m_vlflags(VerilatedVarFlags(vlflags))
, m_pdims(1)
, m_udims(0)
, m_packed(pl, pr) {}
VerilatedVarProps(VerilatedVarType vltype, int vlflags, Packed, int pl, int pr, Unpacked,
int u0l, int u0r)
: m_magic(MAGIC)
, m_vltype(vltype)
, m_vlflags(VerilatedVarFlags(vlflags))
, m_pdims(1)
, m_udims(1)
, m_packed(pl, pr) {
m_unpacked[0].init(u0l, u0r);
}
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Packed, int pl, int pr,
Unpacked, int u0l, int u0r, int u1l, int u1r)
: m_magic(MAGIC), m_vltype(vltype), m_vlflags(VerilatedVarFlags(vlflags)),
m_pdims(1), m_udims(2), m_packed(pl,pr) {
VerilatedVarProps(VerilatedVarType vltype, int vlflags, Packed, int pl, int pr, Unpacked,
int u0l, int u0r, int u1l, int u1r)
: m_magic(MAGIC)
, m_vltype(vltype)
, m_vlflags(VerilatedVarFlags(vlflags))
, m_pdims(1)
, m_udims(2)
, m_packed(pl, pr) {
m_unpacked[0].init(u0l, u0r);
m_unpacked[1].init(u1l, u1r);
}
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
Packed, int pl, int pr,
Unpacked, int u0l, int u0r, int u1l, int u1r, int u2l, int u2r)
: m_magic(MAGIC), m_vltype(vltype),
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(1), m_udims(3), m_packed(pl,pr) {
VerilatedVarProps(VerilatedVarType vltype, int vlflags, Packed, int pl, int pr, Unpacked,
int u0l, int u0r, int u1l, int u1r, int u2l, int u2r)
: m_magic(MAGIC)
, m_vltype(vltype)
, m_vlflags(VerilatedVarFlags(vlflags))
, m_pdims(1)
, m_udims(3)
, m_packed(pl, pr) {
m_unpacked[0].init(u0l, u0r);
m_unpacked[1].init(u1l, u1r);
m_unpacked[2].init(u2l, u2r);

View File

@ -61,8 +61,7 @@ void VlWorkerThread::workerLoop() {
if (VL_LIKELY(!work.m_fnp)) dequeWork(&work);
// Do this here, not above, to avoid a race with the destructor.
if (VL_UNLIKELY(m_exiting.load(std::memory_order_acquire)))
break;
if (VL_UNLIKELY(m_exiting.load(std::memory_order_acquire))) break;
if (VL_LIKELY(work.m_fnp)) {
work.m_fnp(work.m_evenCycle, work.m_sym);
@ -128,8 +127,7 @@ void VlThreadPool::setupProfilingClientThread() {
void VlThreadPool::profileAppendAll(const VlProfileRec& rec) {
VerilatedLockGuard lk(m_mutex);
for (ProfileSet::iterator it = m_allProfiles.begin();
it != m_allProfiles.end(); ++it) {
for (ProfileSet::iterator it = m_allProfiles.begin(); it != m_allProfiles.end(); ++it) {
// Every thread's profile trace gets a copy of rec.
(*it)->emplace_back(rec);
}
@ -156,14 +154,14 @@ void VlThreadPool::profileDump(const char* filenamep, vluint64_t ticksElapsed) {
fprintf(fp, "VLPROF stat yields %" VL_PRI64 "u\n", VlMTaskVertex::yields());
vluint32_t thread_id = 0;
for (ProfileSet::const_iterator pit = m_allProfiles.begin();
pit != m_allProfiles.end(); ++pit) {
for (ProfileSet::const_iterator pit = m_allProfiles.begin(); pit != m_allProfiles.end();
++pit) {
++thread_id;
bool printing = false; // False while in warmup phase
for (ProfileTrace::const_iterator eit = (*pit)->begin(); eit != (*pit)->end(); ++eit) {
switch (eit->m_type) {
case VlProfileRec::TYPE_BARRIER:
case VlProfileRec::TYPE_BARRIER: //
printing = true;
break;
case VlProfileRec::TYPE_MTASK_RUN:

View File

@ -25,12 +25,15 @@
#include <condition_variable>
#include <set>
#include <vector>
// clang-format off
#if defined(__linux)
# include <sched.h> // For sched_getcpu()
#endif
#if defined(__APPLE__)
# include <cpuid.h> // For __cpuid_count()
#endif
// clang-format on
// VlMTaskVertex and VlThreadpool will work with multiple symbol table types.
// Since the type is opaque to VlMTaskVertex and VlThreadPool, represent it
@ -115,10 +118,7 @@ public:
class VlProfileRec {
protected:
friend class VlThreadPool;
enum VlProfileE {
TYPE_MTASK_RUN,
TYPE_BARRIER
};
enum VlProfileE { TYPE_MTASK_RUN, TYPE_BARRIER };
VlProfileE m_type; // Record type
vluint32_t m_mtaskId; // Mtask we're logging
vluint32_t m_predictTime; // How long scheduler predicted would take
@ -173,9 +173,14 @@ private:
VlExecFnp m_fnp; // Function to execute
VlThrSymTab m_sym; // Symbol table to execute
bool m_evenCycle; // Even/odd for flag alternation
ExecRec() : m_fnp(NULL), m_sym(NULL), m_evenCycle(false) {}
ExecRec()
: m_fnp(NULL)
, m_sym(NULL)
, m_evenCycle(false) {}
ExecRec(VlExecFnp fnp, bool evenCycle, VlThrSymTab sym)
: m_fnp(fnp), m_sym(sym), m_evenCycle(evenCycle) {}
: m_fnp(fnp)
, m_sym(sym)
, m_evenCycle(evenCycle) {}
};
// MEMBERS
@ -208,7 +213,7 @@ public:
inline void dequeWork(ExecRec* workp) {
// Spin for a while, waiting for new data
for (int i = 0; i < VL_LOCK_SPINS; ++i) {
if (VL_LIKELY(m_ready_size.load(std::memory_order_relaxed))) {
if (VL_LIKELY(m_ready_size.load(std::memory_order_relaxed))) { //
break;
}
VL_CPU_RELAX();

View File

@ -41,13 +41,9 @@
#include <string>
// Abstract 'vl_hash' and 'vl_equal_to' templates.
template <typename T> struct vl_hash {
size_t operator()(const T& k) const;
};
template <typename T> struct vl_hash { size_t operator()(const T& k) const; };
template <typename T> struct vl_equal_to {
bool operator()(const T& a, const T& b) const;
};
template <typename T> struct vl_equal_to { bool operator()(const T& a, const T& b) const; };
// Specializations of 'vl_hash' and 'vl_equal_to'.
inline size_t vl_hash_bytes(const void* vbufp, size_t nbytes) {
@ -59,60 +55,50 @@ inline size_t vl_hash_bytes(const void* vbufp, size_t nbytes) {
return hash;
}
template <> inline size_t
vl_hash<unsigned int>::operator()(const unsigned int& k) const {
template <> inline size_t vl_hash<unsigned int>::operator()(const unsigned int& k) const {
return k;
}
template <> inline bool
vl_equal_to<unsigned int>::operator()(const unsigned int& a,
template <>
inline bool vl_equal_to<unsigned int>::operator()(const unsigned int& a,
const unsigned int& b) const {
return a == b;
}
template <> inline size_t
vl_hash<std::string>::operator()(const std::string& k) const {
template <> inline size_t vl_hash<std::string>::operator()(const std::string& k) const {
return vl_hash_bytes(k.data(), k.size());
}
template <> inline bool
vl_equal_to<std::string>::operator()(const std::string& a,
template <>
inline bool vl_equal_to<std::string>::operator()(const std::string& a,
const std::string& b) const {
// Don't scan the strings if the sizes are different.
if (a.size() != b.size()) {
return false;
}
if (a.size() != b.size()) return false;
return (0 == a.compare(b)); // Must scan.
}
template <typename T> struct vl_hash<T*> {
size_t operator()(T* kp) const {
return ((sizeof(size_t) == sizeof(kp))
? reinterpret_cast<size_t>(kp)
return ((sizeof(size_t) == sizeof(kp)) ? reinterpret_cast<size_t>(kp)
: vl_hash_bytes(&kp, sizeof(kp)));
}
};
template <typename T> struct vl_equal_to<T*> {
bool operator()(T* ap, T* bp) const {
return ap == bp;
}
bool operator()(T* ap, T* bp) const { return ap == bp; }
};
//===================================================================
//
/// Functional clone of the std::unordered_set hash table.
template <class T_Key,
class T_Hash = vl_hash<T_Key>,
class T_Equal = vl_equal_to<T_Key> >
template <class T_Key, class T_Hash = vl_hash<T_Key>, class T_Equal = vl_equal_to<T_Key> >
class vl_unordered_set {
public:
// TYPES
typedef std::list<T_Key> Bucket;
enum RehashType { GROW, SHRINK };
template <class KK, class VV,
class HH, class EQ> friend class vl_unordered_map;
template <class KK, class VV, class HH, class EQ> friend class vl_unordered_map;
class iterator {
protected:
@ -123,29 +109,23 @@ public:
public:
// CONSTRUCTORS
iterator(size_t bucketIdx, typename Bucket::iterator bit,
const vl_unordered_set* setp)
: m_bucketIdx(bucketIdx), m_bit(bit), m_setp(setp) {}
iterator(size_t bucketIdx, typename Bucket::iterator bit, const vl_unordered_set* setp)
: m_bucketIdx(bucketIdx)
, m_bit(bit)
, m_setp(setp) {}
// METHODS
const T_Key& operator*() const {
return *m_bit;
}
const T_Key& operator*() const { return *m_bit; }
// This should really be 'const T_Key*' type for unordered_set,
// however this iterator is shared with unordered_map whose
// operator-> returns a non-const ValueType*, so keep this
// non-const to avoid having to define a whole separate iterator
// for unordered_map.
T_Key* operator->() const {
return &(*m_bit);
}
T_Key* operator->() const { return &(*m_bit); }
bool operator==(const iterator& other) const {
return ((m_bucketIdx == other.m_bucketIdx)
&& (m_bit == other.m_bit));
}
bool operator!=(const iterator& other) const {
return (!this->operator==(other));
return ((m_bucketIdx == other.m_bucketIdx) && (m_bit == other.m_bit));
}
bool operator!=(const iterator& other) const { return (!this->operator==(other)); }
void advanceUntilValid() {
while (true) {
if (m_bit != m_setp->m_bucketsp[m_bucketIdx].end()) {
@ -202,14 +182,10 @@ public:
, m_equal() {
if (other.m_bucketsp) {
m_bucketsp = new Bucket[numBuckets()];
for (size_t i = 0; i < numBuckets(); i++) {
m_bucketsp[i] = other.m_bucketsp[i];
for (size_t i = 0; i < numBuckets(); i++) m_bucketsp[i] = other.m_bucketsp[i];
}
}
}
~vl_unordered_set() {
VL_DO_DANGLING(delete [] m_bucketsp, m_bucketsp);
}
~vl_unordered_set() { VL_DO_DANGLING(delete[] m_bucketsp, m_bucketsp); }
vl_unordered_set& operator=(const vl_unordered_set& other) {
if (this != &other) {
@ -219,9 +195,7 @@ public:
m_log2Buckets = other.m_log2Buckets;
if (other.m_bucketsp) {
m_bucketsp = new Bucket[numBuckets()];
for (size_t i = 0; i < numBuckets(); i++) {
m_bucketsp[i] = other.m_bucketsp[i];
}
for (size_t i = 0; i < numBuckets(); i++) m_bucketsp[i] = other.m_bucketsp[i];
} else {
m_bucketsp = NULL;
}
@ -251,24 +225,21 @@ public:
return end();
}
const_iterator end() const {
return iterator(VL_ULL(0xFFFFFFFFFFFFFFFF),
const_cast<Bucket&>(m_emptyBucket).begin(), this);
return iterator(VL_ULL(0xFFFFFFFFFFFFFFFF), const_cast<Bucket&>(m_emptyBucket).begin(),
this);
}
bool empty() const { return m_numElements == 0; }
size_t size() const { return m_numElements; }
size_t count(const T_Key& key) const {
return (find(key) == end()) ? 0 : 1;
}
size_t count(const T_Key& key) const { return (find(key) == end()) ? 0 : 1; }
size_t hashToBucket(size_t hashVal) const {
return hashToBucket(hashVal, m_log2Buckets);
}
size_t hashToBucket(size_t hashVal) const { return hashToBucket(hashVal, m_log2Buckets); }
static size_t hashToBucket(size_t hashVal, unsigned log2Buckets) {
// Fibonacci hashing
// See https://probablydance.com/2018/06/16/fibonacci-hashing-the-optimization-that-the-world-forgot-or-a-better-alternative-to-integer-modulo/
// Fibonacci hashing, see
// https://probablydance.com/2018/06/16/fibonacci-hashing-the-optimization
// -that-the-world-forgot-or-a-better-alternative-to-integer-modulo/
//
// * The magic numbers below are UINT_MAX/phi where phi is the
// golden ratio number (1.618...) for either 64- or 32-bit
@ -278,11 +249,9 @@ public:
// function further. This permits the use of very fast client
// hash funcs (like just returning the int or pointer value as
// is!) and tolerates crappy client hash functions pretty well.
size_t mult = hashVal * ((sizeof(size_t) == 8)
? VL_ULL(11400714819323198485)
: 2654435769lu);
size_t result = (mult >> (((sizeof(size_t) == 8)
? 64 : 32) - log2Buckets));
size_t mult
= hashVal * ((sizeof(size_t) == 8) ? VL_ULL(11400714819323198485) : 2654435769lu);
size_t result = (mult >> (((sizeof(size_t) == 8) ? 64 : 32) - log2Buckets));
return result;
}
@ -292,19 +261,15 @@ public:
initBuckets();
Bucket* bucketp = &m_bucketsp[bucketIdxOut];
for (typename Bucket::iterator it = bucketp->begin();
it != bucketp->end(); ++it) {
if (m_equal.operator()(*it, key)) {
return iterator(bucketIdxOut, it, this);
}
for (typename Bucket::iterator it = bucketp->begin(); it != bucketp->end(); ++it) {
if (m_equal.operator()(*it, key)) return iterator(bucketIdxOut, it, this);
}
return end();
}
const_iterator find(const T_Key& key) const {
size_t bucketIdx;
return const_cast<vl_unordered_set*>(this)->find_internal(key,
bucketIdx);
return const_cast<vl_unordered_set*>(this)->find_internal(key, bucketIdx);
}
iterator find(const T_Key& key) {
@ -358,9 +323,7 @@ public:
// for the Scoreboard in V3Partition, which begins tracking
// a huge number of vertices and then tracks a successively
// smaller number over time.
if (needToRehash(SHRINK)) {
rehash(SHRINK);
}
if (needToRehash(SHRINK)) rehash(SHRINK);
return 1;
}
return 0;
@ -419,8 +382,7 @@ private:
size_t new_idx = hashToBucket(hash, new_log2Buckets);
// Avoid mallocing one list elem and freeing another;
// splice just moves it over.
new_bucketsp[new_idx].splice(new_bucketsp[new_idx].begin(),
m_bucketsp[i], bit);
new_bucketsp[new_idx].splice(new_bucketsp[new_idx].begin(), m_bucketsp[i], bit);
}
}
@ -433,9 +395,7 @@ private:
//===================================================================
//
/// Functional clone of the std::unordered_map hash table.
template <class T_Key,
class T_Value,
class T_Hash = vl_hash<T_Key>,
template <class T_Key, class T_Value, class T_Hash = vl_hash<T_Key>,
class T_Equal = vl_equal_to<T_Key> >
class vl_unordered_map {
private:
@ -445,6 +405,7 @@ private:
class KeyHash {
private:
T_Hash key_hash;
public:
KeyHash() {}
size_t operator()(const KeyValPair& kv_pair) const {
@ -455,6 +416,7 @@ private:
class KeyEqual {
private:
T_Equal key_eq;
public:
KeyEqual() {}
bool operator()(const KeyValPair& kv_a, const KeyValPair& kv_b) const {
@ -491,24 +453,19 @@ public:
size_t bucketIdxOut = m_set.hashToBucket(hash);
typename MapSet::Bucket* bucketp = m_set.getBucket(bucketIdxOut);
for (typename MapSet::Bucket::iterator it = bucketp->begin();
it != bucketp->end(); ++it) {
if (mapEq.operator()(it->first, k)) {
return iterator(bucketIdxOut, it, &m_set);
}
for (typename MapSet::Bucket::iterator it = bucketp->begin(); it != bucketp->end(); ++it) {
if (mapEq.operator()(it->first, k)) return iterator(bucketIdxOut, it, &m_set);
}
return end();
}
const_iterator find(const T_Key& k) const {
return const_cast<vl_unordered_map*>(this)->find(k);
}
std::pair<iterator, bool> insert(const KeyValPair& val) {
return m_set.insert(val);
}
std::pair<iterator, bool> insert(const KeyValPair& val) { return m_set.insert(val); }
iterator erase(iterator it) { return m_set.erase(it); }
size_t erase(const T_Key& k) {
iterator it = find(k);
if (it == end()) { return 0; }
if (it == end()) return 0;
m_set.erase(it);
return 1;
}
@ -517,9 +474,7 @@ public:
// std::unordered_map::operator[] relies on it too.
KeyValPair dummy = std::make_pair(k, T_Value());
iterator it = m_set.find(dummy);
if (it == m_set.end()) {
it = m_set.insert(dummy).first;
}
if (it == m_set.end()) it = m_set.insert(dummy).first;
// For the 'set', it's generally not safe to modify
// the value after deref. For the 'map' though, we know
// it's safe to modify the value field and we can allow it:

View File

@ -31,6 +31,7 @@
void VerilatedVcdSc::write_comment(const std::string&) {}
void VerilatedVcdSc::trace(const unsigned int&, const std::string&, const char**) {}
// clang-format off
# define DECL_TRACE_METHOD_A(tp) \
void VerilatedVcdSc::trace(const tp& object, const std::string& name) {}
# define DECL_TRACE_METHOD_B(tp) \
@ -73,6 +74,7 @@ void VerilatedVcdSc::trace(const unsigned int &, const std::string &, const char
DECL_TRACE_METHOD_A( sc_dt::sc_bv_base )
DECL_TRACE_METHOD_A( sc_dt::sc_lv_base )
// clang-format on
//--------------------------------------------------
#elif (SYSTEMC_VERSION > 20011000)
@ -86,6 +88,7 @@ void VerilatedVcdSc::trace(const unsigned int&, const sc_string&, const char**)
#define DECL_TRACE_METHOD_B(tp) \
void VerilatedVcdSc::trace(const tp& object, const sc_string& name, int width) {}
// clang-format off
DECL_TRACE_METHOD_A( bool )
DECL_TRACE_METHOD_A( sc_bit )
DECL_TRACE_METHOD_A( sc_logic )
@ -116,6 +119,7 @@ void VerilatedVcdSc::trace(const unsigned int&, const sc_string&, const char**)
DECL_TRACE_METHOD_A( sc_fxnum_fast )
DECL_TRACE_METHOD_A( sc_bv_base )
DECL_TRACE_METHOD_A( sc_lv_base )
// clang-format on
//--------------------------------------------------
#else
@ -129,6 +133,7 @@ void VerilatedVcdSc::trace(const unsigned int&, const sc_string&, const char**)
#define DECL_TRACE_METHOD_B(tp) \
void VerilatedVcdSc::trace(const tp& object, const sc_string& name, int width) {}
// clang-format off
DECL_TRACE_METHOD_A( bool )
DECL_TRACE_METHOD_B( unsigned char )
DECL_TRACE_METHOD_B( short unsigned int )
@ -154,6 +159,7 @@ void VerilatedVcdSc::trace(const unsigned int&, const sc_string&, const char**)
DECL_TRACE_METHOD_A( sc_signal_resolved_vector )
DECL_TRACE_METHOD_A( sc_bv_ns::sc_bv_base )
DECL_TRACE_METHOD_A( sc_bv_ns::sc_lv_base )
// clang-format on
#endif
#undef DECL_TRACE_METHOD_A

View File

@ -31,12 +31,10 @@
/// This class is passed to the SystemC simulation kernel, just like a
/// documented SystemC trace format.
class VerilatedVcdSc
: sc_trace_file
, public VerilatedVcdC
{
class VerilatedVcdSc : sc_trace_file, public VerilatedVcdC {
// CONSTRUCTORS
VL_UNCOPYABLE(VerilatedVcdSc);
public:
VerilatedVcdSc() {
sc_get_curr_simcontext()->add_trace_file(this);
@ -82,18 +80,18 @@ private:
virtual void set_time_unit(double v, sc_time_unit tu) {}
#endif
//--------------------------------------------------
#if (SYSTEMC_VERSION >= 20050714)
// SystemC 2.1.v1
# define DECL_TRACE_METHOD_A(tp) \
virtual void trace(const tp& object, const std::string& name);
// clang-format off
# define DECL_TRACE_METHOD_A(tp) virtual void trace(const tp& object, const std::string& name);
# define DECL_TRACE_METHOD_B(tp) \
virtual void trace(const tp& object, const std::string& name, int width);
virtual void write_comment(const std::string&);
virtual void trace(const unsigned int&, const std::string&, const char**);
// Formatting matches that of sc_trace.h
# if (SYSTEMC_VERSION >= 20171012)
DECL_TRACE_METHOD_A( sc_event )
DECL_TRACE_METHOD_A( sc_time )
@ -131,12 +129,13 @@ private:
DECL_TRACE_METHOD_A( sc_dt::sc_bv_base )
DECL_TRACE_METHOD_A( sc_dt::sc_lv_base )
// clang-format on
//--------------------------------------------------
#elif (SYSTEMC_VERSION > 20011000)
// SystemC 2.0.1
# define DECL_TRACE_METHOD_A(tp) \
virtual void trace(const tp& object, const sc_string& name);
// clang-format off
# define DECL_TRACE_METHOD_A(tp) virtual void trace(const tp& object, const sc_string& name);
# define DECL_TRACE_METHOD_B(tp) \
virtual void trace(const tp& object, const sc_string& name, int width);
@ -175,12 +174,13 @@ private:
DECL_TRACE_METHOD_A( sc_fxnum_fast )
DECL_TRACE_METHOD_A( sc_bv_base )
DECL_TRACE_METHOD_A( sc_lv_base )
// clang-format on
//--------------------------------------------------
#else
// SystemC 1.2.1beta
# define DECL_TRACE_METHOD_A(tp) \
virtual void trace(const tp& object, const sc_string& name);
// clang-format off
# define DECL_TRACE_METHOD_A(tp) virtual void trace(const tp& object, const sc_string& name);
# define DECL_TRACE_METHOD_B(tp) \
virtual void trace(const tp& object, const sc_string& name, int width);
@ -213,6 +213,7 @@ private:
DECL_TRACE_METHOD_A( sc_bv_ns::sc_bv_base )
DECL_TRACE_METHOD_A( sc_bv_ns::sc_lv_base )
# endif
// clang-format on
#undef DECL_TRACE_METHOD_A
#undef DECL_TRACE_METHOD_B

View File

@ -23,9 +23,6 @@
#define _VERILATED_VPI_CPP_
#if VM_SC
# include "verilated_sc.h"
#endif
#include "verilated.h"
#include "verilated_vpi.h"
#include "verilated_imp.h"
@ -109,10 +106,12 @@ class VerilatedVpioCb : public VerilatedVpio {
t_cb_data m_cbData;
s_vpi_value m_value;
QData m_time;
public:
// cppcheck-suppress uninitVar // m_value
VerilatedVpioCb(const t_cb_data* cbDatap, QData time)
: m_cbData(*cbDatap), m_time(time) {
: m_cbData(*cbDatap)
, m_time(time) {
m_value.format = cbDatap->value ? cbDatap->value->format : vpiSuppressVal;
m_cbData.value = &m_value;
}
@ -129,8 +128,10 @@ public:
class VerilatedVpioConst : public VerilatedVpio {
vlsint32_t m_num;
public:
explicit VerilatedVpioConst(vlsint32_t num) : m_num(num) {}
explicit VerilatedVpioConst(vlsint32_t num)
: m_num(num) {}
virtual ~VerilatedVpioConst() {}
static inline VerilatedVpioConst* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioConst*>(reinterpret_cast<VerilatedVpio*>(h));
@ -142,8 +143,11 @@ public:
class VerilatedVpioRange : public VerilatedVpio {
const VerilatedRange* m_range;
vlsint32_t m_iteration;
public:
explicit VerilatedVpioRange(const VerilatedRange* range) : m_range(range), m_iteration(0) {}
explicit VerilatedVpioRange(const VerilatedRange* range)
: m_range(range)
, m_iteration(0) {}
virtual ~VerilatedVpioRange() {}
static inline VerilatedVpioRange* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioRange*>(reinterpret_cast<VerilatedVpio*>(h));
@ -166,6 +170,7 @@ public:
class VerilatedVpioScope : public VerilatedVpio {
protected:
const VerilatedScope* m_scopep;
public:
explicit VerilatedVpioScope(const VerilatedScope* scopep)
: m_scopep(scopep) {}
@ -195,9 +200,12 @@ protected:
// Determine number of dimensions and return outermost
return (m_varp->dims() > 1) ? m_varp->unpacked() : m_varp->packed();
}
public:
VerilatedVpioVar(const VerilatedVar* varp, const VerilatedScope* scopep)
: m_varp(varp), m_scopep(scopep), m_index(0) {
: m_varp(varp)
, m_scopep(scopep)
, m_index(0) {
m_prevDatap = NULL;
m_mask.u32 = VL_MASK_I(varp->packed().elements());
m_entSize = varp->entSize();
@ -253,7 +261,8 @@ public:
virtual const VerilatedRange* rangep() const { return &(varp()->packed()); }
virtual const char* fullname() const {
static VL_THREAD_LOCAL std::string out;
char num[20]; sprintf(num, "%d", m_index);
char num[20];
sprintf(num, "%d", m_index);
out = std::string(scopep()->name()) + "." + name() + "[" + num + "]";
return out.c_str();
}
@ -263,9 +272,11 @@ class VerilatedVpioVarIter : public VerilatedVpio {
const VerilatedScope* m_scopep;
VerilatedVarNameMap::const_iterator m_it;
bool m_started;
public:
explicit VerilatedVpioVarIter(const VerilatedScope* scopep)
: m_scopep(scopep), m_started(false) { }
: m_scopep(scopep)
, m_started(false) {}
virtual ~VerilatedVpioVarIter() {}
static inline VerilatedVpioVarIter* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioVarIter*>(reinterpret_cast<VerilatedVpio*>(h));
@ -274,12 +285,16 @@ public:
virtual vpiHandle dovpi_scan() {
if (VL_LIKELY(m_scopep->varsp())) {
VerilatedVarNameMap* varsp = m_scopep->varsp();
if (VL_UNLIKELY(!m_started)) { m_it = varsp->begin(); m_started=true; }
else if (VL_UNLIKELY(m_it == varsp->end())) return 0;
else ++m_it;
if (VL_UNLIKELY(!m_started)) {
m_it = varsp->begin();
m_started = true;
} else if (VL_UNLIKELY(m_it == varsp->end())) {
return 0;
} else {
++m_it;
}
if (m_it == varsp->end()) return 0;
return ((new VerilatedVpioVar(&(m_it->second), m_scopep))
->castVpiHandle());
return ((new VerilatedVpioVar(&(m_it->second), m_scopep))->castVpiHandle());
}
return 0; // End of list - only one deep
}
@ -291,21 +306,21 @@ class VerilatedVpioMemoryWordIter : public VerilatedVpio {
vlsint32_t m_iteration;
vlsint32_t m_direction;
bool m_done;
public:
VerilatedVpioMemoryWordIter(const vpiHandle handle, const VerilatedVar* varp)
: m_handle(handle), m_varp(varp), m_iteration(varp->unpacked().right()),
m_direction(VL_LIKELY(varp->unpacked().left() > varp->unpacked().right())
? 1 : -1),
m_done(false) { }
: m_handle(handle)
, m_varp(varp)
, m_iteration(varp->unpacked().right())
, m_direction(VL_LIKELY(varp->unpacked().left() > varp->unpacked().right()) ? 1 : -1)
, m_done(false) {}
virtual ~VerilatedVpioMemoryWordIter() {}
static inline VerilatedVpioMemoryWordIter* castp(vpiHandle h) {
return dynamic_cast<VerilatedVpioMemoryWordIter*>(reinterpret_cast<VerilatedVpio*>(h));
}
virtual vluint32_t type() const { return vpiIterator; }
void iterationInc() {
if (!(m_done = (m_iteration == m_varp->unpacked().left()))) {
m_iteration += m_direction;
}
if (!(m_done = (m_iteration == m_varp->unpacked().left()))) m_iteration += m_direction;
}
virtual vpiHandle dovpi_scan() {
vpiHandle result;
@ -319,6 +334,7 @@ public:
class VerilatedVpioModule : public VerilatedVpioScope {
const char* m_name;
const char* m_fullname;
public:
explicit VerilatedVpioModule(const VerilatedScope* modulep)
: VerilatedVpioScope(modulep) {
@ -337,8 +353,10 @@ public:
class VerilatedVpioModuleIter : public VerilatedVpio {
const std::vector<const VerilatedScope*>* m_vec;
std::vector<const VerilatedScope*>::const_iterator m_it;
public:
explicit VerilatedVpioModuleIter(const std::vector<const VerilatedScope*>& vec) : m_vec(&vec) {
explicit VerilatedVpioModuleIter(const std::vector<const VerilatedScope*>& vec)
: m_vec(&vec) {
m_it = m_vec->begin();
}
virtual ~VerilatedVpioModuleIter() {}
@ -347,9 +365,7 @@ public:
}
virtual vluint32_t type() const { return vpiIterator; }
virtual vpiHandle dovpi_scan() {
if (m_it == m_vec->end()) {
return 0;
}
if (m_it == m_vec->end()) return 0;
const VerilatedScope* modp = *m_it++;
return (new VerilatedVpioModule(modp))->castVpiHandle();
}
@ -413,9 +429,7 @@ public:
}
static void cbTimedRemove(VerilatedVpioCb* cbp) {
VpioTimedCbs::iterator it = s_s.m_timedCbs.find(std::make_pair(cbp->time(), cbp));
if (VL_LIKELY(it != s_s.m_timedCbs.end())) {
s_s.m_timedCbs.erase(it);
}
if (VL_LIKELY(it != s_s.m_timedCbs.end())) { s_s.m_timedCbs.erase(it); }
}
static void callTimedCbs() VL_MT_UNSAFE_ONE {
assertOneCheck();
@ -428,15 +442,14 @@ public:
s_s.m_timedCbs.erase(last_it);
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: timed_callback %p\n", vop););
(vop->cb_rtnp())(vop->cb_datap());
} else {
++it;
}
else { ++it; }
}
}
static QData cbNextDeadline() {
VpioTimedCbs::const_iterator it = s_s.m_timedCbs.begin();
if (VL_LIKELY(it != s_s.m_timedCbs.end())) {
return it->first;
}
if (VL_LIKELY(it != s_s.m_timedCbs.end())) return it->first;
return ~VL_ULL(0); // maxquad
}
static bool callCbs(vluint32_t reason) VL_MT_UNSAFE_ONE {
@ -469,12 +482,11 @@ public:
void* newDatap = varop->varDatap();
void* prevDatap = varop->prevDatap(); // Was malloced when we added the callback
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: value_test %s v[0]=%d/%d %p %p\n",
varop->fullname(),
*((CData*)newDatap), *((CData*)prevDatap),
newDatap, prevDatap););
varop->fullname(), *((CData*)newDatap),
*((CData*)prevDatap), newDatap, prevDatap););
if (memcmp(prevDatap, newDatap, varop->entSize()) != 0) {
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: value_callback %p %s v[0]=%d\n",
vop, varop->fullname(), *((CData*)newDatap)););
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: value_callback %p %s v[0]=%d\n", vop,
varop->fullname(), *((CData*)newDatap)););
update.insert(varop);
vpi_get_value(vop->cb_datap()->obj, vop->cb_datap()->value);
(vop->cb_rtnp())(vop->cb_datap());
@ -512,9 +524,10 @@ class VerilatedVpiError {
// as it will be overwritten.
VerilatedVpiImp::callCbs(cbPLIError);
}
public:
VerilatedVpiError() : m_flag(false) {
public:
VerilatedVpiError()
: m_flag(false) {
m_buff[0] = '\0';
m_errorInfo.product = const_cast<PLI_BYTE8*>(Verilated::productName());
}
@ -565,30 +578,22 @@ VL_THREAD_LOCAL vluint8_t* VerilatedVpio::t_freeHead = NULL;
//======================================================================
// VerilatedVpi implementation
void VerilatedVpi::callTimedCbs() VL_MT_UNSAFE_ONE {
VerilatedVpiImp::callTimedCbs();
}
void VerilatedVpi::callTimedCbs() VL_MT_UNSAFE_ONE { VerilatedVpiImp::callTimedCbs(); }
void VerilatedVpi::callValueCbs() VL_MT_UNSAFE_ONE {
VerilatedVpiImp::callValueCbs();
}
void VerilatedVpi::callValueCbs() VL_MT_UNSAFE_ONE { VerilatedVpiImp::callValueCbs(); }
bool VerilatedVpi::callCbs(vluint32_t reason) VL_MT_UNSAFE_ONE {
return VerilatedVpiImp::callCbs(reason);
}
QData VerilatedVpi::cbNextDeadline() VL_MT_UNSAFE_ONE {
return VerilatedVpiImp::cbNextDeadline();
}
QData VerilatedVpi::cbNextDeadline() VL_MT_UNSAFE_ONE { return VerilatedVpiImp::cbNextDeadline(); }
//======================================================================
// VerilatedVpiImp implementation
VerilatedVpiError* VerilatedVpiImp::error_info() VL_MT_UNSAFE_ONE {
VerilatedVpiImp::assertOneCheck();
if (VL_UNLIKELY(!s_s.m_errorInfop)) {
s_s.m_errorInfop = new VerilatedVpiError();
}
if (VL_UNLIKELY(!s_s.m_errorInfop)) { s_s.m_errorInfop = new VerilatedVpiError(); }
return s_s.m_errorInfop;
}
@ -596,6 +601,7 @@ VerilatedVpiError* VerilatedVpiImp::error_info() VL_MT_UNSAFE_ONE {
// VerilatedVpiError Methods
const char* VerilatedVpiError::strFromVpiVal(PLI_INT32 vpiVal) VL_MT_SAFE {
// clang-format off
static const char* const names[] = {
"*undefined*",
"vpiBinStrVal",
@ -617,10 +623,12 @@ const char* VerilatedVpiError::strFromVpiVal(PLI_INT32 vpiVal) VL_MT_SAFE {
"vpiRawTwoStateVal",
"vpiRawFourStateVal",
};
// clang-format on
if (vpiVal < 0) return names[0];
return names[(vpiVal <= vpiRawFourStateVal) ? vpiVal : 0];
}
const char* VerilatedVpiError::strFromVpiObjType(PLI_INT32 vpiVal) VL_MT_SAFE {
// clang-format off
static const char* const names[] = {
"*undefined*",
"vpiAlways",
@ -759,10 +767,12 @@ const char* VerilatedVpiError::strFromVpiObjType(PLI_INT32 vpiVal) VL_MT_SAFE {
"vpiGenScope",
"vpiGenVar"
};
// clang-format on
if (vpiVal < 0) return names[0];
return names[(vpiVal <= vpiGenVar) ? vpiVal : 0];
}
const char* VerilatedVpiError::strFromVpiMethod(PLI_INT32 vpiVal) VL_MT_SAFE {
// clang-format off
static const char* const names[] = {
"vpiCondition",
"vpiDelay",
@ -799,13 +809,13 @@ const char* VerilatedVpiError::strFromVpiMethod(PLI_INT32 vpiVal) VL_MT_SAFE {
"vpiPrimitive",
"vpiStmt"
};
if (vpiVal>vpiStmt || vpiVal<vpiCondition) {
return "*undefined*";
}
// clang-format on
if (vpiVal > vpiStmt || vpiVal < vpiCondition) return "*undefined*";
return names[vpiVal - vpiCondition];
}
const char* VerilatedVpiError::strFromVpiCallbackReason(PLI_INT32 vpiVal) VL_MT_SAFE {
// clang-format off
static const char* const names[] = {
"*undefined*",
"cbValueChange",
@ -840,11 +850,13 @@ const char* VerilatedVpiError::strFromVpiCallbackReason(PLI_INT32 vpiVal) VL_MT_
"cbNBASynch",
"cbAtEndOfSimTime"
};
// clang-format on
if (vpiVal < 0) return names[0];
return names[(vpiVal <= cbAtEndOfSimTime) ? vpiVal : 0];
}
const char* VerilatedVpiError::strFromVpiProp(PLI_INT32 vpiVal) VL_MT_SAFE {
// clang-format off
static const char* const names[] = {
"*undefined or other*",
"vpiType",
@ -922,9 +934,8 @@ const char* VerilatedVpiError::strFromVpiProp(PLI_INT32 vpiVal) VL_MT_SAFE {
"vpiIsMemory",
"vpiIsProtected"
};
if (vpiVal == vpiUndefined) {
return "vpiUndefined";
}
// clang-format on
if (vpiVal == vpiUndefined) return "vpiUndefined";
return names[(vpiVal <= vpiIsProtected) ? vpiVal : 0];
}
@ -941,9 +952,7 @@ const char* VerilatedVpiError::strFromVpiProp(PLI_INT32 vpiVal) VL_MT_SAFE {
CHECK_RESULT_CSTR(strVal, #enum); \
} while (0)
void VerilatedVpi::selfTest() VL_MT_UNSAFE_ONE {
VerilatedVpiError::selfTest();
}
void VerilatedVpi::selfTest() VL_MT_UNSAFE_ONE { VerilatedVpiError::selfTest(); }
void VerilatedVpiError::selfTest() VL_MT_UNSAFE_ONE {
VerilatedVpiImp::assertOneCheck();
@ -1014,8 +1023,8 @@ vpiHandle vpi_register_cb(p_cb_data cb_data_p) {
return vop->castVpiHandle();
}
default:
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Unsupported callback type %s",
VL_FUNC, VerilatedVpiError::strFromVpiCallbackReason(cb_data_p->reason));
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Unsupported callback type %s", VL_FUNC,
VerilatedVpiError::strFromVpiCallbackReason(cb_data_p->reason));
return NULL;
};
}
@ -1079,9 +1088,7 @@ vpiHandle vpi_handle_by_name(PLI_BYTE8* namep, vpiHandle scope) {
if (scopename.find('.') == std::string::npos) {
// This is a toplevel, hence search in our TOP ports first.
scopep = Verilated::scopeFind("TOP");
if (scopep) {
varp = scopep->varFind(baseNamep);
}
if (scopep) { varp = scopep->varFind(baseNamep); }
}
if (!varp) {
scopep = Verilated::scopeFind(scopename.c_str());
@ -1103,13 +1110,15 @@ vpiHandle vpi_handle_by_index(vpiHandle object, PLI_INT32 indx) {
if (varop->varp()->dims() < 2) return 0;
if (VL_LIKELY(varop->varp()->unpacked().left() >= varop->varp()->unpacked().right())) {
if (VL_UNLIKELY(indx > varop->varp()->unpacked().left()
|| indx < varop->varp()->unpacked().right())) return 0;
|| indx < varop->varp()->unpacked().right()))
return 0;
return (new VerilatedVpioMemoryWord(varop->varp(), varop->scopep(), indx,
indx - varop->varp()->unpacked().right()))
->castVpiHandle();
}
if (VL_UNLIKELY(indx < varop->varp()->unpacked().left()
|| indx > varop->varp()->unpacked().right())) return 0;
|| indx > varop->varp()->unpacked().right()))
return 0;
return (new VerilatedVpioMemoryWord(varop->varp(), varop->scopep(), indx,
indx - varop->varp()->unpacked().left()))
->castVpiHandle();
@ -1176,9 +1185,9 @@ vpiHandle vpi_iterate(PLI_INT32 type, vpiHandle object) {
if (vop->varp()->dims() < 2) return 0;
if (vop->varp()->dims() > 2) {
_VL_VPI_WARNING(__FILE__, __LINE__,
"%s: %s, object %s has unsupported number of indices (%d)",
VL_FUNC, VerilatedVpiError::strFromVpiMethod(type),
vop->fullname() , vop->varp()->dims());
"%s: %s, object %s has unsupported number of indices (%d)", VL_FUNC,
VerilatedVpiError::strFromVpiMethod(type), vop->fullname(),
vop->varp()->dims());
}
return (new VerilatedVpioMemoryWordIter(object, vop->varp()))->castVpiHandle();
}
@ -1189,17 +1198,16 @@ vpiHandle vpi_iterate(PLI_INT32 type, vpiHandle object) {
// Unsupported is multidim list
if (vop->varp()->dims() > 2) {
_VL_VPI_WARNING(__FILE__, __LINE__,
"%s: %s, object %s has unsupported number of indices (%d)",
VL_FUNC, VerilatedVpiError::strFromVpiMethod(type),
vop->fullname() , vop->varp()->dims());
"%s: %s, object %s has unsupported number of indices (%d)", VL_FUNC,
VerilatedVpiError::strFromVpiMethod(type), vop->fullname(),
vop->varp()->dims());
}
return ((new VerilatedVpioRange(vop->rangep()))->castVpiHandle());
}
case vpiReg: {
VerilatedVpioScope* vop = VerilatedVpioScope::castp(object);
if (VL_UNLIKELY(!vop)) return 0;
return ((new VerilatedVpioVarIter(vop->scopep()))
->castVpiHandle());
return ((new VerilatedVpioVarIter(vop->scopep()))->castVpiHandle());
}
case vpiModule: {
VerilatedVpioModule* vop = VerilatedVpioModule::castp(object);
@ -1338,7 +1346,8 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
case VLVT_WDATA: {
int words = VL_WORDS_I(vop->varp()->packed().elements());
if (VL_UNCOVERABLE(words >= VL_MULS_MAX_WORDS)) {
VL_FATAL_MT(__FILE__, __LINE__, "",
VL_FATAL_MT(
__FILE__, __LINE__, "",
"vpi_get_value with more than VL_MULS_MAX_WORDS; increase and recompile");
}
WDataInP datap = (reinterpret_cast<EData*>(vop->varDatap()));
@ -1357,9 +1366,8 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
return;
}
default: {
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname());
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC,
VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
return;
}
}
@ -1377,7 +1385,9 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
if (bits > outStrSz) {
// limit maximum size of output to size of buffer to prevent overrun.
bits = outStrSz;
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Truncating string value of %s for %s"
_VL_VPI_WARNING(
__FILE__, __LINE__,
"%s: Truncating string value of %s for %s"
" as buffer size (%d, VL_MULS_MAX_WORDS=%d) is less than required (%d)",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname(), outStrSz, VL_MULS_MAX_WORDS, bits);
@ -1390,9 +1400,8 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
return;
}
default:
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname());
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC,
VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
return;
}
} else if (value_p->format == vpiOctStrVal) {
@ -1409,7 +1418,9 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
int i;
if (chars > outStrSz) {
// limit maximum size of output to size of buffer to prevent overrun.
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Truncating string value of %s for %s"
_VL_VPI_WARNING(
__FILE__, __LINE__,
"%s: Truncating string value of %s for %s"
" as buffer size (%d, VL_MULS_MAX_WORDS=%d) is less than required (%d)",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname(), outStrSz, VL_MULS_MAX_WORDS, chars);
@ -1441,9 +1452,8 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
}
default:
strcpy(outStr, "0");
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname());
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC,
VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
return;
}
} else if (value_p->format == vpiDecStrVal) {
@ -1451,26 +1461,31 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
switch (vop->varp()->vltype()) {
// outStrSz does not include NULL termination so add one
case VLVT_UINT8:
VL_SNPRINTF(outStr, outStrSz+1, "%hhu",
VL_SNPRINTF(
outStr, outStrSz + 1, "%hhu",
static_cast<unsigned char>(*(reinterpret_cast<CData*>(vop->varDatap()))));
return;
case VLVT_UINT16:
VL_SNPRINTF(outStr, outStrSz+1, "%hu",
VL_SNPRINTF(
outStr, outStrSz + 1, "%hu",
static_cast<unsigned short>(*(reinterpret_cast<SData*>(vop->varDatap()))));
return;
case VLVT_UINT32:
VL_SNPRINTF(outStr, outStrSz+1, "%u",
VL_SNPRINTF(
outStr, outStrSz + 1, "%u",
static_cast<unsigned int>(*(reinterpret_cast<IData*>(vop->varDatap()))));
return;
case VLVT_UINT64:
VL_SNPRINTF(outStr, outStrSz+1, "%llu",
VL_SNPRINTF(
outStr, outStrSz + 1, "%llu",
static_cast<unsigned long long>(*(reinterpret_cast<QData*>(vop->varDatap()))));
return;
default:
strcpy(outStr, "-1");
_VL_VPI_ERROR(__FILE__, __LINE__,
"%s: Unsupported format (%s) for %s, maximum limit is 64 bits",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname());
return;
}
} else if (value_p->format == vpiHexStrVal) {
@ -1486,7 +1501,9 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
int i;
if (chars > outStrSz) {
// limit maximum size of output to size of buffer to prevent overrun.
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Truncating string value of %s for %s"
_VL_VPI_WARNING(
__FILE__, __LINE__,
"%s: Truncating string value of %s for %s"
" as buffer size (%d, VL_MULS_MAX_WORDS=%d) is less than required (%d)",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname(), outStrSz, VL_MULS_MAX_WORDS, chars);
@ -1509,9 +1526,8 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
return;
}
default:
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname());
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC,
VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
return;
}
} else if (value_p->format == vpiStringVal) {
@ -1527,7 +1543,9 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
int i;
if (bytes > outStrSz) {
// limit maximum size of output to size of buffer to prevent overrun.
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Truncating string value of %s for %s"
_VL_VPI_WARNING(
__FILE__, __LINE__,
"%s: Truncating string value of %s for %s"
" as buffer size (%d, VL_MULS_MAX_WORDS=%d) is less than required (%d)",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname(), outStrSz, VL_MULS_MAX_WORDS, bytes);
@ -1542,9 +1560,8 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
return;
}
default:
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname());
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC,
VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
return;
}
} else if (value_p->format == vpiIntVal) {
@ -1562,9 +1579,8 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
case VLVT_UINT64: // FALLTHRU
default:
value_p->value.integer = 0;
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname());
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC,
VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
return;
}
} else if (value_p->format == vpiSuppressVal) {
@ -1573,18 +1589,17 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) as requested for %s",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
return;
}
else if (VerilatedVpioConst* vop = VerilatedVpioConst::castp(object)) {
} else if (VerilatedVpioConst* vop = VerilatedVpioConst::castp(object)) {
if (value_p->format == vpiIntVal) {
value_p->value.integer = vop->num();
return;
}
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC,
VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
return;
}
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format %s",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format));
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format %s", VL_FUNC,
VerilatedVpiError::strFromVpiVal(value_p->format));
}
vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p, p_vpi_time /*time_p*/,
@ -1597,10 +1612,10 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p, p_vpi_time /*time
return 0;
}
if (VerilatedVpioVar* vop = VerilatedVpioVar::castp(object)) {
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: vpi_put_value name=%s fmt=%d vali=%d\n",
vop->fullname(), value_p->format, value_p->value.integer);
VL_DBG_MSGF("- vpi: varp=%p putatp=%p\n",
vop->varp()->datap(), vop->varDatap()););
VL_DEBUG_IF_PLI(
VL_DBG_MSGF("- vpi: vpi_put_value name=%s fmt=%d vali=%d\n", vop->fullname(),
value_p->format, value_p->value.integer);
VL_DBG_MSGF("- vpi: varp=%p putatp=%p\n", vop->varp()->datap(), vop->varDatap()););
if (VL_UNLIKELY(!vop->varp()->isPublicRW())) {
_VL_VPI_WARNING(__FILE__, __LINE__,
"Ignoring vpi_put_value to signal marked read-only,"
@ -1628,22 +1643,18 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p, p_vpi_time /*time
WDataOutP datap = (reinterpret_cast<EData*>(vop->varDatap()));
for (int i = 0; i < words; ++i) {
datap[i] = value_p->value.vector[i].aval;
if (i==(words-1)) {
datap[i] &= vop->mask();
}
if (i == (words - 1)) datap[i] &= vop->mask();
}
return object;
}
case VLVT_UINT64: {
*(reinterpret_cast<QData*>(vop->varDatap())) = _VL_SET_QII(
value_p->value.vector[1].aval & vop->mask(),
value_p->value.vector[0].aval);
value_p->value.vector[1].aval & vop->mask(), value_p->value.vector[0].aval);
return object;
}
default: {
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname());
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC,
VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
return NULL;
}
}
@ -1670,9 +1681,8 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p, p_vpi_time /*time
return object;
}
default:
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname());
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC,
VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
return 0;
}
} else if (value_p->format == vpiOctStrVal) {
@ -1700,9 +1710,10 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p, p_vpi_time /*time
if (digit >= '0' && digit <= '7') {
val.half = digit - '0';
} else {
_VL_VPI_WARNING(__FILE__, __LINE__,
"%s: Non octal character '%c' in '%s' as value %s for %s",
VL_FUNC, digit, value_p->value.str,
_VL_VPI_WARNING(
__FILE__, __LINE__,
"%s: Non octal character '%c' in '%s' as value %s for %s", VL_FUNC,
digit, value_p->value.str,
VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname());
val.half = 0;
@ -1729,15 +1740,12 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p, p_vpi_time /*time
datap[idx.quot + 1] &= vop->mask_byte(idx.quot + 1);
}
// zero off remaining top bytes
for (int i=idx.quot+2; i<bytes; ++i) {
datap[i] = 0;
}
for (int i = idx.quot + 2; i < bytes; ++i) datap[i] = 0;
return object;
}
default:
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname());
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC,
VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
return 0;
}
} else if (value_p->format == vpiDecStrVal) {
@ -1745,28 +1753,31 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p, p_vpi_time /*time
unsigned long long val;
int success = sscanf(value_p->value.str, "%30llu%15s", &val, remainder);
if (success < 1) {
_VL_VPI_ERROR(__FILE__, __LINE__,
"%s: Parsing failed for '%s' as value %s for %s",
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Parsing failed for '%s' as value %s for %s",
VL_FUNC, value_p->value.str,
VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
return 0;
}
if (success > 1) {
_VL_VPI_WARNING(__FILE__, __LINE__,
"%s: Trailing garbage '%s' in '%s' as value %s for %s",
_VL_VPI_WARNING(
__FILE__, __LINE__, "%s: Trailing garbage '%s' in '%s' as value %s for %s",
VL_FUNC, remainder, value_p->value.str,
VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname());
VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
}
switch (vop->varp()->vltype()) {
case VLVT_UINT8:
*(reinterpret_cast<CData*>(vop->varDatap())) = val & vop->mask(); break;
*(reinterpret_cast<CData*>(vop->varDatap())) = val & vop->mask();
break;
case VLVT_UINT16:
*(reinterpret_cast<SData*>(vop->varDatap())) = val & vop->mask(); break;
*(reinterpret_cast<SData*>(vop->varDatap())) = val & vop->mask();
break;
case VLVT_UINT32:
*(reinterpret_cast<IData*>(vop->varDatap())) = val & vop->mask(); break;
case VLVT_UINT64: *(reinterpret_cast<QData*>(vop->varDatap())) = val;
(reinterpret_cast<IData*>(vop->varDatap()))[1] &= vop->mask(); break;
*(reinterpret_cast<IData*>(vop->varDatap())) = val & vop->mask();
break;
case VLVT_UINT64:
*(reinterpret_cast<QData*>(vop->varDatap())) = val;
(reinterpret_cast<IData*>(vop->varDatap()))[1] &= vop->mask();
break;
case VLVT_WDATA:
default:
_VL_VPI_ERROR(__FILE__, __LINE__,
@ -1787,22 +1798,24 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p, p_vpi_time /*time
CData* datap = (reinterpret_cast<CData*>(vop->varDatap()));
char* val = value_p->value.str;
// skip hex ident if one is detected at the start of the string
if (val[0] == '0' && (val[1] == 'x' || val[1] == 'X')) {
val += 2;
}
if (val[0] == '0' && (val[1] == 'x' || val[1] == 'X')) val += 2;
int len = strlen(val);
for (int i = 0; i < chars; ++i) {
char hex;
// compute hex digit value
if (i < len) {
char digit = val[len - i - 1];
if (digit >= '0' && digit <= '9') hex = digit - '0';
else if (digit >= 'a' && digit <= 'f') hex = digit - 'a' + 10;
else if (digit >= 'A' && digit <= 'F') hex = digit - 'A' + 10;
else {
_VL_VPI_WARNING(__FILE__, __LINE__,
"%s: Non hex character '%c' in '%s' as value %s for %s",
VL_FUNC, digit, value_p->value.str,
if (digit >= '0' && digit <= '9') {
hex = digit - '0';
} else if (digit >= 'a' && digit <= 'f') {
hex = digit - 'a' + 10;
} else if (digit >= 'A' && digit <= 'F') {
hex = digit - 'A' + 10;
} else {
_VL_VPI_WARNING(
__FILE__, __LINE__,
"%s: Non hex character '%c' in '%s' as value %s for %s", VL_FUNC,
digit, value_p->value.str,
VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname());
hex = 0;
@ -1823,9 +1836,8 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p, p_vpi_time /*time
return object;
}
default:
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname());
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC,
VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
return 0;
}
} else if (value_p->format == vpiStringVal) {
@ -1845,9 +1857,8 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p, p_vpi_time /*time
return object;
}
default:
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format),
vop->fullname());
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s", VL_FUNC,
VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
return 0;
}
} else if (value_p->format == vpiIntVal) {
@ -1876,8 +1887,8 @@ vpiHandle vpi_put_value(vpiHandle object, p_vpi_value value_p, p_vpi_time /*time
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
return NULL;
}
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for ??",
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format));
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for ??", VL_FUNC,
VerilatedVpiError::strFromVpiVal(value_p->format));
return NULL;
}
@ -1907,8 +1918,7 @@ void vpi_get_time(vpiHandle /*object*/, p_vpi_time time_p) {
time_p->high = itime[1];
return;
}
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported type (%d)",
VL_FUNC, time_p->type);
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported type (%d)", VL_FUNC, time_p->type);
}
// I/O routines
@ -1994,9 +2004,7 @@ PLI_INT32 vpi_chk_error(p_vpi_error_info error_info_p) {
// error_info_p can be NULL, so only return level in that case
VerilatedVpiImp::assertOneCheck();
p_vpi_error_info _error_info_p = VerilatedVpiImp::error_info()->getError();
if (error_info_p && _error_info_p) {
*error_info_p = *_error_info_p;
}
if (error_info_p && _error_info_p) *error_info_p = *_error_info_p;
if (!_error_info_p) return 0; // no error occured
return _error_info_p->level; // return error severity level
}
@ -2061,8 +2069,8 @@ PLI_INT32 vpi_control(PLI_INT32 operation, ...) {
return 1;
}
}
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Unsupported type %s, ignoring",
VL_FUNC, VerilatedVpiError::strFromVpiProp(operation));
_VL_VPI_WARNING(__FILE__, __LINE__, "%s: Unsupported type %s, ignoring", VL_FUNC,
VerilatedVpiError::strFromVpiProp(operation));
return 0;
}

View File

@ -25,6 +25,8 @@
#ifndef _VERILATEDOS_H_
#define _VERILATEDOS_H_ 1 ///< Header Guard
// Current clang-format versions botch #ifdef inclusion, so
// clang-format off
//=========================================================================
// Compiler pragma abstraction
@ -94,7 +96,7 @@
# define VL_RELEASE(...) ///< Function releases a capability/lock (-fthread-safety)
# define VL_RELEASE_SHARED(...) ///< Function releases a shared capability/lock (-fthread-safety)
# define VL_TRY_ACQUIRE(...) ///< Function returns bool if aquired a capability (-fthread-safety)
# define VL_TRY_ACQUIRE_SHARED(...) ///< Function returns bool if aquired a shared capability (-fthread-safety)
# define VL_TRY_ACQUIRE_SHARED(...) ///< Function returns bool if aquired shared (-fthread-safety)
# define VL_REQUIRES(x) ///< Function requires a capability inbound (-fthread-safety)
# define VL_EXCLUDES(x) ///< Function requires not having a capability inbound (-fthread-safety)
# define VL_CAPABILITY(x) ///< Name of capability/lock (-fthread-safety)
@ -130,14 +132,17 @@
#else
# define VL_THREAD_LOCAL ///< Use new C++ static local thread
#endif
#define VL_THREAD ///< Deprecated
#define VL_STATIC_OR_THREAD static ///< Deprecated
#define VL_PURE ///< Comment tag that Function is pure (and thus also VL_MT_SAFE)
#define VL_MT_SAFE ///< Comment tag that function is threadsafe when VL_THREADED
#define VL_MT_SAFE_POSTINIT ///< Comment tag that function is threadsafe when VL_THREADED, only during normal operation (post-init)
#define VL_MT_SAFE_POSTINIT ///< Comment tag that function is threadsafe when VL_THREADED, only
///< during normal operation (post-init)
#define VL_MT_UNSAFE ///< Comment tag that function is not threadsafe when VL_THREADED
#define VL_MT_UNSAFE_ONE ///< Comment tag that function is not threadsafe when VL_THREADED, protected to make sure single-caller
#define VL_MT_UNSAFE_ONE ///< Comment tag that function is not threadsafe when VL_THREADED,
///< protected to make sure single-caller
#ifdef _MSC_VER
# define VL_ULL(c) (c##ULL) ///< Add appropriate suffix to 64-bit constant
@ -391,11 +396,10 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
#define VL_SIZEBITS_E (VL_EDATASIZE - 1) ///< Bit mask for bits in a quad
/// Mask for words with 1's where relevant bits are (0=all bits)
#define VL_MASK_I(nbits) (((nbits) & VL_SIZEBITS_I) \
? ((1U << ((nbits) & VL_SIZEBITS_I) )-1) : ~0)
#define VL_MASK_I(nbits) (((nbits) & VL_SIZEBITS_I) ? ((1U << ((nbits) & VL_SIZEBITS_I)) - 1) : ~0)
/// Mask for quads with 1's where relevant bits are (0=all bits)
#define VL_MASK_Q(nbits) (((nbits) & VL_SIZEBITS_Q) \
? ((VL_ULL(1) << ((nbits) & VL_SIZEBITS_Q) )-VL_ULL(1)) : VL_ULL(~0))
#define VL_MASK_Q(nbits) \
(((nbits) & VL_SIZEBITS_Q) ? ((VL_ULL(1) << ((nbits) & VL_SIZEBITS_Q)) - VL_ULL(1)) : VL_ULL(~0))
/// Mask for EData with 1's where relevant bits are (0=all bits)
#define VL_MASK_E(nbits) VL_MASK_I(nbits)
#define VL_EUL(n) VL_UL(n) ///< Make constant number EData sized
@ -424,7 +428,8 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
/// The vluint64_t argument is loaded with a high-performance counter for profiling
/// or 0x0 if not implemeted on this platform
#if defined(__i386__) || defined(__x86_64__)
# define VL_RDTSC(val) { \
#define VL_RDTSC(val) \
{ \
vluint32_t hi, lo; \
asm volatile("rdtsc" : "=a"(lo), "=d"(hi)); \
(val) = ((vluint64_t)lo) | (((vluint64_t)hi) << 32); \
@ -468,6 +473,7 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
#else
# define VL_STRCASECMP strcasecmp
#endif
// clang-format on
//=========================================================================
// Stringify macros

260
nodist/clang_formatter Executable file
View File

@ -0,0 +1,260 @@
#!/bin/bash
#
# clang-format is used to standardize the indentation of the internal C++
# code.
#
# For the most part clang-format changes provide good consistency, the two
# main exceptions being the indentation of preprocessor directives, and
# tables of statements. Reformatting is generally performed only before
# other large changes are to be made to a file.
#
# "##" files commented out below are not yet clang-format clean.
# "#" files commented out hit a clang-format limitation with ifdefs.
clang-format -i examples/make_hello_c/sim_main.cpp
clang-format -i examples/make_hello_sc/sc_main.cpp
#clang-format -i examples/make_protect_lib/sim_main.cpp
clang-format -i examples/make_tracing_c/sim_main.cpp
clang-format -i examples/make_tracing_sc/sc_main.cpp
clang-format -i include/verilated.cpp
clang-format -i include/verilated.h
clang-format -i include/verilated_config.h.in
clang-format -i include/verilated_cov.cpp
clang-format -i include/verilated_cov.h
clang-format -i include/verilated_cov_key.h
clang-format -i include/verilated_dpi.cpp
clang-format -i include/verilated_dpi.h
clang-format -i include/verilated_fst_c.cpp
clang-format -i include/verilated_fst_c.h
clang-format -i include/verilated_heavy.h
clang-format -i include/verilated_imp.h
clang-format -i include/verilated_save.cpp
clang-format -i include/verilated_save.h
clang-format -i include/verilated_sc.h
clang-format -i include/verilated_sym_props.h
clang-format -i include/verilated_syms.h
clang-format -i include/verilated_threads.cpp
clang-format -i include/verilated_threads.h
clang-format -i include/verilated_unordered_set_map.h
clang-format -i include/verilated_vcd_c.cpp
clang-format -i include/verilated_vcd_c.h
clang-format -i include/verilated_vcd_sc.cpp
clang-format -i include/verilated_vcd_sc.h
clang-format -i include/verilated_vpi.cpp
clang-format -i include/verilated_vpi.h
clang-format -i include/verilatedos.h
clang-format -i nodist/fuzzer/wrapper.cpp
clang-format -i src/V3Active.cpp
clang-format -i src/V3Active.h
clang-format -i src/V3ActiveTop.cpp
clang-format -i src/V3ActiveTop.h
clang-format -i src/V3Assert.cpp
clang-format -i src/V3Assert.h
clang-format -i src/V3AssertPre.cpp
clang-format -i src/V3AssertPre.h
##clang-format -i src/V3Ast.cpp
##clang-format -i src/V3Ast.h
clang-format -i src/V3AstConstOnly.h
##clang-format -i src/V3AstNodes.cpp
##clang-format -i src/V3AstNodes.h
##clang-format -i src/V3Begin.cpp
clang-format -i src/V3Begin.h
clang-format -i src/V3Branch.cpp
clang-format -i src/V3Branch.h
##clang-format -i src/V3Broken.cpp
clang-format -i src/V3Broken.h
##clang-format -i src/V3CCtors.cpp
clang-format -i src/V3CCtors.h
clang-format -i src/V3CUse.cpp
clang-format -i src/V3CUse.h
##clang-format -i src/V3Case.cpp
clang-format -i src/V3Case.h
##clang-format -i src/V3Cast.cpp
clang-format -i src/V3Cast.h
##clang-format -i src/V3Cdc.cpp
clang-format -i src/V3Cdc.h
##clang-format -i src/V3Changed.cpp
clang-format -i src/V3Changed.h
clang-format -i src/V3Class.cpp
clang-format -i src/V3Class.h
##clang-format -i src/V3Clean.cpp
clang-format -i src/V3Clean.h
##clang-format -i src/V3Clock.cpp
clang-format -i src/V3Clock.h
##clang-format -i src/V3Combine.cpp
clang-format -i src/V3Combine.h
clang-format -i src/V3Config.cpp
clang-format -i src/V3Config.h
##clang-format -i src/V3Const.cpp
clang-format -i src/V3Const.h
clang-format -i src/V3Coverage.cpp
clang-format -i src/V3Coverage.h
clang-format -i src/V3CoverageJoin.cpp
clang-format -i src/V3CoverageJoin.h
##clang-format -i src/V3Dead.cpp
clang-format -i src/V3Dead.h
##clang-format -i src/V3Delayed.cpp
clang-format -i src/V3Delayed.h
clang-format -i src/V3Depth.cpp
clang-format -i src/V3Depth.h
clang-format -i src/V3DepthBlock.cpp
clang-format -i src/V3DepthBlock.h
clang-format -i src/V3Descope.cpp
clang-format -i src/V3Descope.h
##clang-format -i src/V3EmitC.cpp
clang-format -i src/V3EmitC.h
##clang-format -i src/V3EmitCBase.h
clang-format -i src/V3EmitCInlines.cpp
##clang-format -i src/V3EmitCMake.cpp
clang-format -i src/V3EmitCMake.h
##clang-format -i src/V3EmitCSyms.cpp
##clang-format -i src/V3EmitMk.cpp
clang-format -i src/V3EmitMk.h
##clang-format -i src/V3EmitV.cpp
clang-format -i src/V3EmitV.h
##clang-format -i src/V3EmitXml.cpp
clang-format -i src/V3EmitXml.h
##clang-format -i src/V3Error.cpp
##clang-format -i src/V3Error.h
##clang-format -i src/V3Expand.cpp
clang-format -i src/V3Expand.h
##clang-format -i src/V3File.cpp
##clang-format -i src/V3File.h
##clang-format -i src/V3FileLine.cpp
##clang-format -i src/V3FileLine.h
##clang-format -i src/V3Gate.cpp
clang-format -i src/V3Gate.h
##clang-format -i src/V3GenClk.cpp
clang-format -i src/V3GenClk.h
clang-format -i src/V3Global.cpp
clang-format -i src/V3Global.h
##clang-format -i src/V3Graph.cpp
clang-format -i src/V3Graph.h
##clang-format -i src/V3GraphAcyc.cpp
##clang-format -i src/V3GraphAlg.cpp
clang-format -i src/V3GraphAlg.h
clang-format -i src/V3GraphDfa.cpp
clang-format -i src/V3GraphDfa.h
clang-format -i src/V3GraphPathChecker.cpp
clang-format -i src/V3GraphPathChecker.h
clang-format -i src/V3GraphStream.h
##clang-format -i src/V3GraphTest.cpp
##clang-format -i src/V3Hashed.cpp
clang-format -i src/V3Hashed.h
##clang-format -i src/V3Inline.cpp
clang-format -i src/V3Inline.h
##clang-format -i src/V3Inst.cpp
clang-format -i src/V3Inst.h
clang-format -i src/V3InstrCount.cpp
clang-format -i src/V3InstrCount.h
clang-format -i src/V3LangCode.h
clang-format -i src/V3LanguageWords.h
##clang-format -i src/V3Life.cpp
clang-format -i src/V3Life.h
##clang-format -i src/V3LifePost.cpp
clang-format -i src/V3LifePost.h
##clang-format -i src/V3LinkCells.cpp
clang-format -i src/V3LinkCells.h
##clang-format -i src/V3LinkDot.cpp
clang-format -i src/V3LinkDot.h
##clang-format -i src/V3LinkJump.cpp
clang-format -i src/V3LinkJump.h
clang-format -i src/V3LinkLValue.cpp
clang-format -i src/V3LinkLValue.h
##clang-format -i src/V3LinkLevel.cpp
clang-format -i src/V3LinkLevel.h
##clang-format -i src/V3LinkParse.cpp
clang-format -i src/V3LinkParse.h
##clang-format -i src/V3LinkResolve.cpp
clang-format -i src/V3LinkResolve.h
clang-format -i src/V3List.h
clang-format -i src/V3Localize.cpp
clang-format -i src/V3Localize.h
clang-format -i src/V3Name.cpp
clang-format -i src/V3Name.h
##clang-format -i src/V3Number.cpp
##clang-format -i src/V3Number.h
clang-format -i src/V3Number_test.cpp
##clang-format -i src/V3Options.cpp
##clang-format -i src/V3Options.h
##clang-format -i src/V3Order.cpp
clang-format -i src/V3Order.h
clang-format -i src/V3OrderGraph.h
##clang-format -i src/V3Os.cpp
clang-format -i src/V3Os.h
##clang-format -i src/V3Param.cpp
clang-format -i src/V3Param.h
clang-format -i src/V3Parse.h
##clang-format -i src/V3ParseGrammar.cpp
##clang-format -i src/V3ParseImp.cpp
##clang-format -i src/V3ParseImp.h
clang-format -i src/V3ParseLex.cpp
clang-format -i src/V3ParseSym.h
##clang-format -i src/V3Partition.cpp
clang-format -i src/V3Partition.h
clang-format -i src/V3PartitionGraph.h
clang-format -i src/V3PreLex.h
##clang-format -i src/V3PreProc.cpp
clang-format -i src/V3PreProc.h
clang-format -i src/V3PreShell.cpp
clang-format -i src/V3PreShell.h
##clang-format -i src/V3Premit.cpp
clang-format -i src/V3Premit.h
##clang-format -i src/V3ProtectLib.cpp
clang-format -i src/V3ProtectLib.h
clang-format -i src/V3Reloop.cpp
clang-format -i src/V3Reloop.h
##clang-format -i src/V3Scope.cpp
clang-format -i src/V3Scope.h
clang-format -i src/V3Scoreboard.cpp
clang-format -i src/V3Scoreboard.h
clang-format -i src/V3SenTree.h
##clang-format -i src/V3Simulate.h
##clang-format -i src/V3Slice.cpp
clang-format -i src/V3Slice.h
##clang-format -i src/V3Split.cpp
clang-format -i src/V3Split.h
##clang-format -i src/V3SplitAs.cpp
clang-format -i src/V3SplitAs.h
##clang-format -i src/V3SplitVar.cpp
clang-format -i src/V3SplitVar.h
clang-format -i src/V3Stats.cpp
clang-format -i src/V3Stats.h
clang-format -i src/V3StatsReport.cpp
clang-format -i src/V3String.cpp
clang-format -i src/V3String.h
##clang-format -i src/V3Subst.cpp
clang-format -i src/V3Subst.h
clang-format -i src/V3SymTable.h
##clang-format -i src/V3TSP.cpp
clang-format -i src/V3TSP.h
##clang-format -i src/V3Table.cpp
clang-format -i src/V3Table.h
##clang-format -i src/V3Task.cpp
clang-format -i src/V3Task.h
clang-format -i src/V3Trace.cpp
clang-format -i src/V3Trace.h
clang-format -i src/V3TraceDecl.cpp
clang-format -i src/V3TraceDecl.h
##clang-format -i src/V3Tristate.cpp
clang-format -i src/V3Tristate.h
##clang-format -i src/V3Undriven.cpp
clang-format -i src/V3Undriven.h
##clang-format -i src/V3Unknown.cpp
clang-format -i src/V3Unknown.h
##clang-format -i src/V3Unroll.cpp
clang-format -i src/V3Unroll.h
##clang-format -i src/V3Width.cpp
clang-format -i src/V3Width.h
clang-format -i src/V3WidthCommit.h
##clang-format -i src/V3WidthSel.cpp
##clang-format -i src/Verilator.cpp
clang-format -i src/VlcBucket.h
clang-format -i src/VlcMain.cpp
clang-format -i src/VlcOptions.h
clang-format -i src/VlcPoint.h
clang-format -i src/VlcSource.h
clang-format -i src/VlcTest.h
clang-format -i src/VlcTop.cpp
clang-format -i src/VlcTop.h
clang-format -i src/config_build.h.in

View File

@ -89,8 +89,7 @@ public:
AstActive* getCActive(FileLine* fl) {
if (!m_cActivep) {
m_cActivep = new AstActive(
fl, "combo",
new AstSenTree(fl, new AstSenItem(fl, AstSenItem::Combo())));
fl, "combo", new AstSenTree(fl, new AstSenItem(fl, AstSenItem::Combo())));
m_cActivep->sensesStorep(m_cActivep->sensesp());
addActive(m_cActivep);
}
@ -99,8 +98,7 @@ public:
AstActive* getIActive(FileLine* fl) {
if (!m_iActivep) {
m_iActivep = new AstActive(
fl, "initial",
new AstSenTree(fl, new AstSenItem(fl, AstSenItem::Initial())));
fl, "initial", new AstSenTree(fl, new AstSenItem(fl, AstSenItem::Initial())));
m_iActivep->sensesStorep(m_iActivep->sensesp());
addActive(m_iActivep);
}
@ -131,6 +129,7 @@ public:
}
return activep;
}
public:
// CONSTRUCTORS
ActiveNamer() {
@ -139,9 +138,7 @@ public:
m_cActivep = NULL;
}
virtual ~ActiveNamer() {}
void main(AstScope* nodep) {
iterate(nodep);
}
void main(AstScope* nodep) { iterate(nodep); }
};
//######################################################################
@ -150,6 +147,7 @@ public:
class ActiveDlyVisitor : public ActiveBaseVisitor {
public:
enum CheckType { CT_SEQ, CT_COMBO, CT_INITIAL, CT_LATCH };
private:
CheckType m_check; // Combo logic or other
AstNode* m_alwaysp; // Always we're under
@ -161,16 +159,17 @@ private:
UINFO(5, " ASSIGNDLY " << nodep << endl);
if (m_check == CT_INITIAL) {
nodep->v3warn(INITIALDLY, "Delayed assignments (<=) in initial or final block\n"
<<nodep->warnMore()<<"... Suggest blocking assignments (=)");
<< nodep->warnMore()
<< "... Suggest blocking assignments (=)");
} else if (m_check == CT_LATCH) {
// Suppress. Shouldn't matter that the interior of the latch races
} else {
nodep->v3warn(COMBDLY, "Delayed assignments (<=) in non-clocked"
" (non flop or latch) block\n"
<<nodep->warnMore()<<"... Suggest blocking assignments (=)");
<< nodep->warnMore()
<< "... Suggest blocking assignments (=)");
}
AstNode* newp = new AstAssign(nodep->fileline(),
nodep->lhsp()->unlinkFrBack(),
AstNode* newp = new AstAssign(nodep->fileline(), nodep->lhsp()->unlinkFrBack(),
nodep->rhsp()->unlinkFrBack());
nodep->replaceWith(newp);
VL_DO_DANGLING(nodep->deleteTree(), nodep);
@ -186,17 +185,18 @@ private:
}
virtual void visit(AstVarRef* nodep) VL_OVERRIDE {
AstVar* varp = nodep->varp();
if (m_check == CT_SEQ
&& m_assignp
&& !varp->isUsedLoopIdx() // Ignore loop indices
if (m_check == CT_SEQ && m_assignp && !varp->isUsedLoopIdx() // Ignore loop indices
&& !varp->isTemp()) {
// Allow turning off warnings on the always, or the variable also
if (!m_alwaysp->fileline()->warnIsOff(V3ErrorCode::BLKSEQ)
&& !m_assignp->fileline()->warnIsOff(V3ErrorCode::BLKSEQ)
&& !varp->fileline()->warnIsOff(V3ErrorCode::BLKSEQ)) {
m_assignp->v3warn(BLKSEQ, "Blocking assignments (=) in sequential (flop or latch) block\n"
<<m_assignp->warnMore()<<"... Suggest delayed assignments (<=)");
m_alwaysp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); // Complain just once for the entire always
m_assignp->v3warn(BLKSEQ,
"Blocking assignments (=) in sequential (flop or latch) block\n"
<< m_assignp->warnMore()
<< "... Suggest delayed assignments (<=)");
m_alwaysp->fileline()->modifyWarnOff(
V3ErrorCode::BLKSEQ, true); // Complain just once for the entire always
varp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true);
}
}
@ -281,8 +281,7 @@ private:
ActiveDlyVisitor dlyvisitor(nodep, ActiveDlyVisitor::CT_INITIAL);
if (!m_scopeFinalp) {
m_scopeFinalp = new AstCFunc(
nodep->fileline(), "_final_"+m_namer.scopep()->nameDotless(),
m_namer.scopep());
nodep->fileline(), "_final_" + m_namer.scopep()->nameDotless(), m_namer.scopep());
m_scopeFinalp->argTypes(EmitCBaseVisitor::symClassVar());
m_scopeFinalp->addInitsp(
new AstCStmt(nodep->fileline(), EmitCBaseVisitor::symTopAssign() + "\n"));
@ -300,9 +299,7 @@ private:
// METHODS
void visitAlways(AstNode* nodep, AstSenTree* oldsensesp, VAlwaysKwd kwd) {
// Move always to appropriate ACTIVE based on its sense list
if (oldsensesp
&& oldsensesp->sensesp()
&& VN_IS(oldsensesp->sensesp(), SenItem)
if (oldsensesp && oldsensesp->sensesp() && VN_IS(oldsensesp->sensesp(), SenItem)
&& VN_CAST(oldsensesp->sensesp(), SenItem)->isNever()) {
// Never executing. Kill it.
UASSERT_OBJ(!oldsensesp->sensesp()->nextp(), nodep,
@ -321,7 +318,8 @@ private:
if (!combo && !sequent) combo = true; // If no list, Verilog 2000: always @ (*)
if (combo && sequent) {
if (!v3Global.opt.bboxUnsup()) {
nodep->v3error("Unsupported: Mixed edge (pos/negedge) and activity (no edge) sensitive activity list");
nodep->v3error("Unsupported: Mixed edge (pos/negedge) and activity "
"(no edge) sensitive activity list");
}
sequent = false;
}
@ -336,8 +334,9 @@ private:
// always (posedge RESET) { if (RESET).... } we know RESET is true.
// Summarize a long list of combo inputs as just "combo"
#ifndef __COVERITY__ // Else dead code on next line.
if (combo) oldsensesp->addSensesp
(new AstSenItem(nodep->fileline(), AstSenItem::Combo()));
if (combo) {
oldsensesp->addSensesp(new AstSenItem(nodep->fileline(), AstSenItem::Combo()));
}
#endif
wantactivep = m_namer.getActive(nodep->fileline(), oldsensesp);
}
@ -358,8 +357,7 @@ private:
} else {
ActiveDlyVisitor dlyvisitor(nodep, ActiveDlyVisitor::CT_COMBO);
}
}
else if (!combo && sequent) {
} else if (!combo && sequent) {
ActiveDlyVisitor dlyvisitor(nodep, ActiveDlyVisitor::CT_SEQ);
}
}
@ -427,8 +425,6 @@ public:
void V3Active::activeAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl);
{
ActiveVisitor visitor (nodep);
} // Destruct before checking
{ ActiveVisitor visitor(nodep); } // Destruct before checking
V3Global::dumpCheckGlobalTree("active", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -66,11 +66,11 @@ private:
}
virtual void visit(AstActive* nodep) VL_OVERRIDE {
UINFO(4, " ACTIVE " << nodep << endl);
V3Const::constifyExpensiveEdit(nodep); // Remove duplicate clocks and such; sensesp() may change!
// Remove duplicate clocks and such; sensesp() may change!
V3Const::constifyExpensiveEdit(nodep);
AstSenTree* sensesp = nodep->sensesp();
UASSERT_OBJ(sensesp, nodep, "NULL");
if (sensesp->sensesp()
&& VN_IS(sensesp->sensesp(), SenItem)
if (sensesp->sensesp() && VN_IS(sensesp->sensesp(), SenItem)
&& VN_CAST(sensesp->sensesp(), SenItem)->isNever()) {
// Never executing. Kill it.
UASSERT_OBJ(!sensesp->sensesp()->nextp(), nodep,
@ -80,9 +80,8 @@ private:
}
// Copy combo tree to settlement tree with duplicated statements
if (sensesp->hasCombo()) {
AstSenTree* newsentreep
= new AstSenTree(nodep->fileline(),
new AstSenItem(nodep->fileline(), AstSenItem::Settle()));
AstSenTree* newsentreep = new AstSenTree(
nodep->fileline(), new AstSenItem(nodep->fileline(), AstSenItem::Settle()));
AstActive* newp = new AstActive(nodep->fileline(), "settle", newsentreep);
newp->sensesStorep(newsentreep);
if (nodep->stmtsp()) newp->addStmtsp(nodep->stmtsp()->cloneTree(true));
@ -146,8 +145,6 @@ public:
void V3ActiveTop::activeTopAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl);
{
ActiveTopVisitor visitor (nodep);
} // Destruct before checking
{ ActiveTopVisitor visitor(nodep); } // Destruct before checking
V3Global::dumpCheckGlobalTree("activetop", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -47,11 +47,9 @@ private:
// METHODS
string assertDisplayMessage(AstNode* nodep, const string& prefix, const string& message) {
return (string("[%0t] "+prefix+": ")+nodep->fileline()->filebasename()
+":"+cvtToStr(nodep->fileline()->lineno())
+": Assertion failed in %m"
+((message != "")?": ":"")+message
+"\n");
return (string("[%0t] " + prefix + ": ") + nodep->fileline()->filebasename() + ":"
+ cvtToStr(nodep->fileline()->lineno()) + ": Assertion failed in %m"
+ ((message != "") ? ": " : "") + message + "\n");
}
void replaceDisplay(AstDisplay* nodep, const string& prefix) {
nodep->displayType(AstDisplayType::DT_WRITE);
@ -86,8 +84,8 @@ private:
AstNode* newFireAssertUnchecked(AstNode* nodep, const string& message) {
// 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;
replaceDisplay(dispp, "%%Error"); // Convert to standard DISPLAY format
bodysp->addNext(new AstStop(nodep->fileline(), true));
@ -137,8 +135,11 @@ private:
ifp = new AstIf(nodep->fileline(), propp, bodysp, NULL);
bodysp = ifp;
} else if (VN_IS(nodep, Assert)) {
if (nodep->immediate()) ++m_statAsImm;
else ++m_statAsNotImm;
if (nodep->immediate()) {
++m_statAsImm;
} else {
++m_statAsNotImm;
}
if (passsp) passsp = newIfAssertOn(passsp);
if (failsp) failsp = newIfAssertOn(failsp);
if (!failsp) failsp = newFireAssertUnchecked(nodep, "'assert' failed.");
@ -153,9 +154,10 @@ private:
AstNode* newp;
if (sentreep) {
newp = new AstAlways(nodep->fileline(),
VAlwaysKwd::ALWAYS, sentreep, bodysp);
} else { newp = bodysp; }
newp = new AstAlways(nodep->fileline(), VAlwaysKwd::ALWAYS, sentreep, bodysp);
} else {
newp = bodysp;
}
// Install it
if (selfDestruct) {
// Delete it after making the tree. This way we can tell the user
@ -186,7 +188,7 @@ private:
iterateAndNextNull(ifp->ifsp());
// If the last else is not an else if, recurse into that too.
if (ifp->elsesp() && !nextifp) {
if (ifp->elsesp() && !nextifp) { //
iterateAndNextNull(ifp->elsesp());
}
@ -199,9 +201,7 @@ private:
}
// Record if this ends with an 'else' that does not have an if
if (ifp->elsesp() && !nextifp) {
hasDefaultElse = true;
}
if (ifp->elsesp() && !nextifp) hasDefaultElse = true;
ifp = nextifp;
} while (ifp);
@ -217,10 +217,9 @@ private:
AstNode* ohot = ((allow_none || hasDefaultElse)
? static_cast<AstNode*>(new AstOneHot0(nodep->fileline(), propp))
: static_cast<AstNode*>(new AstOneHot(nodep->fileline(), propp)));
AstIf* checkifp = new AstIf(nodep->fileline(),
new AstLogNot(nodep->fileline(), ohot),
newFireAssert(nodep, "'unique if' statement violated"),
newifp);
AstIf* checkifp
= new AstIf(nodep->fileline(), new AstLogNot(nodep->fileline(), ohot),
newFireAssert(nodep, "'unique if' statement violated"), newifp);
checkifp->branchPred(VBranchPred::BP_UNLIKELY);
nodep->replaceWith(checkifp);
pushDeletep(nodep);
@ -234,15 +233,16 @@ private:
iterateChildren(nodep);
if (!nodep->user1SetOnce()) {
bool has_default = false;
for (AstCaseItem* itemp = nodep->itemsp();
itemp; itemp = VN_CAST(itemp->nextp(), CaseItem)) {
for (AstCaseItem* itemp = nodep->itemsp(); itemp;
itemp = VN_CAST(itemp->nextp(), CaseItem)) {
if (itemp->isDefault()) has_default = true;
}
if (nodep->fullPragma() || nodep->priorityPragma()) {
// Simply need to add a default if there isn't one already
++m_statAsFull;
if (!has_default) {
nodep->addItemsp(new AstCaseItem(nodep->fileline(), NULL/*DEFAULT*/,
nodep->addItemsp(new AstCaseItem(
nodep->fileline(), NULL /*DEFAULT*/,
newFireAssert(nodep, "synthesis full_case, but non-match found")));
}
}
@ -271,8 +271,11 @@ private:
nodep->exprp()->cloneTree(false),
icondp->cloneTree(false));
}
if (propp) propp = new AstConcat(icondp->fileline(), onep, propp);
else propp = onep;
if (propp) {
propp = new AstConcat(icondp->fileline(), onep, propp);
} else {
propp = onep;
}
}
}
// Empty case means no property
@ -283,9 +286,10 @@ private:
= (allow_none
? static_cast<AstNode*>(new AstOneHot0(nodep->fileline(), propp))
: static_cast<AstNode*>(new AstOneHot(nodep->fileline(), propp)));
AstIf* ifp = new AstIf(nodep->fileline(),
new AstLogNot(nodep->fileline(), ohot),
newFireAssert(nodep, "synthesis parallel_case, but multiple matches found"),
AstIf* ifp = new AstIf(
nodep->fileline(), new AstLogNot(nodep->fileline(), ohot),
newFireAssert(nodep,
"synthesis parallel_case, but multiple matches found"),
NULL);
ifp->branchPred(VBranchPred::BP_UNLIKELY);
nodep->addNotParallelp(ifp);
@ -306,9 +310,9 @@ private:
UASSERT_OBJ(ticks >= 1, nodep, "0 tick should have been checked in V3Width");
AstNode* inp = nodep->exprp()->unlinkFrBack();
AstVar* invarp = NULL;
AstSenTree* sentreep = nodep->sentreep(); sentreep->unlinkFrBack();
AstAlways* alwaysp = new AstAlways(nodep->fileline(), VAlwaysKwd::ALWAYS,
sentreep, NULL);
AstSenTree* sentreep = nodep->sentreep();
sentreep->unlinkFrBack();
AstAlways* alwaysp = new AstAlways(nodep->fileline(), VAlwaysKwd::ALWAYS, sentreep, NULL);
m_modp->addStmtp(alwaysp);
for (uint32_t i = 0; i < ticks; ++i) {
AstVar* outvarp = new AstVar(nodep->fileline(), AstVarType::MODULETEMP,
@ -316,8 +320,7 @@ private:
inp->dtypep());
m_modp->addStmtp(outvarp);
AstNode* assp = new AstAssignDly(nodep->fileline(),
new AstVarRef(nodep->fileline(), outvarp, true),
inp);
new AstVarRef(nodep->fileline(), outvarp, true), inp);
alwaysp->addStmtp(assp);
// if (debug()>-9) assp->dumpTree(cout, "-ass: ");
invarp = outvarp;
@ -404,8 +407,6 @@ public:
void V3Assert::assertAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl);
{
AssertVisitor visitor (nodep);
} // Destruct before checking
{ AssertVisitor visitor(nodep); } // Destruct before checking
V3Global::dumpCheckGlobalTree("assert", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -61,9 +61,7 @@ private:
}
return newp;
}
void clearAssertInfo() {
m_senip = NULL;
}
void clearAssertInfo() { m_senip = NULL; }
// VISITORS
//========== Statements
@ -81,9 +79,7 @@ private:
}
virtual void visit(AstAlways* nodep) VL_OVERRIDE {
iterateAndNextNull(nodep->sensesp());
if (nodep->sensesp()) {
m_seniAlwaysp = nodep->sensesp()->sensesp();
}
if (nodep->sensesp()) m_seniAlwaysp = nodep->sensesp()->sensesp();
iterateAndNextNull(nodep->bodysp());
m_seniAlwaysp = NULL;
}
@ -93,9 +89,7 @@ private:
clearAssertInfo();
// Find Clocking's buried under nodep->exprsp
iterateChildren(nodep);
if (!nodep->immediate()) {
nodep->sentreep(newSenTree(nodep));
}
if (!nodep->immediate()) nodep->sentreep(newSenTree(nodep));
clearAssertInfo();
}
virtual void visit(AstPast* nodep) VL_OVERRIDE {
@ -106,21 +100,18 @@ private:
virtual void visit(AstPropClocked* nodep) VL_OVERRIDE {
// No need to iterate the body, once replace will get iterated
iterateAndNextNull(nodep->sensesp());
if (m_senip) {
nodep->v3error("Unsupported: Only one PSL clock allowed per assertion");
}
if (m_senip) nodep->v3error("Unsupported: Only one PSL clock allowed per assertion");
// Block is the new expression to evaluate
AstNode* blockp = nodep->propp()->unlinkFrBack();
if (nodep->disablep()) {
if (VN_IS(nodep->backp(), Cover)) {
blockp = new AstAnd(nodep->disablep()->fileline(),
new AstNot(nodep->disablep()->fileline(),
nodep->disablep()->unlinkFrBack()),
blockp = new AstAnd(
nodep->disablep()->fileline(),
new AstNot(nodep->disablep()->fileline(), nodep->disablep()->unlinkFrBack()),
blockp);
} else {
blockp = new AstOr(nodep->disablep()->fileline(),
nodep->disablep()->unlinkFrBack(),
blockp);
nodep->disablep()->unlinkFrBack(), blockp);
}
}
// Unlink and just keep a pointer to it, convert to sentree as needed
@ -152,8 +143,6 @@ public:
void V3AssertPre::assertPreAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl);
{
AssertPreVisitor visitor (nodep);
} // Destruct before checking
{ AssertPreVisitor visitor(nodep); } // Destruct before checking
V3Global::dumpCheckGlobalTree("assertpre", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -111,9 +111,7 @@ private:
void calc_tasks() {
for (CFuncVec::iterator it = m_cfuncsp.begin(); it != m_cfuncsp.end(); ++it) {
AstCFunc* nodep = *it;
if (!nodep->dontInline()) {
nodep->isInline(true);
}
if (!nodep->dontInline()) nodep->isInline(true);
}
}

View File

@ -58,27 +58,21 @@ private:
packagep->classp(nodep);
v3Global.rootp()->addModulep(packagep);
// Add package to hierarchy
AstCell* cellp = new AstCell(packagep->fileline(),
packagep->fileline(),
packagep->name(),
packagep->name(),
NULL, NULL, NULL);
AstCell* cellp = new AstCell(packagep->fileline(), packagep->fileline(), packagep->name(),
packagep->name(), NULL, NULL, NULL);
cellp->modp(packagep);
v3Global.rootp()->topModulep()->addStmtp(cellp);
// Find class's scope
// Alternative would be to move this and related to V3Scope
AstScope* classScopep = NULL;
for (AstNode* itp = nodep->stmtsp(); itp; itp = itp->nextp()) {
if ((classScopep = VN_CAST(itp, Scope))) {
break;
}
if ((classScopep = VN_CAST(itp, Scope))) break;
}
UASSERT_OBJ(classScopep, nodep, "No scope under class");
// Add scope
AstScope* scopep = new AstScope(nodep->fileline(),
packagep, classScopep->name(), classScopep->aboveScopep(),
classScopep->aboveCellp());
AstScope* scopep = new AstScope(nodep->fileline(), packagep, classScopep->name(),
classScopep->aboveScopep(), classScopep->aboveCellp());
packagep->addStmtp(scopep);
// Iterate
string prevPrefix = m_prefix;

View File

@ -346,7 +346,9 @@ public:
bool waive(V3ErrorCode code, const string& match) {
for (Waivers::const_iterator it = m_waivers.begin(); it != m_waivers.end(); ++it) {
if (((it->first == code) || (it->first == V3ErrorCode::I_LINT))
&& VString::wildmatch(match, it->second)) return true;
&& VString::wildmatch(match, it->second)) {
return true;
}
}
return false;
}

View File

@ -47,7 +47,9 @@ private:
AstNode* m_varRefp; // How to get to this element
AstNode* m_chgRefp; // How to get to this element
ToggleEnt(const string& comment, AstNode* vp, AstNode* cp)
: m_comment(comment), m_varRefp(vp), m_chgRefp(cp) {}
: m_comment(comment)
, m_varRefp(vp)
, m_chgRefp(cp) {}
~ToggleEnt() {}
void cleanup() {
VL_DO_CLEAR(m_varRefp->deleteTree(), m_varRefp = NULL);
@ -74,14 +76,11 @@ private:
const char* varIgnoreToggle(AstVar* nodep) {
// Return true if this shouldn't be traced
// See also similar rule in V3TraceDecl::varIgnoreTrace
if (!nodep->isToggleCoverable())
return "Not relevant signal type";
if (!nodep->isToggleCoverable()) return "Not relevant signal type";
if (!v3Global.opt.coverageUnderscore()) {
string prettyName = nodep->prettyName();
if (prettyName[0] == '_')
return "Leading underscore";
if (prettyName.find("._") != string::npos)
return "Inlined leading underscore";
if (prettyName[0] == '_') return "Leading underscore";
if (prettyName.find("._") != string::npos) return "Inlined leading underscore";
}
if ((nodep->width() * nodep->dtypep()->arrayUnpackedElements()) > 256) {
return "Wide bus/array > 256 bits";
@ -91,15 +90,14 @@ private:
return NULL;
}
AstCoverInc* newCoverInc(FileLine* fl, const string& hier,
const string& page_prefix, const string& comment,
const string& trace_var_name) {
AstCoverInc* newCoverInc(FileLine* fl, const string& hier, const string& page_prefix,
const string& comment, const string& trace_var_name) {
// For line coverage, we may have multiple if's on one line, so disambiguate if
// everything is otherwise identical
// (Don't set column otherwise as it may result in making bins not match up with
// different types of coverage enabled.)
string key = fl->filename()+"\001"+cvtToStr(fl->lineno())
+"\001"+hier+"\001"+page_prefix+"\001"+comment;
string key = fl->filename() + "\001" + cvtToStr(fl->lineno()) + "\001" + hier + "\001"
+ page_prefix + "\001" + comment;
int column = 0;
FileMap::iterator it = m_fileps.find(key);
if (it == m_fileps.end()) {
@ -122,27 +120,23 @@ private:
AstCoverInc* incp = new AstCoverInc(fl, declp);
if (!trace_var_name.empty() && v3Global.opt.traceCoverage()) {
AstVar* varp = new AstVar(incp->fileline(),
AstVarType::MODULETEMP, trace_var_name,
AstVar* varp = new AstVar(incp->fileline(), AstVarType::MODULETEMP, trace_var_name,
incp->findUInt32DType());
varp->trace(true);
varp->fileline()->modifyWarnOff(V3ErrorCode::UNUSED, true);
m_modp->addStmtp(varp);
UINFO(5, "New coverage trace: " << varp << endl);
AstAssign* assp = new AstAssign(
incp->fileline(),
new AstVarRef(incp->fileline(), varp, true),
new AstAdd(incp->fileline(),
new AstVarRef(incp->fileline(), varp, false),
incp->fileline(), new AstVarRef(incp->fileline(), varp, true),
new AstAdd(incp->fileline(), new AstVarRef(incp->fileline(), varp, false),
new AstConst(incp->fileline(), AstConst::WidthedValue(), 32, 1)));
incp->addNext(assp);
}
return incp;
}
string traceNameForLine(AstNode* nodep, const string& type) {
return "vlCoverageLineTrace_"+nodep->fileline()->filebasenameNoExt()
+"__"+cvtToStr(nodep->fileline()->lineno())
+"_"+type;
return "vlCoverageLineTrace_" + nodep->fileline()->filebasenameNoExt() + "__"
+ cvtToStr(nodep->fileline()->lineno()) + "_" + type;
}
// VISITORS - BOTH
virtual void visit(AstNodeModule* nodep) VL_OVERRIDE {
@ -169,8 +163,8 @@ private:
}
virtual void visit(AstVar* nodep) VL_OVERRIDE {
iterateChildren(nodep);
if (m_modp && !m_inModOff && !m_inToggleOff
&& nodep->fileline()->coverageOn() && v3Global.opt.coverageToggle()) {
if (m_modp && !m_inModOff && !m_inToggleOff && nodep->fileline()->coverageOn()
&& v3Global.opt.coverageToggle()) {
const char* disablep = varIgnoreToggle(nodep);
if (disablep) {
UINFO(4, " Disable Toggle: " << disablep << " " << nodep << endl);
@ -189,8 +183,8 @@ private:
// Add signal to hold the old value
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);
m_modp->addStmtp(chgVarp);
@ -198,46 +192,41 @@ private:
// This is necessarily an O(n^2) expansion, which is why
// we limit coverage to signals with < 256 bits.
ToggleEnt newvec (string(""),
new AstVarRef(nodep->fileline(), nodep, false),
ToggleEnt newvec(string(""), new AstVarRef(nodep->fileline(), nodep, false),
new AstVarRef(nodep->fileline(), chgVarp, true));
toggleVarRecurse(nodep->dtypeSkipRefp(), 0, newvec,
nodep, chgVarp);
toggleVarRecurse(nodep->dtypeSkipRefp(), 0, newvec, nodep, chgVarp);
newvec.cleanup();
}
}
}
void toggleVarBottom(const ToggleEnt& above, const AstVar* varp) {
AstCoverToggle* newp
= new AstCoverToggle(varp->fileline(),
newCoverInc(varp->fileline(), "", "v_toggle",
varp->name()+above.m_comment, ""),
above.m_varRefp->cloneTree(true),
above.m_chgRefp->cloneTree(true));
AstCoverToggle* newp = new AstCoverToggle(
varp->fileline(),
newCoverInc(varp->fileline(), "", "v_toggle", varp->name() + above.m_comment, ""),
above.m_varRefp->cloneTree(true), above.m_chgRefp->cloneTree(true));
m_modp->addStmtp(newp);
}
void toggleVarRecurse(AstNodeDType* dtypep, int depth, // per-iteration
const ToggleEnt& above,
AstVar* varp, AstVar* chgVarp) { // Constant
const ToggleEnt& above, AstVar* varp, AstVar* chgVarp) { // Constant
if (const AstBasicDType* bdtypep = VN_CAST(dtypep, BasicDType)) {
if (bdtypep->isRanged()) {
for (int index_docs=bdtypep->lsb(); index_docs<bdtypep->msb()+1; index_docs++) {
for (int index_docs = bdtypep->lsb(); index_docs < bdtypep->msb() + 1;
index_docs++) {
int index_code = index_docs - bdtypep->lsb();
ToggleEnt newent(above.m_comment + string("[") + cvtToStr(index_docs) + "]",
new AstSel(varp->fileline(),
above.m_varRefp->cloneTree(true), index_code, 1),
new AstSel(varp->fileline(),
above.m_chgRefp->cloneTree(true), index_code, 1));
new AstSel(varp->fileline(), above.m_varRefp->cloneTree(true),
index_code, 1),
new AstSel(varp->fileline(), above.m_chgRefp->cloneTree(true),
index_code, 1));
toggleVarBottom(newent, varp);
newent.cleanup();
}
} else {
toggleVarBottom(above, varp);
}
}
else if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
} else if (AstUnpackArrayDType* adtypep = VN_CAST(dtypep, UnpackArrayDType)) {
for (int index_docs = adtypep->lsb(); index_docs <= adtypep->msb(); ++index_docs) {
int index_code = index_docs - adtypep->lsb();
ToggleEnt newent(above.m_comment + string("[") + cvtToStr(index_docs) + "]",
@ -245,13 +234,11 @@ private:
above.m_varRefp->cloneTree(true), index_code),
new AstArraySel(varp->fileline(),
above.m_chgRefp->cloneTree(true), index_code));
toggleVarRecurse(adtypep->subDTypep()->skipRefp(), depth+1,
newent,
varp, chgVarp);
toggleVarRecurse(adtypep->subDTypep()->skipRefp(), depth + 1, newent, varp,
chgVarp);
newent.cleanup();
}
}
else if (AstPackArrayDType* adtypep = VN_CAST(dtypep, PackArrayDType)) {
} else if (AstPackArrayDType* adtypep = VN_CAST(dtypep, PackArrayDType)) {
for (int index_docs = adtypep->lsb(); index_docs <= adtypep->msb(); ++index_docs) {
AstNodeDType* subtypep = adtypep->subDTypep()->skipRefp();
int index_code = index_docs - adtypep->lsb();
@ -260,16 +247,14 @@ private:
index_code * subtypep->width(), subtypep->width()),
new AstSel(varp->fileline(), above.m_chgRefp->cloneTree(true),
index_code * subtypep->width(), subtypep->width()));
toggleVarRecurse(adtypep->subDTypep()->skipRefp(), depth+1,
newent,
varp, chgVarp);
toggleVarRecurse(adtypep->subDTypep()->skipRefp(), depth + 1, newent, varp,
chgVarp);
newent.cleanup();
}
}
else if (AstStructDType* adtypep = VN_CAST(dtypep, StructDType)) {
} else if (AstStructDType* adtypep = VN_CAST(dtypep, StructDType)) {
// For now it's packed, so similar to array
for (AstMemberDType* itemp = adtypep->membersp();
itemp; itemp=VN_CAST(itemp->nextp(), MemberDType)) {
for (AstMemberDType* itemp = adtypep->membersp(); itemp;
itemp = VN_CAST(itemp->nextp(), MemberDType)) {
AstNodeDType* subtypep = itemp->subDTypep()->skipRefp();
int index_code = itemp->lsb();
ToggleEnt newent(above.m_comment + string(".") + itemp->name(),
@ -277,43 +262,37 @@ private:
index_code, subtypep->width()),
new AstSel(varp->fileline(), above.m_chgRefp->cloneTree(true),
index_code, subtypep->width()));
toggleVarRecurse(subtypep, depth+1,
newent,
varp, chgVarp);
toggleVarRecurse(subtypep, depth + 1, newent, varp, chgVarp);
newent.cleanup();
}
}
else if (AstUnionDType* adtypep = VN_CAST(dtypep, UnionDType)) {
} else if (AstUnionDType* adtypep = VN_CAST(dtypep, UnionDType)) {
// Arbitrarily handle only the first member of the union
if (AstMemberDType* itemp = adtypep->membersp()) {
AstNodeDType* subtypep = itemp->subDTypep()->skipRefp();
ToggleEnt newent(above.m_comment + string(".") + itemp->name(),
above.m_varRefp->cloneTree(true),
above.m_chgRefp->cloneTree(true));
toggleVarRecurse(subtypep, depth+1,
newent,
varp, chgVarp);
toggleVarRecurse(subtypep, depth + 1, newent, varp, chgVarp);
newent.cleanup();
}
}
else {
} else {
dtypep->v3fatalSrc("Unexpected node data type in toggle coverage generation: "
<< dtypep->prettyTypeName());
}
}
// VISITORS - LINE COVERAGE
virtual void visit(AstIf* nodep) VL_OVERRIDE { // Note not AstNodeIf; other types don't get covered
virtual void
visit(AstIf* nodep) VL_OVERRIDE { // Note not AstNodeIf; other types don't get covered
UINFO(4, " IF: " << nodep << endl);
if (m_checkBlock) {
// An else-if. When we iterate the if, use "elsif" marking
bool elsif = (VN_IS(nodep->elsesp(), If)
&& !VN_CAST(nodep->elsesp(), If)->nextp());
bool elsif = (VN_IS(nodep->elsesp(), If) && !VN_CAST(nodep->elsesp(), If)->nextp());
if (elsif) VN_CAST(nodep->elsesp(), If)->user1(true);
//
iterateAndNextNull(nodep->ifsp());
if (m_checkBlock && !m_inModOff
&& nodep->fileline()->coverageOn() && v3Global.opt.coverageLine()) { // if a "if" branch didn't disable it
if (m_checkBlock && !m_inModOff && nodep->fileline()->coverageOn()
&& v3Global.opt.coverageLine()) { // if a "if" branch didn't disable it
UINFO(4, " COVER: " << nodep << endl);
if (nodep->user1()) {
nodep->addIfsp(newCoverInc(nodep->fileline(), "", "v_line", "elsif",
@ -327,13 +306,12 @@ private:
if (nodep->elsesp()) {
m_checkBlock = true;
iterateAndNextNull(nodep->elsesp());
if (m_checkBlock && !m_inModOff
&& nodep->fileline()->coverageOn() && v3Global.opt.coverageLine()) { // if a "else" branch didn't disable it
if (m_checkBlock && !m_inModOff && nodep->fileline()->coverageOn()
&& v3Global.opt.coverageLine()) { // if a "else" branch didn't disable it
UINFO(4, " COVER: " << nodep << endl);
if (!elsif) { // elsif done inside if()
nodep->addElsesp(newCoverInc(nodep->elsesp()->fileline(),
"", "v_line", "else",
traceNameForLine(nodep, "else")));
nodep->addElsesp(newCoverInc(nodep->elsesp()->fileline(), "", "v_line",
"else", traceNameForLine(nodep, "else")));
}
}
}
@ -342,8 +320,8 @@ private:
}
virtual void visit(AstCaseItem* nodep) VL_OVERRIDE {
UINFO(4, " CASEI: " << nodep << endl);
if (m_checkBlock && !m_inModOff
&& nodep->fileline()->coverageOn() && v3Global.opt.coverageLine()) {
if (m_checkBlock && !m_inModOff && nodep->fileline()->coverageOn()
&& v3Global.opt.coverageLine()) {
iterateAndNextNull(nodep->bodysp());
if (m_checkBlock) { // if the case body didn't disable it
UINFO(4, " COVER: " << nodep << endl);
@ -424,8 +402,6 @@ public:
void V3Coverage::coverage(AstNetlist* rootp) {
UINFO(2, __FUNCTION__ << ": " << endl);
{
CoverageVisitor visitor (rootp);
} // Destruct before checking
{ CoverageVisitor visitor(rootp); } // Destruct before checking
V3Global::dumpCheckGlobalTree("coverage", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -17,7 +17,6 @@
// If two COVERTOGGLEs have same VARSCOPE, combine them
//*************************************************************************
#include "config_build.h"
#include "verilatedos.h"
@ -88,7 +87,8 @@ private:
UINFO(8, " new " << removep->incp()->declp() << endl);
// Mark the found node as a duplicate of the first node
// (Not vice-versa as we have the iterator for the found node)
removep->unlinkFrBack(); VL_DO_DANGLING(pushDeletep(removep), removep);
removep->unlinkFrBack();
VL_DO_DANGLING(pushDeletep(removep), removep);
// Remove node from comparison so don't hit it again
hashed.erase(dupit);
++m_statToggleJoins;
@ -114,9 +114,7 @@ private:
public:
// CONSTRUCTORS
explicit CoverageJoinVisitor(AstNetlist* nodep) {
iterate(nodep);
}
explicit CoverageJoinVisitor(AstNetlist* nodep) { iterate(nodep); }
virtual ~CoverageJoinVisitor() {
V3Stats::addStat("Coverage, Toggle points joined", m_statToggleJoins);
}
@ -127,8 +125,6 @@ public:
void V3CoverageJoin::coverageJoin(AstNetlist* rootp) {
UINFO(2, __FUNCTION__ << ": " << endl);
{
CoverageJoinVisitor visitor (rootp);
} // Destruct before checking
{ CoverageJoinVisitor visitor(rootp); } // Destruct before checking
V3Global::dumpCheckGlobalTree("coveragejoin", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -69,8 +69,7 @@ private:
nodep->replaceWith(newp);
// Put assignment before the referencing statement
AstAssign* assp = new AstAssign(nodep->fileline(),
new AstVarRef(nodep->fileline(), varp, true),
nodep);
new AstVarRef(nodep->fileline(), varp, true), nodep);
AstNRelinker linker2;
m_stmtp->unlinkFrBack(&linker2);
assp->addNext(m_stmtp);
@ -110,8 +109,7 @@ private:
}
}
// Operators
virtual void visit(AstNodeTermop* nodep) VL_OVERRIDE {
}
virtual void visit(AstNodeTermop* nodep) VL_OVERRIDE {}
virtual void visit(AstNodeMath* nodep) VL_OVERRIDE {
// We have some operator defines that use 2 parens, so += 2.
m_depth += 2;
@ -119,8 +117,7 @@ private:
iterateChildren(nodep);
m_depth -= 2;
if (m_stmtp
&& (v3Global.opt.compLimitParens() >= 1) // Else compiler doesn't need it
if (m_stmtp && (v3Global.opt.compLimitParens() >= 1) // Else compiler doesn't need it
&& (m_maxdepth - m_depth) > v3Global.opt.compLimitParens()
&& !VN_IS(nodep->backp(), NodeStmt) // Not much point if we're about to use it
) {
@ -172,8 +169,6 @@ public:
void V3Depth::depthAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl);
{
DepthVisitor visitor (nodep);
} // Destruct before checking
{ DepthVisitor visitor(nodep); } // Destruct before checking
V3Global::dumpCheckGlobalTree("depth", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}

View File

@ -136,8 +136,6 @@ public:
void V3DepthBlock::depthBlockAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl);
{
DepthBlockVisitor visitor (nodep);
} // Destruct before checking
{ DepthBlockVisitor visitor(nodep); } // Destruct before checking
V3Global::dumpCheckGlobalTree("deepblock", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -119,8 +119,7 @@ private:
} else if (relativeRefOk && scopep == m_scopep) {
m_needThis = true;
return "this->";
} else if (relativeRefOk && scopep->aboveScopep()
&& scopep->aboveScopep()==m_scopep) {
} else if (relativeRefOk && scopep->aboveScopep() && scopep->aboveScopep() == m_scopep) {
// Reference to scope of cell directly under this module, can just "cell->"
string name = scopep->name();
string::size_type pos;
@ -179,8 +178,8 @@ private:
UASSERT_OBJ(funcp->scopep(), funcp, "Not scoped");
UINFO(6, " Wrapping " << name << " " << funcp << endl);
UINFO(6, " at " << newfuncp->argTypes()
<< " und " << funcp->argTypes() << endl);
UINFO(6,
" at " << newfuncp->argTypes() << " und " << funcp->argTypes() << endl);
funcp->declPrivate(true);
AstNode* argsp = NULL;
for (AstNode* stmtp = newfuncp->argsp(); stmtp; stmtp = stmtp->nextp()) {
@ -311,8 +310,6 @@ public:
void V3Descope::descopeAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl);
{
DescopeVisitor visitor (nodep);
} // Destruct before checking
{ DescopeVisitor visitor(nodep); } // Destruct before checking
V3Global::dumpCheckGlobalTree("descope", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -107,9 +107,7 @@ class EmitCInlines : EmitCBaseVisitor {
public:
explicit EmitCInlines(AstNetlist* nodep) {
iterate(nodep);
if (v3Global.needHInlines()) {
emitInt();
}
if (v3Global.needHInlines()) emitInt();
}
};

View File

@ -29,9 +29,8 @@ class V3EmitV {
public:
static void emitv();
static void verilogForTree(AstNode* nodep, std::ostream& os = std::cout);
static void verilogPrefixedTree(AstNode* nodep, std::ostream& os,
const string& prefix, int flWidth,
AstSenTree* domainp, bool user3mark);
static void verilogPrefixedTree(AstNode* nodep, std::ostream& os, const string& prefix,
int flWidth, AstSenTree* domainp, bool user3mark);
static void emitvFiles();
};

View File

@ -76,7 +76,7 @@ void V3Global::readFiles() {
}
void V3Global::dumpCheckGlobalTree(const string& stagename, int newNumber, bool doDump) {
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename(stagename + ".tree", newNumber),
false, doDump);
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename(stagename + ".tree", newNumber), false,
doDump);
if (v3Global.opt.stats()) V3Stats::statsStage(stagename);
}

View File

@ -17,10 +17,12 @@
#ifndef _V3GLOBAL_H_
#define _V3GLOBAL_H_ 1
// clang-format off
#include "config_build.h"
#ifndef HAVE_CONFIG_BUILD
# error "Something failed during ./configure as config_build.h is incomplete. Perhaps you used autoreconf, don't."
#endif
// clang-format on
#include "verilatedos.h"
@ -35,21 +37,19 @@ class AstNetlist;
//======================================================================
// Statics
//######################################################################
class VWidthMinUsage {
public:
enum en {
LINT_WIDTH,
MATCHES_WIDTH,
VERILOG_WIDTH
};
enum en { LINT_WIDTH, MATCHES_WIDTH, VERILOG_WIDTH };
enum en m_e;
inline VWidthMinUsage() : m_e(LINT_WIDTH) {}
inline VWidthMinUsage()
: m_e(LINT_WIDTH) {}
// cppcheck-suppress noExplicitConstructor
inline VWidthMinUsage(en _e) : m_e(_e) {}
explicit inline VWidthMinUsage(int _e) : m_e(static_cast<en>(_e)) {}
inline VWidthMinUsage(en _e)
: m_e(_e) {}
explicit inline VWidthMinUsage(int _e)
: m_e(static_cast<en>(_e)) {}
operator en() const { return m_e; }
};
inline bool operator==(const VWidthMinUsage& lhs, const VWidthMinUsage& rhs) {
@ -97,7 +97,10 @@ public:
, m_needTraceDumper(false)
, m_dpi(false) {}
AstNetlist* makeNetlist();
void boot() { UASSERT(!m_rootp, "call once"); m_rootp = makeNetlist(); }
void boot() {
UASSERT(!m_rootp, "call once");
m_rootp = makeNetlist();
}
void clear();
// ACCESSORS (general)
AstNetlist* rootp() const { return m_rootp; }
@ -107,7 +110,8 @@ public:
// METHODS
void readFiles();
void checkTree();
static void dumpCheckGlobalTree(const string& stagename, int newNumber=0, bool doDump=true);
static void dumpCheckGlobalTree(const string& stagename, int newNumber = 0,
bool doDump = true);
void assertDTypesResolved(bool flag) { m_assertDTypesResolved = flag; }
void widthMinUsage(const VWidthMinUsage& flag) { m_widthMinUsage = flag; }
bool constRemoveXs() const { return m_constRemoveXs; }
@ -115,7 +119,8 @@ public:
string debugFilename(const string& nameComment, int newNumber = 0) {
++m_debugFileNumber;
if (newNumber) m_debugFileNumber = newNumber;
char digits[100]; sprintf(digits, "%03d", m_debugFileNumber);
char digits[100];
sprintf(digits, "%03d", m_debugFileNumber);
return opt.makeDir() + "/" + opt.prefix() + "_" + digits + "_" + nameComment;
}
bool needC11() const { return m_needC11; }

View File

@ -47,16 +47,20 @@ typedef bool (*V3EdgeFuncP)(const V3GraphEdge* edgep);
class GraphWay {
public:
enum en { FORWARD=0,
enum en {
FORWARD = 0,
REVERSE = 1,
NUM_WAYS = 2 // NUM_WAYS is not an actual way, it's typically
// // an array dimension or loop bound.
};
enum en m_e;
inline GraphWay() : m_e(FORWARD) {}
inline GraphWay()
: m_e(FORWARD) {}
// cppcheck-suppress noExplicitConstructor
inline GraphWay(en _e) : m_e(_e) {}
explicit inline GraphWay(int _e) : m_e(static_cast<en>(_e)) {}
inline GraphWay(en _e)
: m_e(_e) {}
explicit inline GraphWay(int _e)
: m_e(static_cast<en>(_e)) {}
operator en() const { return m_e; }
const char* ascii() const {
static const char* const names[] = {"FORWARD", "REVERSE"};
@ -78,8 +82,10 @@ private:
// MEMBERS
V3List<V3GraphVertex*> m_vertices; // All vertices
static int s_debug;
protected:
friend class V3GraphVertex; friend class V3GraphEdge;
friend class V3GraphVertex;
friend class V3GraphEdge;
friend class GraphAcyc;
// METHODS
void acyclicDFS();
@ -91,6 +97,7 @@ protected:
void verticesUnlink() { m_vertices.reset(); }
// ACCESSORS
static int debug();
public:
V3Graph();
virtual ~V3Graph();
@ -181,8 +188,10 @@ public:
class V3GraphVertex {
// Vertices may be a 'gate'/wire statement OR a variable
protected:
friend class V3Graph; friend class V3GraphEdge;
friend class GraphAcyc; friend class GraphAlgRank;
friend class V3Graph;
friend class V3GraphEdge;
friend class GraphAcyc;
friend class GraphAlgRank;
V3ListEnt<V3GraphVertex*> m_vertices; // All vertices, linked list
V3List<V3GraphEdge*> m_outs; // Outbound edges,linked list
V3List<V3GraphEdge*> m_ins; // Inbound edges, linked list
@ -202,11 +211,13 @@ protected:
protected:
// CONSTRUCTORS
V3GraphVertex(V3Graph* graphp, const V3GraphVertex& old);
public:
explicit V3GraphVertex(V3Graph* graphp);
//! Clone copy constructor. Doesn't copy edges or user/userp.
virtual V3GraphVertex* clone(V3Graph* graphp) const {
return new V3GraphVertex(graphp, *this); }
return new V3GraphVertex(graphp, *this);
}
virtual ~V3GraphVertex() {}
void unlinkEdges(V3Graph* graphp);
void unlinkDelete(V3Graph* graphp);
@ -246,8 +257,7 @@ public:
bool outEmpty() const { return outBeginp() == NULL; }
bool outSize1() const;
uint32_t outHash() const;
V3GraphEdge* beginp(GraphWay way) const {
return way.forward() ? outBeginp() : inBeginp(); }
V3GraphEdge* beginp(GraphWay way) const { return way.forward() ? outBeginp() : inBeginp(); }
// METHODS
/// Error reporting
void v3errorEnd(std::ostringstream& str) const;
@ -269,8 +279,10 @@ public:
// ENUMS
enum Cutable { NOT_CUTABLE = false, CUTABLE = true }; // For passing to V3GraphEdge
protected:
friend class V3Graph; friend class V3GraphVertex;
friend class GraphAcyc; friend class GraphAcycEdge;
friend class V3Graph;
friend class V3GraphVertex;
friend class GraphAcyc;
friend class GraphAcycEdge;
V3ListEnt<V3GraphEdge*> m_outs; // Next Outbound edge for same vertex (linked list)
V3ListEnt<V3GraphEdge*> m_ins; // Next Inbound edge for same vertex (linked list)
//
@ -283,8 +295,8 @@ protected:
uint32_t m_user; // Marker for some algorithms
};
// METHODS
void init(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top,
int weight, bool cutable=false);
void init(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight,
bool cutable = false);
void cut() { m_weight = 0; } // 0 weight is same as disconnected
void outPushBack();
void inPushBack();
@ -294,15 +306,17 @@ protected:
const V3GraphEdge& old) {
init(graphp, fromp, top, old.m_weight, old.m_cutable);
}
public:
//! Add DAG from one node to the specified node
V3GraphEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top,
int weight, bool cutable=false) {
V3GraphEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight,
bool cutable = false) {
init(graphp, fromp, top, weight, cutable);
}
//! Clone copy constructor. Doesn't copy existing vertices or user/userp.
virtual V3GraphEdge* clone(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top) const {
return new V3GraphEdge(graphp, fromp, top, *this); }
return new V3GraphEdge(graphp, fromp, top, *this);
}
virtual ~V3GraphEdge() {}
// METHODS
virtual string name() const { return m_fromp->name() + "->" + m_top->name(); }
@ -334,8 +348,7 @@ public:
// ITERATORS
V3GraphEdge* outNextp() const { return m_outs.nextp(); }
V3GraphEdge* inNextp() const { return m_ins.nextp(); }
V3GraphEdge* nextp(GraphWay way) const {
return way.forward() ? outNextp() : inNextp(); }
V3GraphEdge* nextp(GraphWay way) const { return way.forward() ? outNextp() : inNextp(); }
};
//============================================================================

View File

@ -32,8 +32,8 @@
DfaVertex* DfaGraph::findStart() {
DfaVertex* startp = NULL;
for (V3GraphVertex* vertexp = this->verticesBeginp();
vertexp; vertexp=vertexp->verticesNextp()) {
for (V3GraphVertex* vertexp = this->verticesBeginp(); vertexp;
vertexp = vertexp->verticesNextp()) {
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
if (vvertexp->start()) {
UASSERT_OBJ(!startp, vertexp, "Multiple start points in NFA graph");
@ -95,8 +95,16 @@ private:
// Hashing
static uint32_t hashVertex(V3GraphVertex* vertexp) {
union { void* up; struct {uint32_t upper; uint32_t lower;} l;} u;
u.l.upper = 0; u.l.lower = 0; u.up = vertexp;
union {
void* up;
struct {
uint32_t upper;
uint32_t lower;
} l;
} u;
u.l.upper = 0;
u.l.lower = 0;
u.up = vertexp;
return u.l.upper ^ u.l.lower;
}
@ -108,8 +116,8 @@ private:
uint32_t hash = 0;
// Foreach NFA state (this DFA state was formed from)
if (debug()) nextStep();
for (V3GraphEdge* dfaEdgep = dfaStatep->outBeginp();
dfaEdgep; dfaEdgep=dfaEdgep->outNextp()) {
for (V3GraphEdge* dfaEdgep = dfaStatep->outBeginp(); dfaEdgep;
dfaEdgep = dfaEdgep->outNextp()) {
if (nfaState(dfaEdgep->top())) {
DfaVertex* nfaStatep = static_cast<DfaVertex*>(dfaEdgep->top());
hash ^= hashVertex(nfaStatep);
@ -126,8 +134,8 @@ private:
uint32_t hashDfaOrigins(const DfaStates& nfasWithInput) {
// Find the NFA states this dfa came from,
uint32_t hash = 0;
for (DfaStates::const_iterator nfaIt=nfasWithInput.begin();
nfaIt!=nfasWithInput.end(); ++nfaIt) {
for (DfaStates::const_iterator nfaIt = nfasWithInput.begin(); nfaIt != nfasWithInput.end();
++nfaIt) {
DfaVertex* nfaStatep = *nfaIt;
hash ^= hashVertex(nfaStatep);
}
@ -140,8 +148,8 @@ private:
nextStep();
// Mark all input vertexes
int num1s = 0;
for (DfaStates::const_iterator nfaIt=nfasWithInput.begin();
nfaIt!=nfasWithInput.end(); ++nfaIt) {
for (DfaStates::const_iterator nfaIt = nfasWithInput.begin(); nfaIt != nfasWithInput.end();
++nfaIt) {
DfaVertex* nfaStatep = *nfaIt;
nfaStatep->user(m_step);
num1s++;
@ -151,7 +159,8 @@ private:
// Check comparison; must all be marked
// (Check all in dfa2p were in dfa1p)
int num2s = 0;
for (V3GraphEdge* dfaEdgep = dfa2p->outBeginp(); dfaEdgep; dfaEdgep=dfaEdgep->outNextp()) {
for (V3GraphEdge* dfaEdgep = dfa2p->outBeginp(); dfaEdgep;
dfaEdgep = dfaEdgep->outNextp()) {
if (nfaState(dfaEdgep->top())) {
if (dfaEdgep->top()->user() != m_step) return false;
num2s++;
@ -185,21 +194,20 @@ private:
return NULL; // No match
}
void findNfasWithInput(DfaVertex* dfaStatep, DfaInput input,
DfaStates& nfasWithInput) {
void findNfasWithInput(DfaVertex* dfaStatep, DfaInput input, DfaStates& nfasWithInput) {
// Return all NFA states, with the given input transition from
// the nfa states a given dfa state was constructed from.
nextStep();
nfasWithInput.clear(); // NFAs with given input
// Foreach NFA state (this DFA state was formed from)
for (V3GraphEdge* dfaEdgep = dfaStatep->outBeginp();
dfaEdgep; dfaEdgep=dfaEdgep->outNextp()) {
for (V3GraphEdge* dfaEdgep = dfaStatep->outBeginp(); dfaEdgep;
dfaEdgep = dfaEdgep->outNextp()) {
if (nfaState(dfaEdgep->top())) {
DfaVertex* nfaStatep = static_cast<DfaVertex*>(dfaEdgep->top());
// Foreach input transition (on this nfaStatep)
for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp();
nfaEdgep; nfaEdgep=nfaEdgep->outNextp()) {
for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp(); nfaEdgep;
nfaEdgep = nfaEdgep->outNextp()) {
DfaEdge* cNfaEdgep = static_cast<DfaEdge*>(nfaEdgep);
if (cNfaEdgep->input().toNodep() == input.toNodep()) {
DfaVertex* nextStatep = static_cast<DfaVertex*>(cNfaEdgep->top());
@ -219,11 +227,12 @@ private:
DfaStates nfasTodo = nfasWithInput;
nfasWithInput.clear(); // Now the completed list
while (!nfasTodo.empty()) {
DfaVertex* nfaStatep = nfasTodo.front(); nfasTodo.pop_front();
DfaVertex* nfaStatep = nfasTodo.front();
nfasTodo.pop_front();
nfasWithInput.push_back(nfaStatep);
// Foreach epsilon-reachable (on this nfaStatep)
for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp();
nfaEdgep; nfaEdgep=nfaEdgep->outNextp()) {
for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp(); nfaEdgep;
nfaEdgep = nfaEdgep->outNextp()) {
DfaEdge* cNfaEdgep = static_cast<DfaEdge*>(nfaEdgep);
if (cNfaEdgep->epsilon()) {
DfaVertex* nextStatep = static_cast<DfaVertex*>(cNfaEdgep->top());
@ -259,23 +268,24 @@ private:
UINFO(5, "Starting state conversion...\n");
// Form DFA starting state from epsilon closure of NFA start
nextStep();
DfaStates workps; workps.push_back(nfaStartp);
DfaStates workps;
workps.push_back(nfaStartp);
while (!workps.empty()) { // While work
DfaVertex* nfaStatep = workps.back(); workps.pop_back();
DfaVertex* nfaStatep = workps.back();
workps.pop_back();
// UINFO(9," Processing "<<nfaStatep<<endl);
nfaStatep->user(m_step); // Mark as processed
// Add a edge so we can find NFAs from a given DFA.
// The NFA will never see this edge, because we only look at TO edges.
new DfaEdge(graphp(), dfaStartp, nfaStatep, DfaEdge::NA());
// Find epsilon closure of this nfa node, and destinations to work list
for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp();
nfaEdgep; nfaEdgep=nfaEdgep->outNextp()) {
for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp(); nfaEdgep;
nfaEdgep = nfaEdgep->outNextp()) {
DfaEdge* cNfaEdgep = static_cast<DfaEdge*>(nfaEdgep);
DfaVertex* ecNfaStatep = static_cast<DfaVertex*>(nfaEdgep->top());
// UINFO(9," Consider "<<nfaEdgep->top()<<" EP "<<cNfaEdgep->epsilon()<<endl);
if (cNfaEdgep->epsilon()
&& unseenNfaThisStep(ecNfaStatep)) { // Not processed?
if (cNfaEdgep->epsilon() && unseenNfaThisStep(ecNfaStatep)) { // Not processed?
workps.push_back(ecNfaStatep);
}
}
@ -286,25 +296,27 @@ private:
int i = 0;
UINFO(5, "Main state conversion...\n");
while (!dfaUnprocps.empty()) {
DfaVertex* dfaStatep = dfaUnprocps.back(); dfaUnprocps.pop_back();
DfaVertex* dfaStatep = dfaUnprocps.back();
dfaUnprocps.pop_back();
UINFO(9, " On dfaState " << dfaStatep << endl);
// From this dfaState, what corresponding nfaStates have what inputs?
std::set<int> inputs;
// Foreach NFA state (this DFA state was formed from)
for (V3GraphEdge* dfaEdgep = dfaStatep->outBeginp();
dfaEdgep; dfaEdgep=dfaEdgep->outNextp()) {
for (V3GraphEdge* dfaEdgep = dfaStatep->outBeginp(); dfaEdgep;
dfaEdgep = dfaEdgep->outNextp()) {
if (nfaState(dfaEdgep->top())) {
DfaVertex* nfaStatep = static_cast<DfaVertex*>(dfaEdgep->top());
// Foreach input on this nfaStatep
for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp();
nfaEdgep; nfaEdgep=nfaEdgep->outNextp()) {
for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp(); nfaEdgep;
nfaEdgep = nfaEdgep->outNextp()) {
DfaEdge* cNfaEdgep = static_cast<DfaEdge*>(nfaEdgep);
if (!cNfaEdgep->epsilon()) {
if (inputs.find(cNfaEdgep->input().toInt()) == inputs.end()) {
inputs.insert(cNfaEdgep->input().toInt());
UINFO(9, " Input to " << dfaStatep << " is "
<<(cNfaEdgep->input().toInt())<<" via "<<nfaStatep<<endl);
<< (cNfaEdgep->input().toInt()) << " via "
<< nfaStatep << endl);
}
}
}
@ -312,7 +324,8 @@ private:
}
// Foreach input state (NFA inputs of this DFA state)
for (std::set<int>::const_iterator inIt=inputs.begin(); inIt!=inputs.end(); ++inIt) {
for (std::set<int>::const_iterator inIt = inputs.begin(); inIt != inputs.end();
++inIt) {
DfaInput input = *inIt;
UINFO(9, " ===" << ++i << "=======================\n");
UINFO(9, " On input " << cvtToHex(input.toNodep()) << endl);
@ -347,11 +360,10 @@ private:
// Remove old NFA states
UINFO(5, "Removing NFA states...\n");
if (debug() >= 6) m_graphp->dumpDotFilePrefixed("dfa_withnfa");
for (V3GraphVertex* nextp,*vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=nextp) {
for (V3GraphVertex *nextp, *vertexp = m_graphp->verticesBeginp(); vertexp;
vertexp = nextp) {
nextp = vertexp->verticesNextp();
if (nfaState(vertexp)) {
VL_DO_DANGLING(vertexp->unlinkDelete(m_graphp), vertexp);
}
if (nfaState(vertexp)) VL_DO_DANGLING(vertexp->unlinkDelete(m_graphp), vertexp);
}
UINFO(5, "Done.\n");
@ -367,9 +379,7 @@ public:
~GraphNfaToDfa() {}
};
void DfaGraph::nfaToDfa() {
GraphNfaToDfa(this, &V3GraphEdge::followAlwaysTrue);
}
void DfaGraph::nfaToDfa() { GraphNfaToDfa(this, &V3GraphEdge::followAlwaysTrue); }
//######################################################################
//######################################################################
@ -399,8 +409,8 @@ private:
void optimize_accepting_out() {
// Delete outbound edges from accepting states
// (As once we've accepted, we no longer care about anything else.)
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp();
vertexp; vertexp=vertexp->verticesNextp()) {
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp;
vertexp = vertexp->verticesNextp()) {
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
if (vvertexp->accepting()) {
for (V3GraphEdge *nextp, *edgep = vertexp->outBeginp(); edgep; edgep = nextp) {
@ -421,11 +431,13 @@ private:
m_graphp->userClearVertices();
DfaVertex* startp = graphp()->findStart();
std::stack<V3GraphVertex*> workps; workps.push(startp);
std::stack<V3GraphVertex*> workps;
workps.push(startp);
// Mark all nodes connected to start
while (!workps.empty()) {
V3GraphVertex* vertexp = workps.top(); workps.pop();
V3GraphVertex* vertexp = workps.top();
workps.pop();
vertexp->user(2); // Processed
// Add nodes from here to the work list
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
@ -438,11 +450,10 @@ private:
}
// Delete all nodes not connected
for (V3GraphVertex* nextp,*vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=nextp) {
for (V3GraphVertex *nextp, *vertexp = m_graphp->verticesBeginp(); vertexp;
vertexp = nextp) {
nextp = vertexp->verticesNextp();
if (!vertexp->user()) {
VL_DO_DANGLING(vertexp->unlinkDelete(m_graphp), vertexp);
}
if (!vertexp->user()) { VL_DO_DANGLING(vertexp->unlinkDelete(m_graphp), vertexp); }
}
}
@ -457,8 +468,8 @@ private:
// Find all dead vertexes
std::stack<DfaVertex*> workps;
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp();
vertexp; vertexp=vertexp->verticesNextp()) {
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp;
vertexp = vertexp->verticesNextp()) {
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
workps.push(vvertexp);
vertexp->user(1);
@ -470,14 +481,14 @@ private:
// While deadness... Delete and find new dead nodes.
while (!workps.empty()) {
DfaVertex* vertexp = workps.top(); workps.pop();
DfaVertex* vertexp = workps.top();
workps.pop();
vertexp->user(0);
if (isDead(vertexp)) {
// Add nodes that go here to the work list
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
DfaVertex* fromvertexp = static_cast<DfaVertex*>(edgep->fromp());
if (fromvertexp != vertexp
&& !fromvertexp->user()) {
if (fromvertexp != vertexp && !fromvertexp->user()) {
workps.push(fromvertexp);
fromvertexp->user(1);
}
@ -487,6 +498,7 @@ private:
}
}
}
public:
DfaGraphReduce(V3Graph* graphp, V3EdgeFuncP edgeFuncp)
: GraphAlg<>(graphp, edgeFuncp) {
@ -501,9 +513,7 @@ public:
~DfaGraphReduce() {}
};
void DfaGraph::dfaReduce() {
DfaGraphReduce(this, &V3GraphEdge::followAlwaysTrue);
}
void DfaGraph::dfaReduce() { DfaGraphReduce(this, &V3GraphEdge::followAlwaysTrue); }
//######################################################################
//######################################################################
@ -537,8 +547,8 @@ private:
void add_complement_edges() {
// Find accepting vertex
DfaVertex* acceptp = NULL;
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp();
vertexp; vertexp=vertexp->verticesNextp()) {
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp;
vertexp = vertexp->verticesNextp()) {
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
if (vvertexp->accepting()) {
acceptp = vvertexp;
@ -549,8 +559,8 @@ private:
if (!acceptp) v3fatalSrc("No accepting vertex in DFA");
// Remap edges
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp();
vertexp; vertexp=vertexp->verticesNextp()) {
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp;
vertexp = vertexp->verticesNextp()) {
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
// UINFO(9, " on vertex "<<vvertexp->name()<<endl);
if (!vvertexp->accepting() && vvertexp != m_tempNewerReject) {
@ -568,7 +578,8 @@ private:
// NOT of all values goes to accept
// We make a edge for each value to OR, IE
// 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);
newp->complement(!newp->complement());
newp->user(1);
@ -579,6 +590,7 @@ private:
}
}
}
public:
DfaGraphComplement(V3Graph* dfagraphp, V3EdgeFuncP edgeFuncp)
: GraphAlg<>(dfagraphp, edgeFuncp) {
@ -598,6 +610,4 @@ public:
VL_UNCOPYABLE(DfaGraphComplement);
};
void DfaGraph::dfaComplement() {
DfaGraphComplement(this, &V3GraphEdge::followAlwaysTrue);
}
void DfaGraph::dfaComplement() { DfaGraphComplement(this, &V3GraphEdge::followAlwaysTrue); }

View File

@ -87,10 +87,12 @@ public:
// CONSTRUCTORS
explicit DfaVertex(DfaGraph* graphp, bool start = false, bool accepting = false)
: V3GraphVertex(graphp)
, m_start(start), m_accepting(accepting) {}
, m_start(start)
, m_accepting(accepting) {}
using V3GraphVertex::clone; // We are overriding, not overloading clone(V3Graph*)
virtual DfaVertex* clone(DfaGraph* graphp) {
return new DfaVertex(graphp, start(), accepting()); }
return new DfaVertex(graphp, start(), accepting());
}
virtual ~DfaVertex() {}
// ACCESSORS
virtual string dotShape() const { return (accepting() ? "doublecircle" : ""); }
@ -118,21 +120,21 @@ public:
// CONSTRUCTORS
DfaEdge(DfaGraph* graphp, DfaVertex* fromp, DfaVertex* top, const DfaInput& input)
: V3GraphEdge(graphp, fromp, top, 1)
, m_input(input), m_complement(false) {}
, m_input(input)
, m_complement(false) {}
DfaEdge(DfaGraph* graphp, DfaVertex* fromp, DfaVertex* top, const DfaEdge* copyfrom)
: V3GraphEdge(graphp, fromp, top, copyfrom->weight())
, m_input(copyfrom->input()), m_complement(copyfrom->complement()) {}
, m_input(copyfrom->input())
, m_complement(copyfrom->complement()) {}
virtual ~DfaEdge() {}
// METHODS
virtual string dotColor() const {
return (na() ? "yellow"
: epsilon() ? "green"
: "black"); }
virtual string dotColor() const { return (na() ? "yellow" : epsilon() ? "green" : "black"); }
virtual string dotLabel() const {
return (na() ? ""
: epsilon() ? "e"
: complement() ? ("not " + cvtToStr(input().toInt()))
: cvtToStr(input().toInt())); }
: cvtToStr(input().toInt()));
}
virtual string dotStyle() const { return (na() || cutable()) ? "dashed" : ""; }
bool epsilon() const { return input().toInt() == EPSILON().toInt(); }
bool na() const { return input().toInt() == NA().toInt(); }

View File

@ -41,7 +41,8 @@ struct GraphPCNode {
vluint64_t m_seenAtGeneration;
// CONSTRUCTORS
GraphPCNode() : m_seenAtGeneration(0) {
GraphPCNode()
: m_seenAtGeneration(0) {
for (int w = 0; w < GraphWay::NUM_WAYS; w++) m_cp[w] = 0;
}
~GraphPCNode() {}
@ -53,8 +54,7 @@ struct GraphPCNode {
GraphPathChecker::GraphPathChecker(const V3Graph* graphp, V3EdgeFuncP edgeFuncp)
: GraphAlg<const V3Graph>(graphp, edgeFuncp)
, m_generation(0) {
for (V3GraphVertex* vxp = graphp->verticesBeginp();
vxp; vxp = vxp->verticesNextp()) {
for (V3GraphVertex* vxp = graphp->verticesBeginp(); vxp; vxp = vxp->verticesNextp()) {
// Setup tracking structure for each node. If delete a vertex
// there would be a leak, but ok as accept only const V3Graph*'s.
vxp->userp(new GraphPCNode);
@ -66,8 +66,7 @@ GraphPathChecker::GraphPathChecker(const V3Graph* graphp, V3EdgeFuncP edgeFuncp)
GraphPathChecker::~GraphPathChecker() {
// Free every GraphPCNode
for (V3GraphVertex* vxp = m_graphp->verticesBeginp();
vxp; vxp = vxp->verticesNextp()) {
for (V3GraphVertex* vxp = m_graphp->verticesBeginp(); vxp; vxp = vxp->verticesNextp()) {
GraphPCNode* nodep = static_cast<GraphPCNode*>(vxp->userp());
VL_DO_DANGLING(delete nodep, nodep);
vxp->userp(NULL);
@ -79,8 +78,7 @@ void GraphPathChecker::initHalfCriticalPaths(GraphWay way, bool checkOnly) {
GraphWay rev = way.invert();
while (const V3GraphVertex* vertexp = order.nextp()) {
unsigned critPathCost = 0;
for (V3GraphEdge* edgep = vertexp->beginp(rev);
edgep; edgep = edgep->nextp(rev)) {
for (V3GraphEdge* edgep = vertexp->beginp(rev); edgep; edgep = edgep->nextp(rev)) {
if (!m_edgeFuncp(edgep)) continue;
V3GraphVertex* wrelativep = edgep->furtherp(rev);
@ -90,16 +88,15 @@ void GraphPathChecker::initHalfCriticalPaths(GraphWay way, bool checkOnly) {
GraphPCNode* ourUserp = static_cast<GraphPCNode*>(vertexp->userp());
if (checkOnly) {
UASSERT_OBJ(ourUserp->m_cp[way] == critPathCost,
vertexp, "Validation of critical paths failed");
UASSERT_OBJ(ourUserp->m_cp[way] == critPathCost, vertexp,
"Validation of critical paths failed");
} else {
ourUserp->m_cp[way] = critPathCost;
}
}
}
bool GraphPathChecker::pathExistsInternal(const V3GraphVertex* ap,
const V3GraphVertex* bp,
bool GraphPathChecker::pathExistsInternal(const V3GraphVertex* ap, const V3GraphVertex* bp,
unsigned* costp) {
GraphPCNode* auserp = static_cast<GraphPCNode*>(ap->userp());
GraphPCNode* buserp = static_cast<GraphPCNode*>(bp->userp());
@ -118,31 +115,23 @@ bool GraphPathChecker::pathExistsInternal(const V3GraphVertex* ap,
if (ap == bp) return true;
// Rule out an a->b path based on their CPs
if (auserp->m_cp[GraphWay::REVERSE] < buserp->m_cp[GraphWay::REVERSE] + 1) {
return false;
}
if (buserp->m_cp[GraphWay::FORWARD] < auserp->m_cp[GraphWay::FORWARD] + 1) {
return false;
}
if (auserp->m_cp[GraphWay::REVERSE] < buserp->m_cp[GraphWay::REVERSE] + 1) return false;
if (buserp->m_cp[GraphWay::FORWARD] < auserp->m_cp[GraphWay::FORWARD] + 1) return false;
// Slow path; visit some extended family
bool foundPath = false;
for (V3GraphEdge* edgep = ap->outBeginp();
edgep && !foundPath; edgep = edgep->outNextp()) {
for (V3GraphEdge* edgep = ap->outBeginp(); edgep && !foundPath; edgep = edgep->outNextp()) {
if (!m_edgeFuncp(edgep)) continue;
unsigned childCost;
if (pathExistsInternal(edgep->top(), bp, &childCost)) {
foundPath = true;
}
if (pathExistsInternal(edgep->top(), bp, &childCost)) foundPath = true;
if (costp) *costp += childCost;
}
return foundPath;
}
bool GraphPathChecker::pathExistsFrom(const V3GraphVertex* fromp,
const V3GraphVertex* top) {
bool GraphPathChecker::pathExistsFrom(const V3GraphVertex* fromp, const V3GraphVertex* top) {
incGeneration();
return pathExistsInternal(fromp, top);
}
@ -151,12 +140,10 @@ bool GraphPathChecker::isTransitiveEdge(const V3GraphEdge* edgep) {
const V3GraphVertex* fromp = edgep->fromp();
const V3GraphVertex* top = edgep->top();
incGeneration();
for (const V3GraphEdge* fromOutp = fromp->outBeginp();
fromOutp; fromOutp = fromOutp->outNextp()) {
for (const V3GraphEdge* fromOutp = fromp->outBeginp(); fromOutp;
fromOutp = fromOutp->outNextp()) {
if (fromOutp == edgep) continue;
if (pathExistsInternal(fromOutp->top(), top)) {
return true;
}
if (pathExistsInternal(fromOutp->top(), top)) return true;
}
return false;
}

View File

@ -75,6 +75,7 @@ private:
if (m_lessThan.operator()(b.vertexp(), a.vertexp())) return false;
return a.m_pos < b.m_pos;
}
private:
VL_UNCOPYABLE(VxHolderCmp);
};
@ -91,8 +92,7 @@ private:
public:
// CONSTRUCTORS
explicit GraphStream(const V3Graph* graphp,
GraphWay way = GraphWay::FORWARD,
explicit GraphStream(const V3Graph* graphp, GraphWay way = GraphWay::FORWARD,
const T_Compare& lessThan = T_Compare())
// NOTE: Perhaps REVERSE way should also reverse the sense of the
// lessThan function? For now the only usage of REVERSE is not
@ -102,8 +102,8 @@ public:
, m_last(m_readyVertices.end())
, m_way(way) {
uint32_t pos = 0;
for (const V3GraphVertex* vxp = graphp->verticesBeginp();
vxp; vxp=vxp->verticesNextp()) {
for (const V3GraphVertex* vxp = graphp->verticesBeginp(); vxp;
vxp = vxp->verticesNextp()) {
// Every vertex initially is waiting, or ready.
if (way == GraphWay::FORWARD) {
if (vxp->inEmpty()) {
@ -111,8 +111,7 @@ public:
m_readyVertices.insert(newVx);
} else {
uint32_t depCount = 0;
for (V3GraphEdge* depp = vxp->inBeginp();
depp; depp = depp->inNextp()) {
for (V3GraphEdge* depp = vxp->inBeginp(); depp; depp = depp->inNextp()) {
depCount++;
}
VxHolder newVx(vxp, pos++, depCount);
@ -124,8 +123,7 @@ public:
m_readyVertices.insert(newVx);
} else {
uint32_t depCount = 0;
for (V3GraphEdge* depp = vxp->outBeginp();
depp; depp = depp->outNextp()) {
for (V3GraphEdge* depp = vxp->outBeginp(); depp; depp = depp->outNextp()) {
depCount++;
}
VxHolder newVx(vxp, pos++, depCount);
@ -177,9 +175,7 @@ public:
// Wrap curIt. Expect to wrap, and make another pass, to find
// newly-ready elements that could have appeared ahead of the
// m_last iterator
if (curIt == m_readyVertices.end()) {
curIt = m_readyVertices.begin();
}
if (curIt == m_readyVertices.end()) { curIt = m_readyVertices.begin(); }
}
if (curIt != m_readyVertices.end()) {
@ -198,12 +194,10 @@ public:
private:
void unblockDeps(const V3GraphVertex* vertexp) {
if (m_way == GraphWay::FORWARD) {
for (V3GraphEdge* edgep = vertexp->outBeginp();
edgep; edgep=edgep->outNextp()) {
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep = edgep->outNextp()) {
V3GraphVertex* toVertexp = edgep->top();
typename WaitingVertices::iterator it =
m_waitingVertices.find(toVertexp);
typename WaitingVertices::iterator it = m_waitingVertices.find(toVertexp);
UASSERT_OBJ(it != m_waitingVertices.end(), toVertexp,
"Found edge into vertex not in waiting list.");
if (it->second.unblock()) {
@ -212,12 +206,10 @@ private:
}
}
} else {
for (V3GraphEdge* edgep = vertexp->inBeginp();
edgep; edgep=edgep->inNextp()) {
for (V3GraphEdge* edgep = vertexp->inBeginp(); edgep; edgep = edgep->inNextp()) {
V3GraphVertex* fromVertexp = edgep->fromp();
typename WaitingVertices::iterator it =
m_waitingVertices.find(fromVertexp);
typename WaitingVertices::iterator it = m_waitingVertices.find(fromVertexp);
UASSERT_OBJ(it != m_waitingVertices.end(), fromVertexp,
"Found edge into vertex not in waiting list.");
if (it->second.unblock()) {

View File

@ -52,6 +52,7 @@ class V3Hashed : public VHashedBase {
public:
typedef std::multimap<V3Hash, AstNode*> HashMmap;
typedef HashMmap::iterator iterator;
private:
// MEMBERS
HashMmap m_hashMmap; // hashvalue -> nodes with that hash
@ -67,9 +68,13 @@ public:
iterator end() { return m_hashMmap.end(); }
// METHODS
void clear() { m_hashMmap.clear(); AstNode::user4ClearTree(); }
void clear() {
m_hashMmap.clear();
AstNode::user4ClearTree();
}
void check(); // Check assertions on structure
iterator hashAndInsert(AstNode* nodep); // Hash the node, and insert into map. Return iterator to inserted
// Hash the node, and insert into map. Return iterator to inserted
iterator hashAndInsert(AstNode* nodep);
void hash(AstNode* nodep); // Only hash the node
bool sameNodes(AstNode* node1p, AstNode* node2p); // After hashing, and tell if identical
void erase(iterator it); // Remove node from structures

View File

@ -29,8 +29,8 @@ class V3Inst {
public:
static void instAll(AstNetlist* nodep);
static void dearrayAll(AstNetlist* nodep);
static AstAssignW* pinReconnectSimple(AstPin* pinp, AstCell* cellp,
bool forTristate, bool alwaysCvt=false);
static AstAssignW* pinReconnectSimple(AstPin* pinp, AstCell* cellp, bool forTristate,
bool alwaysCvt = false);
static void checkOutputShort(AstPin* nodep);
};

View File

@ -52,15 +52,16 @@ private:
uint32_t m_savedCount;
AstNode* m_nodep;
InstrCountVisitor* m_visitor;
public:
// CONSTRUCTORS
VisitBase(InstrCountVisitor* visitor, AstNode* nodep)
: m_nodep(nodep), m_visitor(visitor) {
: m_nodep(nodep)
, m_visitor(visitor) {
m_savedCount = m_visitor->startVisitBase(nodep);
}
~VisitBase() {
m_visitor->endVisitBase(m_savedCount, m_nodep);
}
~VisitBase() { m_visitor->endVisitBase(m_savedCount, m_nodep); }
private:
VL_UNCOPYABLE(VisitBase);
};
@ -68,13 +69,12 @@ private:
public:
// CONSTRUCTORS
InstrCountVisitor(AstNode* nodep, bool assertNoDups, std::ostream* osp)
: m_instrCount(0),
m_startNodep(nodep),
m_tracingCall(false),
m_inCFunc(false),
m_assertNoDups(assertNoDups),
m_osp(osp)
{
: m_instrCount(0)
, m_startNodep(nodep)
, m_tracingCall(false)
, m_inCFunc(false)
, m_assertNoDups(assertNoDups)
, m_osp(osp) {
if (nodep) iterate(nodep);
}
virtual ~InstrCountVisitor() {}
@ -110,8 +110,7 @@ private:
return savedCount;
}
void endVisitBase(uint32_t savedCount, AstNode* nodep) {
UINFO(8, "cost "<<std::setw(6)<<std::left<<m_instrCount
<<" "<<nodep<<endl);
UINFO(8, "cost " << std::setw(6) << std::left << m_instrCount << " " << nodep << endl);
markCost(nodep);
m_instrCount += savedCount;
}
@ -275,7 +274,8 @@ private:
public:
// CONSTRUCTORS
InstrCountDumpVisitor(AstNode* nodep, std::ostream* osp)
: m_osp(osp), m_depth(0) {
: m_osp(osp)
, m_depth(0) {
// No check for NULL output, so...
UASSERT_OBJ(osp, nodep, "Don't call if not dumping");
if (nodep) iterate(nodep);
@ -288,8 +288,7 @@ private:
virtual void visit(AstNode* nodep) VL_OVERRIDE {
++m_depth;
if (unsigned costPlus1 = nodep->user4()) {
*m_osp <<" "<<indent()
<<"cost "<<std::setw(6)<<std::left<<(costPlus1-1)
*m_osp << " " << indent() << "cost " << std::setw(6) << std::left << (costPlus1 - 1)
<< " " << nodep << endl;
iterateChildren(nodep);
}

View File

@ -43,30 +43,26 @@ public:
_ENUM_END
};
const char* ascii() const {
const char* const names[] = {
// These must match the `begin_keywords values.
" ERROR",
"1364-1995",
"1364-2001",
"1364-2005",
"1800-2005",
"1800-2009",
"1800-2012",
"1800-2017"
};
const char* const names[] = {// These must match the `begin_keywords values.
" ERROR", "1364-1995", "1364-2001", "1364-2005",
"1800-2005", "1800-2009", "1800-2012", "1800-2017"};
return names[m_e];
}
static V3LangCode mostRecent() { return V3LangCode(L1800_2017); }
bool systemVerilog() const { return m_e == L1800_2005 || m_e == L1800_2009
|| m_e == L1800_2012 || m_e == L1800_2017; }
bool systemVerilog() const {
return m_e == L1800_2005 || m_e == L1800_2009 || m_e == L1800_2012 || m_e == L1800_2017;
}
bool legal() const { return m_e != L_ERROR; }
//
enum en m_e;
inline V3LangCode() : m_e(L_ERROR) {}
inline V3LangCode()
: m_e(L_ERROR) {}
// cppcheck-suppress noExplicitConstructor
inline V3LangCode(en _e) : m_e(_e) {}
inline V3LangCode(en _e)
: m_e(_e) {}
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; }
};

View File

@ -31,11 +31,10 @@ class V3LanguageWords {
struct Singleton {
KeywordMap s_kwdMap; // List of keywords, and what language applies
Singleton() { init(); }
void addKwd(const string& kwd, const string& why) {
s_kwdMap.insert(make_pair(kwd, why));
}
void addKwd(const string& kwd, const string& why) { s_kwdMap.insert(make_pair(kwd, why)); }
void init();
};
public:
typedef KeywordMap::const_iterator const_iterator;
// METHODS
@ -46,12 +45,17 @@ class V3LanguageWords {
if (it == s().s_kwdMap.end()) return "";
return it->second;
}
private:
static Singleton& s() { static Singleton s_s; return s_s; }
static Singleton& s() {
static Singleton s_s;
return s_s;
}
};
inline void V3LanguageWords::Singleton::init() {
// C++ keywords
// clang-format off
addKwd("NULL", "C++ common word");
addKwd("abort", "C++ common word");
addKwd("alignas", "C++11 keyword");
@ -242,6 +246,7 @@ inline void V3LanguageWords::Singleton::init() {
addKwd("`undefineall", "Verilog preprocessor directive");
addKwd("`verilator_config", "Verilator preprocessor directive");
addKwd("`verilog", "Verilator preprocessor directive");
// clang-format on
}
#endif // Guard

View File

@ -31,6 +31,7 @@ class V3LinkDot {
private:
static int debug();
static void linkDotGuts(AstNetlist* rootp, VLinkDotStep step);
public:
static void linkDotPrimary(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl);

View File

@ -48,14 +48,11 @@ private:
// Result handing
virtual void visit(AstNodeVarRef* nodep) VL_OVERRIDE {
// VarRef: LValue its reference
if (m_setRefLvalue) {
nodep->lvalue(true);
}
if (m_setRefLvalue) nodep->lvalue(true);
if (nodep->varp()) {
if (nodep->lvalue() && !m_ftaskp
&& nodep->varp()->isReadOnly()) {
nodep->v3warn(ASSIGNIN, "Assigning to input/const variable: "
<<nodep->prettyNameQ());
if (nodep->lvalue() && !m_ftaskp && nodep->varp()->isReadOnly()) {
nodep->v3warn(ASSIGNIN,
"Assigning to input/const variable: " << nodep->prettyNameQ());
}
}
iterateChildren(nodep);
@ -292,9 +289,7 @@ public:
void V3LinkLValue::linkLValue(AstNetlist* nodep) {
UINFO(4, __FUNCTION__ << ": " << endl);
{
LinkLValueVisitor visitor(nodep, false);
} // Destruct before checking
{ LinkLValueVisitor visitor(nodep, false); } // Destruct before checking
V3Global::dumpCheckGlobalTree("linklvalue", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
void V3LinkLValue::linkLValueSet(AstNode* nodep) {

View File

@ -27,29 +27,32 @@
template <class T> class V3List;
template <class T> class V3ListEnt;
template <class T>
class V3List {
template <class T> class V3List {
// List container for linked list of elements of type *T (T is a pointer type)
private:
// MEMBERS
T m_headp; // First element
T m_tailp; // Last element
friend class V3ListEnt<T>;
public:
V3List()
: m_headp(NULL), m_tailp(NULL) {}
: m_headp(NULL)
, m_tailp(NULL) {}
~V3List() {}
// METHODS
T begin() const { return m_headp; }
T end() const { return NULL; }
bool empty() const { return m_headp == NULL; }
void reset() { m_headp = NULL; m_tailp = NULL; } // clear() without walking the list
void reset() { // clear() without walking the list
m_headp = NULL;
m_tailp = NULL;
}
};
//============================================================================
template <class T>
class V3ListEnt {
template <class T> class V3ListEnt {
// List entry for linked list of elements of type *T (T is a pointer type)
private:
// MEMBERS
@ -62,9 +65,11 @@ private:
// to get our new pointer information
return (V3ListEnt*)(((vluint8_t*)newbasep) + offset);
}
public:
V3ListEnt()
: m_nextp(NULL), m_prevp(NULL) {}
: m_nextp(NULL)
, m_prevp(NULL) {}
~V3ListEnt() {
#ifdef VL_DEBUG
// Load bogus pointers so we can catch deletion bugs
@ -99,10 +104,16 @@ public:
// "this" must be a element inside of *oldp
// cppcheck-suppress thisSubtraction
size_t offset = (size_t)(vluint8_t*)(this) - (size_t)(vluint8_t*)(oldp);
if (m_nextp) baseToListEnt(m_nextp, offset)->m_prevp = m_prevp;
else listr.m_tailp = m_prevp;
if (m_prevp) baseToListEnt(m_prevp, offset)->m_nextp = m_nextp;
else listr.m_headp = m_nextp;
if (m_nextp) {
baseToListEnt(m_nextp, offset)->m_prevp = m_prevp;
} else {
listr.m_tailp = m_prevp;
}
if (m_prevp) {
baseToListEnt(m_prevp, offset)->m_nextp = m_nextp;
} else {
listr.m_headp = m_nextp;
}
m_prevp = m_nextp = NULL;
}
};

View File

@ -85,9 +85,7 @@ private:
public:
// CONSTRUCTORS
explicit LocalizeDehierVisitor(AstNetlist* nodep) {
iterate(nodep);
}
explicit LocalizeDehierVisitor(AstNetlist* nodep) { iterate(nodep); }
virtual ~LocalizeDehierVisitor() {}
};
@ -130,8 +128,7 @@ private:
if ((nodep->isMovableToBlock() // Blocktemp
|| !flags.m_notStd) // Or used only in block
&& !flags.m_notOpt // Optimizable
&& !nodep->isClassMember()
&& nodep->user1p()) { // Single cfunc
&& !nodep->isClassMember() && nodep->user1p()) { // Single cfunc
// We don't need to test for tracing; it would be in the tracefunc if it was needed
UINFO(4, " ModVar->BlkVar " << nodep << endl);
++m_statLocVars;
@ -185,8 +182,7 @@ private:
}
virtual void visit(AstVar* nodep) VL_OVERRIDE {
if (!nodep->isSigPublic()
&& !nodep->isPrimaryIO()
if (!nodep->isSigPublic() && !nodep->isPrimaryIO()
&& !m_cfuncp) { // Not already inside a function
UINFO(4, " BLKVAR " << nodep << endl);
m_varps.push_back(nodep);
@ -197,8 +193,7 @@ private:
if (!VarFlags(nodep->varp()).m_notOpt) {
if (!m_cfuncp) { // Not in function, can't optimize
clearOptimizable(nodep->varp(), "BVnofunc");
}
else {
} else {
// If we're scoping down to it, it isn't really in the same block
if (!nodep->hierThis()) clearOptimizable(nodep->varp(), "HierRef");
// Allow a variable to appear in only a single function

View File

@ -60,8 +60,8 @@ private:
} else {
string rsvd = m_words.isKeyword(nodep->name());
if (rsvd != "") {
nodep->v3warn(SYMRSVDWORD, "Symbol matches "+rsvd
+": "<<nodep->prettyNameQ());
nodep->v3warn(SYMRSVDWORD,
"Symbol matches " + rsvd + ": " << nodep->prettyNameQ());
string newname = string("__SYM__") + nodep->name();
nodep->name(newname);
nodep->editCountInc();
@ -83,8 +83,8 @@ private:
// Add __PVT__ to names of local signals
virtual void visit(AstVar* nodep) VL_OVERRIDE {
// Don't iterate... Don't need temps for RANGES under the Var.
rename(nodep, ((!m_modp || !m_modp->isTop())
&& !nodep->isSigPublic()
rename(nodep,
((!m_modp || !m_modp->isTop()) && !nodep->isSigPublic()
&& !nodep->isFuncLocal() // Isn't exposed, and would mess up dpi import wrappers
&& !nodep->isTemp())); // Don't bother to rename internal signals
}
@ -102,8 +102,7 @@ private:
}
virtual void visit(AstCell* nodep) VL_OVERRIDE {
if (!nodep->user1()) {
rename(nodep, (!nodep->modp()->modPublic()
&& !VN_IS(nodep->modp(), ClassPackage)));
rename(nodep, (!nodep->modp()->modPublic() && !VN_IS(nodep->modp(), ClassPackage)));
iterateChildren(nodep);
}
}
@ -125,10 +124,13 @@ private:
if (nodep->aboveCellp()) iterate(nodep->aboveCellp());
// Always recompute name (as many levels above scope may have changed)
// Same formula as V3Scope
nodep->name(nodep->isTop() ? "TOP"
nodep->name(nodep->isTop()
? "TOP"
: VN_IS(m_modp, Class) ? ("TOP." + m_modp->name())
: VN_IS(m_modp, ClassPackage) ? ("TOP." + m_modp->name())
: (nodep->aboveScopep()->name() + "." + nodep->aboveCellp()->name()));
: VN_IS(m_modp, ClassPackage)
? ("TOP." + m_modp->name())
: (nodep->aboveScopep()->name() + "."
+ nodep->aboveCellp()->name()));
nodep->editCountInc();
iterateChildren(nodep);
}
@ -151,8 +153,6 @@ public:
void V3Name::nameAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl);
{
NameVisitor visitor (nodep);
} // Destruct before checking
{ NameVisitor visitor(nodep); } // Destruct before checking
V3Global::dumpCheckGlobalTree("name", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}

View File

@ -41,37 +41,68 @@ void test(const string& lhss, const string& op, const string& rhss, const string
V3Number expnum(fl, e1);
V3Number gotnum(fl, expnum.width());
if (op=="redOr") gotnum.opRedOr (lhnum);
else if (op=="redAnd") gotnum.opRedAnd (lhnum);
else if (op=="redXor") gotnum.opRedXor (lhnum);
else if (op=="redXnor") gotnum.opRedXnor (lhnum);
else if (op=="concat") gotnum.opConcat (lhnum, rhnum);
else if (op=="repl") gotnum.opRepl (lhnum, rhnum);
else if (op=="~") gotnum.opNot (lhnum);
else if (op=="!") gotnum.opLogNot (lhnum);
else if (op=="negate") gotnum.opNegate (lhnum);
else if (op=="+") gotnum.opAdd (lhnum, rhnum);
else if (op=="-") gotnum.opSub (lhnum, rhnum);
else if (op=="*") gotnum.opMul (lhnum, rhnum);
else if (op=="/") gotnum.opDiv (lhnum, rhnum);
else if (op=="%") gotnum.opModDiv (lhnum, rhnum);
else if (op=="&") gotnum.opAnd (lhnum, rhnum);
else if (op=="|") gotnum.opOr (lhnum, rhnum);
else if (op=="<") gotnum.opLt (lhnum, rhnum);
else if (op==">") gotnum.opGt (lhnum, rhnum);
else if (op==">>") gotnum.opShiftR (lhnum, rhnum);
else if (op=="<<") gotnum.opShiftL (lhnum, rhnum);
else if (op=="==") gotnum.opEq (lhnum, rhnum);
else if (op=="===") gotnum.opCaseEq (lhnum, rhnum);
else if (op=="==?") gotnum.opWildEq (lhnum, rhnum);
else if (op=="!=") gotnum.opNeq (lhnum, rhnum);
else if (op=="!==") gotnum.opCaseNeq (lhnum, rhnum);
else if (op=="!=?") gotnum.opWildNeq (lhnum, rhnum);
else if (op=="<=") gotnum.opLte (lhnum, rhnum);
else if (op==">=") gotnum.opGte (lhnum, rhnum);
else if (op=="&&") gotnum.opLogAnd (lhnum, rhnum);
else if (op=="||") gotnum.opLogOr (lhnum, rhnum);
else v3fatalSrc("Bad opcode: "<<op);
if (op == "redOr") {
gotnum.opRedOr(lhnum);
} else if (op == "redAnd") {
gotnum.opRedAnd(lhnum);
} else if (op == "redXor") {
gotnum.opRedXor(lhnum);
} else if (op == "redXnor") {
gotnum.opRedXnor(lhnum);
} else if (op == "concat") {
gotnum.opConcat(lhnum, rhnum);
} else if (op == "repl") {
gotnum.opRepl(lhnum, rhnum);
} else if (op == "~") {
gotnum.opNot(lhnum);
} else if (op == "!") {
gotnum.opLogNot(lhnum);
} else if (op == "negate") {
gotnum.opNegate(lhnum);
} else if (op == "+") {
gotnum.opAdd(lhnum, rhnum);
} else if (op == "-") {
gotnum.opSub(lhnum, rhnum);
} else if (op == "*") {
gotnum.opMul(lhnum, rhnum);
} else if (op == "/") {
gotnum.opDiv(lhnum, rhnum);
} else if (op == "%") {
gotnum.opModDiv(lhnum, rhnum);
} else if (op == "&") {
gotnum.opAnd(lhnum, rhnum);
} else if (op == "|") {
gotnum.opOr(lhnum, rhnum);
} else if (op == "<") {
gotnum.opLt(lhnum, rhnum);
} else if (op == ">") {
gotnum.opGt(lhnum, rhnum);
} else if (op == ">>") {
gotnum.opShiftR(lhnum, rhnum);
} else if (op == "<<") {
gotnum.opShiftL(lhnum, rhnum);
} else if (op == "==") {
gotnum.opEq(lhnum, rhnum);
} else if (op == "===") {
gotnum.opCaseEq(lhnum, rhnum);
} else if (op == "==?") {
gotnum.opWildEq(lhnum, rhnum);
} else if (op == "!=") {
gotnum.opNeq(lhnum, rhnum);
} else if (op == "!==") {
gotnum.opCaseNeq(lhnum, rhnum);
} else if (op == "!=?") {
gotnum.opWildNeq(lhnum, rhnum);
} else if (op == "<=") {
gotnum.opLte(lhnum, rhnum);
} else if (op == ">=") {
gotnum.opGte(lhnum, rhnum);
} else if (op == "&&") {
gotnum.opLogAnd(lhnum, rhnum);
} else if (op == "||") {
gotnum.opLogOr(lhnum, rhnum);
} else
v3fatalSrc("Bad opcode: " << op);
UINFO(0, "------- Test:\n"
<< " " << lhnum << " " << op << endl
@ -81,9 +112,7 @@ void test(const string& lhss, const string& op, const string& rhss, const string
V3Number ok(fl, 1);
ok.opCaseEq(expnum, gotnum);
if (ok.toUInt()!=1) {
v3fatalSrc("%Error:Test FAILED");
}
if (ok.toUInt() != 1) { v3fatalSrc("%Error:Test FAILED"); }
free(l1);
free(r1);
@ -106,7 +135,8 @@ int main() {
test("57'h000000010F0CCE7", "*", "57'h10", "57'h10F0CCE70");
test("57'h000000010F0CCE7", "*", "57'h0DE34E7FFFFFFFF", "57'h02A9D57EF0F3319");
test("67'h7FFFFFFFFFFFFFFFF", "*", "67'h4000000003C8A8D6A", "67'h3FFFFFFFFC3757296");
test("99'h7FFFFFFFFFFFFFFFFFFFFFFFF", "*", "99'h0000000000000000091338A80", "99'h7FFFFFFFFFFFFFFFF6ECC7580");
test("99'h7FFFFFFFFFFFFFFFFFFFFFFFF", "*", "99'h0000000000000000091338A80",
"99'h7FFFFFFFFFFFFFFFF6ECC7580");
cout << "Test completed\n";
}

View File

@ -36,7 +36,6 @@
// OrderPreCutEdge
//*************************************************************************
#ifndef _V3ORDERGRAPH_H_
#define _V3ORDERGRAPH_H_
@ -62,7 +61,8 @@ enum OrderWeights {
WEIGHT_POST = 2, // Post-delayed used var
WEIGHT_PRE = 3, // Breakable pre-delayed used var
WEIGHT_MEDIUM = 8, // Medium weight just so dot graph looks nice
WEIGHT_NORMAL = 32 }; // High weight just so dot graph looks nice
WEIGHT_NORMAL = 32
}; // High weight just so dot graph looks nice
struct OrderVEdgeType {
enum en {
@ -84,20 +84,21 @@ struct OrderVEdgeType {
_ENUM_END
};
const char* ascii() const {
static const char* const names[] = {
"%E-vedge", "VERTEX_INPUTS", "VERTEX_SETTLE", "VERTEX_LOGIC",
"VERTEX_VARSTD", "VERTEX_VARPRE", "VERTEX_VARPOST",
"VERTEX_VARPORD", "VERTEX_VARSETTLE", "VERTEX_MOVE",
"EDGE_STD", "EDGE_CHANGEDET", "EDGE_COMBOCUT",
"EDGE_PRECUT", "EDGE_POSTCUT", "_ENUM_END"
};
static const char* const names[]
= {"%E-vedge", "VERTEX_INPUTS", "VERTEX_SETTLE", "VERTEX_LOGIC",
"VERTEX_VARSTD", "VERTEX_VARPRE", "VERTEX_VARPOST", "VERTEX_VARPORD",
"VERTEX_VARSETTLE", "VERTEX_MOVE", "EDGE_STD", "EDGE_CHANGEDET",
"EDGE_COMBOCUT", "EDGE_PRECUT", "EDGE_POSTCUT", "_ENUM_END"};
return names[m_e];
}
enum en m_e;
inline OrderVEdgeType() : m_e(VERTEX_UNKNOWN) {}
inline OrderVEdgeType()
: m_e(VERTEX_UNKNOWN) {}
// cppcheck-suppress noExplicitConstructor
inline OrderVEdgeType(en _e) : m_e(_e) {}
explicit inline OrderVEdgeType(int _e) : m_e(static_cast<en>(_e)) {}
inline OrderVEdgeType(en _e)
: m_e(_e) {}
explicit inline OrderVEdgeType(int _e)
: m_e(static_cast<en>(_e)) {}
operator en() const { return m_e; }
};
inline bool operator==(const OrderVEdgeType& lhs, const OrderVEdgeType& rhs) {
@ -139,11 +140,16 @@ class OrderEitherVertex : public V3GraphVertex {
bool m_isFromInput; // From input, or derived therefrom (conservatively false)
protected:
OrderEitherVertex(V3Graph* graphp, const OrderEitherVertex& old)
: V3GraphVertex(graphp, old), m_scopep(old.m_scopep), m_domainp(old.m_domainp)
: V3GraphVertex(graphp, old)
, m_scopep(old.m_scopep)
, m_domainp(old.m_domainp)
, m_isFromInput(old.m_isFromInput) {}
public:
OrderEitherVertex(V3Graph* graphp, AstScope* scopep, AstSenTree* domainp)
: V3GraphVertex(graphp), m_scopep(scopep), m_domainp(domainp)
: V3GraphVertex(graphp)
, m_scopep(scopep)
, m_domainp(domainp)
, m_isFromInput(false) {}
virtual ~OrderEitherVertex() {}
virtual OrderEitherVertex* clone(V3Graph* graphp) const = 0;
@ -162,6 +168,7 @@ public:
class OrderInputsVertex : public OrderEitherVertex {
OrderInputsVertex(V3Graph* graphp, const OrderInputsVertex& old)
: OrderEitherVertex(graphp, old) {}
public:
OrderInputsVertex(V3Graph* graphp, AstSenTree* domainp)
: OrderEitherVertex(graphp, NULL, domainp) {
@ -169,7 +176,8 @@ public:
}
virtual ~OrderInputsVertex() {}
virtual OrderInputsVertex* clone(V3Graph* graphp) const {
return new OrderInputsVertex(graphp, *this); }
return new OrderInputsVertex(graphp, *this);
}
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_INPUTS; }
virtual string name() const { return "*INPUTS*"; }
virtual string dotColor() const { return "green"; }
@ -180,12 +188,14 @@ public:
class OrderSettleVertex : public OrderEitherVertex {
OrderSettleVertex(V3Graph* graphp, const OrderSettleVertex& old)
: OrderEitherVertex(graphp, old) {}
public:
OrderSettleVertex(V3Graph* graphp, AstSenTree* domainp)
: OrderEitherVertex(graphp, NULL, domainp) {}
virtual ~OrderSettleVertex() {}
virtual OrderSettleVertex* clone(V3Graph* graphp) const {
return new OrderSettleVertex(graphp, *this); }
return new OrderSettleVertex(graphp, *this);
}
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_SETTLE; }
virtual string name() const { return "*SETTLE*"; }
virtual string dotColor() const { return "green"; }
@ -195,20 +205,26 @@ public:
class OrderLogicVertex : public OrderEitherVertex {
AstNode* m_nodep;
protected:
OrderLogicVertex(V3Graph* graphp, const OrderLogicVertex& old)
: OrderEitherVertex(graphp, old), m_nodep(old.m_nodep) {}
: OrderEitherVertex(graphp, old)
, m_nodep(old.m_nodep) {}
public:
OrderLogicVertex(V3Graph* graphp, AstScope* scopep, AstSenTree* domainp, AstNode* nodep)
: OrderEitherVertex(graphp, scopep, domainp), m_nodep(nodep) {}
: OrderEitherVertex(graphp, scopep, domainp)
, m_nodep(nodep) {}
virtual ~OrderLogicVertex() {}
virtual OrderLogicVertex* clone(V3Graph* graphp) const {
return new OrderLogicVertex(graphp, *this); }
return new OrderLogicVertex(graphp, *this);
}
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_LOGIC; }
virtual bool domainMatters() { return true; }
// ACCESSORS
virtual string name() const {
return (cvtToHex(m_nodep)+"\\n "+cvtToStr(nodep()->typeName())); }
return (cvtToHex(m_nodep) + "\\n " + cvtToStr(nodep()->typeName()));
}
AstNode* nodep() const { return m_nodep; }
virtual string dotColor() const { return "yellow"; }
};
@ -220,12 +236,16 @@ class OrderVarVertex : public OrderEitherVertex {
protected:
OrderVarVertex(V3Graph* graphp, const OrderVarVertex& old)
: OrderEitherVertex(graphp, old)
, m_varScp(old.m_varScp), m_isClock(old.m_isClock)
, m_varScp(old.m_varScp)
, m_isClock(old.m_isClock)
, m_isDelayed(old.m_isDelayed) {}
public:
OrderVarVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
: OrderEitherVertex(graphp, scopep, NULL), m_varScp(varScp)
, m_isClock(false), m_isDelayed(false) {}
: OrderEitherVertex(graphp, scopep, NULL)
, m_varScp(varScp)
, m_isClock(false)
, m_isDelayed(false) {}
virtual ~OrderVarVertex() {}
virtual OrderVarVertex* clone(V3Graph* graphp) const = 0;
virtual OrderVEdgeType type() const = 0;
@ -241,12 +261,14 @@ public:
class OrderVarStdVertex : public OrderVarVertex {
OrderVarStdVertex(V3Graph* graphp, const OrderVarStdVertex& old)
: OrderVarVertex(graphp, old) {}
public:
OrderVarStdVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
: OrderVarVertex(graphp, scopep, varScp) {}
virtual ~OrderVarStdVertex() {}
virtual OrderVarStdVertex* clone(V3Graph* graphp) const {
return new OrderVarStdVertex(graphp, *this); }
return new OrderVarStdVertex(graphp, *this);
}
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARSTD; }
virtual string name() const { return (cvtToHex(varScp()) + "\\n " + varScp()->name()); }
virtual string dotColor() const { return "skyblue"; }
@ -255,12 +277,14 @@ public:
class OrderVarPreVertex : public OrderVarVertex {
OrderVarPreVertex(V3Graph* graphp, const OrderVarPreVertex& old)
: OrderVarVertex(graphp, old) {}
public:
OrderVarPreVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
: OrderVarVertex(graphp, scopep, varScp) {}
virtual ~OrderVarPreVertex() {}
virtual OrderVarPreVertex* clone(V3Graph* graphp) const {
return new OrderVarPreVertex(graphp, *this); }
return new OrderVarPreVertex(graphp, *this);
}
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARPRE; }
virtual string name() const { return (cvtToHex(varScp()) + " PRE\\n " + varScp()->name()); }
virtual string dotColor() const { return "lightblue"; }
@ -269,11 +293,13 @@ public:
class OrderVarPostVertex : public OrderVarVertex {
OrderVarPostVertex(V3Graph* graphp, const OrderVarPostVertex& old)
: OrderVarVertex(graphp, old) {}
public:
OrderVarPostVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
: OrderVarVertex(graphp, scopep, varScp) {}
virtual OrderVarPostVertex* clone(V3Graph* graphp) const {
return new OrderVarPostVertex(graphp, *this); }
return new OrderVarPostVertex(graphp, *this);
}
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARPOST; }
virtual ~OrderVarPostVertex() {}
virtual string name() const { return (cvtToHex(varScp()) + " POST\\n " + varScp()->name()); }
@ -283,12 +309,14 @@ public:
class OrderVarPordVertex : public OrderVarVertex {
OrderVarPordVertex(V3Graph* graphp, const OrderVarPordVertex& old)
: OrderVarVertex(graphp, old) {}
public:
OrderVarPordVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
: OrderVarVertex(graphp, scopep, varScp) {}
virtual ~OrderVarPordVertex() {}
virtual OrderVarPordVertex* clone(V3Graph* graphp) const {
return new OrderVarPordVertex(graphp, *this); }
return new OrderVarPordVertex(graphp, *this);
}
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARPORD; }
virtual string name() const { return (cvtToHex(varScp()) + " PORD\\n " + varScp()->name()); }
virtual string dotColor() const { return "NavyBlue"; }
@ -297,12 +325,14 @@ public:
class OrderVarSettleVertex : public OrderVarVertex {
OrderVarSettleVertex(V3Graph* graphp, const OrderVarSettleVertex& old)
: OrderVarVertex(graphp, old) {}
public:
OrderVarSettleVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
: OrderVarVertex(graphp, scopep, varScp) {}
virtual ~OrderVarSettleVertex() {}
virtual OrderVarSettleVertex* clone(V3Graph* graphp) const {
return new OrderVarSettleVertex(graphp, *this); }
return new OrderVarSettleVertex(graphp, *this);
}
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_VARSETTLE; }
virtual string name() const { return (cvtToHex(varScp()) + " STL\\n " + varScp()->name()); }
virtual string dotColor() const { return "PowderBlue"; }
@ -329,26 +359,36 @@ protected:
public:
// CONSTRUCTORS
OrderMoveVertex(V3Graph* graphp, OrderLogicVertex* logicp)
: V3GraphVertex(graphp), m_logicp(logicp), m_state(POM_WAIT), m_domScopep(NULL) {}
: V3GraphVertex(graphp)
, m_logicp(logicp)
, m_state(POM_WAIT)
, m_domScopep(NULL) {}
virtual ~OrderMoveVertex() {}
virtual OrderMoveVertex* clone(V3Graph* graphp) const {
v3fatalSrc("Unsupported"); return NULL; }
v3fatalSrc("Unsupported");
return NULL;
}
// METHODS
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_MOVE; }
virtual string dotColor() const {
if (logicp()) return logicp()->dotColor();
else return "";
if (logicp()) {
return logicp()->dotColor();
} else {
return "";
}
}
virtual FileLine* fileline() const {
if (logicp()) return logicp()->fileline();
else return NULL;
if (logicp()) {
return logicp()->fileline();
} else {
return NULL;
}
}
virtual string name() const {
string nm;
if (logicp()) {
nm = logicp()->name();
nm += (string("\\nMV:")
+" d="+cvtToHex(logicp()->domainp())
nm += (string("\\nMV:") + " d=" + cvtToHex(logicp()->domainp())
+ " s=" + cvtToHex(logicp()->scopep()));
} else {
nm = "nul";
@ -383,30 +423,36 @@ class MTaskMoveVertex : public V3GraphVertex {
protected:
friend class OrderVisitor;
friend class MTaskMoveVertexMaker;
public:
MTaskMoveVertex(V3Graph* graphp, OrderLogicVertex* logicp,
const OrderEitherVertex* varp,
MTaskMoveVertex(V3Graph* graphp, OrderLogicVertex* logicp, const OrderEitherVertex* varp,
const AstScope* scopep, const AstSenTree* domainp)
: V3GraphVertex(graphp), m_logicp(logicp),
m_varp(varp), m_scopep(scopep), m_domainp(domainp) {
UASSERT(!(logicp && varp),
"MTaskMoveVertex: logicp and varp may not both be set!\n");
: V3GraphVertex(graphp)
, m_logicp(logicp)
, m_varp(varp)
, m_scopep(scopep)
, m_domainp(domainp) {
UASSERT(!(logicp && varp), "MTaskMoveVertex: logicp and varp may not both be set!\n");
}
virtual ~MTaskMoveVertex() {}
virtual MTaskMoveVertex* clone(V3Graph* graphp) const {
v3fatalSrc("Unsupported"); return NULL; }
v3fatalSrc("Unsupported");
return NULL;
}
virtual OrderVEdgeType type() const { return OrderVEdgeType::VERTEX_MOVE; }
virtual string dotColor() const {
if (logicp()) return logicp()->dotColor();
else return "yellow";
if (logicp()) {
return logicp()->dotColor();
} else {
return "yellow";
}
}
virtual string name() const {
string nm;
if (logicp()) {
nm = logicp()->name();
nm += (string("\\nMV:")
+" d="+cvtToHex(logicp()->domainp())
+" s="+cvtToHex(logicp()->scopep())
nm += (string("\\nMV:") + " d=" + cvtToHex(logicp()->domainp()) + " s="
+ cvtToHex(logicp()->scopep())
// "color()" represents the mtask ID.
+ "\\nt=" + cvtToStr(color()));
} else {
@ -426,12 +472,12 @@ public:
class OrderEdge : public V3GraphEdge {
protected:
OrderEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top,
const OrderEdge& old)
OrderEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, const OrderEdge& old)
: V3GraphEdge(graphp, fromp, top, old) {}
public:
OrderEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top,
int weight, bool cutable=false)
OrderEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top, int weight,
bool cutable = false)
: V3GraphEdge(graphp, fromp, top, weight, cutable) {}
virtual ~OrderEdge() {}
virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_STD; }
@ -461,13 +507,14 @@ class OrderComboCutEdge : public OrderEdge {
OrderComboCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top,
const OrderComboCutEdge& old)
: OrderEdge(graphp, fromp, top, old) {}
public:
OrderComboCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top)
: OrderEdge(graphp, fromp, top, WEIGHT_COMBO, CUTABLE) {}
virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_COMBOCUT; }
virtual ~OrderComboCutEdge() {}
virtual OrderComboCutEdge* clone(V3Graph* graphp,
V3GraphVertex* fromp, V3GraphVertex* top) const {
virtual OrderComboCutEdge* clone(V3Graph* graphp, V3GraphVertex* fromp,
V3GraphVertex* top) const {
return new OrderComboCutEdge(graphp, fromp, top, *this);
}
virtual string dotColor() const { return "yellowGreen"; }
@ -482,13 +529,14 @@ class OrderPostCutEdge : public OrderEdge {
OrderPostCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top,
const OrderPostCutEdge& old)
: OrderEdge(graphp, fromp, top, old) {}
public:
OrderPostCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top)
: OrderEdge(graphp, fromp, top, WEIGHT_COMBO, CUTABLE) {}
virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_POSTCUT; }
virtual ~OrderPostCutEdge() {}
virtual OrderPostCutEdge* clone(V3Graph* graphp,
V3GraphVertex* fromp, V3GraphVertex* top) const {
virtual OrderPostCutEdge* clone(V3Graph* graphp, V3GraphVertex* fromp,
V3GraphVertex* top) const {
return new OrderPostCutEdge(graphp, fromp, top, *this);
}
virtual string dotColor() const { return "PaleGreen"; }
@ -503,12 +551,13 @@ class OrderPreCutEdge : public OrderEdge {
OrderPreCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top,
const OrderPreCutEdge& old)
: OrderEdge(graphp, fromp, top, old) {}
public:
OrderPreCutEdge(V3Graph* graphp, V3GraphVertex* fromp, V3GraphVertex* top)
: OrderEdge(graphp, fromp, top, WEIGHT_PRE, CUTABLE) {}
virtual OrderVEdgeType type() const { return OrderVEdgeType::EDGE_PRECUT; }
virtual OrderPreCutEdge* clone(V3Graph* graphp,
V3GraphVertex* fromp, V3GraphVertex* top) const {
virtual OrderPreCutEdge* clone(V3Graph* graphp, V3GraphVertex* fromp,
V3GraphVertex* top) const {
return new OrderPreCutEdge(graphp, fromp, top, *this);
}
virtual ~OrderPreCutEdge() {}

View File

@ -34,12 +34,16 @@ public:
// METHODS (generic filename utilities)
static string filenameFromDirBase(const string& dir, const string& basename);
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
/// Return non-directory part of filename
static string filenameNonDir(const string& filename);
/// Return non-extensioned (no .) part of filename
static string filenameNonExt(const string& 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 filenameSubstitute(const string& filename); ///< Return filename with env vars removed
/// Return filename with env vars removed
static string filenameSubstitute(const string& filename);
static string filenameRealPath(const string& filename); ///< Return realpath of filename
static bool filenameIsRel(const string& filename); ///< True if relative
@ -56,7 +60,8 @@ public:
// METHODS (time & performance)
static void u_sleep(int64_t usec); ///< Sleep for a given number of microseconds.
static uint64_t timeUsecs(); ///< Return wall time since epoch in microseconds, or 0 if not implemented
/// Return wall time since epoch in microseconds, or 0 if not implemented
static uint64_t timeUsecs();
static uint64_t memUsageBytes(); ///< Return memory usage in bytes, or 0 if not implemented
};

View File

@ -39,18 +39,15 @@
class V3Lexer : public V3LexerBase {
public:
// CONSTRUCTORS
V3Lexer() : V3LexerBase(NULL) {}
V3Lexer()
: V3LexerBase(NULL) {}
~V3Lexer() {}
// METHODS
void statePop() {
yy_pop_state();
}
void statePop() { yy_pop_state(); }
void unputString(const char* textp, size_t length) {
// Add characters to input stream in back-to-front order
const char* cp = textp;
for (cp += length - 1; length--; cp--) {
unput(*cp);
}
for (cp += length - 1; length--; cp--) unput(*cp);
}
};

View File

@ -76,8 +76,7 @@ public:
if (entp) {
UINFO(9, "symTableNextId under " << entp << "-" << entp->type().ascii() << endl);
m_symTableNextId = getTable(entp);
}
else {
} else {
UINFO(9, "symTableNextId under NULL" << endl);
m_symTableNextId = NULL;
}
@ -95,7 +94,8 @@ public:
void pushNew(AstNode* nodep) { pushNewUnder(nodep, NULL); }
void pushNewUnder(AstNode* nodep, VSymEnt* parentp) {
if (!parentp) parentp = symCurrentp();
VSymEnt* symp = findNewTable(nodep); // Will set user4p, which is how we connect table to node
VSymEnt* symp
= findNewTable(nodep); // Will set user4p, which is how we connect table to node
symp->fallbackp(parentp);
reinsert(nodep, parentp);
pushScope(symp);
@ -106,9 +106,13 @@ public:
}
void popScope(AstNode* nodep) {
if (symCurrentp()->nodep() != nodep) {
if (debug()) { showUpward(); dump(cout, "-mism: "); }
if (debug()) {
showUpward();
dump(cout, "-mism: ");
}
nodep->v3fatalSrc("Symbols suggest ending " << symCurrentp()->nodep()->prettyTypeName()
<<" but parser thinks ending "<<nodep->prettyTypeName());
<< " but parser thinks ending "
<< nodep->prettyTypeName());
return;
}
m_sympStack.pop_back();
@ -117,20 +121,22 @@ public:
}
void showUpward() {
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;
UINFO(1, " " << symp->nodep() << endl);
}
UINFO(1, "ParseSym Current: " << symCurrentp()->nodep() << endl);
}
void dump(std::ostream& os, const string& indent="") {
m_syms.dump(os, indent);
}
void dump(std::ostream& os, const string& indent = "") { m_syms.dump(os, indent); }
AstNode* findEntUpward(const string& name) {
// Lookup the given string as an identifier, return type of the id, scanning upward
VSymEnt* foundp = symCurrentp()->findIdFallback(name);
if (foundp) return foundp->nodep();
else return NULL;
if (foundp) {
return foundp->nodep();
} else {
return NULL;
}
}
void importItem(AstNode* packagep, const string& id_or_star) {
// Import from package::id_or_star to this

View File

@ -61,6 +61,7 @@ public:
// Operate on the final ExecMTask graph, immediately prior to code
// generation time.
static void finalize();
private:
static void finalizeCosts(V3Graph* execMTaskGraphp);
static void setupMTaskDeps(V3Graph* mtasksp, const Vx2MTaskMap* vx2mtaskp);
@ -79,9 +80,11 @@ private:
// MEMBERS
mutable vluint64_t m_nextId;
mutable PtrMap m_id;
public:
// CONSTRUCTORS
PartPtrIdMap() : m_nextId(0) {}
PartPtrIdMap()
: m_nextId(0) {}
// METHODS
vluint64_t findId(const void* ptrp) const {
PtrMap::const_iterator it = m_id.find(ptrp);

View File

@ -30,7 +30,8 @@
class AbstractMTask : public V3GraphVertex {
public:
AbstractMTask(V3Graph* graphp) : V3GraphVertex(graphp) {}
AbstractMTask(V3Graph* graphp)
: V3GraphVertex(graphp) {}
virtual ~AbstractMTask() {}
virtual uint32_t id() const = 0;
virtual uint32_t cost() const = 0;
@ -41,7 +42,8 @@ public:
// TYPES
typedef std::list<MTaskMoveVertex*> VxList;
// CONSTRUCTORS
AbstractLogicMTask(V3Graph* graphp) : AbstractMTask(graphp) {}
AbstractLogicMTask(V3Graph* graphp)
: AbstractMTask(graphp) {}
virtual ~AbstractLogicMTask() {}
// METHODS
// Set of logic vertices in this mtask. Order is not significant.
@ -64,16 +66,17 @@ private:
const ExecMTask* m_packNextp; // Next for static (pack_mtasks) scheduling
bool m_threadRoot; // Is root thread
VL_UNCOPYABLE(ExecMTask);
public:
ExecMTask(V3Graph* graphp, AstMTaskBody* bodyp, uint32_t id)
: AbstractMTask(graphp),
m_bodyp(bodyp),
m_id(id),
m_priority(0),
m_cost(0),
m_thread(0xffffffff),
m_packNextp(NULL),
m_threadRoot(false) {}
: AbstractMTask(graphp)
, m_bodyp(bodyp)
, m_id(id)
, m_priority(0)
, m_cost(0)
, m_thread(0xffffffff)
, m_packNextp(NULL)
, m_threadRoot(false) {}
AstMTaskBody* bodyp() const { return m_bodyp; }
virtual uint32_t id() const { return m_id; }
uint32_t priority() const { return m_priority; }
@ -100,6 +103,8 @@ public:
}
};
inline std::ostream& operator<<(std::ostream& os, const ExecMTask& rhs) {
rhs.dump(os); return os; }
rhs.dump(os);
return os;
}
#endif // Guard

View File

@ -34,6 +34,7 @@ class V3PreProcImp;
// Token codes
// If changing, see V3PreProc.cpp's V3PreProcImp::tokenName()
// clang-format off
#define VP_EOF 0 // Must be zero, a.k.a. YY_NULL, a.k.a. yy_terminate();
#define VP_EOF_ERROR 400
@ -65,10 +66,13 @@ class V3PreProcImp;
#define VP_JOIN 314
#define VP_PSL 350
// clang-format on
//======================================================================
// Externs created by flex
// We add a prefix so that other lexers/flexers in the same program won't collide.
// clang-format off
#ifndef yy_create_buffer
# define yy_create_buffer V3PreLex_create_buffer
# define yy_delete_buffer V3PreLex_delete_buffer
@ -100,6 +104,7 @@ struct yy_buffer_state;
typedef struct yy_buffer_state* YY_BUFFER_STATE;
# define YY_BUF_SIZE 16384
#endif
// clang-format on
extern int yylex();
extern void yyrestart(FILE*);
@ -131,14 +136,16 @@ public:
bool m_file; // Buffer is start of new file
int m_termState; // Termination fsm
VPreStream(FileLine* fl, V3PreLex* lexp)
: m_curFilelinep(fl), m_lexp(lexp),
m_ignNewlines(0),
m_eof(false), m_file(false), m_termState(0) {
: m_curFilelinep(fl)
, m_lexp(lexp)
, m_ignNewlines(0)
, m_eof(false)
, m_file(false)
, m_termState(0) {
lexStreamDepthAdd(1);
}
~VPreStream() {
lexStreamDepthAdd(-1);
}
~VPreStream() { lexStreamDepthAdd(-1); }
private:
void lexStreamDepthAdd(int delta);
};
@ -184,7 +191,10 @@ class V3PreLex {
initFirstBuffer(filelinep);
}
~V3PreLex() {
while (!m_streampStack.empty()) { delete m_streampStack.top(); m_streampStack.pop(); }
while (!m_streampStack.empty()) {
delete m_streampStack.top();
m_streampStack.pop();
}
VL_DO_CLEAR(yy_delete_buffer(m_bufferState), m_bufferState = NULL);
}

View File

@ -47,9 +47,9 @@ public:
DEFINE_RECURSION_LEVEL_MAX = 1000, // How many `def substitutions before an error
LINE_TOKEN_MAX = 20000, // How many tokens on a line before an error
INCLUDE_DEPTH_MAX = 500, // How many `includes deep before an error
STREAM_DEPTH_LEVEL_MAX = 2000, // How many streams deep (sometimes `def deep) before an error
// // Set more than DEFINE_RECURSION_LEVEL_MAX
// // or INCLUDE_DEPTH_MAX
// Streams deep (sometimes `def deep) before an error.
// Set more than DEFINE_RECURSION_LEVEL_MAX or INCLUDE_DEPTH_MAX.
STREAM_DEPTH_LEVEL_MAX = 2000,
NEWLINES_VS_TICKLINE = 20 // Use `line in place of this many newlines
};
@ -80,9 +80,10 @@ public:
virtual void include(const string& filename) = 0; // Request a include file be processed
virtual void undef(const string& name) = 0; // Remove a definition
virtual void define(FileLine* fileline, const string& name,
const string& value, const string& params="",
bool cmdline=false) = 0; // `define without any parameters
virtual void define(FileLine* fileline, const string& name, const string& value,
const string& params = "",
bool cmdline = false)
= 0; // `define without any parameters
virtual void defineCmdLine(FileLine* fileline, const string& name,
const string& value) { // `define without any parameters
define(fileline, name, value, "", true);
@ -97,10 +98,9 @@ public:
protected:
// CONSTRUCTORS
V3PreProc() {
m_debug = 0;
}
V3PreProc() { m_debug = 0; }
void configure(FileLine* fl);
public:
static V3PreProc* createPreProc(FileLine* fl);
virtual ~V3PreProc() {}

View File

@ -64,8 +64,10 @@ protected:
s_preprocp->defineCmdLine(prefl, "VERILATOR", "1"); // LEAK_OK
s_preprocp->defineCmdLine(prefl, "verilator", "1"); // LEAK_OK
s_preprocp->defineCmdLine(prefl, "verilator3", "1"); // LEAK_OK
s_preprocp->defineCmdLine(prefl, "systemc_clock", "/*verilator systemc_clock*/"); // LEAK_OK
s_preprocp->defineCmdLine(prefl, "coverage_block_off", "/*verilator coverage_block_off*/"); // LEAK_OK
s_preprocp->defineCmdLine(prefl, "systemc_clock",
"/*verilator systemc_clock*/"); // LEAK_OK
s_preprocp->defineCmdLine(prefl, "coverage_block_off",
"/*verilator coverage_block_off*/"); // LEAK_OK
if (prefl->language().systemVerilog()) {
// Synthesis compatibility
s_preprocp->defineCmdLine(prefl, "SYSTEMVERILOG", "1"); // LEAK_OK
@ -109,8 +111,8 @@ protected:
// intervening +<lang>ext+ options since it was first encountered.
FileLine* modfileline = new FileLine(modfilename);
modfileline->language(v3Global.opt.fileLanguage(modfilename));
V3Parse::ppPushText(parsep, (string("`begin_keywords \"")
+modfileline->language().ascii()+"\"\n"));
V3Parse::ppPushText(
parsep, (string("`begin_keywords \"") + modfileline->language().ascii() + "\"\n"));
}
while (!s_preprocp->isEof()) {
@ -122,7 +124,8 @@ protected:
void preprocInclude(FileLine* fl, const string& modname) {
if (modname[0] == '/' || modname[0] == '\\') {
fl->v3warn(INCABSPATH, "Suggest `include with absolute path be made relative, and use +include: "
fl->v3warn(INCABSPATH,
"Suggest `include with absolute path be made relative, and use +include: "
<< modname);
}
preprocOpen(fl, s_filterp, modname, V3Os::filenameDir(fl->filename()),
@ -130,8 +133,8 @@ protected:
}
private:
string preprocOpen(FileLine* fl, VInFilter* filterp,
const string& modname, const string& lastpath,
string preprocOpen(FileLine* fl, VInFilter* filterp, const string& modname,
const string& lastpath,
const string& errmsg) { // Error message or "" to suppress
// Returns filename if successful
// Try a pure name in case user has a bogus `filename they don't expect
@ -163,9 +166,7 @@ VInFilter* V3PreShellImp::s_filterp = NULL;
//######################################################################
// Perl class functions
void V3PreShell::boot(char** env) {
V3PreShellImp::s_preImp.boot(env);
}
void V3PreShell::boot(char** env) { V3PreShellImp::s_preImp.boot(env); }
bool V3PreShell::preproc(FileLine* fl, const string& modname, VInFilter* filterp,
V3ParseImp* parsep, const string& errmsg) {
return V3PreShellImp::s_preImp.preproc(fl, modname, filterp, parsep, errmsg);
@ -177,12 +178,8 @@ void V3PreShell::defineCmdLine(const string& name, const string& value) {
FileLine* prefl = new FileLine(FileLine::commandLineFilename());
V3PreShellImp::s_preprocp->defineCmdLine(prefl, name, value);
}
void V3PreShell::undef(const string& name) {
V3PreShellImp::s_preprocp->undef(name);
}
void V3PreShell::dumpDefines(std::ostream& os) {
V3PreShellImp::s_preprocp->dumpDefines(os);
}
void V3PreShell::undef(const string& name) { V3PreShellImp::s_preprocp->undef(name); }
void V3PreShell::dumpDefines(std::ostream& os) { V3PreShellImp::s_preprocp->dumpDefines(os); }
void V3PreShell::candidateDefines(VSpellCheck* spellerp) {
V3PreShellImp::s_preprocp->candidateDefines(spellerp);
}

View File

@ -76,8 +76,7 @@ private:
AstVar* varp = VN_CAST(cfuncp->user1p(), Var);
if (!varp) {
string newvarname = string("__Vilp");
varp = new AstVar(fl, AstVarType::STMTTEMP,
newvarname, VFlagLogicPacked(), 32);
varp = new AstVar(fl, AstVarType::STMTTEMP, newvarname, VFlagLogicPacked(), 32);
UASSERT_OBJ(cfuncp, fl, "Assignment not under a function");
cfuncp->addInitsp(varp);
cfuncp->user1p(varp);
@ -87,11 +86,11 @@ private:
void mergeEnd() {
if (!m_mgAssignps.empty()) {
uint32_t items = m_mgIndexHi - m_mgIndexLo + 1;
UINFO(9, "End merge iter="<<items<<" "<<m_mgIndexHi<<":"<<m_mgIndexLo
<<" "<<m_mgAssignps[0]<<endl);
UINFO(9, "End merge iter=" << items << " " << m_mgIndexHi << ":" << m_mgIndexLo << " "
<< m_mgAssignps[0] << endl);
if (items >= RELOOP_MIN_ITERS) {
UINFO(6, "Reloop merging items="<<items<<" "<<m_mgIndexHi<<":"<<m_mgIndexLo
<<" "<<m_mgAssignps[0]<<endl);
UINFO(6, "Reloop merging items=" << items << " " << m_mgIndexHi << ":"
<< m_mgIndexLo << " " << m_mgAssignps[0] << endl);
++m_statReloops;
m_statReItems += items;
@ -103,11 +102,11 @@ private:
AstNode* initp = new AstAssign(fl, new AstVarRef(fl, itp, true),
new AstConst(fl, m_mgIndexLo));
AstNode* condp = new AstLte(fl, new AstVarRef(fl, itp, false),
new AstConst(fl, m_mgIndexHi));
AstNode* incp = new AstAssign(fl, new AstVarRef(fl, itp, true),
new AstAdd(fl, new AstConst(fl, 1),
new AstVarRef(fl, itp, false)));
AstNode* condp
= new AstLte(fl, new AstVarRef(fl, itp, false), new AstConst(fl, m_mgIndexHi));
AstNode* incp = new AstAssign(
fl, new AstVarRef(fl, itp, true),
new AstAdd(fl, new AstConst(fl, 1), new AstVarRef(fl, itp, false)));
AstWhile* whilep = new AstWhile(fl, condp, NULL, incp);
initp->addNext(whilep);
bodyp->replaceWith(initp);
@ -154,15 +153,27 @@ private:
// Left select WordSel or ArraySel
AstNodeSel* lselp = VN_CAST(nodep->lhsp(), NodeSel);
if (!lselp) { mergeEnd(); return; } // Not ever merged
if (!lselp) { // Not ever merged
mergeEnd();
return;
}
// Of a constant index
AstConst* lbitp = VN_CAST(lselp->bitp(), Const);
if (!lbitp) { mergeEnd(); return; }
if (lbitp->width() > 32) { mergeEnd(); return; } // Assoc arrays can do this
if (!lbitp) {
mergeEnd();
return;
}
if (lbitp->width() > 32) { // Assoc arrays can do this
mergeEnd();
return;
}
uint32_t index = lbitp->toUInt();
// Of variable
AstNodeVarRef* lvarrefp = VN_CAST(lselp->fromp(), NodeVarRef);
if (!lvarrefp) { mergeEnd(); return; }
if (!lvarrefp) {
mergeEnd();
return;
}
// RHS is a constant or a select
AstConst* rconstp = VN_CAST(nodep->rhsp(), Const);
@ -170,38 +181,38 @@ private:
AstNodeVarRef* rvarrefp = NULL;
if (rconstp) { // Ok
} else {
if (!rselp) { mergeEnd(); return; }
if (!rselp) {
mergeEnd();
return;
}
AstConst* rbitp = VN_CAST(rselp->bitp(), Const);
rvarrefp = VN_CAST(rselp->fromp(), NodeVarRef);
if (!rbitp || rbitp->toUInt() != index
|| !rvarrefp
if (!rbitp || rbitp->toUInt() != index || !rvarrefp
|| lvarrefp->varp() == rvarrefp->varp()) {
mergeEnd(); return;
mergeEnd();
return;
}
}
if (m_mgSelLp) { // Old merge
if (m_mgCfuncp == m_cfuncp
&& m_mgNextp == nodep
&& m_mgSelLp->same(lselp)
if (m_mgCfuncp == m_cfuncp && m_mgNextp == nodep && m_mgSelLp->same(lselp)
&& m_mgVarrefLp->same(lvarrefp)
&& (m_mgConstRp
? (rconstp && m_mgConstRp->same(rconstp))
: (rselp
&& m_mgSelRp->same(rselp)
&& m_mgVarrefRp->same(rvarrefp)))
&& (index == m_mgIndexLo-1
|| index == m_mgIndexHi+1)) {
: (rselp && m_mgSelRp->same(rselp) && m_mgVarrefRp->same(rvarrefp)))
&& (index == m_mgIndexLo - 1 || index == m_mgIndexHi + 1)) {
// Sequentially next to last assign; continue merge
if (index == m_mgIndexLo-1) m_mgIndexLo = index;
else if (index == m_mgIndexHi+1) m_mgIndexHi = index;
UINFO(9, "Continue merge i="<<index
<<" "<<m_mgIndexHi<<":"<<m_mgIndexLo<<" "<<nodep<<endl);
if (index == m_mgIndexLo - 1) {
m_mgIndexLo = index;
} else if (index == m_mgIndexHi + 1) {
m_mgIndexHi = index;
}
UINFO(9, "Continue merge i=" << index << " " << m_mgIndexHi << ":" << m_mgIndexLo
<< " " << nodep << endl);
m_mgAssignps.push_back(nodep);
m_mgNextp = nodep->nextp();
return;
}
else {
} else {
// This assign doesn't merge with previous assign,
// but should start a new merge
mergeEnd();
@ -252,8 +263,6 @@ public:
void V3Reloop::reloopAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl);
{
ReloopVisitor visitor(nodep);
} // Destruct before checking
{ ReloopVisitor visitor(nodep); } // Destruct before checking
V3Global::dumpCheckGlobalTree("reloop", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}

View File

@ -25,7 +25,8 @@ public:
uint32_t m_score;
uint32_t m_id;
// CONSTRUCTORS
explicit ScoreboardTestElem(uint32_t score) : m_score(score) {
explicit ScoreboardTestElem(uint32_t score)
: m_score(score) {
static uint32_t s_serial = 0;
m_id = ++s_serial;
}
@ -33,9 +34,7 @@ public:
// METHODS
static uint32_t scoreFn(const ScoreboardTestElem* elp) { return elp->m_score; }
bool operator< (const ScoreboardTestElem& other) const {
return m_id < other.m_id;
}
bool operator<(const ScoreboardTestElem& other) const { return m_id < other.m_id; }
};
void V3ScoreboardBase::selfTest() {
@ -52,8 +51,7 @@ void V3ScoreboardBase::selfTest() {
sb.addElem(&e3);
UASSERT(sb.needsRescore(), "SelfTest: Newly filled sb should need a rescore.");
UASSERT(sb.needsRescore(&e1),
"SelfTest: Individual newly-added element should need rescore");
UASSERT(sb.needsRescore(&e1), "SelfTest: Individual newly-added element should need rescore");
UASSERT(NULL == sb.bestp(),
"SelfTest: Newly filled sb should have nothing eligible for Bestp()");
@ -64,14 +62,12 @@ void V3ScoreboardBase::selfTest() {
"SelfTest: Newly rescored sb should not need an element rescored");
UASSERT(e2.m_score == sb.cachedScore(&e2),
"SelfTest: Cached score should match current score");
UASSERT(&e1 == sb.bestp(),
"SelfTest: Should return element with lowest (best) score");
UASSERT(&e1 == sb.bestp(), "SelfTest: Should return element with lowest (best) score");
// Change one element's score
sb.hintScoreChanged(&e2);
e2.m_score = 21;
UASSERT(sb.needsRescore(&e2),
"SelfTest: Should need rescore on elem after hintScoreChanged");
UASSERT(sb.needsRescore(&e2), "SelfTest: Should need rescore on elem after hintScoreChanged");
// Remove an element
UASSERT(sb.contains(&e1), "SelfTest: e1 should be there");

View File

@ -64,6 +64,7 @@ public:
typedef void pointer;
typedef std::ptrdiff_t difference_type;
typedef std::bidirectional_iterator_tag iterator_category;
protected:
friend class SortByValueMap;
@ -77,8 +78,7 @@ public:
explicit const_iterator(SortByValueMap* sbmvp) // for end()
: m_sbvmp(sbmvp)
, m_end(true) {}
const_iterator(typename Val2Keys::iterator valIt,
typename KeySet::iterator keyIt,
const_iterator(typename Val2Keys::iterator valIt, typename KeySet::iterator keyIt,
SortByValueMap* sbvmp)
: m_keyIt(keyIt)
, m_valIt(valIt)
@ -135,6 +135,7 @@ public:
--m_keyIt;
UASSERT(m_keyIt != m_valIt->second.end(), "Value bucket should have key");
}
public:
const T_Key& key() const { return *m_keyIt; }
const T_Value& value() const { return m_valIt->first; }
@ -151,15 +152,10 @@ public:
// sequences. So check m_end before comparing m_valIt, and
// compare m_valIt's before comparing m_keyIt to ensure nothing
// here is undefined.
if (m_end || other.m_end) {
return m_end && other.m_end;
}
return ((m_valIt == other.m_valIt)
&& (m_keyIt == other.m_keyIt));
}
bool operator!=(const const_iterator& other) const {
return (!this->operator==(other));
if (m_end || other.m_end) return m_end && other.m_end;
return ((m_valIt == other.m_valIt) && (m_keyIt == other.m_keyIt));
}
bool operator!=(const const_iterator& other) const { return (!this->operator==(other)); }
// WARNING: Cleverness.
//
@ -209,8 +205,7 @@ public:
// CONSTRUCTORS
explicit iterator(SortByValueMap* sbvmp)
: const_iterator(sbvmp) {}
iterator(typename Val2Keys::iterator valIt,
typename KeySet::iterator keyIt,
iterator(typename Val2Keys::iterator valIt, typename KeySet::iterator keyIt,
SortByValueMap* sbvmp)
: const_iterator(valIt, keyIt, sbvmp) {}
@ -248,49 +243,33 @@ private:
}
void removeKeyFromOldVal(iterator it) {
it.m_valIt->second.erase(it.m_keyIt);
if (it.m_valIt->second.empty()) {
m_vals.erase(it.m_valIt);
}
if (it.m_valIt->second.empty()) m_vals.erase(it.m_valIt);
}
public:
iterator begin() {
typename Val2Keys::iterator valIt = m_vals.begin();
if (valIt == m_vals.end()) {
return end();
}
if (valIt == m_vals.end()) return end();
typename KeySet::const_iterator keyIt = valIt->second.begin();
return iterator(valIt, keyIt, this);
}
const_iterator begin() const {
SortByValueMap* mutp = const_cast<SortByValueMap*>(this);
typename Val2Keys::iterator valIt = mutp->m_vals.begin();
if (valIt == mutp->m_vals.end()) {
return end();
}
if (valIt == mutp->m_vals.end()) return end();
typename KeySet::const_iterator keyIt = valIt->second.begin();
return const_iterator(valIt, keyIt, mutp);
}
iterator end() {
return iterator(this);
}
iterator end() { return iterator(this); }
const_iterator end() const {
// Safe to cast away const; the const_iterator will still enforce
// it. Same for the const begin() below.
return const_iterator(const_cast<SortByValueMap*>(this));
}
reverse_iterator rbegin() {
return reverse_iterator(end());
}
reverse_iterator rend() {
return reverse_iterator(begin());
}
const_reverse_iterator rbegin() const {
return const_reverse_iterator(end());
}
const_reverse_iterator rend() const {
return const_reverse_iterator(begin());
}
reverse_iterator rbegin() { return reverse_iterator(end()); }
reverse_iterator rend() { return reverse_iterator(begin()); }
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
iterator find(const T_Key& k) {
typename Key2Val::iterator kvit = m_keys.find(k);
@ -335,12 +314,8 @@ public:
void erase(const reverse_iterator& it) {
erase(*it); // Dereferencing returns a copy of the forward iterator
}
bool has(const T_Key& k) const {
return (m_keys.find(k) != m_keys.end());
}
bool empty() const {
return m_keys.empty();
}
bool has(const T_Key& k) const { return (m_keys.find(k) != m_keys.end()); }
bool empty() const { return m_keys.empty(); }
// Look up a value. Returns a reference for efficiency. Note this must
// be a const reference, otherwise the client could corrupt the sorted
// order of m_byValue by reaching through and changing the value.
@ -375,9 +350,7 @@ private:
/// when the subset of elements whose scores change is much smaller than
/// the full set size.
template <typename T_Elem,
typename T_Score,
class T_ElemCompare = std::less<T_Elem> >
template <typename T_Elem, typename T_Score, class T_ElemCompare = std::less<T_Elem> >
class V3Scoreboard {
private:
// TYPES
@ -412,8 +385,7 @@ public:
// bestp() until after the next rescore().
void addElem(const T_Elem* elp) {
if (m_slowAsserts) {
UASSERT(!contains(elp),
"Adding element to scoreboard that was already in scoreboard");
UASSERT(!contains(elp), "Adding element to scoreboard that was already in scoreboard");
}
m_unknown.insert(elp);
}
@ -470,22 +442,19 @@ public:
bool needsRescore() { return !m_unknown.empty(); }
// False if elp's score is known to V3Scoreboard,
// else true if elp's score is unknown until the next rescore().
bool needsRescore(const T_Elem* elp) {
return (m_unknown.find(elp) != m_unknown.end());
}
bool needsRescore(const T_Elem* elp) { return (m_unknown.find(elp) != m_unknown.end()); }
// Retrieve the last known score for an element.
T_Score cachedScore(const T_Elem* elp) {
typename SortedMap::iterator result = m_sorted.find(elp);
UASSERT(result != m_sorted.end(),
"V3Scoreboard::cachedScore() failed to find element");
UASSERT(result != m_sorted.end(), "V3Scoreboard::cachedScore() failed to find element");
return (*result).value();
}
// For each element whose score is unknown to V3Scoreboard,
// call the client's scoring function to get a new score,
// and sort all elements by their current score.
void rescore() {
for (typename NeedRescoreSet::iterator it = m_unknown.begin();
it != m_unknown.end(); ++it) {
for (typename NeedRescoreSet::iterator it = m_unknown.begin(); it != m_unknown.end();
++it) {
const T_Elem* elp = *it;
T_Score sortScore = m_scoreFnp(elp);
m_sorted.set(elp, sortScore);

View File

@ -81,9 +81,7 @@ public:
AstSenTree* find(AstSenTree* likep) {
AstSenTree* resultp = NULL;
Set::iterator it = m_trees.find(likep);
if (it != m_trees.end()) {
resultp = *it;
}
if (it != m_trees.end()) resultp = *it;
return resultp;
}
void clear() { m_trees.clear(); }
@ -103,9 +101,7 @@ private:
virtual void visit(AstNodeModule* nodep) VL_OVERRIDE {
// Only do the top
if (nodep->isTop()) {
iterateChildren(nodep);
}
if (nodep->isTop()) iterateChildren(nodep);
}
virtual void visit(AstTopScope* nodep) VL_OVERRIDE {
m_topscopep = nodep;
@ -145,15 +141,12 @@ public:
}
return treep;
}
public:
// CONSTRUCTORS
SenTreeFinder() {
clear();
}
SenTreeFinder() { clear(); }
virtual ~SenTreeFinder() {}
void main(AstTopScope* nodep) {
iterate(nodep);
}
void main(AstTopScope* nodep) { iterate(nodep); }
};
#endif // Guard

View File

@ -92,8 +92,11 @@ private:
iterateChildrenConst(nodep);
if (m_counting && nodep->dtypep()) {
if (nodep->isUsedClock()) ++m_statVarClock;
if (VN_IS(nodep->dtypeSkipRefp(), UnpackArrayDType)) ++m_statVarArray;
else m_statVarBytes += nodep->dtypeSkipRefp()->widthTotalBytes();
if (VN_IS(nodep->dtypeSkipRefp(), UnpackArrayDType)) {
++m_statVarArray;
} else {
m_statVarBytes += nodep->dtypeSkipRefp()->widthTotalBytes();
}
if (int(m_statVarWidths.size()) <= nodep->width()) {
m_statVarWidths.resize(nodep->width() + 5);
if (v3Global.opt.statsVars()) m_statVarWidthNames.resize(nodep->width() + 5);
@ -125,9 +128,7 @@ private:
// Condition is part of cost allocated to PREVIOUS block
iterateAndNextConstNull(nodep->condp());
// Track prediction
if (m_counting) {
++m_statPred[nodep->branchPred()];
}
if (m_counting) ++m_statPred[nodep->branchPred()];
if (!m_fast) {
// Count everything
iterateChildrenConst(nodep);
@ -206,10 +207,12 @@ private:
allNodes(nodep);
iterateChildrenConst(nodep);
}
public:
// CONSTRUCTORS
StatsVisitor(AstNetlist* nodep, const string& stage, bool fast)
: m_stage(stage), m_fast(fast) {
: m_stage(stage)
, m_fast(fast) {
UINFO(9, "Starting stats, fast=" << fast << endl);
m_cfuncp = NULL;
m_counting = !m_fast;
@ -237,12 +240,13 @@ public:
if (v3Global.opt.statsVars()) {
NameMap& nameMapr = m_statVarWidthNames.at(i);
for (NameMap::iterator it = nameMapr.begin(); it != nameMapr.end(); ++it) {
std::ostringstream os; os<<"Vars, width "
<<std::setw(5)<<std::dec<<i<<" "<<it->first;
std::ostringstream os;
os << "Vars, width " << std::setw(5) << std::dec << i << " " << it->first;
V3Stats::addStat(m_stage, os.str(), it->second);
}
} else {
std::ostringstream os; os<<"Vars, width "<<std::setw(5)<<std::dec<<i;
std::ostringstream os;
os << "Vars, width " << std::setw(5) << std::dec << i;
V3Stats::addStat(m_stage, os.str(), count);
}
}
@ -258,8 +262,9 @@ public:
for (int type2 = 0; type2 < AstType::_ENUM_END; type2++) {
double count = double(m_statAbove[type][type2]);
if (count != 0.0) {
V3Stats::addStat(m_stage, (string("Node pairs, ")
+AstType(type).ascii()+"_"+AstType(type2).ascii()),
V3Stats::addStat(m_stage,
(string("Node pairs, ") + AstType(type).ascii() + "_"
+ AstType(type2).ascii()),
count);
}
}
@ -268,8 +273,8 @@ public:
for (int type = 0; type < VBranchPred::_ENUM_END; type++) {
double count = double(m_statPred[type]);
if (count != 0.0) {
V3Stats::addStat(m_stage, (string("Branch prediction, ")
+ VBranchPred(type).ascii()), count);
V3Stats::addStat(
m_stage, (string("Branch prediction, ") + VBranchPred(type).ascii()), count);
}
}
}

View File

@ -31,19 +31,37 @@ class VDouble0 {
double m_d; ///< Count of occurrences/ value
public:
// METHODS
VDouble0() : m_d(0) {}
VDouble0()
: m_d(0) {}
~VDouble0() {}
// Implicit conversion operators:
inline explicit VDouble0(const vluint64_t v) : m_d(v) { }
inline explicit VDouble0(const vluint64_t v)
: m_d(v) {}
inline operator double() const { return m_d; }
// Explicit operators:
inline VDouble0& operator++() { ++m_d; return *this; } // prefix
inline VDouble0 operator++(int) { VDouble0 old=*this; m_d++; return old; } // postfix
inline VDouble0& operator= (const double v) { m_d = v; return *this; }
inline VDouble0& operator+=(const double v) { m_d += v; return *this; }
inline VDouble0& operator-=(const double v) { m_d -= v; return *this; }
inline VDouble0& operator++() { // prefix
++m_d;
return *this;
}
inline VDouble0 operator++(int) { // postfix
VDouble0 old = *this;
m_d++;
return old;
}
inline VDouble0& operator=(const double v) {
m_d = v;
return *this;
}
inline VDouble0& operator+=(const double v) {
m_d += v;
return *this;
}
inline VDouble0& operator-=(const double v) {
m_d -= v;
return *this;
}
};
//============================================================================
@ -70,9 +88,13 @@ public:
otherp->m_printit = false;
}
// CONSTRUCTORS
V3Statistic(const string& stage, const string& name,
double count, bool sumit=false, bool perf=false)
: m_name(name), m_count(count), m_stage(stage), m_sumit(sumit), m_perf(perf)
V3Statistic(const string& stage, const string& name, double count, bool sumit = false,
bool perf = false)
: m_name(name)
, m_count(count)
, m_stage(stage)
, m_sumit(sumit)
, m_perf(perf)
, m_printit(true) {}
virtual ~V3Statistic() {}
};
@ -83,13 +105,17 @@ class V3Stats {
public:
static void addStat(const V3Statistic&);
static void addStat(const string& stage, const string& name, double count) {
addStat(V3Statistic(stage, name, count)); }
addStat(V3Statistic(stage, name, count));
}
static void addStat(const string& name, double count) {
addStat(V3Statistic("*", name, count)); }
addStat(V3Statistic("*", name, count));
}
static void addStatSum(const string& name, double count) {
addStat(V3Statistic("*", name, count, true)); }
addStat(V3Statistic("*", name, count, true));
}
static void addStatPerf(const string& name, double count) {
addStat(V3Statistic("*", name, count, true, true)); }
addStat(V3Statistic("*", name, count, true, true));
}
/// Called each stage
static void statsStage(const string& name);
/// Called by the top level to collect statistics
@ -99,5 +125,4 @@ public:
static void statsReport();
};
#endif // Guard

View File

@ -63,8 +63,8 @@ class StatsReport {
V3Statistic* lastp = NULL;
for (ByName::iterator it = byName.begin(); it != byName.end(); ++it) {
V3Statistic* repp = it->second;
if (lastp && lastp->sumit() && lastp->printit()
&& lastp->name() == repp->name() && lastp->stage() == repp->stage()) {
if (lastp && lastp->sumit() && lastp->printit() && lastp->name() == repp->name()
&& lastp->stage() == repp->stage()) {
repp->combineWith(lastp);
}
lastp = repp;
@ -157,9 +157,7 @@ class StatsReport {
{
string commaName = lastName;
string::size_type pos;
if ((pos = commaName.find(',')) != string::npos) {
commaName.erase(pos);
}
if ((pos = commaName.find(',')) != string::npos) commaName.erase(pos);
if (lastCommaName != commaName) {
lastCommaName = commaName;
os << endl;
@ -181,9 +179,7 @@ class StatsReport {
public:
// METHODS
static void addStat(const V3Statistic& stat) {
s_allStats.push_back(stat);
}
static void addStat(const V3Statistic& stat) { s_allStats.push_back(stat); }
// CONSTRUCTORS
explicit StatsReport(std::ofstream* aofp)
@ -212,15 +208,14 @@ void V3Statistic::dump(std::ofstream& os) const {
//######################################################################
// Top Stats class
void V3Stats::addStat(const V3Statistic& stat) {
StatsReport::addStat(stat);
}
void V3Stats::addStat(const V3Statistic& stat) { StatsReport::addStat(stat); }
void V3Stats::statsStage(const string& name) {
static double lastWallTime = -1;
static int fileNumber = 0;
char digits[100]; sprintf(digits, "%03d", ++fileNumber);
char digits[100];
sprintf(digits, "%03d", ++fileNumber);
const string digitName = string(digits) + "_" + name;
double wallTime = V3Os::timeUsecs() / 1.0e6;

View File

@ -33,16 +33,12 @@ size_t VName::s_maxLength = 0; // Disabled
inline bool VString::wildmatchi(const char* s, const char* p) {
for (; *p; s++, p++) {
if (*p != '*') {
if (((*s)!=(*p)) && *p != '?')
return false;
}
else {
if (((*s) != (*p)) && *p != '?') return false;
} else {
// Trailing star matches everything.
if (!*++p) return true;
while (!wildmatch(s, p)) {
if (*++s == '\0') {
return false;
}
if (*++s == '\0') return false;
}
return true;
}
@ -53,16 +49,12 @@ inline bool VString::wildmatchi(const char* s, const char* p) {
bool VString::wildmatch(const char* s, const char* p) {
for (; *p; s++, p++) {
if (*p != '*') {
if (((*s)!=(*p)) && *p != '?')
return false;
}
else {
if (((*s) != (*p)) && *p != '?') return false;
} else {
// Trailing star matches everything.
if (!*++p) return true;
while (!wildmatchi(s, p)) {
if (*++s == '\0') {
return false;
}
if (*++s == '\0') return false;
}
return true;
}
@ -86,17 +78,13 @@ string VString::dot(const string& a, const string& dot, const string& b) {
string VString::downcase(const string& str) {
string out = str;
for (string::iterator pos = out.begin(); pos != out.end(); ++pos) {
*pos = tolower(*pos);
}
for (string::iterator pos = out.begin(); pos != out.end(); ++pos) *pos = tolower(*pos);
return out;
}
string VString::upcase(const string& str) {
string out = str;
for (string::iterator pos = out.begin(); pos != out.end(); ++pos) {
*pos = toupper(*pos);
}
for (string::iterator pos = out.begin(); pos != out.end(); ++pos) *pos = toupper(*pos);
return out;
}
@ -112,8 +100,11 @@ string VString::quotePercent(const string& str) {
string VString::spaceUnprintable(const string& str) {
string out;
for (string::const_iterator pos = str.begin(); pos != str.end(); ++pos) {
if (isprint(*pos)) out += *pos;
else out += ' ';
if (isprint(*pos)) {
out += *pos;
} else {
out += ' ';
}
}
return out;
}
@ -128,16 +119,17 @@ bool VString::isWhitespace(const string& str) {
//######################################################################
// VHashSha256
static const uint32_t sha256K[] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
static const uint32_t sha256K[]
= {0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4,
0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe,
0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f,
0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b,
0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116,
0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7,
0xc67178f2};
static inline uint32_t shaRotr32(uint32_t lhs, uint32_t rhs) VL_ATTR_ALWINLINE;
static inline uint32_t shaRotr32(uint32_t lhs, uint32_t rhs) {
@ -150,9 +142,7 @@ static inline void sha256Block(uint32_t* h, const uint32_t* chunk) {
const uint32_t* p = chunk;
// Initialize working variables to current hash value
for (unsigned i = 0; i < 8; i++) {
ah[i] = h[i];
}
for (unsigned i = 0; i < 8; i++) ah[i] = h[i];
// Compression function main loop
for (unsigned i = 0; i < 4; ++i) {
uint32_t w[16];
@ -169,12 +159,10 @@ static inline void sha256Block(uint32_t* h, const uint32_t* chunk) {
^ shaRotr32(w[(j + 14) & 0xf], 19) ^ (w[(j + 14) & 0xf] >> 10);
w[j] = w[j] + s0 + w[(j + 9) & 0xf] + s1;
}
const uint32_t s1 = shaRotr32(ah[4], 6)
^ shaRotr32(ah[4], 11) ^ shaRotr32(ah[4], 25);
const uint32_t s1 = shaRotr32(ah[4], 6) ^ shaRotr32(ah[4], 11) ^ shaRotr32(ah[4], 25);
const uint32_t ch = (ah[4] & ah[5]) ^ (~ah[4] & ah[6]);
const uint32_t temp1 = ah[7] + s1 + ch + sha256K[i << 4 | j] + w[j];
const uint32_t s0 = shaRotr32(ah[0], 2)
^ shaRotr32(ah[0], 13) ^ shaRotr32(ah[0], 22);
const uint32_t s0 = shaRotr32(ah[0], 2) ^ shaRotr32(ah[0], 13) ^ shaRotr32(ah[0], 22);
const uint32_t maj = (ah[0] & ah[1]) ^ (ah[0] & ah[2]) ^ (ah[1] & ah[2]);
const uint32_t temp2 = s0 + maj;
@ -191,7 +179,6 @@ static inline void sha256Block(uint32_t* h, const uint32_t* chunk) {
for (unsigned i = 0; i < 8; ++i) h[i] += ah[i];
}
void VHashSha256::insert(const void* datap, size_t length) {
UASSERT(!m_final, "Called VHashSha256::insert after finalized the hash value");
m_totLength += length;
@ -243,8 +230,8 @@ void VHashSha256::finalize() {
for (int i = 0; i < 16; ++i) w[i] = 0;
size_t blockPos = 0;
for (; blockPos < m_remainder.length(); ++blockPos) {
w[blockPos >> 2] |= ((static_cast<uint32_t>(m_remainder[blockPos]))
<< ((3 - (blockPos & 3)) << 3));
w[blockPos >> 2]
|= ((static_cast<uint32_t>(m_remainder[blockPos])) << ((3 - (blockPos & 3)) << 3));
}
w[blockPos >> 2] |= 0x80 << ((3 - (blockPos & 3)) << 3);
if (m_remainder.length() >= 56) {
@ -260,7 +247,8 @@ void VHashSha256::finalize() {
string VHashSha256::digestBinary() {
finalize();
string out; out.reserve(32);
string out;
out.reserve(32);
for (size_t i = 0; i < 32; ++i) {
out += (m_inthash[i >> 2] >> (((3 - i) & 0x3) << 3)) & 0xff;
}
@ -280,7 +268,8 @@ uint64_t VHashSha256::digestUInt64() {
string VHashSha256::digestHex() {
static const char digits[16 + 1] = "0123456789abcdef";
const string& binhash = digestBinary();
string out; out.reserve(70);
string out;
out.reserve(70);
for (size_t byte = 0; byte < 32; ++byte) {
out += digits[(binhash[byte] >> 4) & 0xf];
out += digits[(binhash[byte] >> 0) & 0xf];
@ -296,7 +285,8 @@ string VHashSha256::digestSymbol() {
static const char digits[64 + 1]
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB";
const string& binhash = digestBinary();
string out; out.reserve(28);
string out;
out.reserve(28);
int pos = 0;
for (; pos < (256 / 8) - 2; pos += 3) {
out += digits[((binhash[pos] >> 2) & 0x3f)];
@ -310,8 +300,8 @@ string VHashSha256::digestSymbol() {
return out;
}
void VHashSha256::selfTestOne(const string& data, const string& data2,
const string& exp, const string& exp64) {
void VHashSha256::selfTestOne(const string& data, const string& data2, const string& exp,
const string& exp64) {
VHashSha256 digest(data);
if (data2 != "") digest.insert(data2);
if (VL_UNCOVERABLE(digest.digestHex() != exp)) {
@ -327,11 +317,9 @@ void VHashSha256::selfTestOne(const string& data, const string& data2,
}
void VHashSha256::selfTest() {
selfTestOne("", "",
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
selfTestOne("", "", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"47DEQpj8HBSaABTImWA5JCeuQeRkm5NMpJWZG3hS");
selfTestOne("a", "",
"ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb",
selfTestOne("a", "", "ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb",
"ypeBEsobvcr6wjGzmiPcTaeG7BgUfE5yuYB3haBu");
selfTestOne("The quick brown fox jumps over the lazy dog", "",
"d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592",
@ -420,13 +408,11 @@ VSpellCheck::EditDistance VSpellCheck::cutoffDistance(size_t goal_len, size_t ca
return (max_length + 2) / 3;
}
string VSpellCheck::bestCandidateInfo(const string& goal,
EditDistance& distancer) {
string VSpellCheck::bestCandidateInfo(const string& goal, EditDistance& distancer) {
string bestCandidate;
size_t gLen = goal.length();
distancer = LENGTH_LIMIT * 10;
for (Candidates::const_iterator it = m_candidates.begin();
it != m_candidates.end(); ++it) {
for (Candidates::const_iterator it = m_candidates.begin(); it != m_candidates.end(); ++it) {
const string candidate = *it;
size_t cLen = candidate.length();
@ -438,8 +424,8 @@ string VSpellCheck::bestCandidateInfo(const string& goal,
if (min_distance > cutoff) continue; // Short-circuit if already too bad
EditDistance dist = editDistance(goal, candidate);
UINFO(9, "EditDistance dist="<<dist<<" cutoff="<<cutoff
<<" goal="<<goal<<" candidate="<<candidate<<endl);
UINFO(9, "EditDistance dist=" << dist << " cutoff=" << cutoff << " goal=" << goal
<< " candidate=" << candidate << endl);
if (dist < distancer && dist <= cutoff) {
distancer = dist;
bestCandidate = candidate;
@ -451,8 +437,7 @@ string VSpellCheck::bestCandidateInfo(const string& goal,
return bestCandidate;
}
void VSpellCheck::selfTestDistanceOne(const string& a, const string& b,
EditDistance expected) {
void VSpellCheck::selfTestDistanceOne(const string& a, const string& b, EditDistance expected) {
UASSERT_SELFTEST(EditDistance, editDistance(a, b), expected);
UASSERT_SELFTEST(EditDistance, editDistance(b, a), expected);
}

View File

@ -30,17 +30,29 @@
// Global string-related functions
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();
}
template <class T> std::string cvtToHex(const T* tp) {
std::ostringstream os; os<<static_cast<const void*>(tp); return os.str();
std::ostringstream os;
os << static_cast<const void*>(tp);
return os.str();
}
inline uint32_t cvtToHash(const void* vp) {
// We can shove a 64 bit pointer into a 32 bit bucket
// On 32-bit systems, lower is always 0, but who cares?
union { const void* up; struct {uint32_t upper; uint32_t lower;} l;} u;
u.l.upper = 0; u.l.lower = 0; u.up = vp;
union {
const void* up;
struct {
uint32_t upper;
uint32_t lower;
} l;
} u;
u.l.upper = 0;
u.l.lower = 0;
u.up = vp;
return u.l.upper ^ u.l.lower;
}
@ -55,6 +67,7 @@ inline string ucfirst(const string& text) {
class VString {
static bool wildmatchi(const char* s, const char* p);
public:
// METHODS (generic string utilities)
// Return true if p with ? or *'s matches s
@ -95,7 +108,10 @@ class VHashSha256 {
public:
// CONSTRUCTORS
VHashSha256() { init(); }
explicit VHashSha256(const string& data) { init(); insert(data); }
explicit VHashSha256(const string& data) {
init();
insert(data);
}
~VHashSha256() {}
// METHODS
@ -107,20 +123,26 @@ public:
// Inerting hash data
void insert(const void* datap, size_t length); // Process data into the digest
void insert(const string& data) { insert(data.data(), data.length()); } // Process data into the digest
void insert(const string& data) {
insert(data.data(), data.length());
} // Process data into the digest
void insert(uint64_t value) { insert(cvtToStr(value)); }
private:
void init() {
m_inthash[0] = 0x6a09e667; m_inthash[1] = 0xbb67ae85;
m_inthash[2] = 0x3c6ef372; m_inthash[3] = 0xa54ff53a;
m_inthash[4] = 0x510e527f; m_inthash[5] = 0x9b05688c;
m_inthash[6] = 0x1f83d9ab; m_inthash[7] = 0x5be0cd19;
m_inthash[0] = 0x6a09e667;
m_inthash[1] = 0xbb67ae85;
m_inthash[2] = 0x3c6ef372;
m_inthash[3] = 0xa54ff53a;
m_inthash[4] = 0x510e527f;
m_inthash[5] = 0x9b05688c;
m_inthash[6] = 0x1f83d9ab;
m_inthash[7] = 0x5be0cd19;
m_final = false;
m_totLength = 0;
}
static void selfTestOne(const string& data, const string& data2,
const string& exp, const string& exp64);
static void selfTestOne(const string& data, const string& data2, const string& exp,
const string& exp64);
void finalize(); // Process remaining data
};
@ -136,10 +158,14 @@ class VName {
static size_t s_minLength; // Length to preserve if over maxLength
public:
// CONSTRUCTORS
explicit VName(const string& name) : m_name(name) {}
explicit VName(const string& name)
: m_name(name) {}
~VName() {}
// METHODS
void name(const string& name) { m_name = name; m_hashed = ""; }
void name(const string& name) {
m_name = name;
m_hashed = "";
}
string name() const { return m_name; }
string hashedName();
// CONFIG STATIC METHODS
@ -178,16 +204,19 @@ public:
// Return friendly message
string bestCandidateMsg(const string& goal) {
string candidate = bestCandidate(goal);
if (candidate.empty()) return "";
else return string("... Suggested alternative: '")+candidate+"'";
if (candidate.empty()) {
return "";
} else {
return string("... Suggested alternative: '") + candidate + "'";
}
}
static void selfTest();
private:
static EditDistance editDistance(const string& s, const string& t);
static EditDistance cutoffDistance(size_t goal_len, size_t candidate_len);
string bestCandidateInfo(const string& goal, EditDistance& distancer);
static void selfTestDistanceOne(const string& a, const string& b,
EditDistance expected);
static void selfTestDistanceOne(const string& a, const string& b, EditDistance expected);
static void selfTestSuggestOne(bool matches, const string& c, const string& goal,
EditDistance dist);
};

View File

@ -61,7 +61,6 @@ class VSymEnt {
static inline int debug() { return 0; } // NOT runtime, too hot of a function
#endif
public:
typedef IdNameMap::const_iterator const_iterator;
const_iterator begin() const { return m_idNameMap.begin(); }
const_iterator end() const { return m_idNameMap.end(); }
@ -79,9 +78,11 @@ public:
os << indent << "| ^ duplicate, so no children printed\n";
} else {
doneSymsr.insert(this);
for (IdNameMap::const_iterator it=m_idNameMap.begin(); it!=m_idNameMap.end(); ++it) {
for (IdNameMap::const_iterator it = m_idNameMap.begin(); it != m_idNameMap.end();
++it) {
if (numLevels >= 1) {
it->second->dumpIterate(os, doneSymsr, indent+"| ", numLevels-1, it->first);
it->second->dumpIterate(os, doneSymsr, indent + "| ", numLevels - 1,
it->first);
}
}
}
@ -120,12 +121,13 @@ public:
bool imported() const { return m_imported; }
void imported(bool flag) { m_imported = flag; }
void insert(const string& name, VSymEnt* entp) {
UINFO(9, " SymInsert se"<<cvtToHex(this)
<<" '"<<name<<"' se"<<cvtToHex(entp)<<" "<<entp->nodep()<<endl);
UINFO(9, " SymInsert se" << cvtToHex(this) << " '" << name << "' se" << cvtToHex(entp)
<< " " << entp->nodep() << endl);
if (name != "" && m_idNameMap.find(name) != m_idNameMap.end()) {
if (!V3Error::errorCount()) { // Else may have just reported warning
if (debug() >= 9 || V3Error::debugDefault()) dump(cout, "- err-dump: ", 1);
entp->nodep()->v3fatalSrc("Inserting two symbols with same name: "<<name<<endl);
entp->nodep()->v3fatalSrc("Inserting two symbols with same name: " << name
<< endl);
}
} else {
m_idNameMap.insert(make_pair(name, entp));
@ -134,8 +136,8 @@ public:
void reinsert(const string& name, VSymEnt* entp) {
IdNameMap::iterator it = m_idNameMap.find(name);
if (name != "" && it != m_idNameMap.end()) {
UINFO(9, " SymReinsert se"<<cvtToHex(this)
<<" '"<<name<<"' se"<<cvtToHex(entp)<<" "<<entp->nodep()<<endl);
UINFO(9, " SymReinsert se" << cvtToHex(this) << " '" << name << "' se"
<< cvtToHex(entp) << " " << entp->nodep() << endl);
it->second = entp; // Replace
} else {
insert(name, entp);
@ -145,9 +147,12 @@ public:
// Find identifier without looking upward through symbol hierarchy
// First, scan this begin/end block or module for the name
IdNameMap::const_iterator it = m_idNameMap.find(name);
UINFO(9, " SymFind se"<<cvtToHex(this)<<" '"<<name
<<"' -> "<<(it == m_idNameMap.end() ? "NONE"
: "se"+cvtToHex(it->second)+" n="+cvtToHex(it->second->nodep()))<<endl);
UINFO(9, " SymFind se"
<< cvtToHex(this) << " '" << name << "' -> "
<< (it == m_idNameMap.end()
? "NONE"
: "se" + cvtToHex(it->second) + " n=" + cvtToHex(it->second->nodep()))
<< endl);
if (it != m_idNameMap.end()) return (it->second);
return NULL;
}
@ -161,8 +166,7 @@ public:
}
void candidateIdFlat(VSpellCheck* spellerp, const VNodeMatcher* matcherp) const {
// Suggest alternative symbol candidates without looking upward through symbol hierarchy
for (IdNameMap::const_iterator it = m_idNameMap.begin();
it != m_idNameMap.end(); ++it) {
for (IdNameMap::const_iterator it = m_idNameMap.begin(); it != m_idNameMap.end(); ++it) {
const AstNode* itemp = it->second->nodep();
if (itemp && (!matcherp || matcherp->nodeMatch(itemp))) {
spellerp->pushCandidate(itemp->prettyName());
@ -176,10 +180,10 @@ public:
// Then suggest the upper begin/end block or module
if (m_fallbackp) m_fallbackp->candidateIdFallback(spellerp, matcherp);
}
private:
void importOneSymbol(VSymGraph* graphp, const string& name, const VSymEnt* srcp) {
if (srcp->exported()
&& !findIdFlat(name)) { // Don't insert over existing entry
if (srcp->exported() && !findIdFlat(name)) { // Don't insert over existing entry
VSymEnt* symp = new VSymEnt(graphp, srcp);
symp->exported(false); // Can't reimport an import without an export
symp->imported(true);
@ -193,14 +197,13 @@ private:
}
}
}
public:
void importFromPackage(VSymGraph* graphp, const VSymEnt* srcp, const string& id_or_star) {
// Import tokens from source symbol table into this symbol table
if (id_or_star != "*") {
IdNameMap::const_iterator it = srcp->m_idNameMap.find(id_or_star);
if (it != srcp->m_idNameMap.end()) {
importOneSymbol(graphp, it->first, it->second);
}
if (it != srcp->m_idNameMap.end()) importOneSymbol(graphp, it->first, it->second);
} else {
for (IdNameMap::const_iterator it = srcp->m_idNameMap.begin();
it != srcp->m_idNameMap.end(); ++it) {
@ -212,9 +215,7 @@ public:
// Export tokens from source symbol table into this symbol table
if (id_or_star != "*") {
IdNameMap::const_iterator it = srcp->m_idNameMap.find(id_or_star);
if (it != srcp->m_idNameMap.end()) {
exportOneSymbol(graphp, it->first, it->second);
}
if (it != srcp->m_idNameMap.end()) exportOneSymbol(graphp, it->first, it->second);
} else {
for (IdNameMap::const_iterator it = srcp->m_idNameMap.begin();
it != srcp->m_idNameMap.end(); ++it) {
@ -250,15 +251,14 @@ public:
string scopes;
for (IdNameMap::iterator it = m_idNameMap.begin(); it != m_idNameMap.end(); ++it) {
AstNode* itemp = it->second->nodep();
if (VN_IS(itemp, Cell)
|| (VN_IS(itemp, Module) && VN_CAST(itemp, Module)->isTop())) {
if (VN_IS(itemp, Cell) || (VN_IS(itemp, Module) && VN_CAST(itemp, Module)->isTop())) {
if (scopes != "") scopes += ", ";
scopes += AstNode::prettyName(it->first);
}
}
if (scopes == "") scopes = "<no cells found>";
std::cerr<<V3Error::warnMore()<<"... Known scopes under '"<<prettyName<<"': "
<<scopes<<endl;
std::cerr << V3Error::warnMore() << "... Known scopes under '" << prettyName
<< "': " << scopes << endl;
if (debug()) dump(std::cerr, " KnownScope: ", 1);
}
};
@ -277,14 +277,11 @@ class VSymGraph {
// CONSTRUCTORS
VL_UNCOPYABLE(VSymGraph);
public:
explicit VSymGraph(AstNetlist* nodep) {
m_symRootp = new VSymEnt(this, nodep);
}
explicit VSymGraph(AstNetlist* nodep) { m_symRootp = new VSymEnt(this, nodep); }
~VSymGraph() {
for (SymStack::iterator it = m_symsp.begin(); it != m_symsp.end(); ++it) {
delete (*it);
}
for (SymStack::iterator it = m_symsp.begin(); it != m_symsp.end(); ++it) delete (*it);
}
public:
@ -298,7 +295,10 @@ public:
bool first = true;
for (SymStack::iterator it = m_symsp.begin(); it != m_symsp.end(); ++it) {
if (doneSyms.find(*it) == doneSyms.end()) {
if (first) { first=false; os<<"%%Warning: SymEnt Orphans:\n"; }
if (first) {
first = false;
os << "%%Warning: SymEnt Orphans:\n";
}
(*it)->dumpIterate(os, doneSyms, indent, 9999, "Orphan");
}
}

View File

@ -69,13 +69,15 @@ public:
enum { ACTIVITY_ALWAYS = ((1UL << 31) - 2) };
enum { ACTIVITY_SLOW = 0 };
TraceActivityVertex(V3Graph* graphp, AstNode* nodep, bool slow)
: V3GraphVertex(graphp), m_insertp(nodep) {
: V3GraphVertex(graphp)
, m_insertp(nodep) {
m_activityCode = 0;
m_activityCodeValid = false;
m_slow = slow;
}
TraceActivityVertex(V3Graph* graphp, vlsint32_t code)
: V3GraphVertex(graphp), m_insertp(NULL) {
: V3GraphVertex(graphp)
, m_insertp(NULL) {
m_activityCode = code;
m_activityCodeValid = true;
m_slow = false;
@ -87,24 +89,33 @@ public:
return m_insertp;
}
virtual string name() const {
if (activityAlways()) return "*ALWAYS*";
else return (string(slow()?"*SLOW* ":""))+insertp()->name();
if (activityAlways()) {
return "*ALWAYS*";
} else {
return (string(slow() ? "*SLOW* " : "")) + insertp()->name();
}
}
virtual string dotColor() const { return slow() ? "yellowGreen" : "green"; }
bool activityCodeValid() const { return m_activityCodeValid; }
vlsint32_t activityCode() const { return m_activityCode; }
bool activityAlways() const { return activityCode() == ACTIVITY_ALWAYS; }
void activityCode(vlsint32_t code) { m_activityCode = code; m_activityCodeValid = true;}
void activityCode(vlsint32_t code) {
m_activityCode = code;
m_activityCodeValid = true;
}
bool slow() const { return m_slow; }
void slow(bool flag) { if (!flag) m_slow = false; }
void slow(bool flag) {
if (!flag) m_slow = false;
}
};
class TraceCFuncVertex : public V3GraphVertex {
AstCFunc* m_nodep;
public:
TraceCFuncVertex(V3Graph* graphp, AstCFunc* nodep)
: V3GraphVertex(graphp), m_nodep(nodep) {
}
: V3GraphVertex(graphp)
, m_nodep(nodep) {}
virtual ~TraceCFuncVertex() {}
// ACCESSORS
AstCFunc* nodep() const { return m_nodep; }
@ -115,10 +126,14 @@ public:
class TraceTraceVertex : public V3GraphVertex {
AstTraceInc* m_nodep; // TRACEINC this represents
TraceTraceVertex* m_duplicatep; // NULL, or other vertex with the real code() that duplicates this one
// NULL, or other vertex with the real code() that duplicates this one
TraceTraceVertex* m_duplicatep;
public:
TraceTraceVertex(V3Graph* graphp, AstTraceInc* nodep)
: V3GraphVertex(graphp), m_nodep(nodep), m_duplicatep(NULL) {}
: V3GraphVertex(graphp)
, m_nodep(nodep)
, m_duplicatep(NULL) {}
virtual ~TraceTraceVertex() {}
// ACCESSORS
AstTraceInc* nodep() const { return m_nodep; }
@ -127,17 +142,18 @@ public:
virtual FileLine* fileline() const { return nodep()->fileline(); }
TraceTraceVertex* duplicatep() const { return m_duplicatep; }
void duplicatep(TraceTraceVertex* dupp) {
UASSERT_OBJ(!duplicatep(), nodep(),
"Assigning duplicatep() to already duplicated node");
UASSERT_OBJ(!duplicatep(), nodep(), "Assigning duplicatep() to already duplicated node");
m_duplicatep = dupp;
}
};
class TraceVarVertex : public V3GraphVertex {
AstVarScope* m_nodep;
public:
TraceVarVertex(V3Graph* graphp, AstVarScope* nodep)
: V3GraphVertex(graphp), m_nodep(nodep) {}
: V3GraphVertex(graphp)
, m_nodep(nodep) {}
virtual ~TraceVarVertex() {}
// ACCESSORS
AstVarScope* nodep() const { return m_nodep; }
@ -206,8 +222,8 @@ private:
"Trace duplicate back needs consistency,"
" so we can map duplicates back to TRACEINCs");
hashed.hash(nodep->valuep());
UINFO(8, " Hashed "<<std::hex<<hashed.nodeHash(nodep->valuep())
<<" "<<nodep<<endl);
UINFO(8, " Hashed " << std::hex << hashed.nodeHash(nodep->valuep()) << " "
<< nodep << endl);
// Just keep one node in the map and point all duplicates to this node
if (hashed.findDuplicate(nodep->valuep()) == hashed.end()) {
@ -291,9 +307,7 @@ private:
for (V3GraphVertex *nextp, *itp = m_graph.verticesBeginp(); itp; itp = nextp) {
nextp = itp->verticesNextp();
if (TraceActivityVertex* vvertexp = dynamic_cast<TraceActivityVertex*>(itp)) {
if (!vvertexp->outBeginp()) {
vvertexp->unlinkDelete(&m_graph);
}
if (!vvertexp->outBeginp()) { vvertexp->unlinkDelete(&m_graph); }
}
}
}
@ -328,13 +342,10 @@ private:
= new AstBasicDType(m_chgFuncp->fileline(), VFlagLogicPacked(), 1);
v3Global.rootp()->typeTablep()->addTypesp(newScalarDtp);
AstNodeDType* newArrDtp = new AstUnpackArrayDType(
m_chgFuncp->fileline(),
newScalarDtp,
new AstRange(m_chgFuncp->fileline(),
VNumRange(m_activityNumber-1, 0, false)));
m_chgFuncp->fileline(), newScalarDtp,
new AstRange(m_chgFuncp->fileline(), VNumRange(m_activityNumber - 1, 0, false)));
v3Global.rootp()->typeTablep()->addTypesp(newArrDtp);
newvarp = new AstVar(m_chgFuncp->fileline(),
AstVarType::MODULETEMP,
newvarp = new AstVar(m_chgFuncp->fileline(), AstVarType::MODULETEMP,
"__Vm_traceActivity", newArrDtp);
} else {
// For tighter code; round to next word point.
@ -353,8 +364,8 @@ private:
if (!vvertexp->activityAlways()) {
FileLine* fl = vvertexp->insertp()->fileline();
uint32_t acode = vvertexp->activityCode();
vvertexp->insertp()->addNextHere
(new AstAssign(fl, selectActivity(fl, acode, true),
vvertexp->insertp()->addNextHere(
new AstAssign(fl, selectActivity(fl, acode, true),
new AstConst(fl, AstConst::LogicTrue())));
}
}
@ -363,19 +374,17 @@ private:
AstNode* selectActivity(FileLine* flp, uint32_t acode, bool lvalue) {
if (v3Global.opt.mtasks()) {
return new AstArraySel(
flp, new AstVarRef(flp, m_activityVscp, lvalue), acode);
return new AstArraySel(flp, new AstVarRef(flp, m_activityVscp, lvalue), acode);
} else {
return new AstSel(
flp, new AstVarRef(flp, m_activityVscp, lvalue), acode, 1);
return new AstSel(flp, new AstVarRef(flp, m_activityVscp, lvalue), acode, 1);
}
}
AstCFunc* newCFunc(AstCFuncType type, const string& name, AstCFunc* basep) {
AstCFunc* funcp = new AstCFunc(basep->fileline(), name, basep->scopep());
funcp->slow(basep->slow());
funcp->argTypes(EmitCBaseVisitor::symClassVar()
+", "+v3Global.opt.traceClassBase()+"* vcdp, uint32_t code");
funcp->argTypes(EmitCBaseVisitor::symClassVar() + ", " + v3Global.opt.traceClassBase()
+ "* vcdp, uint32_t code");
funcp->funcType(type);
funcp->symProlog(true);
basep->addNext(funcp);
@ -404,8 +413,7 @@ private:
return funcp;
}
void addToChgSub(AstNode* underp, AstNode* stmtsp) {
if (!m_chgSubFuncp
|| (m_chgSubParentp != underp)
if (!m_chgSubFuncp || (m_chgSubParentp != underp)
|| (m_chgSubStmts && v3Global.opt.outputSplitCTrace()
&& m_chgSubStmts > v3Global.opt.outputSplitCTrace())) {
m_chgSubFuncp = newCFuncSub(m_chgFuncp, underp);
@ -421,7 +429,8 @@ private:
UINFO(9, "Making trees\n");
typedef std::set<uint32_t> ActCodeSet; // All activity numbers applying to a given trace
typedef std::multimap<ActCodeSet,TraceTraceVertex*> TraceVec; // For activity set, what traces apply
typedef std::multimap<ActCodeSet, TraceTraceVertex*>
TraceVec; // For activity set, what traces apply
TraceVec traces;
// Form sort structure
@ -476,7 +485,8 @@ private:
AstNode* addp = assignTraceCode(vvertexp, vvertexp->nodep(), needChg);
if (addp) { // Else no activity or duplicate
if (actset.find(TraceActivityVertex::ACTIVITY_NEVER) != actset.end()) {
vvertexp->nodep()->v3fatalSrc("If never, needChg=0 and shouldn't need to add.");
vvertexp->nodep()->v3fatalSrc(
"If never, needChg=0 and shouldn't need to add.");
} else if (actset.find(TraceActivityVertex::ACTIVITY_ALWAYS) != actset.end()) {
// Must always set it; add to base of function
addToChgSub(m_chgFuncp, addp);
@ -487,12 +497,14 @@ private:
// Build a new IF statement
FileLine* fl = addp->fileline();
AstNode* condp = NULL;
for (ActCodeSet::const_iterator csit = actset.begin();
csit != actset.end(); ++csit) {
for (ActCodeSet::const_iterator csit = actset.begin(); csit != actset.end();
++csit) {
uint32_t acode = *csit;
AstNode* selp = selectActivity(fl, acode, false);
if (condp) condp = new AstOr(fl, condp, selp);
else condp = selp;
if (condp)
condp = new AstOr(fl, condp, selp);
else
condp = selp;
}
AstIf* ifp = new AstIf(fl, condp, NULL, NULL);
ifp->branchPred(VBranchPred::BP_UNLIKELY);
@ -517,9 +529,9 @@ private:
m_chgFuncp->addFinalsp(clrp);
}
} else {
AstNode* clrp = new AstAssign(fl, new AstVarRef(fl, m_activityVscp, true),
new AstConst(fl, AstConst::WidthedValue(),
m_activityVscp->width(), 0));
AstNode* clrp = new AstAssign(
fl, new AstVarRef(fl, m_activityVscp, true),
new AstConst(fl, AstConst::WidthedValue(), m_activityVscp->width(), 0));
m_fullFuncp->addFinalsp(clrp->cloneTree(true));
m_chgFuncp->addFinalsp(clrp);
}
@ -558,9 +570,9 @@ private:
} else {
assignDeclCode(nodep->declp());
}
UINFO(8," Created code="<<nodep->declp()->code()
<<" "<<(codePreassigned?"[PREASS]":"")
<<" "<<(needChg?"[CHG]":"")<<" "<<nodep<<endl);
UINFO(8, " Created code=" << nodep->declp()->code() << " "
<< (codePreassigned ? "[PREASS]" : "") << " "
<< (needChg ? "[CHG]" : "") << " " << nodep << endl);
AstNode* incAddp = NULL;
if (!codePreassigned) {
@ -673,11 +685,12 @@ private:
m_chgFuncp = nodep;
}
V3GraphVertex* funcVtxp = getCFuncVertexp(nodep);
if (!m_finding) { // If public, we need a unique activity code to allow for sets directly in this func
if (nodep->funcPublic() || nodep->dpiExport()
|| nodep == v3Global.rootp()->evalp()) {
if (!m_finding) { // If public, we need a unique activity code to allow for sets directly
// in this func
if (nodep->funcPublic() || nodep->dpiExport() || nodep == v3Global.rootp()->evalp()) {
// Need a non-null place to remember to later add a statement; make one
if (!nodep->stmtsp()) nodep->addStmtsp(
if (!nodep->stmtsp())
nodep->addStmtsp(
new AstComment(nodep->fileline(), "Tracing activity check", true));
V3GraphVertex* activityVtxp = getActivityVertexp(nodep->stmtsp(), nodep->slow());
new V3GraphEdge(&m_graph, activityVtxp, funcVtxp, 1);
@ -715,8 +728,7 @@ private:
|| nodep->varp()->isSigPublic()) { // Or ones user can change
new V3GraphEdge(&m_graph, m_alwaysVtxp, traceVtxp, 1);
}
}
else if (m_funcp && m_finding && nodep->lvalue()) {
} else if (m_funcp && m_finding && nodep->lvalue()) {
UASSERT_OBJ(nodep->varScopep(), nodep, "No var scope?");
V3GraphVertex* funcVtxp = getCFuncVertexp(m_funcp);
V3GraphVertex* varVtxp = nodep->varScopep()->user1u().toGraphVertex();
@ -763,8 +775,6 @@ public:
void V3Trace::traceAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl);
{
TraceVisitor visitor(nodep);
} // Destruct before checking
{ TraceVisitor visitor(nodep); } // Destruct before checking
V3Global::dumpCheckGlobalTree("trace", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -62,16 +62,12 @@ private:
AstVar* varp = nodep->varp();
if (!varp->isTrace()) {
return "Verilator trace_off";
}
else if (!nodep->isTrace()) {
} else if (!nodep->isTrace()) {
return "Verilator cell trace_off";
}
else if (!v3Global.opt.traceUnderscore()) {
} else if (!v3Global.opt.traceUnderscore()) {
string prettyName = varp->prettyName();
if (!prettyName.empty() && prettyName[0] == '_')
return "Leading underscore";
if (prettyName.find("._") != string::npos)
return "Inlined leading underscore";
if (!prettyName.empty() && prettyName[0] == '_') return "Leading underscore";
if (prettyName.find("._") != string::npos) return "Inlined leading underscore";
}
return NULL;
}
@ -108,14 +104,18 @@ private:
return funcp;
}
void addTraceDecl(const VNumRange& arrayRange,
int widthOverride) { // If !=0, is packed struct/array where basicp size misreflects one element
int widthOverride) { // If !=0, is packed struct/array where basicp size
// misreflects one element
VNumRange bitRange;
AstBasicDType* bdtypep = m_traValuep->dtypep()->basicp();
if (widthOverride) bitRange = VNumRange(widthOverride-1, 0, false);
else if (bdtypep) bitRange = bdtypep->nrange();
AstTraceDecl* declp = new AstTraceDecl(m_traVscp->fileline(), m_traShowname,
m_traVscp->varp(), m_traValuep,
bitRange, arrayRange, m_interface);
if (widthOverride) {
bitRange = VNumRange(widthOverride - 1, 0, false);
} else if (bdtypep) {
bitRange = bdtypep->nrange();
}
AstTraceDecl* declp
= new AstTraceDecl(m_traVscp->fileline(), m_traShowname, m_traVscp->varp(),
m_traValuep, bitRange, arrayRange, m_interface);
UINFO(9, "Decl " << declp << endl);
if (!m_interface && v3Global.opt.outputSplitCTrace()
@ -127,15 +127,14 @@ private:
m_initSubFuncp->addStmtsp(declp);
m_initSubStmts += EmitCBaseCounterVisitor(declp).count();
m_chgFuncp->addStmtsp(new AstTraceInc(m_traVscp->fileline(),
declp, m_traValuep->cloneTree(true)));
m_chgFuncp->addStmtsp(
new AstTraceInc(m_traVscp->fileline(), declp, m_traValuep->cloneTree(true)));
// The full version will get constructed in V3Trace
}
void addIgnore(const char* why) {
++m_statIgnSigs;
m_initSubFuncp->addStmtsp(
new AstComment(m_traVscp->fileline(),
"Tracing: "+m_traShowname+" // Ignored: "+why, true));
m_initSubFuncp->addStmtsp(new AstComment(
m_traVscp->fileline(), "Tracing: " + m_traShowname + " // Ignored: " + why, true));
}
// VISITORS
@ -195,8 +194,7 @@ private:
// Generally this equation doesn't need updating, instead use
// varp->isTrace() and/or vscIgnoreTrace.
if ((!nodep->varp()->isTemp() || nodep->varp()->isTrace())
&& !nodep->varp()->isClassMember()
&& !nodep->varp()->isFuncLocal()) {
&& !nodep->varp()->isClassMember() && !nodep->varp()->isFuncLocal()) {
UINFO(5, " vsc " << nodep << endl);
AstVar* varp = nodep->varp();
AstScope* scopep = nodep->scopep();
@ -217,8 +215,11 @@ private:
addIgnore(vscIgnoreTrace(nodep));
} else {
++m_statSigs;
if (nodep->valuep()) m_traValuep = nodep->valuep()->cloneTree(true);
else m_traValuep = new AstVarRef(nodep->fileline(), nodep, false);
if (nodep->valuep()) {
m_traValuep = nodep->valuep()->cloneTree(true);
} else {
m_traValuep = new AstVarRef(nodep->fileline(), nodep, false);
}
{
// Recurse into data type of the signal; the visitors will call addTraceDecl()
iterate(varp->dtypep()->skipRefToEnump());
@ -233,22 +234,20 @@ private:
}
// VISITORS - Data types when tracing
virtual void visit(AstConstDType* nodep) VL_OVERRIDE {
if (m_traVscp) {
iterate(nodep->subDTypep()->skipRefToEnump());
}
if (m_traVscp) iterate(nodep->subDTypep()->skipRefToEnump());
}
virtual void visit(AstRefDType* nodep) VL_OVERRIDE {
if (m_traVscp) {
iterate(nodep->subDTypep()->skipRefToEnump());
}
if (m_traVscp) iterate(nodep->subDTypep()->skipRefToEnump());
}
virtual void visit(AstUnpackArrayDType* nodep) VL_OVERRIDE {
// Note more specific dtypes above
if (m_traVscp) {
if (static_cast<int>(nodep->arrayUnpackedElements()) > v3Global.opt.traceMaxArray()) {
addIgnore("Wide memory > --trace-max-array ents");
} else if (VN_IS(nodep->subDTypep()->skipRefToEnump(), BasicDType) // Nothing lower than this array
&& m_traVscp->dtypep()->skipRefToEnump() == nodep) { // Nothing above this array
} else if (VN_IS(nodep->subDTypep()->skipRefToEnump(),
BasicDType) // Nothing lower than this array
&& m_traVscp->dtypep()->skipRefToEnump()
== nodep) { // Nothing above this array
// Simple 1-D array, use existing V3EmitC runtime loop rather than unrolling
// This will put "(index)" at end of signal name for us
if (m_traVscp->dtypep()->skipRefToEnump()->isString()) {
@ -264,9 +263,8 @@ private:
AstNode* oldValuep = m_traValuep;
{
m_traShowname += string("(") + cvtToStr(i) + string(")");
m_traValuep = new AstArraySel(nodep->fileline(),
m_traValuep->cloneTree(true),
i - nodep->lsb());
m_traValuep = new AstArraySel(
nodep->fileline(), m_traValuep->cloneTree(true), i - nodep->lsb());
m_traValuep->dtypep(subtypep);
iterate(subtypep);
@ -316,16 +314,16 @@ private:
if (!nodep->packed()) {
addIgnore("Unsupported: Unpacked struct/union");
} else {
for (AstMemberDType* itemp = nodep->membersp();
itemp; itemp=VN_CAST(itemp->nextp(), MemberDType)) {
for (AstMemberDType* itemp = nodep->membersp(); itemp;
itemp = VN_CAST(itemp->nextp(), MemberDType)) {
AstNodeDType* subtypep = itemp->subDTypep()->skipRefToEnump();
string oldShowname = m_traShowname;
AstNode* oldValuep = m_traValuep;
{
m_traShowname += string(" ") + itemp->prettyName();
if (VN_IS(nodep, StructDType)) {
m_traValuep = new AstSel(nodep->fileline(),
m_traValuep->cloneTree(true),
m_traValuep
= new AstSel(nodep->fileline(), m_traValuep->cloneTree(true),
itemp->lsb(), subtypep->width());
m_traValuep->dtypep(subtypep);
iterate(subtypep);
@ -350,9 +348,7 @@ private:
}
}
}
virtual void visit(AstEnumDType* nodep) VL_OVERRIDE {
iterate(nodep->skipRefp());
}
virtual void visit(AstEnumDType* nodep) VL_OVERRIDE { iterate(nodep->skipRefp()); }
virtual void visit(AstNodeDType* nodep) VL_OVERRIDE {
// Note more specific dtypes above
if (!m_traVscp) return;
@ -388,8 +384,6 @@ public:
void V3TraceDecl::traceDeclAll(AstNetlist* nodep) {
UINFO(2, __FUNCTION__ << ": " << endl);
{
TraceDeclVisitor visitor (nodep);
} // Destruct before checking
{ TraceDeclVisitor visitor(nodep); } // Destruct before checking
V3Global::dumpCheckGlobalTree("tracedecl", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

View File

@ -23,9 +23,11 @@
#include "V3Error.h"
#include "V3Ast.h"
// clang-format off
#ifndef _V3WIDTH_CPP_
# error "V3WidthCommit for V3Width internal use only"
#endif
// clang-format on
//######################################################################
@ -55,9 +57,7 @@ public:
// CONSTRUCTORS
WidthRemoveVisitor() {}
virtual ~WidthRemoveVisitor() {}
AstNode* mainAcceptEdit(AstNode* nodep) {
return iterateSubtreeReturnEdits(nodep);
}
AstNode* mainAcceptEdit(AstNode* nodep) { return iterateSubtreeReturnEdits(nodep); }
};
//######################################################################
@ -72,8 +72,7 @@ class WidthCommitVisitor : public AstNVisitor {
public:
// METHODS
static AstConst* newIfConstCommitSize(AstConst* nodep) {
if (((nodep->dtypep()->width() != nodep->num().width())
|| !nodep->num().sized())
if (((nodep->dtypep()->width() != nodep->num().width()) || !nodep->num().sized())
&& !nodep->num().isString()) { // Need to force the number from unsized to sized
V3Number num(nodep, nodep->dtypep()->width());
num.opAssign(nodep->num());
@ -103,8 +102,11 @@ private:
if (AstBasicDType* bdtypep = VN_CAST(nodep, BasicDType)) {
AstBasicDType* newp = nodep->findInsertSameDType(bdtypep);
if (newp != bdtypep && debug() >= 9) {
UINFO(9,"dtype replacement "); nodep->dumpSmall(cout);
cout<<" ----> "; newp->dumpSmall(cout); cout<<endl;
UINFO(9, "dtype replacement ");
nodep->dumpSmall(cout);
cout << " ----> ";
newp->dumpSmall(cout);
cout << endl;
}
return newp;
}
@ -116,16 +118,15 @@ private:
iterate(nodep->dtypep()); // Do datatype first
if (AstConst* newp = newIfConstCommitSize(nodep)) {
nodep->replaceWith(newp);
AstNode* oldp = nodep; nodep = newp;
AstNode* oldp = nodep;
nodep = newp;
// if (debug()>4) oldp->dumpTree(cout, " fixConstSize_old: ");
// if (debug()>4) newp->dumpTree(cout, " _new: ");
VL_DO_DANGLING(pushDeletep(oldp), oldp);
}
editDType(nodep);
}
virtual void visit(AstNodeDType* nodep) VL_OVERRIDE {
visitIterateNodeDType(nodep);
}
virtual void visit(AstNodeDType* nodep) VL_OVERRIDE { visitIterateNodeDType(nodep); }
virtual void visit(AstNodeUOrStructDType* nodep) VL_OVERRIDE {
if (nodep->user1SetOnce()) return; // Process once
visitIterateNodeDType(nodep);
@ -158,6 +159,7 @@ private:
iterateChildren(nodep);
editDType(nodep);
}
public:
// CONSTRUCTORS
explicit WidthCommitVisitor(AstNetlist* nodep) {

View File

@ -47,9 +47,7 @@ private:
v3fatal("Out of memory increasing buckets");
}
m_datap = newp;
for (vluint64_t i = oldsize; i < m_dataSize; i += 64) {
m_datap[i / 64] = 0;
}
for (vluint64_t i = oldsize; i < m_dataSize; i += 64) m_datap[i / 64] = 0;
}
public:

View File

@ -14,14 +14,16 @@
//
//*************************************************************************
// Cheat for speed and compile .cpp files into one object
// clang-format off
#include "config_build.h"
#ifndef HAVE_CONFIG_BUILD
# error "Something failed during ./configure as config_build.h is incomplete. Perhaps you used autoreconf, don't."
#endif
// clang-format on
#include "verilatedos.h"
// Cheat for speed and compile .cpp files into one object
#define _V3ERROR_NO_GLOBAL_ 1
#include "V3Error.cpp"
#include "V3String.cpp"

View File

@ -34,6 +34,7 @@ typedef std::set<string> VlStringSet;
class VlcOptions {
// MEMBERS (general options)
// clang-format off
string m_annotateOut; // main switch: --annotate I<output_directory>
bool m_annotateAll; // main switch: --annotate-all
int m_annotateMin; // main switch: --annotate-min I<count>
@ -41,6 +42,7 @@ class VlcOptions {
bool m_rank; // main switch: --rank
bool m_unlink; // main switch: --unlink
string m_writeFile; // main switch: --write
// clang-format on
private:
// METHODS

View File

@ -67,8 +67,7 @@ public:
const string namestr = name();
for (const char* cp = namestr.c_str(); *cp; ++cp) {
if (*cp == '\001') {
if (0 == strncmp(cp + 1, shortKey, shortLen)
&& cp[shortLen + 1] == '\002') {
if (0 == strncmp(cp + 1, shortKey, shortLen) && cp[shortLen + 1] == '\002') {
cp += shortLen + 2; // Skip \001+short+\002
const char* ep = cp;
while (*ep && *ep != '\001') ++ep;
@ -110,7 +109,8 @@ public:
public:
// CONSTRUCTORS
VlcPoints() : m_numPoints(0) {}
VlcPoints()
: m_numPoints(0) {}
~VlcPoints() {}
// METHODS

View File

@ -89,9 +89,7 @@ public:
// METHODS
void incCount(int lineno, int column, vluint64_t count, bool ok) {
LinenoMap::iterator lit = m_lines.find(lineno);
if (lit == m_lines.end()) {
lit = m_lines.insert(make_pair(lineno, ColumnMap())).first;
}
if (lit == m_lines.end()) lit = m_lines.insert(make_pair(lineno, ColumnMap())).first;
ColumnMap& cmap = lit->second;
ColumnMap::iterator cit = cmap.find(column);
if (cit == cmap.end()) {

View File

@ -126,9 +126,7 @@ public:
return testp;
}
void clearUser() {
for (ByName::iterator it = m_tests.begin(); it != m_tests.end(); ++it) {
(*it)->user(0);
}
for (ByName::iterator it = m_tests.begin(); it != m_tests.end(); ++it) (*it)->user(0);
}
};

View File

@ -114,7 +114,10 @@ void VlcTop::rank() {
// then hierarchically solve a small subset of tests, and take resulting
// solution and move up to larger subset of tests. (Aka quick sort.)
while (true) {
if (debug()) { UINFO(9, "Left on iter" << nextrank << ": "); remaining.dump(); }
if (debug()) {
UINFO(9, "Left on iter" << nextrank << ": ");
remaining.dump();
}
VlcTest* bestTestp = NULL;
vluint64_t bestRemain = 0;
for (std::vector<VlcTest*>::iterator it = bytime.begin(); it != bytime.end(); ++it) {
@ -151,7 +154,8 @@ void VlcTop::annotateCalc() {
string threshStr = point.thresh();
unsigned thresh = (!threshStr.empty()) ? atoi(threshStr.c_str()) : opt.annotateMin();
bool ok = (point.count() >= thresh);
UINFO(9, "AnnoCalc count " << filename << " " << lineno << " " << point.count() << endl);
UINFO(9,
"AnnoCalc count " << filename << " " << lineno << " " << point.count() << endl);
source.incCount(lineno, column, point.count(), ok);
}
}

View File

@ -37,6 +37,7 @@
// If set to "", this default is ignored and the user is expected
// to set them at Verilator runtime.
// clang-format off
#ifndef DEFENV_SYSTEMC
# define DEFENV_SYSTEMC ""
#endif
@ -52,6 +53,7 @@
#ifndef DEFENV_VERILATOR_ROOT
# define DEFENV_VERILATOR_ROOT ""
#endif
// clang-format on
//**********************************************************************
//**** Compile options