Compare commits

...
43 Commits
Author SHA1 Message Date
Wilson Snyder 379177d2f4 Version bump 2017-09-23 10:04:52 -04:00
Wilson Snyder fb193d6172 Internals: Ignore gmon.out 2017-09-23 09:52:06 -04:00
Wilson Snyder 16234bb713 Tests: Call driver's run instead of private _run. 2017-09-23 08:50:39 -04:00
Wilson Snyder 3f14e649b5 Internals: Use singleton in place of global 2017-09-23 07:44:52 -04:00
Wilson Snyder c2e8062f84 Verilated headers no longer "use namespace std;" 2017-09-23 07:32:37 -04:00
Wilson Snyder 5d3fef21b0 Cleanup misc spacing and unneeded stuff in emitted headers. 2017-09-22 22:27:03 -04:00
Wilson Snyder b64e1b4a49 Fix inverted sync/async message. 2017-09-22 18:57:53 -04:00
Wilson Snyder 89f414b185 Less verbosity for IEEE warnings in earlier commit this rev. 2017-09-21 22:07:49 -04:00
Wilson Snyder 47e13cfdf4 Optimize concat/replicate+replicate. 2017-09-21 21:05:42 -04:00
Wilson Snyder 48d3ce46d8 Commenary 2017-09-21 18:39:23 -04:00
Wilson Snyder 89c8449ec0 Support package export, bug1217. 2017-09-20 21:04:59 -04:00
Xavier Delacour 331fcb633e Update .gitconfig 2017-09-20 07:57:09 -04:00
Wilson Snyder bffc2233a0 Commentary about IMPERFECTSCH. Add test. 2017-09-19 21:01:03 -04:00
Wilson Snyder 393b5d48b2 Better optimize Shift-And constructs. 2017-09-19 20:56:17 -04:00
Wilson Snyder 6006cdff2c Fix wide array indices causing compile error. 2017-09-19 20:04:45 -04:00
Wilson Snyder d6b10465f3 Improve more errors to note IEEE 2017-09-18 23:06:31 -04:00
Wilson Snyder b3cf5c4f5f Improve error to note common :: package errors 2017-09-18 22:54:54 -04:00
Wilson Snyder 3862f2f022 Note IEEE in 32 bit decimal oversized 2017-09-18 22:50:26 -04:00
Wilson Snyder 38ab22bf1d Simplify VL_CONST_W macro generation for faster compiles. 2017-09-18 21:36:18 -04:00
Wilson Snyder ce16f7689d Fix clang 3.8 warnings 2017-09-18 20:05:56 -04:00
Wilson Snyder b06a329466 Fix GCC 4.4 false warning 2017-09-18 08:30:04 -04:00
Wilson Snyder c5b24f3850 Internals: Remove dead code, bug1215. 2017-09-18 07:13:58 -04:00
Wilson Snyder 103b956581 Default to -O2 for Verilator itself, for 20%+ 2017-09-17 23:25:20 -04:00
Wilson Snyder 63361fc56e Add performance information to --stats file. 2017-09-17 22:52:57 -04:00
Wilson Snyder 1e9e334929 Internals: Name cleanup. No functional change. 2017-09-16 11:06:35 -04:00
Wilson Snyder f30d71b0c5 Internals: Better prefetching for ~5%. 2017-09-16 07:55:48 -04:00
Wilson Snyder fee4aba9ec Internals: Fix GCC constant warnings. 2017-09-15 18:26:09 -04:00
Wilson Snyder f1960273a0 Internals: Fix over-aggressive debug 2017-09-15 18:25:52 -04:00
Wilson Snyder 778564e63b Compling: Turn on -Wextra when using --enable-ccwarn 2017-09-14 23:28:02 -04:00
Wilson Snyder cf6a69da27 Internals: Fix some cast and fallthrough warnings. No functional change 2017-09-14 23:27:06 -04:00
Wilson Snyder 960b2ed023 Internals: Fix some shadow and other warnings. No functional change 2017-09-14 23:26:23 -04:00
Mike Popoloski 74420550e6 Fix .name connections on interfaces, bug1214.
Signed-off-by: Wilson Snyder <[email protected]>
2017-09-14 21:24:13 -04:00
Mike Popoloski cb5887b376 Support module port parameters without defaults, bug 1213.
Signed-off-by: Wilson Snyder <[email protected]>
2017-09-14 21:20:20 -04:00
Wilson Snyder 41b40157d8 Fix non-colon array of interface modports, bug1212. 2017-09-14 21:15:56 -04:00
Wilson Snyder b11b693c08 Fix constant function default parameters, bug1211. 2017-09-13 19:47:11 -04:00
Wilson Snyder 256eb4bba0 Support or/and/xor array intrinsic methods, bug1210. 2017-09-13 19:37:47 -04:00
Wilson Snyder 77804b4d38 Fix GCC noreturn compile error, bug1209. 2017-09-13 19:27:59 -04:00
Wilson Snyder 8c9ca7a1b3 Fix LITENDIAN warning on arrayed cells, bug1202. 2017-09-13 19:09:49 -04:00
Wilson Snyder 9d055f8c13 Fix ordering of arrayed cell wide connections, bug1202 partial. 2017-09-12 19:34:10 -04:00
Wilson Snyder 3dacd87dfb Fix enum ranges without colons, bug1204. 2017-09-12 18:53:57 -04:00
Wilson Snyder 691fbb0c42 Tests: Support newer VCS. 2017-09-12 18:42:58 -04:00
Wilson Snyder c28a6eef3b Fix whitespace issues, bug1203. 2017-09-11 19:18:58 -04:00
Wilson Snyder 17fed3fedd devel release 2017-09-07 21:15:48 -04:00
248 changed files with 2279 additions and 1077 deletions
+4
View File
@@ -1,3 +1,5 @@
\#*
.#*
*~
*.old
*.gz
@@ -20,8 +22,10 @@ configure
dddrun*
doxygen-doc
gdbrun*
gmon.out
internals.txt
verilator.txt
verilator_bin*
verilator_coverage_bin*
verilator.pc
**/obj_dir/*
+34
View File
@@ -2,6 +2,40 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. Thanks!
* Verilator 3.912 2017-09-23
** Verilated headers no longer "use namespace std;"
User's code without "std::" prefixes may need "use namespace std;" to compile.
*** Support or/and/xor array intrinsic methods, bug1210. [Mike Popoloski]
*** Support package export, bug1217. [Usuario Eda]
*** Fix ordering of arrayed cell wide connections, bug1202 partial. [Mike Popoloski]
**** Support module port parameters without defaults, bug 1213. [Mike Popoloski]
**** Add performance information to --stats file.
**** Simplify VL_CONST_W macro generation for faster compiles.
**** Fix LITENDIAN warning on arrayed cells, bug1202. [Mike Popoloski]
**** Fix enum ranges without colons, bug1204. [Mike Popoloski]
**** Fix GCC noreturn compile error, bug1209. [Mike Popoloski]
**** Fix constant function default parameters, bug1211. [Mike Popoloski]
**** Fix non-colon array of interface modports, bug1212. [Mike Popoloski]
**** Fix .name connections on interfaces, bug1214. [Mike Popoloski]
**** Fix wide array indices causing compile error.
**** Better optimize Shift-And, and replication constructs.
* Verilator 3.910 2017-09-07
*** SystemPerl mode (-sp-deprecated) has been removed.
+1 -1
View File
@@ -51,7 +51,7 @@ output (not Verilator itself) compiles under MSVC++ 2008 and newer.
=head1 INSTALLATION
For more details see
For more details see
L<http://www.veripool.org/projects/verilator/wiki/Installing>.
If you will be modifying Verilator, you should use the "git" method as it
+1 -1
View File
@@ -41,7 +41,7 @@ Testing:
* // verilator debug in code so can see only tree affecting those nodes
Usability:
* Detect and pre-remove most UNOPTFLATs (4.000)
* Detect and pre-remove most UNOPTFLATs (4.000)
* Better reporting of unopt problems, including what lines of code
* Report more errors (all of them?) before exiting [Eugene Weber]
* Auto-create scons config files
+15 -6
View File
@@ -182,7 +182,9 @@ sub run {
warn "%Error: $command\n";
}
if ($status & 127) {
if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV
if (($status & 127) == 4 # SIGILL
|| ($status & 127) == 8 # SIGFPA
|| ($status & 127) == 11) { # SIGSEGV
warn "%Error: Verilator internal fault, sorry. Consider trying --debug --gdbbt\n" if !$Debug;
} elsif (($status & 127) == 6) { # SIGABRT
warn "%Error: Verilator aborted. Consider trying --debug --gdbbt\n" if !$Debug;
@@ -349,7 +351,8 @@ descriptions in the next sections for more information.
+verilog1995ext+<ext> Synonym for +1364-1995ext+<ext>
+verilog2001ext+<ext> Synonym for +1364-2001ext+<ext>
--vpi Enable VPI compiles
-Werror-<message> Convert warning to error
-Wall Enable all style warnings
-Werror-<message> Convert warnings to errors
-Wfuture-<message> Disable unknown message warnings
-Wno-<message> Disable warning
-Wno-lint Disable all lint warnings
@@ -1198,8 +1201,9 @@ Enable use of VPI and linking against the verilated_vpi.cpp files.
=item -Wall
Enable all warnings, including code style warnings that are normally
disabled by default.
Enable all code style warnings, including code style warnings that are
normally disabled by default. Equivelent to "-Wwarn-lint -Wwarn-style".
Excludes some specialty warnings, i.e. IMPERFECTSCH.
=item -Werror-I<message>
@@ -3154,8 +3158,8 @@ correctly.
Warns that the scheduling of the model is not absolutely perfect, and some
manual code edits may result in faster performance. This warning defaults
to off, and must be turned on explicitly before the top module statement is
processed.
to off, is not part of -Wall, and must be turned on explicitly before the
top module statement is processed.
=item IMPLICIT
@@ -3205,6 +3209,11 @@ Warns that a packed vector is declared with little endian bit numbering
and little numbering is now thus often due to simple oversight instead of
intent.
Also warns that a cell is declared with little endian range (i.e. [0:7] or
[7]) and is connected to a N-wide signal. Based on IEEE the bits will
likely be backwards from what you expect (i.e. cell [0] will connect to
signal bit [N-1] not bit [0]).
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
+12 -3
View File
@@ -6,8 +6,9 @@
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
#AC_INIT([Verilator],[#.### devel])
AC_INIT([Verilator],[3.910 2017-09-07])
AC_INIT([Verilator],[3.912 2017-09-23])
# When releasing, also update header of Changes file
# and commit using "devel release" or "Version bump" message
AC_CONFIG_HEADER(src/config_build.h)
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h verilator.pc)
@@ -139,15 +140,22 @@ AC_DEFUN([_MY_CXX_CHECK_OPT],
CXXFLAGS="$ACO_SAVE_CXXFLAGS"
])# _MY_CXX_CHECK_OPT
# Flags for compiling Verilator internals including parser
# Flags for compiling Verilator internals including parser, and Verilated files
# These turn on extra warnings and are only used with 'configure --enable-ccwarn'
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wextra)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wlogical-op)
AC_SUBST(CFG_CXXFLAGS_WEXTRA)
# Flags for compiling Verilator internals including parser always
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Qunused-arguments)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-faligned-new)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-fno-delete-null-pointer-checks)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-unused-parameter)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-undefined-bool-conversion)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-shadow)
AC_SUBST(CFG_CXXFLAGS_SRC)
# Flags for compiling Verilator parser (in addition to above CFG_CXXFLAGS_SRC)
# Flags for compiling Verilator parser always (in addition to above CFG_CXXFLAGS_SRC)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-char-subscripts)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-null-conversion)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-parentheses-equality)
@@ -169,6 +177,7 @@ _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-uninitialized)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-but-set-variable)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-parameter)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-variable)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-shadow)
AC_SUBST(CFG_CXXFLAGS_NO_UNUSED)
# Checks for library functions.
+51 -51
View File
@@ -308,7 +308,7 @@ WDataOutP VL_POW_WWQ(int obits, int lbits, int rbits, WDataOutP owp, WDataInP lw
WData rhsw[2]; VL_SET_WQ(rhsw, rhs);
return VL_POW_WWW(obits,lbits,rbits,owp,lwp,rhsw);
}
QData VL_POW_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp) {
QData VL_POW_QQW(int, int, int rbits, QData lhs, WDataInP rwp) {
// Skip check for rhs == 0, as short-circuit doesn't save time
if (VL_UNLIKELY(lhs==0)) return 0;
QData power = lhs;
@@ -364,7 +364,7 @@ QData VL_POWSS_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp, bool lsig
// Do a va_arg returning a quad, assuming input argument is anything less than wide
#define _VL_VA_ARG_Q(ap, bits) (((bits) <= VL_WORDSIZE) ? va_arg(ap,IData) : va_arg(ap,QData))
void _vl_vsformat(string& output, const char* formatp, va_list ap) {
void _vl_vsformat(std::string& output, const char* formatp, va_list ap) {
// Format a Verilog $write style format into the output list
// The format must be pre-processed (and lower cased) by Verilator
// Arguments are in "width, arg-value (or WDataIn* if wide)" form
@@ -420,7 +420,7 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
}
case '@': { // Verilog/C++ string
va_arg(ap, int); // # bits is ignored
const string* cstrp = va_arg(ap, const string*);
const std::string* cstrp = va_arg(ap, const std::string*);
output += *cstrp;
break;
}
@@ -559,7 +559,7 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
}
break;
default:
string msg = string("Unknown _vl_vsformat code: ")+pos[0];
std::string msg = std::string("Unknown _vl_vsformat code: ")+pos[0];
vl_fatal(__FILE__,__LINE__,"",msg.c_str());
break;
} // switch
@@ -577,7 +577,7 @@ static inline void _vl_vsss_advance(FILE* fp, int& floc) {
if (fp) fgetc(fp);
else floc -= 8;
}
static inline int _vl_vsss_peek(FILE* fp, int& floc, WDataInP fromp, const string& fstr) {
static inline int _vl_vsss_peek(FILE* fp, int& floc, WDataInP fromp, const std::string& fstr) {
// Get a character without advancing
if (fp) {
int data = fgetc(fp);
@@ -594,14 +594,14 @@ static inline int _vl_vsss_peek(FILE* fp, int& floc, WDataInP fromp, const stri
}
}
}
static inline void _vl_vsss_skipspace(FILE* fp, int& floc, WDataInP fromp, const string& fstr) {
static inline void _vl_vsss_skipspace(FILE* fp, int& floc, WDataInP fromp, const std::string& fstr) {
while (1) {
int c = _vl_vsss_peek(fp, floc, fromp, fstr);
if (c==EOF || !isspace(c)) return;
_vl_vsss_advance(fp, floc);
}
}
static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp, const string& fstr,
static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp, const std::string& fstr,
char* tmpp, const char* acceptp) {
// Read into tmp, consisting of characters from acceptp list
char* cp = tmpp;
@@ -651,7 +651,7 @@ static inline void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const
IData _vl_vsscanf(FILE* fp, // If a fscanf
int fbits, WDataInP fromp, // Else if a sscanf
const string& fstr, // if a sscanf to string
const std::string& fstr, // if a sscanf to string
const char* formatp, va_list ap) {
// Read a Verilog $sscanf/$fscanf style format into the output list
// The format must be pre-processed (and lower cased) by Verilator
@@ -706,10 +706,10 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
_vl_vsss_skipspace(fp,floc,fromp,fstr);
_vl_vsss_read(fp,floc,fromp,fstr, tmp, NULL);
if (!tmp[0]) goto done;
int pos = ((int)strlen(tmp))-1;
int lpos = ((int)strlen(tmp))-1;
int lsb = 0;
for (int i=0; i<obits && pos>=0; --pos) {
_vl_vsss_setbit(owp,obits,lsb, 8, tmp[pos]); lsb+=8;
for (int i=0; i<obits && lpos>=0; --lpos) {
_vl_vsss_setbit(owp,obits,lsb, 8, tmp[lpos]); lsb+=8;
}
break;
}
@@ -766,7 +766,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
break;
}
default:
string msg = string("Unknown _vl_vsscanf code: ")+pos[0];
std::string msg = std::string("Unknown _vl_vsscanf code: ")+pos[0];
vl_fatal(__FILE__,__LINE__,"",msg.c_str());
break;
} // switch
@@ -852,7 +852,7 @@ IData VL_FGETS_IXI(int obits, void* destp, IData fpi) {
return got;
}
IData VL_FOPEN_NI(const string& filename, IData mode) {
IData VL_FOPEN_NI(const std::string& filename, IData mode) {
char modez[5];
_VL_VINT_TO_STRING(VL_WORDSIZE, modez, &mode);
return VL_FOPEN_S(filename.c_str(), modez);
@@ -880,7 +880,7 @@ void VL_FCLOSE_I(IData fdi) {
}
void VL_SFORMAT_X(int obits, CData& destr, const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
VL_STATIC_OR_THREAD std::string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
@@ -891,7 +891,7 @@ void VL_SFORMAT_X(int obits, CData& destr, const char* formatp, ...) {
}
void VL_SFORMAT_X(int obits, SData& destr, const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
VL_STATIC_OR_THREAD std::string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
@@ -902,7 +902,7 @@ void VL_SFORMAT_X(int obits, SData& destr, const char* formatp, ...) {
}
void VL_SFORMAT_X(int obits, IData& destr, const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
VL_STATIC_OR_THREAD std::string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
@@ -913,7 +913,7 @@ void VL_SFORMAT_X(int obits, IData& destr, const char* formatp, ...) {
}
void VL_SFORMAT_X(int obits, QData& destr, const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
VL_STATIC_OR_THREAD std::string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
@@ -924,7 +924,7 @@ void VL_SFORMAT_X(int obits, QData& destr, const char* formatp, ...) {
}
void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
VL_STATIC_OR_THREAD std::string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
@@ -934,7 +934,7 @@ void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) {
_VL_STRING_TO_VINT(obits, destp, (int)output.length(), output.c_str());
}
void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...) {
void VL_SFORMAT_X(int obits_ignored, std::string &output, const char* formatp, ...) {
if (obits_ignored) {}
output = "";
va_list ap;
@@ -943,8 +943,8 @@ void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...) {
va_end(ap);
}
string VL_SFORMATF_NX(const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
std::string VL_SFORMATF_NX(const char* formatp, ...) {
VL_STATIC_OR_THREAD std::string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
@@ -955,7 +955,7 @@ string VL_SFORMATF_NX(const char* formatp, ...) {
}
void VL_WRITEF(const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
VL_STATIC_OR_THREAD std::string output; // static only for speed
output = "";
va_list ap;
va_start(ap,formatp);
@@ -967,7 +967,7 @@ void VL_WRITEF(const char* formatp, ...) {
}
void VL_FWRITEF(IData fpi, const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
VL_STATIC_OR_THREAD std::string output; // static only for speed
output = "";
FILE* fp = VL_CVT_I_FP(fpi);
if (VL_UNLIKELY(!fp)) return;
@@ -1016,7 +1016,7 @@ IData VL_SSCANF_IWX(int lbits, WDataInP lwp, const char* formatp, ...) {
va_end(ap);
return got;
}
IData VL_SSCANF_INX(int, const string& ld, const char* formatp, ...) {
IData VL_SSCANF_INX(int, const std::string& ld, const char* formatp, ...) {
va_list ap;
va_start(ap,formatp);
IData got = _vl_vsscanf(NULL, ld.length()*8, NULL, ld, formatp, ap);
@@ -1034,12 +1034,12 @@ void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
WDataInP ofilenamep, void* memp, IData start, IData end) {
char ofilenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
_VL_VINT_TO_STRING(fnwords*VL_WORDSIZE, ofilenamez, ofilenamep);
string ofilenames(ofilenamez);
std::string ofilenames(ofilenamez);
return VL_READMEM_N(hex,width,depth,array_lsb,fnwords,ofilenames,memp,start,end);
}
void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords,
const string& ofilenamep, void* memp, IData start, IData end) {
const std::string& ofilenamep, void* memp, IData start, IData end) {
if (fnwords) {}
FILE* fp = fopen(ofilenamep.c_str(), "r");
if (VL_UNLIKELY(!fp)) {
@@ -1150,13 +1150,13 @@ IData VL_SYSTEM_IW(int lhswords, WDataInP filenamep) {
}
IData VL_TESTPLUSARGS_I(const char* formatp) {
const string& match = VerilatedImp::argPlusMatch(formatp);
const std::string& match = VerilatedImp::argPlusMatch(formatp);
if (match == "") return 0;
else return 1;
}
IData VL_VALUEPLUSARGS_INW(int rbits, const string& ld, WDataOutP rwp) {
string prefix;
IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rwp) {
std::string prefix;
bool inPct = false;
bool done = false;
char fmt = ' ';
@@ -1179,16 +1179,16 @@ IData VL_VALUEPLUSARGS_INW(int rbits, const string& ld, WDataOutP rwp) {
}
}
const string& match = VerilatedImp::argPlusMatch(prefix.c_str());
const std::string& match = VerilatedImp::argPlusMatch(prefix.c_str());
const char* dp = match.c_str() + 1 /*leading + */ + prefix.length();
if (match == "") return 0;
VL_ZERO_RESET_W(rbits, rwp);
switch (tolower(fmt)) {
case 'd':
vlsint64_t ld;
sscanf(dp,"%30" VL_PRI64 "d",&ld);
VL_SET_WQ(rwp,ld);
vlsint64_t lld;
sscanf(dp,"%30" VL_PRI64 "d",&lld);
VL_SET_WQ(rwp,lld);
break;
case 'b':
_vl_vsss_based(rwp,rbits, 1, dp, 0, (int)strlen(dp));
@@ -1214,8 +1214,8 @@ IData VL_VALUEPLUSARGS_INW(int rbits, const string& ld, WDataOutP rwp) {
_VL_CLEAN_INPLACE_W(rbits,rwp);
return 1;
}
IData VL_VALUEPLUSARGS_INN(int, const string& ld, string& rdr) {
string prefix;
IData VL_VALUEPLUSARGS_INN(int, const std::string& ld, std::string& rdr) {
std::string prefix;
bool inPct = false;
bool done = false;
for (const char* posp = ld.c_str(); !done && *posp; ++posp) {
@@ -1235,15 +1235,15 @@ IData VL_VALUEPLUSARGS_INN(int, const string& ld, string& rdr) {
}
}
}
const string& match = VerilatedImp::argPlusMatch(prefix.c_str());
const std::string& match = VerilatedImp::argPlusMatch(prefix.c_str());
const char* dp = match.c_str() + 1 /*leading + */ + prefix.length();
if (match == "") return 0;
rdr = string(dp);
rdr = std::string(dp);
return 1;
}
const char* vl_mc_scan_plusargs(const char* prefixp) {
const string& match = VerilatedImp::argPlusMatch(prefixp);
const std::string& match = VerilatedImp::argPlusMatch(prefixp);
static VL_THREAD char outstr[VL_VALUE_STRING_MAX_WIDTH];
if (match == "") return NULL;
strncpy(outstr, match.c_str()+strlen(prefixp)+1, // +1 to skip the "+"
@@ -1255,7 +1255,7 @@ const char* vl_mc_scan_plusargs(const char* prefixp) {
//===========================================================================
// Heavy functions
string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp) {
std::string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp) {
// See also _VL_VINT_TO_STRING
char destout[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
int obits = lwords * VL_WORDSIZE;
@@ -1272,7 +1272,7 @@ string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp) {
start = false; // Drop leading 0s
}
}
return string(destout, len);
return std::string(destout, len);
}
//===========================================================================
@@ -1311,7 +1311,7 @@ void Verilated::commandArgs(int argc, const char** argv) {
}
const char* Verilated::commandArgsPlusMatch(const char* prefixp) {
const string& match = VerilatedImp::argPlusMatch(prefixp);
const std::string& match = VerilatedImp::argPlusMatch(prefixp);
static VL_THREAD char outstr[VL_VALUE_STRING_MAX_WIDTH];
if (match == "") return "";
strncpy(outstr, match.c_str(), VL_VALUE_STRING_MAX_WIDTH);
@@ -1442,19 +1442,19 @@ 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(__FILE__,__LINE__,"",(string("Unsupported multi-dimensional public varInsert: ")+namep).c_str());
vl_fatal(__FILE__,__LINE__,"",(std::string("Unsupported multi-dimensional public varInsert: ")+namep).c_str());
}
}
va_end(ap);
m_varsp->insert(make_pair(namep,var));
m_varsp->insert(std::make_pair(namep,var));
}
// cppcheck-suppress unusedFunction // Used by applications
VerilatedVar* VerilatedScope::varFind(const char* namep) const {
if (VL_LIKELY(m_varsp)) {
VerilatedVarNameMap::iterator it = m_varsp->find(namep);
if (VL_LIKELY(it != m_varsp->end())) {
if (VL_LIKELY(it != m_varsp->end())) {
return &(it->second);
}
}
@@ -1463,19 +1463,19 @@ VerilatedVar* VerilatedScope::varFind(const char* namep) const {
void* VerilatedScope::exportFindNullError(int funcnum) {
// Slowpath - Called only when find has failed
string msg = (string("Testbench C called '")
+VerilatedImp::exportName(funcnum)
+"' but scope wasn't set, perhaps due to dpi import call without 'context'");
std::string msg = (std::string("Testbench C called '")
+VerilatedImp::exportName(funcnum)
+"' but scope wasn't set, perhaps due to dpi import call without 'context'");
vl_fatal("unknown",0,"", msg.c_str());
return NULL;
}
void* VerilatedScope::exportFindError(int funcnum) const {
// Slowpath - Called only when find has failed
string msg = (string("Testbench C called '")
+VerilatedImp::exportName(funcnum)
+"' but this DPI export function exists only in other scopes, not scope '"
+name()+"'");
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("unknown",0,"", msg.c_str());
return NULL;
}
+50 -18
View File
@@ -40,7 +40,6 @@
// <iostream> avoided to reduce compile time
// <map> avoided and instead in verilated_heavy.h to reduce compile time
// <string> avoided and instead in verilated_heavy.h to reduce compile time
using namespace std;
//=============================================================================
// Switches
@@ -1726,7 +1725,7 @@ static inline WDataOutP VL_SHIFTRS_WWW(int obits,int lbits,int rbits,WDataOutP o
if (VL_UNLIKELY(rwp[i])) { // Huge shift 1>>32 or more
int lmsw = VL_WORDS_I(obits)-1;
IData sign = VL_SIGNONES_I(lbits,lwp[lmsw]);
for (int i=0; i <= lmsw; ++i) owp[i] = sign;
for (int j=0; j <= lmsw; ++j) owp[j] = sign;
owp[lmsw] &= VL_MASK_I(lbits);
return owp;
}
@@ -1895,64 +1894,97 @@ static inline WDataOutP VL_COND_WIWW(int obits, int, int, int,
// Constification
// VL_CONST_W_#X(int obits, WDataOutP owp, IData data0, .... IData data(#-1))
// Sets wide vector words to specified constant words, zeros upper data.
// Sets wide vector words to specified constant words.
// These macros are used when o might represent more words then are given as constants,
// hence all upper words must be zeroed.
// If changing the number of functions here, also change EMITCINLINES_NUM_CONSTW
#define _END(obits,wordsSet) \
for(int i=(wordsSet);i<VL_WORDS_I(obits);++i) o[i] = (IData)0x0; \
return o
#define VL_HAVE_CONST_W_1X
static inline WDataOutP VL_CONST_W_1X(int obits, WDataOutP o,
IData d0) {
o[0]=d0;
_END(obits,1); }
#define VL_HAVE_CONST_W_2X
static inline WDataOutP VL_CONST_W_2X(int obits, WDataOutP o,
IData d1,IData d0) {
o[0]=d0; o[1]=d1;
_END(obits,2); }
#define VL_HAVE_CONST_W_3X
static inline WDataOutP VL_CONST_W_3X(int obits, WDataOutP o,
IData d2,IData d1,IData d0) {
o[0]=d0; o[1]=d1; o[2]=d2;
_END(obits,3); }
#define VL_HAVE_CONST_W_4X
static inline WDataOutP VL_CONST_W_4X(int obits, WDataOutP o,
IData d3,IData d2,IData d1,IData d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3;
_END(obits,4); }
#define VL_HAVE_CONST_W_5X
static inline WDataOutP VL_CONST_W_5X(int obits, WDataOutP o,
IData d4,IData d3,IData d2,IData d1,IData d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4;
_END(obits,5); }
#define VL_HAVE_CONST_W_6X
static inline WDataOutP VL_CONST_W_6X(int obits, WDataOutP o,
IData d5,IData d4,IData d3,IData d2,IData d1,IData d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5;
_END(obits,6); }
#define VL_HAVE_CONST_W_7X
static inline WDataOutP VL_CONST_W_7X(int obits, WDataOutP o,
IData d6,IData d5,IData d4,IData d3,IData d2,IData d1,IData d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6;
_END(obits,7); }
#define VL_HAVE_CONST_W_8X
static inline WDataOutP VL_CONST_W_8X(int obits, WDataOutP o,
IData d7,IData d6,IData d5,IData d4,IData d3,IData d2,IData d1,IData d0) {
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
_END(obits,8); }
#define VL_HAVE_CONST_W_9X
static inline WDataOutP VL_CONST_W_9X(int obits, WDataOutP o,
IData d8,
IData d7,IData d6,IData d5,IData d4,IData d3,IData d2,IData d1,IData d0) {
//
static inline WDataOutP VL_CONSTHI_W_1X(int obits, int lsb, WDataOutP obase,
IData d0) {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0;
_END(obits,1); }
static inline WDataOutP VL_CONSTHI_W_2X(int obits, int lsb, WDataOutP obase,
IData d1,IData d0) {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1;
_END(obits,2); }
static inline WDataOutP VL_CONSTHI_W_3X(int obits, int lsb, WDataOutP obase,
IData d2,IData d1,IData d0) {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2;
_END(obits,3); }
static inline WDataOutP VL_CONSTHI_W_4X(int obits, int lsb, WDataOutP obase,
IData d3,IData d2,IData d1,IData d0) {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3;
_END(obits,4); }
static inline WDataOutP VL_CONSTHI_W_5X(int obits, int lsb, WDataOutP obase,
IData d4,IData d3,IData d2,IData d1,IData d0) {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4;
_END(obits,5); }
static inline WDataOutP VL_CONSTHI_W_6X(int obits, int lsb, WDataOutP obase,
IData d5,IData d4,IData d3,IData d2,IData d1,IData d0) {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5;
_END(obits,6); }
static inline WDataOutP VL_CONSTHI_W_7X(int obits, int lsb, WDataOutP obase,
IData d6,IData d5,IData d4,IData d3,IData d2,IData d1,IData d0) {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6;
_END(obits,7); }
static inline WDataOutP VL_CONSTHI_W_8X(int obits, int lsb, WDataOutP obase,
IData d7,IData d6,IData d5,IData d4,IData d3,IData d2,IData d1,IData d0) {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
o[8]=d8;
_END(obits,9); }
_END(obits,8); }
#undef _END
// Partial constant, lower words of vector wider than 8*32, starting at bit number lsb
static inline void VL_CONSTLO_W_8X(int lsb, WDataOutP obase,
IData d7, IData d6, IData d5, IData d4, IData d3, IData d2, IData d1, IData d0) {
WDataOutP o = obase + VL_WORDS_I(lsb);
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7; }
//======================================================================
#endif /*_VERILATED_H_*/
+3 -2
View File
@@ -18,6 +18,8 @@ CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@
# Compiler flags to use to turn off unused and generated code warnings, such as -Wno-div-by-zero
CFG_CXXFLAGS_NO_UNUSED = @CFG_CXXFLAGS_NO_UNUSED@
# Compiler flags that turn on extra warnings
CFG_CXXFLAGS_WEXTRA = @CFG_CXXFLAGS_WEXTRA@
######################################################################
# Programs
@@ -48,8 +50,7 @@ VK_CPPFLAGS_ALWAYS += \
$(CFG_CXXFLAGS_NO_UNUSED) \
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
VK_CPPFLAGS_WALL += -Wall \
-Werror
VK_CPPFLAGS_WALL += -Wall $(CFG_CXXFLAGS_WEXTRA) -Werror
endif
CPPFLAGS += -I. $(VK_CPPFLAGS_WALL) $(VK_CPPFLAGS_ALWAYS)
+42 -42
View File
@@ -90,9 +90,9 @@ public:
class VerilatedCovImp : VerilatedCovImpBase {
private:
// TYPES
typedef map<string,int> ValueIndexMap;
typedef map<int,string> IndexValueMap;
typedef deque<VerilatedCovImpItem*> ItemList;
typedef std::map<std::string,int> ValueIndexMap;
typedef std::map<int,std::string> IndexValueMap;
typedef std::deque<VerilatedCovImpItem*> ItemList;
private:
// MEMBERS
@@ -119,18 +119,18 @@ public:
private:
// PRIVATE METHODS
int valueIndex(const string& value) {
int valueIndex(const std::string& value) {
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);
m_valueIndexes.insert(make_pair(value, nextIndex));
m_indexValues.insert(make_pair(nextIndex, value));
m_valueIndexes.insert(std::make_pair(value, nextIndex));
m_indexValues.insert(std::make_pair(nextIndex, value));
return nextIndex;
}
string dequote(const string& text) {
std::string dequote(const std::string& text) {
// Quote any special characters
string rtn;
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]);
@@ -141,7 +141,7 @@ private:
}
return rtn;
}
bool legalKey(const string& key) {
bool legalKey(const std::string& key) {
// Because we compress long keys to a single letter, and
// don't want applications to either get confused if they use
// a letter differently, nor want them to rely on our compression...
@@ -150,17 +150,17 @@ private:
if (key.length()==2 && isdigit(key[1])) return false;
return true;
}
string keyValueFormatter (const string& key, const string& value) {
string name;
std::string keyValueFormatter (const std::string& key, const std::string& value) {
std::string name;
if (key.length()==1 && isalpha(key[0])) {
name += string("\001")+key;
name += std::string("\001")+key;
} else {
name += string("\001")+dequote(key);
name += std::string("\001")+dequote(key);
}
name += string("\002")+dequote(value);
name += std::string("\002")+dequote(value);
return name;
}
string combineHier (const string& old, const string& add) {
std::string combineHier (const std::string& old, const std::string& add) {
// (foo.a.x, foo.b.x) => foo.*.x
// (foo.a.x, foo.b.y) => foo.*
// (foo.a.x, foo.b) => foo.*
@@ -178,7 +178,7 @@ private:
// We used to backup and split on only .'s but it seems better to be verbose
// and not assume . is the separator
string prefix = string(a,apre-a);
std::string prefix = std::string(a,apre-a);
// Scan backward to last mismatch
const char* apost = a+strlen(a)-1;
@@ -187,19 +187,19 @@ private:
&& apost>apre && bpost>bpre) { apost--; bpost--; }
// Forward to . so we have a whole word
string suffix = *bpost ? string(bpost+1) : "";
std::string suffix = *bpost ? std::string(bpost+1) : "";
string out = prefix+"*"+suffix;
std::string out = prefix+"*"+suffix;
//cout << "\nch pre="<<prefix<<" s="<<suffix<<"\nch a="<<old<<"\nch b="<<add<<"\nch o="<<out<<endl;
return out;
}
bool itemMatchesString(VerilatedCovImpItem* itemp, const string& match) {
bool itemMatchesString(VerilatedCovImpItem* itemp, const std::string& match) {
for (int i=0; i<MAX_KEYS; ++i) {
if (itemp->m_keys[i] != KEY_UNDEF) {
// We don't compare keys, only values
string val = m_indexValues[itemp->m_vals[i]];
if (string::npos != val.find(match)) { // Found
std::string val = m_indexValues[itemp->m_vals[i]];
if (std::string::npos != val.find(match)) { // Found
return true;
}
}
@@ -263,18 +263,18 @@ public:
assert(m_insertp);
// First two key/vals are filename
ckeyps[0]="filename"; valps[0]=m_insertFilenamep;
string linestr = vlCovCvtToStr(m_insertLineno);
std::string linestr = vlCovCvtToStr(m_insertLineno);
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++;
string page_default = "sp_user/"+string(fnstartp,fnendp-fnstartp);
std::string page_default = "sp_user/"+std::string(fnstartp,fnendp-fnstartp);
ckeyps[2]="page"; valps[2]=page_default.c_str();
// Keys -> strings
string keys[MAX_KEYS];
std::string keys[MAX_KEYS];
for (int i=0; i<MAX_KEYS; ++i) {
if (ckeyps[i] && ckeyps[i][0]) {
keys[i] = ckeyps[i];
@@ -294,15 +294,15 @@ public:
// Insert the values
int addKeynum=0;
for (int i=0; i<MAX_KEYS; ++i) {
const string key = keys[i];
const std::string key = keys[i];
if (keys[i]!="") {
const string val = valps[i];
const std::string val = valps[i];
//cout<<" "<<__FUNCTION__<<" "<<key<<" = "<<val<<endl;
m_insertp->m_keys[addKeynum] = valueIndex(key);
m_insertp->m_vals[addKeynum] = valueIndex(val);
addKeynum++;
if (!legalKey(key)) {
string msg = "%Error: Coverage keys of one character, or letter+digit are illegal: "+key;
std::string msg = "%Error: Coverage keys of one character, or letter+digit are illegal: "+key;
vl_fatal("",0,"",msg.c_str());
}
}
@@ -318,27 +318,27 @@ public:
#endif
selftest();
ofstream os (filename);
std::ofstream os (filename);
if (os.fail()) {
string msg = (string)"%Error: Can't write '"+filename+"'";
std::string msg = (std::string)"%Error: Can't write '"+filename+"'";
vl_fatal("",0,"",msg.c_str());
return;
}
os << "# SystemC::Coverage-3\n";
// Build list of events; totalize if collapsing hierarchy
typedef map<string,pair<string,vluint64_t> > EventMap;
EventMap eventCounts;
typedef std::map<std::string,std::pair<std::string,vluint64_t> > EventMap;
EventMap eventCounts;
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
VerilatedCovImpItem* itemp = *(it);
string name;
string hier;
std::string name;
std::string hier;
bool per_instance = false;
for (int i=0; i<MAX_KEYS; ++i) {
if (itemp->m_keys[i] != KEY_UNDEF) {
string key = VerilatedCovKey::shortKey(m_indexValues[itemp->m_keys[i]]);
string val = m_indexValues[itemp->m_vals[i]];
std::string key = VerilatedCovKey::shortKey(m_indexValues[itemp->m_keys[i]]);
std::string val = m_indexValues[itemp->m_vals[i]];
if (key == VL_CIK_PER_INSTANCE) {
if (val != "0") per_instance = true;
}
@@ -363,21 +363,21 @@ public:
// Find or insert the named event
EventMap::iterator cit = eventCounts.find(name);
if (cit != eventCounts.end()) {
const string& oldhier = cit->second.first;
const std::string& oldhier = cit->second.first;
cit->second.second += itemp->count();
cit->second.first = combineHier(oldhier, hier);
} else {
eventCounts.insert(make_pair(name, make_pair(hier,itemp->count())));
eventCounts.insert(std::make_pair(name, make_pair(hier,itemp->count())));
}
}
// Output body
for (EventMap::iterator it=eventCounts.begin(); it!=eventCounts.end(); ++it) {
os<<"C '"<<dec;
os<<"C '"<<std::dec;
os<<it->first;
if (it->second.first != "") os<<keyValueFormatter(VL_CIK_HIER,it->second.first);
os<<"' "<<it->second.second;
os<<endl;
os<<std::endl;
}
}
};
@@ -441,9 +441,9 @@ void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
}
// Backward compatibility for Verilator
void VerilatedCov::_insertp (A(0), A(1), K(2),int val2, K(3),int val3,
K(4),const string& val4, A(5),A(6)) {
string val2str = vlCovCvtToStr(val2);
string val3str = vlCovCvtToStr(val3);
K(4),const std::string& val4, A(5),A(6)) {
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),
+2 -3
View File
@@ -27,7 +27,6 @@
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
//=============================================================================
/// Conditionally compile coverage code
@@ -75,7 +74,7 @@ using namespace std;
/// Convert VL_COVER_INSERT value arguments to strings
template< class T> std::string vlCovCvtToStr (const T& t) {
ostringstream os; os<<t; return os.str();
std::ostringstream os; os<<t; return os.str();
}
//=============================================================================
@@ -115,7 +114,7 @@ public:
,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 string& val4, A(5),A(6));
K(4),const std::string& val4, A(5),A(6));
#undef K
#undef A
+1 -2
View File
@@ -25,7 +25,6 @@
#include "verilatedos.h"
#include <string>
using namespace std;
//=============================================================================
// Data used to edit below file, using vlcovgen
@@ -105,7 +104,7 @@ VLCOVGEN_ITEM("name=>'weight', short=>'w', group=>0, default=>undef, descr
class VerilatedCovKey {
public:
static string shortKey(const string& key) {
static std::string shortKey(const std::string& key) {
// VLCOVGEN_SHORT_AUTO_EDIT_BEGIN
if (key == "col0") return VL_CIK_COL0;
if (key == "col0_name") return VL_CIK_COL0_NAME;
+1 -1
View File
@@ -40,7 +40,7 @@
// Not supported yet
#define _VL_SVDPI_UNIMP() \
vl_fatal(__FILE__,__LINE__,"",(string("%%Error: Unsupported DPI function: ")+VL_FUNC).c_str())
vl_fatal(__FILE__,__LINE__,"",(std::string("%%Error: Unsupported DPI function: ")+VL_FUNC).c_str())
// Function requires a "context" in the import declaration
#define _VL_SVDPI_CONTEXT_WARN() \
+17 -17
View File
@@ -36,49 +36,49 @@
//======================================================================
// Conversion functions
extern string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp);
inline string VL_CVT_PACK_STR_NQ(QData lhs) {
extern std::string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp);
inline std::string VL_CVT_PACK_STR_NQ(QData lhs) {
WData lw[2]; VL_SET_WQ(lw, lhs);
return VL_CVT_PACK_STR_NW(2, lw);
}
inline string VL_CVT_PACK_STR_NN(const string& lhs) {
inline std::string VL_CVT_PACK_STR_NN(const std::string& lhs) {
return lhs;
}
inline string VL_CVT_PACK_STR_NI(IData lhs) {
inline std::string VL_CVT_PACK_STR_NI(IData lhs) {
WData lw[1]; lw[0] = lhs;
return VL_CVT_PACK_STR_NW(1, lw);
}
inline string VL_CONCATN_NNN(const string& lhs, const string& rhs) {
inline std::string VL_CONCATN_NNN(const std::string& lhs, const std::string& rhs) {
return lhs+rhs;
}
inline string VL_REPLICATEN_NNQ(int,int,int, const string& lhs, IData rep) {
string out; out.reserve(lhs.length() * rep);
inline std::string VL_REPLICATEN_NNQ(int,int,int, const std::string& lhs, IData rep) {
std::string out; out.reserve(lhs.length() * rep);
for (unsigned times=0; times<rep; ++times) out += lhs;
return out;
}
inline string VL_REPLICATEN_NNI(int obits,int lbits,int rbits, const string& lhs, IData rep) {
inline std::string VL_REPLICATEN_NNI(int obits,int lbits,int rbits, const std::string& lhs, IData rep) {
return VL_REPLICATEN_NNQ(obits,lbits,rbits,lhs,rep);
}
extern IData VL_FOPEN_NI(const string& filename, IData mode);
extern IData VL_FOPEN_NI(const std::string& filename, IData mode);
extern void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords,
const string& ofilename, void* memp, IData start, IData end);
extern IData VL_SSCANF_INX(int lbits, const string& ld, const char* formatp, ...);
extern void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...);
extern string VL_SFORMATF_NX(const char* formatp, ...);
extern IData VL_VALUEPLUSARGS_INW(int rbits, const string& ld, WDataOutP rdp);
inline IData VL_VALUEPLUSARGS_INI(int rbits, const string& ld, IData& rdr) {
const std::string& ofilename, void* memp, IData start, IData end);
extern IData VL_SSCANF_INX(int lbits, const std::string& ld, const char* formatp, ...);
extern void VL_SFORMAT_X(int obits_ignored, std::string &output, const char* formatp, ...);
extern std::string VL_SFORMATF_NX(const char* formatp, ...);
extern IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rdp);
inline IData VL_VALUEPLUSARGS_INI(int rbits, const std::string& ld, IData& rdr) {
WData rwp[2]; // WData must always be at least 2
IData got = VL_VALUEPLUSARGS_INW(rbits,ld,rwp);
if (got) rdr = rwp[0];
return got;
}
inline IData VL_VALUEPLUSARGS_INQ(int rbits, const string& ld, QData& rdr) {
inline IData VL_VALUEPLUSARGS_INQ(int rbits, const std::string& ld, QData& rdr) {
WData rwp[2];
IData got = VL_VALUEPLUSARGS_INW(rbits,ld,rwp);
if (got) rdr = VL_SET_QW(rwp);
return got;
}
extern IData VL_VALUEPLUSARGS_INN(int, const string& ld, string& rdr);
extern IData VL_VALUEPLUSARGS_INN(int, const std::string& ld, std::string& rdr);
#endif // Guard
+13 -13
View File
@@ -47,9 +47,9 @@ class VerilatedImp {
// Whole class is internal use only - Global information shared between verilated*.cpp files.
// TYPES
typedef vector<string> ArgVec;
typedef map<pair<const void*,void*>,void*> UserMap;
typedef map<const char*, int, VerilatedCStrCmp> ExportNameMap;
typedef std::vector<std::string> ArgVec;
typedef std::map<std::pair<const void*,void*>,void*> UserMap;
typedef std::map<const char*, int, VerilatedCStrCmp> ExportNameMap;
// MEMBERS
static VerilatedImp s_s; ///< Static Singleton; One and only static this
@@ -65,8 +65,8 @@ class VerilatedImp {
int m_exportNext; ///< Next export funcnum
// File I/O
vector<FILE*> m_fdps; ///< File descriptors
deque<IData> m_fdFree; ///< List of free descriptors (SLOW - FOPEN/CLOSE only)
std::vector<FILE*> m_fdps; ///< File descriptors
std::deque<IData> m_fdFree; ///< List of free descriptors (SLOW - FOPEN/CLOSE only)
public: // But only for verilated*.cpp
// CONSTRUCTORS
@@ -100,7 +100,7 @@ public: // But only for verilated*.cpp
for (int i=0; i<argc; ++i) s_s.m_argVec.push_back(argv[i]);
s_s.m_argVecLoaded = true; // Can't just test later for empty vector, no arguments is ok
}
static string argPlusMatch(const char* prefixp) {
static std::string argPlusMatch(const char* prefixp) {
// Note prefixp does not include the leading "+"
size_t len = strlen(prefixp);
if (VL_UNLIKELY(!s_s.m_argVecLoaded)) {
@@ -122,13 +122,13 @@ public: // But only for verilated*.cpp
// There's often many more scopes than userdata's and thus having a ~48byte
// per map overhead * N scopes would take much more space and cache thrashing.
static inline void userInsert(const void* scopep, void* userKey, void* userData) {
UserMap::iterator it=s_s.m_userMap.find(make_pair(scopep,userKey));
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, make_pair(make_pair(scopep,userKey),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) {
UserMap::iterator it=s_s.m_userMap.find(make_pair(scopep,userKey));
UserMap::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;
}
@@ -159,7 +159,7 @@ public: // But only for verilated*.cpp
// Slow ok - called once/scope at construction
VerilatedScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
if (it == s_s.m_nameMap.end()) {
s_s.m_nameMap.insert(it, make_pair(scopep->name(),scopep));
s_s.m_nameMap.insert(it, std::make_pair(scopep->name(),scopep));
}
}
static inline const VerilatedScope* scopeFind(const char* namep) {
@@ -198,7 +198,7 @@ public: // But only for verilated*.cpp
// Slow ok - called once/function at creation
ExportNameMap::iterator it=s_s.m_exportMap.find(namep);
if (it == s_s.m_exportMap.end()) {
s_s.m_exportMap.insert(it, make_pair(namep, s_s.m_exportNext++));
s_s.m_exportMap.insert(it, std::make_pair(namep, s_s.m_exportNext++));
return s_s.m_exportNext++;
} else {
return it->second;
@@ -207,8 +207,8 @@ public: // But only for verilated*.cpp
static int exportFind(const char* namep) {
ExportNameMap::iterator it=s_s.m_exportMap.find(namep);
if (VL_LIKELY(it != s_s.m_exportMap.end())) return it->second;
string msg = (string("%Error: Testbench C called ")+namep
+" but no such DPI export function name exists in ANY model");
std::string msg = (std::string("%Error: Testbench C called ")+namep
+" but no such DPI export function name exists in ANY model");
vl_fatal("unknown",0,"", msg.c_str());
return -1;
}
+9 -9
View File
@@ -60,8 +60,8 @@ bool VerilatedDeserialize::readDiffers (const void* __restrict datap, size_t siz
VerilatedDeserialize& VerilatedDeserialize::readAssert (const void* __restrict datap, size_t size) {
if (VL_UNLIKELY(readDiffers(datap,size))) {
string fn = filename();
string msg = (string)"Can't deserialize save-restore file as was made from different model";
std::string fn = filename();
std::string msg = (std::string)"Can't deserialize save-restore file as was made from different model";
vl_fatal(fn.c_str(), 0, "", msg.c_str());
close();
}
@@ -81,8 +81,8 @@ void VerilatedSerialize::header() {
void VerilatedDeserialize::header() {
VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_HEADER_STR, strlen(VLTSAVE_HEADER_STR)))) {
string fn = filename();
string msg = (string)"Can't deserialize; file has wrong header signature";
std::string fn = filename();
std::string msg = (std::string)"Can't deserialize; file has wrong header signature";
vl_fatal(fn.c_str(), 0, "", msg.c_str());
close();
}
@@ -98,8 +98,8 @@ void VerilatedSerialize::trailer() {
void VerilatedDeserialize::trailer() {
VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_TRAILER_STR, strlen(VLTSAVE_TRAILER_STR)))) {
string fn = filename();
string msg = (string)"Can't deserialize; file has wrong end-of-file signature";
std::string fn = filename();
std::string msg = (std::string)"Can't deserialize; file has wrong end-of-file signature";
vl_fatal(fn.c_str(), 0, "", msg.c_str());
close();
}
@@ -187,7 +187,7 @@ void VerilatedSave::flush() {
} else if (got < 0) {
if (errno != EAGAIN && errno != EINTR) {
// write failed, presume error (perhaps out of disk space)
string msg = string(__FUNCTION__)+": "+strerror(errno);
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
vl_fatal("",0,"",msg.c_str());
close();
break;
@@ -204,7 +204,7 @@ void VerilatedRestore::fill() {
for (vluint8_t* sp=m_cp; sp < m_endp;) *rp++ = *sp++; // Overlaps
m_endp = m_bufp + (m_endp - m_cp);
m_cp = m_bufp; // Reset buffer
// Read into buffer starting at m_endp
// Read into buffer starting at m_endp
while (1) {
ssize_t remaining = (m_bufp+bufferSize() - m_endp);
if (remaining==0) break;
@@ -215,7 +215,7 @@ void VerilatedRestore::fill() {
} else if (got < 0) {
if (errno != EAGAIN && errno != EINTR) {
// write failed, presume error (perhaps out of disk space)
string msg = string(__FUNCTION__)+": "+strerror(errno);
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
vl_fatal("",0,"",msg.c_str());
close();
break;
+6 -7
View File
@@ -25,7 +25,6 @@
#include "verilatedos.h"
#include <string>
using namespace std;
//=============================================================================
// VerilatedSerialBase - internal base class for common code between VerilatedSerialize and VerilatedDeserialize
@@ -37,7 +36,7 @@ protected:
vluint8_t* m_cp; ///< Current pointer into m_bufp buffer
vluint8_t* m_bufp; ///< Output buffer
bool m_isOpen; ///< True indicates open file/stream
string m_filename;
std::string m_filename;
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
inline static size_t bufferInsertSize() { return 16*1024; }
@@ -58,7 +57,7 @@ public:
}
// METHODS
bool isOpen() const { return m_isOpen; }
string filename() const { return m_filename; }
std::string filename() const { return m_filename; }
virtual void close() { flush(); }
virtual void flush() {}
};
@@ -150,7 +149,7 @@ public:
virtual ~VerilatedSave() { close(); }
// METHODS
void open(const char* filenamep); ///< Open the file; call isOpen() to see if errors
void open(const string& filename) { open(filename.c_str()); }
void open(const std::string& filename) { open(filename.c_str()); }
virtual void close();
virtual void flush();
};
@@ -169,7 +168,7 @@ public:
// METHODS
void open(const char* filenamep); ///< Open the file; call isOpen() to see if errors
void open(const string& filename) { open(filename.c_str()); }
void open(const std::string& filename) { open(filename.c_str()); }
virtual void close();
virtual void flush() {}
virtual void fill();
@@ -219,12 +218,12 @@ inline VerilatedSerialize& operator<<(VerilatedSerialize& os, float& rhs) {
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, float& rhs) {
return os.read(&rhs, sizeof(rhs));
}
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, string& rhs) {
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, std::string& rhs) {
vluint32_t len=rhs.length();
os<<len;
return os.write(rhs.data(), len);
}
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, string& rhs) {
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, std::string& rhs) {
vluint32_t len=0;
os>>len;
rhs.resize(len);
+4 -3
View File
@@ -36,7 +36,7 @@
/// Verilator range
// See also V3Ast::VNumRange
class VerilatedRange {
class VerilatedRange {
int m_left;
int m_right;
protected:
@@ -91,13 +91,14 @@ struct VerilatedCStrCmp {
};
class VerilatedScopeNameMap
: public map<const char*, const VerilatedScope*, VerilatedCStrCmp> {
: public std::map<const char*, const VerilatedScope*, VerilatedCStrCmp> {
public:
VerilatedScopeNameMap() {}
~VerilatedScopeNameMap() {}
};
class VerilatedVarNameMap : public map<const char*, VerilatedVar, VerilatedCStrCmp> {
class VerilatedVarNameMap
: public std::map<const char*, VerilatedVar, VerilatedCStrCmp> {
public:
VerilatedVarNameMap() {}
~VerilatedVarNameMap() {}
+25 -30
View File
@@ -46,11 +46,6 @@
# define O_NONBLOCK 0
#endif
//=============================================================================
// Global
vector<VerilatedVcd*> VerilatedVcd::s_vcdVecp; ///< List of all created traces
//=============================================================================
// VerilatedVcdCallInfo
/// Internal callback routines for each module being traced.
@@ -79,7 +74,7 @@ protected:
//=============================================================================
// VerilatedVcdFile
bool VerilatedVcdFile::open(const string& name) {
bool VerilatedVcdFile::open(const std::string& name) {
m_fd = ::open(name.c_str(), O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK, 0666);
return (m_fd>=0);
}
@@ -121,7 +116,7 @@ void VerilatedVcd::open (const char* filename) {
// Set member variables
m_filename = filename;
s_vcdVecp.push_back(this);
singleton().s_vcdVecp.push_back(this);
// SPDIFF_OFF
// Set callback so an early exit will flush us
@@ -150,7 +145,7 @@ void VerilatedVcd::openNext (bool incFilename) {
closePrev(); // Close existing
if (incFilename) {
// Find _0000.{ext} in filename
string name = m_filename;
std::string name = m_filename;
size_t pos=name.rfind(".");
if (pos>8 && 0==strncmp("_cat",name.c_str()+pos-8,4)
&& isdigit(name.c_str()[pos-4])
@@ -205,18 +200,18 @@ void VerilatedVcd::makeNameMap() {
// This comes from user instantiations with no name - IE Vtop("").
bool nullScope = false;
for (NameMap::iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) {
const string& hiername = it->first;
const std::string& hiername = it->first;
if (hiername.size() >= 1 && hiername[0] == '\t') nullScope=true;
}
if (nullScope) {
NameMap* newmapp = new NameMap;
for (NameMap::iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) {
const string& hiername = it->first;
const string& decl = it->second;
string newname = string("top");
const std::string& hiername = it->first;
const std::string& decl = it->second;
std::string newname = std::string("top");
if (hiername[0] != '\t') newname += ' ';
newname += hiername;
newmapp->insert(make_pair(newname,decl));
newmapp->insert(std::make_pair(newname,decl));
}
deleteNameMap();
m_namemapp = newmapp;
@@ -234,8 +229,8 @@ VerilatedVcd::~VerilatedVcd() {
deleteNameMap();
if (m_filep && m_fileNewed) { delete m_filep; m_filep = NULL; }
// Remove from list of traces
vector<VerilatedVcd*>::iterator pos = find(s_vcdVecp.begin(), s_vcdVecp.end(), this);
if (pos != s_vcdVecp.end()) { s_vcdVecp.erase(pos); }
VcdVec::iterator pos = find(singleton().s_vcdVecp.begin(), singleton().s_vcdVecp.end(), this);
if (pos != singleton().s_vcdVecp.end()) { singleton().s_vcdVecp.erase(pos); }
}
void VerilatedVcd::closePrev () {
@@ -326,7 +321,7 @@ void VerilatedVcd::bufferFlush () {
} else if (got < 0) {
if (errno != EAGAIN && errno != EINTR) {
// write failed, presume error (perhaps out of disk space)
string msg = (string)"VerilatedVcd::bufferFlush: "+strerror(errno);
std::string msg = (std::string)"VerilatedVcd::bufferFlush: "+strerror(errno);
vl_fatal("",0,"",msg.c_str());
closeErr();
break;
@@ -369,7 +364,7 @@ double VerilatedVcd::timescaleToDouble (const char* unitp) {
return value;
}
string VerilatedVcd::doubleToTimescale (double value) {
std::string VerilatedVcd::doubleToTimescale (double value) {
const char* suffixp = "s";
if (value>=1e0) { suffixp="s"; value *= 1e0; }
else if (value>=1e-3 ) { suffixp="ms"; value *= 1e3; }
@@ -398,7 +393,7 @@ void VerilatedVcd::dumpHeader () {
printStr("$date "); printStr(ctime(&time_str)); printStr(" $end\n");
printStr("$timescale ");
const string& timeResStr = doubleToTimescale(m_timeRes);
const std::string& timeResStr = doubleToTimescale(m_timeRes);
printStr(timeResStr.c_str());
printStr(" $end\n");
@@ -417,8 +412,8 @@ void VerilatedVcd::dumpHeader () {
// Print the signal names
const char* lastName = "";
for (NameMap::iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) {
const string& hiernamestr = it->first;
const string& decl = it->second;
const std::string& hiernamestr = it->first;
const std::string& decl = it->second;
// Determine difference between the old and new names
const char* hiername = hiernamestr.c_str();
@@ -472,7 +467,7 @@ void VerilatedVcd::dumpHeader () {
deleteNameMap();
}
void VerilatedVcd::module (const string& name) {
void VerilatedVcd::module (const std::string& name) {
m_modName = name;
}
@@ -485,7 +480,7 @@ void VerilatedVcd::declare (vluint32_t code, const char* name, const char* wirep
if (tri) codesNeeded *= 2; // Space in change array for __en signals
// Make sure array is large enough
m_nextCode = max(nextCode(), code+codesNeeded);
m_nextCode = std::max(nextCode(), code+codesNeeded);
if (m_sigs.capacity() <= m_nextCode) {
m_sigs.reserve(m_nextCode*2); // Power-of-2 allocation speeds things up
}
@@ -503,10 +498,10 @@ void VerilatedVcd::declare (vluint32_t code, const char* name, const char* wirep
// Tab separates final scope from signal name
// Tab sorts before spaces, so signals nicely will print before scopes
// Note the hiername may be nothing, if so we'll add "\t{name}"
string nameasstr = name;
std::string nameasstr = name;
if (m_modName!="") { nameasstr = m_modName+m_scopeEscape+nameasstr; } // Optional ->module prefix
string hiername;
string basename;
std::string hiername;
std::string basename;
for (const char* cp=nameasstr.c_str(); *cp; cp++) {
if (isScopeEscape(*cp)) {
// Ahh, we've just read a scope, not a basename
@@ -520,7 +515,7 @@ void VerilatedVcd::declare (vluint32_t code, const char* name, const char* wirep
hiername += "\t"+basename;
// Print reference
string decl = "$var ";
std::string decl = "$var ";
if (m_evcd) decl += "port"; else decl += wirep; // usually "wire"
char buf [1000];
sprintf(buf, " %2d ", bits);
@@ -543,7 +538,7 @@ void VerilatedVcd::declare (vluint32_t code, const char* name, const char* wirep
decl += buf;
}
decl += " $end\n";
m_namemapp->insert(make_pair(hiername,decl));
m_namemapp->insert(std::make_pair(hiername,decl));
}
void VerilatedVcd::declBit (vluint32_t code, const char* name, int arraynum)
@@ -596,7 +591,7 @@ void VerilatedVcd::addCallback (
void* userthis)
{
if (VL_UNLIKELY(isOpen())) {
string msg = (string)"Internal: "+__FILE__+"::"+__FUNCTION__+" called with already open file";
std::string msg = (std::string)"Internal: "+__FILE__+"::"+__FUNCTION__+" called with already open file";
vl_fatal(__FILE__,__LINE__,"",msg.c_str());
}
VerilatedVcdCallInfo* vci = new VerilatedVcdCallInfo(initcb, fullcb, changecb, userthis, nextCode());
@@ -647,8 +642,8 @@ void VerilatedVcd::dumpDone () {
// Static members
void VerilatedVcd::flush_all() {
for (vluint32_t ent = 0; ent< s_vcdVecp.size(); ent++) {
VerilatedVcd* vcdp = s_vcdVecp[ent];
for (vluint32_t ent = 0; ent< singleton().s_vcdVecp.size(); ent++) {
VerilatedVcd* vcdp = singleton().s_vcdVecp[ent];
vcdp->flush();
}
}
+21 -17
View File
@@ -28,7 +28,6 @@
#include <string>
#include <vector>
#include <map>
using namespace std;
class VerilatedVcd;
class VerilatedVcdCallInfo;
@@ -45,7 +44,7 @@ public:
// METHODS
VerilatedVcdFile() : m_fd(0) {}
virtual ~VerilatedVcdFile() {}
virtual bool open(const string& name);
virtual bool open(const std::string& name);
virtual void close();
virtual ssize_t write(const char* bufp, ssize_t len);
};
@@ -80,13 +79,13 @@ private:
bool m_fileNewed; ///< m_filep needs destruction
bool m_isOpen; ///< True indicates open file
bool m_evcd; ///< True for evcd format
string m_filename; ///< Filename we're writing to (if open)
std::string m_filename; ///< Filename we're writing to (if open)
vluint64_t m_rolloverMB; ///< MB of file size to rollover at
char m_scopeEscape; ///< Character to separate scope components
int m_modDepth; ///< Depth of module hierarchy
bool m_fullDump; ///< True indicates dump ignoring if changed
vluint32_t m_nextCode; ///< Next code number to assign
string m_modName; ///< Module name being traced now
std::string m_modName; ///< Module name being traced now
double m_timeRes; ///< Time resolution (ns/ms etc)
double m_timeUnit; ///< Time units (ns/ms etc)
vluint64_t m_timeLastDump; ///< Last time we did a dump
@@ -98,11 +97,16 @@ private:
vluint64_t m_wroteBytes; ///< Number of bytes written to this file
vluint32_t* m_sigs_oldvalp; ///< Pointer to old signal values
vector<VerilatedVcdSig> m_sigs; ///< Pointer to signal information
vector<VerilatedVcdCallInfo*> m_callbacks; ///< Routines to perform dumping
typedef map<string,string> NameMap;
NameMap* m_namemapp; ///< List of names for the header
static vector<VerilatedVcd*> s_vcdVecp; ///< List of all created traces
std::vector<VerilatedVcdSig> m_sigs; ///< Pointer to signal information
std::vector<VerilatedVcdCallInfo*> m_callbacks; ///< Routines to perform dumping
typedef std::map<std::string,std::string> NameMap;
NameMap* m_namemapp; ///< List of names for the header
typedef std::vector<VerilatedVcd*> VcdVec;
struct Singleton {
VcdVec s_vcdVecp; ///< List of all created traces
};
static Singleton& singleton() { static Singleton s; return s; }
void bufferResize(vluint64_t minsize);
void bufferFlush();
@@ -136,8 +140,8 @@ private:
if (code>=(94)) *m_writep++ = ((char)((code/94)%94+33));
*m_writep++ = ((char)((code)%94+33));
}
static string stringCode (vluint32_t code) {
string out;
static std::string stringCode (vluint32_t code) {
std::string out;
if (code>=(94*94*94)) out += ((char)((code/94/94/94)%94+33));
if (code>=(94*94)) out += ((char)((code/94/94)%94+33));
if (code>=(94)) out += ((char)((code/94)%94+33));
@@ -175,13 +179,13 @@ public:
void close (); ///< Close the file
void set_time_unit (const char* unit); ///< Set time units (s/ms, defaults to ns)
void set_time_unit (const string& unit) { set_time_unit(unit.c_str()); }
void set_time_unit (const std::string& unit) { set_time_unit(unit.c_str()); }
void set_time_resolution (const char* unit); ///< Set time resolution (s/ms, defaults to ns)
void set_time_resolution (const string& unit) { set_time_resolution(unit.c_str()); }
void set_time_resolution (const std::string& unit) { set_time_resolution(unit.c_str()); }
double timescaleToDouble (const char* unitp);
string doubleToTimescale (double value);
std::string doubleToTimescale (double value);
/// Inside dumping routines, called each cycle to make the dump
void dump (vluint64_t timeui);
@@ -194,7 +198,7 @@ public:
void* userthis);
/// Inside dumping routines, declare a module
void module (const string& name);
void module (const std::string& name);
/// Inside dumping routines, declare a signal
void declBit (vluint32_t code, const char* name, int arraynum);
void declBus (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
@@ -433,11 +437,11 @@ public:
/// Set time units (s/ms, defaults to ns)
/// See also VL_TIME_PRECISION, and VL_TIME_MULTIPLIER in verilated.h
void set_time_unit (const char* unit) { m_sptrace.set_time_unit(unit); }
void set_time_unit (const string& unit) { set_time_unit(unit.c_str()); }
void set_time_unit (const std::string& unit) { set_time_unit(unit.c_str()); }
/// Set time resolution (s/ms, defaults to ns)
/// See also VL_TIME_PRECISION, and VL_TIME_MULTIPLIER in verilated.h
void set_time_resolution (const char* unit) { m_sptrace.set_time_resolution(unit); }
void set_time_resolution (const string& unit) { set_time_resolution(unit.c_str()); }
void set_time_resolution (const std::string& unit) { set_time_resolution(unit.c_str()); }
/// Internal class access
inline VerilatedVcd* spTrace () { return &m_sptrace; };
+5 -5
View File
@@ -386,7 +386,7 @@ const char* VerilatedVpiError::strFromVpiProp(PLI_INT32 vpiVal) {
#define CHECK_RESULT_CSTR(got, exp) \
if (strcmp((got),(exp))) { \
string msg = string("%Error: ") \
std::string msg = std::string("%Error: ") \
+ "GOT = '"+((got)?(got):"<null>")+"'" \
+ " EXP = '"+((exp)?(exp):"<null>")+"'"; \
vl_fatal(__FILE__,__LINE__,"",msg.c_str()); \
@@ -502,9 +502,9 @@ vpiHandle vpi_handle_by_name(PLI_BYTE8* namep, vpiHandle scope) {
VerilatedVpioScope* voScopep = VerilatedVpioScope::castp(scope);
const VerilatedVar* varp;
const VerilatedScope* scopep;
string scopeAndName = namep;
std::string scopeAndName = namep;
if (voScopep) {
scopeAndName = string(voScopep->fullname()) + "." + namep;
scopeAndName = std::string(voScopep->fullname()) + "." + namep;
namep = (PLI_BYTE8*)scopeAndName.c_str();
}
{
@@ -514,11 +514,11 @@ vpiHandle vpi_handle_by_name(PLI_BYTE8* namep, vpiHandle scope) {
return (new VerilatedVpioScope(scopep))->castVpiHandle();
}
const char* baseNamep = scopeAndName.c_str();
string scopename;
std::string scopename;
const char* dotp = strrchr(namep, '.');
if (VL_LIKELY(dotp)) {
baseNamep = dotp+1;
scopename = string(namep,dotp-namep);
scopename = std::string(namep,dotp-namep);
}
scopep = Verilated::scopeFind(scopename.c_str());
if (!scopep) return NULL;
+15 -14
View File
@@ -215,8 +215,8 @@ public:
virtual const VerilatedRange* rangep() const { return &get_range(); }
virtual const char* name() { return m_varp->name(); }
virtual const char* fullname() {
VL_STATIC_OR_THREAD string out;
out = string(m_scopep->name())+"."+name();
VL_STATIC_OR_THREAD std::string out;
out = std::string(m_scopep->name())+"."+name();
return out.c_str();
}
void* prevDatap() const { return m_prevDatap; }
@@ -243,9 +243,9 @@ public:
virtual vluint32_t size() const { return varp()->range().elements(); }
virtual const VerilatedRange* rangep() const { return &(varp()->range()); }
virtual const char* fullname() {
VL_STATIC_OR_THREAD string out;
VL_STATIC_OR_THREAD std::string out;
char num[20]; sprintf(num,"%d",m_index);
out = string(scopep()->name())+"."+name()+"["+num+"]";
out = std::string(scopep()->name())+"."+name()+"["+num+"]";
return out.c_str();
}
};
@@ -301,8 +301,8 @@ public:
struct VerilatedVpiTimedCbsCmp {
/// Ordering sets keyed by time, then callback descriptor
bool operator() (const pair<QData,VerilatedVpioCb*>& a,
const pair<QData,VerilatedVpioCb*>& b) const {
bool operator() (const std::pair<QData,VerilatedVpioCb*>& a,
const std::pair<QData,VerilatedVpioCb*>& b) const {
if (a.first < b.first) return 1;
if (a.first > b.first) return 0;
return a.second < b.second;
@@ -313,8 +313,8 @@ class VerilatedVpiError;
class VerilatedVpi {
enum { CB_ENUM_MAX_VALUE = cbAtEndOfSimTime+1 }; // Maxium callback reason
typedef list<VerilatedVpioCb*> VpioCbList;
typedef set<pair<QData,VerilatedVpioCb*>,VerilatedVpiTimedCbsCmp > VpioTimedCbs;
typedef std::list<VerilatedVpioCb*> VpioCbList;
typedef std::set<std::pair<QData,VerilatedVpioCb*>,VerilatedVpiTimedCbsCmp > VpioTimedCbs;
struct product_info {
PLI_BYTE8* product;
@@ -339,7 +339,7 @@ public:
s_s.m_cbObjLists[vop->reason()].push_back(vop);
}
static void cbTimedAdd(VerilatedVpioCb* vop) {
s_s.m_timedCbs.insert(make_pair(vop->time(), vop));
s_s.m_timedCbs.insert(std::make_pair(vop->time(), vop));
}
static void cbReasonRemove(VerilatedVpioCb* cbp) {
VpioCbList& cbObjList = s_s.m_cbObjLists[cbp->reason()];
@@ -350,7 +350,7 @@ public:
}
}
static void cbTimedRemove(VerilatedVpioCb* cbp) {
VpioTimedCbs::iterator it=s_s.m_timedCbs.find(make_pair(cbp->time(),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);
}
@@ -389,7 +389,8 @@ public:
}
static void callValueCbs() {
VpioCbList& cbObjList = s_s.m_cbObjLists[cbValueChange];
set<VerilatedVpioVar*> update; // set of objects to update after callbacks
typedef std::set<VerilatedVpioVar*> VpioVarSet;
VpioVarSet update; // set of objects to update after callbacks
for (VpioCbList::iterator it=cbObjList.begin(); it!=cbObjList.end();) {
if (VL_UNLIKELY(!*it)) { // Deleted earlier, cleanup
it = cbObjList.erase(it);
@@ -411,7 +412,7 @@ public:
}
}
}
for (set<VerilatedVpioVar*>::iterator it=update.begin(); it!=update.end(); ++it) {
for (VpioVarSet::iterator it=update.begin(); it!=update.end(); ++it) {
memcpy((*it)->prevDatap(), (*it)->varDatap(), (*it)->entSize());
}
}
@@ -462,8 +463,8 @@ public:
m_errorInfo.level = level;
return this;
}
void setMessage(string file, PLI_INT32 line, string message, ...) {
static VL_THREAD string filehold;
void setMessage(std::string file, PLI_INT32 line, std::string message, ...) {
static VL_THREAD std::string filehold;
_VL_VPI_ERROR_SET;
m_errorInfo.state = vpiPLI;
filehold = file;
+3
View File
@@ -46,6 +46,7 @@
# define VL_FUNC __func__
# define VL_LIKELY(x) __builtin_expect(!!(x), 1)
# define VL_UNLIKELY(x) __builtin_expect(!!(x), 0)
# define VL_UNREACHABLE __builtin_unreachable();
# define VL_PREFETCH_RD(p) __builtin_prefetch((p),0)
# define VL_PREFETCH_RW(p) __builtin_prefetch((p),1)
#elif defined(_MSC_VER)
@@ -57,6 +58,7 @@
# define VL_FUNC __FUNCTION__
# define VL_LIKELY(x) (!!(x))
# define VL_UNLIKELY(x) (!!(x))
# define VL_UNREACHABLE
# define VL_PREFETCH_RD(p)
# define VL_PREFETCH_RW(p)
#else
@@ -68,6 +70,7 @@
# define VL_FUNC "__func__" ///< Name of current function for error macros
# define VL_LIKELY(x) (!!(x)) ///< Boolean expression more often true than false
# define VL_UNLIKELY(x) (!!(x)) ///< Boolean expression more often false than true
# define VL_UNREACHABLE ///< Point that may never be reached
# define VL_PREFETCH_RD(p) ///< Prefetch data with read intent
# define VL_PREFETCH_RW(p) ///< Prefetch data with read/write intent
#endif
+7 -7
View File
@@ -124,7 +124,7 @@ if [ x"$dir_arg" != x ]; then
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
@@ -134,7 +134,7 @@ else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
@@ -162,7 +162,7 @@ dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
@@ -201,17 +201,17 @@ else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
@@ -242,7 +242,7 @@ else
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
+1 -1
View File
@@ -709,7 +709,7 @@ Start GDB, then C<start> with the remaining arguments.
Temporary breakpoint 1, main (argc=13, argv=0xbfffefa4, env=0xbfffefdc)
at ../Verilator.cpp:615
615 ios::sync_with_stdio();
(gdb)
(gdb)
You can then continue execution with breakpoints as required.
+1 -1
View File
@@ -8,7 +8,7 @@ use strict;
#======================================================================
# main
eval `modulecmd perl add synopsys-vcs_mx`;
eval `modulecmd perl add synopsys-sim`;
exec('vcs',@ARGV);
#######################################################################
+4 -2
View File
@@ -64,6 +64,8 @@ LDFLAGS += @LDFLAGS@
EXEEXT = @EXEEXT@
CFG_CXXFLAGS_SRC = @CFG_CXXFLAGS_SRC@
CFG_CXXFLAGS_PARSER = @CFG_CXXFLAGS_PARSER@
# Compiler flags that turn on extra warnings
CFG_CXXFLAGS_WEXTRA = @CFG_CXXFLAGS_WEXTRA@
#### End of system configuration section. ####
@@ -73,7 +75,7 @@ TGT = ../../verilator_bin
#################
ifeq ($(VL_DEBUG),)
# Optimize
COPT = -O
COPT = -O2
else
# Debug
COPT = -ggdb -DVL_DEBUG
@@ -97,7 +99,7 @@ CPPFLAGS += -DYYDEBUG # Required to get nice error messages
CPPFLAGS += $(COPT)
CPPFLAGS += -MP # Only works on recent GCC versions
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
CPPFLAGS += -W -Wall $(CFG_CXXFLAGS_SRC) -Werror
CPPFLAGS += -W -Wall $(CFG_CXXFLAGS_WEXTRA) $(CFG_CXXFLAGS_SRC) -Werror
#CPPFLAGS += -pedantic-errors
else
CPPFLAGS += $(CFG_CXXFLAGS_SRC)
+2 -2
View File
@@ -176,7 +176,7 @@ private:
if (m_check == CT_INITIAL) {
nodep->v3warn(INITIALDLY,"Delayed assignments (<=) in initial or final block; suggest blocking assignments (=).");
} else if (m_check == CT_LATCH) {
// Suppress. Shouldn't matter that the interior of the latch races
// 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; suggest blocking assignments (=).");
}
@@ -438,5 +438,5 @@ public:
void V3Active::activeAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ActiveVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("active.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("active", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -160,5 +160,5 @@ public:
void V3ActiveTop::activeTopAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ActiveTopVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("activetop.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("activetop", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+6 -6
View File
@@ -162,7 +162,7 @@ private:
// Bye
pushDeletep(nodep); VL_DANGLING(nodep);
}
virtual void visit(AstIf* nodep) {
if (nodep->user1SetOnce()) return;
if (nodep->uniquePragma() || nodep->unique0Pragma()) {
@@ -177,12 +177,12 @@ private:
// Recurse into the true case.
ifp->ifsp()->iterateAndNext(*this);
// If the last else is not an else if, recurse into that too.
if (ifp->elsesp() && !nextifp) {
ifp->elsesp()->iterateAndNext(*this);
}
// Build a bitmask of the true predicates
AstNode* predp = ifp->condp()->cloneTree(false);
if (propp) {
@@ -195,13 +195,13 @@ private:
if (ifp->elsesp() && !nextifp) {
hasDefaultElse = true;
}
ifp = nextifp;
} while (ifp);
AstNode *newifp = nodep->cloneTree(false);
bool allow_none = nodep->unique0Pragma();
// Note: if this ends with an 'else', then we don't need to validate that one of the
// predicates evaluates to true.
AstNode* ohot = ((allow_none || hasDefaultElse)
@@ -344,5 +344,5 @@ public:
void V3Assert::assertAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
AssertVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("assert.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("assert", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -137,5 +137,5 @@ public:
void V3AssertPre::assertPreAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
AssertPreVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("assertpre.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("assertpre", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+6 -2
View File
@@ -716,6 +716,7 @@ void AstNode::deleteTree() {
#ifdef VL_LEAK_CHECKS
void* AstNode::operator new(size_t size) {
// Optimization note: Aligning to cache line is a loss, due to lost packing
AstNode* objp = static_cast<AstNode*>(::operator new(size));
V3Broken::addNewed(objp);
return objp;
@@ -734,6 +735,7 @@ void AstNode::operator delete(void* objp, size_t size) {
void AstNode::iterateChildren(AstNVisitor& v) {
// This is a very hot function
// Optimization note: Grabbing m_op#p->m_nextp is a net loss
ASTNODE_PREFETCH(m_op1p);
ASTNODE_PREFETCH(m_op2p);
ASTNODE_PREFETCH(m_op3p);
@@ -766,11 +768,13 @@ void AstNode::iterateAndNext(AstNVisitor& v) {
#ifdef VL_DEBUG // Otherwise too hot of a function for debug
if (VL_UNLIKELY(nodep && !nodep->m_backp)) nodep->v3fatalSrc("iterateAndNext node has no back");
#endif
if (nodep) ASTNODE_PREFETCH(nodep->m_nextp);
while (nodep) { // effectively: if (!this) return; // Callers rely on this
if (nodep->m_nextp) ASTNODE_PREFETCH(nodep->m_nextp->m_nextp);
AstNode* niterp = nodep; // This address may get stomped via m_iterpp if the node is edited
ASTNODE_PREFETCH(nodep->m_nextp);
// Desirable check, but many places where multiple iterations are OK
//if (VL_UNLIKELY(niterp->m_iterpp)) niterp->v3fatalSrc("IterateAndNext under iterateAndNext may miss edits");
// Optimization note: Doing PREFETCH_RW on m_iterpp is a net even
// cppcheck-suppress nullPointer
niterp->m_iterpp = &niterp;
niterp->accept(v);
@@ -975,7 +979,7 @@ void AstNode::dumpTreeGdb() { // For GDB only
dumpTree(cout);
}
void AstNode::dumpTreeFileGdb(const char* filenamep) { // For GDB only
string filename = filenamep ? filenamep : v3Global.debugFilename("debug.tree",98);
string filename = filenamep ? filenamep : v3Global.debugFilename("debug",98);
v3Global.rootp()->dumpTreeFile(filename);
}
+5 -1
View File
@@ -226,7 +226,7 @@ string AstVar::vlArgType(bool named, bool forReturn, bool forFunc) const {
arg += "float";
} else if (strtype) {
if (isInOnly()) arg += "const ";
arg += "string";
arg += "std::string";
} else if (widthMin() <= 8) {
arg += "CData";
} else if (widthMin() <= 16) {
@@ -891,6 +891,10 @@ void AstNodeModule::dump(ostream& str) {
if (inLibrary()) str<<" [LIB]";
if (dead()) str<<" [DEAD]";
}
void AstPackageExport::dump(ostream& str) {
this->AstNode::dump(str);
str<<" -> "<<packagep();
}
void AstPackageImport::dump(ostream& str) {
this->AstNode::dump(str);
str<<" -> "<<packagep();
+40 -12
View File
@@ -127,15 +127,18 @@ public:
setOp2p(new AstConst(fl,range.hi())); setOp3p(new AstConst(fl,range.lo()));
}
ASTNODE_NODE_FUNCS(Range)
AstNode* msbp() const { return op2p(); } // op2 = Msb expression
AstNode* lsbp() const { return op3p(); } // op3 = Lsb expression
AstNode* msbp() const { return op2p(); } // op2 = Msb expression
AstNode* lsbp() const { return op3p(); } // op3 = Lsb expression
AstNode* leftp() const { return littleEndian()?lsbp():msbp(); } // How to show a declaration
AstNode* rightp() const { return littleEndian()?msbp():lsbp(); }
int msbConst() const { AstConst* constp=msbp()->castConst(); return (constp?constp->toSInt():0); }
int lsbConst() const { AstConst* constp=lsbp()->castConst(); return (constp?constp->toSInt():0); }
int elementsConst() const { return (msbConst()>lsbConst()) ? msbConst()-lsbConst()+1 : lsbConst()-msbConst()+1; }
bool littleEndian() const { return m_littleEndian; }
void littleEndian(bool flag) { m_littleEndian=flag; }
int msbConst() const { AstConst* constp=msbp()->castConst(); return (constp?constp->toSInt():0); }
int lsbConst() const { AstConst* constp=lsbp()->castConst(); return (constp?constp->toSInt():0); }
int elementsConst() const { return (msbConst()>lsbConst()) ? msbConst()-lsbConst()+1 : lsbConst()-msbConst()+1; }
int leftConst() const { AstConst* constp=leftp()->castConst(); return (constp?constp->toSInt():0); }
int rightConst() const { AstConst* constp=rightp()->castConst(); return (constp?constp->toSInt():0); }
int leftToRightInc() const { return littleEndian()?1:-1; }
bool littleEndian() const { return m_littleEndian; }
void littleEndian(bool flag) { m_littleEndian=flag; }
virtual void dump(ostream& str);
virtual string emitC() { V3ERROR_NA; return ""; }
virtual V3Hash sameHash() const { return V3Hash(); }
@@ -254,7 +257,7 @@ public:
m_uniqueNum = uniqueNumInc();
}
ASTNODE_NODE_FUNCS(DefImplicitDType)
virtual bool same(AstNode* samep) const { return m_uniqueNum==samep->castDefImplicitDType()->m_uniqueNum; }
virtual bool same(AstNode* samep) const { return m_uniqueNum==samep->castDefImplicitDType()->m_uniqueNum; }
virtual bool similarDType(AstNodeDType* samep) const {
return type()==samep->type() && same(samep); }
virtual V3Hash sameHash() const { return V3Hash(m_uniqueNum); }
@@ -406,8 +409,8 @@ public:
void rangep(AstRange* nodep) { setNOp1p(nodep); }
void setSignedState(VSignedState signst) {
// Note NOSIGN does NOT change the state; this is required by the parser
if (signst==signedst_UNSIGNED) numeric(VSignedState(signst));
else if (signst==signedst_SIGNED) numeric(VSignedState(signst));
if (signst==signedst_UNSIGNED) numeric(signst);
else if (signst==signedst_SIGNED) numeric(signst);
}
// METHODS
virtual AstBasicDType* basicp() const { return (AstBasicDType*)this; } // (Slow) recurse down to find basic data type
@@ -1505,6 +1508,31 @@ public:
virtual string verilogKwd() const { return "primitive"; }
};
class AstPackageExportStarStar : public AstNode {
// A package export *::* declaration
public:
AstPackageExportStarStar(FileLine* fl)
: AstNode (fl) {}
ASTNODE_NODE_FUNCS(PackageExportStarStar)
};
class AstPackageExport : public AstNode {
private:
// A package export declaration
string m_name;
AstPackage* m_packagep; // Package hierarchy
public:
AstPackageExport(FileLine* fl, AstPackage* packagep, const string& name)
: AstNode (fl), m_name(name), m_packagep(packagep) {}
ASTNODE_NODE_FUNCS(PackageExport)
virtual const char* broken() const { BROKEN_RTN(!m_packagep || !m_packagep->brokeExists()); return NULL; }
virtual void cloneRelink() { if (m_packagep && m_packagep->clonep()) m_packagep = m_packagep->clonep(); }
virtual void dump(ostream& str);
virtual string name() const { return m_name; }
AstPackage* packagep() const { return m_packagep; }
void packagep(AstPackage* nodep) { m_packagep=nodep; }
};
class AstPackageImport : public AstNode {
private:
// A package import declaration
@@ -1794,7 +1822,7 @@ public:
}}
virtual bool same(AstNode* samep) const {
return (m_packagep==samep->castPackageRef()->m_packagep); }
virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_packagep)); }
virtual V3Hash sameHash() const { return V3Hash(m_packagep); }
virtual void dump(ostream& str=cout);
AstPackage* packagep() const { return m_packagep; }
void packagep(AstPackage* nodep) { m_packagep=nodep; }
@@ -1916,7 +1944,7 @@ public:
}
ASTNODE_NODE_FUNCS(SenItem)
virtual void dump(ostream& str);
virtual V3Hash sameHash() const { return V3Hash(V3Hash(edgeType())); }
virtual V3Hash sameHash() const { return V3Hash(edgeType()); }
virtual bool same(AstNode* samep) const {
return edgeType()==samep->castSenItem()->edgeType(); }
AstEdgeType edgeType() const { return m_edgeType; } // * = Posedge/negedge
+1 -1
View File
@@ -296,5 +296,5 @@ void V3Begin::debeginAll(AstNetlist* nodep) {
if (state.anyFuncInBegin()) {
BeginRelinkVisitor brvisitor (nodep,&state);
}
V3Global::dumpCheckGlobalTree("begin.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("begin", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+5 -1
View File
@@ -66,12 +66,16 @@ public:
}
if (iter!=s_nodes.end()) s_nodes.erase(iter);
}
#if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 4
// GCC 4.4.* compiler warning bug, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=39390
# pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif
static void addNewed(const AstNode* nodep) {
// Called by operator new on any node - only if VL_LEAK_CHECKS
if (debug()>=9) cout<<"-nodeNew: "<<(void*)(nodep)<<endl;
NodeMap::iterator iter = s_nodes.find(nodep);
if (iter!=s_nodes.end() || (iter->second & FLAG_ALLOCATED)) {
((AstNode*)(nodep))->v3fatalSrc("Newing AstNode object that is already allocated");
nodep->v3fatalSrc("Newing AstNode object that is already allocated");
}
if (iter == s_nodes.end()) {
int flags = FLAG_ALLOCATED; // This int needed to appease GCC 4.1.2
+1 -1
View File
@@ -489,7 +489,7 @@ public:
void V3Case::caseAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
CaseVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("case.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("case", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Case::caseLint(AstNodeCase* nodep) {
UINFO(4,__FUNCTION__<<": "<<endl);
+1 -1
View File
@@ -188,5 +188,5 @@ public:
void V3Cast::castAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
CastVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("cast.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("cast", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+4 -4
View File
@@ -111,8 +111,8 @@ private:
AstVarScope* m_vscp; // Original (non-change) variable we're change-detecting
AstVarScope* m_newvscp; // New (change detect) variable we're change-detecting
AstNode* m_varEqnp; // Original var's equation to get var value
AstNode* m_newLvEqnp; // New var's equation to read value
AstNode* m_newRvEqnp; // New var's equation to set value
AstNode* m_newLvEqnp; // New var's equation to read value
AstNode* m_newRvEqnp; // New var's equation to set value
uint32_t m_detects; // # detects created
// CONSTANTS
@@ -278,7 +278,7 @@ private:
}
}
virtual void visit(AstNodeMath* nodep) {
// Short-circuit
// Short-circuit
}
//--------------------
// Default: Just iterate
@@ -302,5 +302,5 @@ void V3Changed::changedAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ChangedState state;
ChangedVisitor visitor (nodep, &state);
V3Global::dumpCheckGlobalTree("changed.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("changed", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -297,5 +297,5 @@ public:
void V3Clean::cleanAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
CleanVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("clean.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("clean", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+2 -2
View File
@@ -879,7 +879,7 @@ class GaterVisitor : public GaterBaseVisitor {
public:
// CONSTUCTORS
explicit GaterVisitor(AstNode* nodep) {
explicit GaterVisitor(AstNetlist* nodep) {
// AstAlways visitor does the real work, so most zeroing needs to be in clear()
clear();
nodep->accept(*this);
@@ -915,5 +915,5 @@ void V3ClkGater::clkGaterAll(AstNetlist* nodep) {
// While the gater does well at some modules, it seems to slow down many others
UINFO(5,"ClkGater is disabled due to performance issues\n");
//GaterVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("clkgater.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("clkgater", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -413,5 +413,5 @@ public:
void V3Clock::clockAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ClockVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("clock.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("clock", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -474,5 +474,5 @@ public:
void V3Combine::combineAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
CombineVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("combine.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("combine", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+88 -14
View File
@@ -305,8 +305,7 @@ private:
return (nodep->lsbp()->castConst()
&& nodep->widthp()->castConst()
&& nodep->lsbConst()==0
&& (int)nodep->widthConst()==nodep->fromp()->width()
&& 1);
&& (int)nodep->widthConst()==nodep->fromp()->width());
}
bool operandSelExtend(AstSel* nodep) {
// A pattern created by []'s after offsets have been removed
@@ -342,6 +341,33 @@ private:
replaceWChild(nodep, bip); VL_DANGLING(nodep);
return true;
}
bool operandSelShiftLower(AstSel* nodep) {
// AND({a}, SHIFTR({b}, {c})) is often shorthand in C for Verilog {b}[{c} :+ {a}]
// becomes thought other optimizations
// SEL(SHIFTR({a},{b}),{lsb},{width}) -> SEL({a},{lsb+b},{width})
AstShiftR* shiftp = nodep->fromp()->castShiftR();
if (!(m_doV
&& shiftp
&& shiftp->rhsp()->castConst()
&& nodep->lsbp()->castConst()
&& nodep->widthp()->castConst()
)) return false;
AstNode* ap = shiftp->lhsp();
AstConst* bp = shiftp->rhsp()->castConst();
AstConst* lp = nodep->lsbp()->castConst();
if (bp->isWide() || bp->num().isFourState() || bp->num().isNegative()
|| lp->isWide() || lp->num().isFourState() || lp->num().isNegative()) return false;
int newLsb = lp->toSInt() + bp->toSInt();
if (newLsb + nodep->widthConst() > ap->width()) return false;
//
UINFO(9, "SEL(SHIFTR(a,b),l,w) -> SEL(a,l+b,w)\n");
if (debug()>=9) nodep->dumpTree(cout,"SEL(SH)-in:");
AstSel* newp = new AstSel(nodep->fileline(), ap->unlinkFrBack(), newLsb, nodep->widthConst());
newp->dtypeFrom(nodep);
if (debug()>=9) newp->dumpTree(cout,"SEL(SH)-ou:");
nodep->replaceWith(newp); VL_DANGLING(nodep);
return true;
}
bool operandBiExtendConst(AstNodeBiop* nodep) {
// Loop unrolling favors standalone compares
@@ -1367,22 +1393,67 @@ private:
}
nodep->deleteTree(); VL_DANGLING(nodep);
}
void replaceSelReplicate(AstSel* nodep) {
// SEL(REPLICATE(a,b),1,bit) => SEL(a,1,bit)
bool operandSelReplicate(AstSel* nodep) {
// SEL(REPLICATE(from,rep),lsb,width) => SEL(from,0,width) as long as SEL's width <= b's width
AstReplicate* repp = nodep->fromp()->castReplicate();
AstNode* fromp = repp->lhsp()->unlinkFrBack();
AstConst* lsbp = nodep->lsbp()->castConst();
AstNode* widthp = nodep->widthp()->unlinkFrBack();
AstNode* fromp = repp->lhsp();
AstConst* lsbp = nodep->lsbp()->castConst(); if (!lsbp) return false;
AstNode* widthp = nodep->widthp(); if (!widthp->castConst()) return false;
if (!fromp->width()) nodep->v3fatalSrc("Not widthed");
if ((lsbp->toUInt() / fromp->width())
!= ((lsbp->toUInt()+nodep->width()-1) / fromp->width())) return false;
//
fromp->unlinkFrBack();
widthp->unlinkFrBack();
AstSel* newp = new AstSel(nodep->fileline(),
fromp,
new AstConst(lsbp->fileline(), lsbp->toUInt() % fromp->width()),
widthp);
newp->dtypeFrom(nodep);
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
return true;
}
bool operandRepRep(AstReplicate* nodep) {
// REPLICATE(REPLICATE2(from2,cnt2),cnt1) => REPLICATE(from2,(cnt1+cnt2))
AstReplicate* rep2p = nodep->lhsp()->castReplicate();
AstNode* from2p = rep2p->lhsp();
AstConst* cnt1p = nodep->rhsp()->castConst(); if (!cnt1p) return false;
AstConst* cnt2p = rep2p->rhsp()->castConst(); if (!cnt2p) return false;
//
from2p->unlinkFrBack();
cnt1p->unlinkFrBack();
cnt2p->unlinkFrBack();
AstReplicate* newp = new AstReplicate(nodep->fileline(),
from2p, cnt1p->toUInt()*cnt2p->toUInt());
newp->dtypeFrom(nodep);
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
return true;
}
bool operandConcatSame(AstConcat* nodep) {
// CONCAT(fromp,fromp) -> REPLICATE(fromp,1+1)
// CONCAT(REP(fromp,cnt1),fromp) -> REPLICATE(fromp,cnt1+1)
// CONCAT(fromp,REP(fromp,cnt1)) -> REPLICATE(fromp,1+cnt1)
// CONCAT(REP(fromp,cnt1),REP(fromp,cnt2)) -> REPLICATE(fromp,cnt1+cnt2)
AstNode* from1p = nodep->lhsp(); uint32_t cnt1 = 1;
AstNode* from2p = nodep->rhsp(); uint32_t cnt2 = 1;
if (from1p->castReplicate()) {
AstConst* cnt1p = from1p->castReplicate()->rhsp()->castConst(); if (!cnt1p) return false;
from1p = from1p->castReplicate()->lhsp();
cnt1 = cnt1p->toUInt();
}
if (from2p->castReplicate()) {
AstConst* cnt2p = from2p->castReplicate()->rhsp()->castConst(); if (!cnt2p) return false;
from2p = from2p->castReplicate()->lhsp();
cnt2 = cnt2p->toUInt();
}
if (!operandsSame(from1p,from2p)) return false;
//
from1p->unlinkFrBack();
AstReplicate* newp = new AstReplicate(nodep->fileline(), from1p, cnt1+cnt2);
newp->dtypeFrom(nodep);
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
return true;
}
void replaceSelIntoBiop(AstSel* nodep) {
// SEL(BUFIF1(a,b),1,bit) => BUFIF1(SEL(a,1,bit),SEL(b,1,bit))
AstNodeBiop* fromp = nodep->fromp()->unlinkFrBack()->castNodeBiop();
@@ -2242,6 +2313,8 @@ private:
TREEOPV("AstExtendS{$lhsp.castExtendS}", "replaceExtend(nodep, nodep->lhsp()->castExtendS()->lhsp())");
TREEOPV("AstReplicate{$lhsp, $rhsp.isOne, $lhsp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs
TREEOPV("AstReplicateN{$lhsp, $rhsp.isOne, $lhsp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs
TREEOPV("AstReplicate{$lhsp.castReplicate, operandRepRep(nodep)}", "DONE"); // {2{3{lhs}}}->{6{lhs}}
TREEOPV("AstConcat{operandConcatSame(nodep)}", "DONE"); // {a,a}->{2{a}}, {a,2{a}}->{3{a}, etc
// Next rule because AUTOINST puts the width of bits in
// to pins, even when the widths are exactly the same across the hierarchy.
TREEOPV("AstSel{operandSelExtend(nodep)}", "DONE");
@@ -2253,9 +2326,10 @@ private:
TREEOPV("AstSel{$fromp.castSub, operandSelBiLower(nodep)}", "DONE");
TREEOPV("AstSel{$fromp.castXnor,operandSelBiLower(nodep)}", "DONE");
TREEOPV("AstSel{$fromp.castXor, operandSelBiLower(nodep)}", "DONE");
TREEOPV("AstSel{$fromp.castShiftR, operandSelShiftLower(nodep)}", "DONE");
TREEOPC("AstSel{$fromp.castConst, $lsbp.castConst, $widthp.castConst, }", "replaceConst(nodep)");
TREEOPV("AstSel{$fromp.castConcat, $lsbp.castConst, $widthp.castConst, }", "replaceSelConcat(nodep)");
TREEOPV("AstSel{$fromp.castReplicate, $lsbp.castConst, $widthp.isOne, }", "replaceSelReplicate(nodep)");
TREEOPV("AstSel{$fromp.castReplicate, $lsbp.castConst, $widthp.castConst, operandSelReplicate(nodep) }", "DONE");
// V3Tristate requires selects below BufIf1.
// Also do additional operators that are bit-independent, but only definite
// win if bit select is a constant (otherwise we may need to compute bit index several times)
@@ -2409,14 +2483,14 @@ void V3Const::constifyAllLint(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (ConstVisitor::PROC_V_WARN);
(void)visitor.mainAcceptEdit(nodep);
V3Global::dumpCheckGlobalTree("const.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("const", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Const::constifyCpp(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (ConstVisitor::PROC_CPP);
(void)visitor.mainAcceptEdit(nodep);
V3Global::dumpCheckGlobalTree("const_cpp.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("const_cpp", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
AstNode* V3Const::constifyEdit(AstNode* nodep) {
@@ -2432,7 +2506,7 @@ void V3Const::constifyAllLive(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (ConstVisitor::PROC_LIVE);
(void)visitor.mainAcceptEdit(nodep);
V3Global::dumpCheckGlobalTree("const.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("const", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Const::constifyAll(AstNetlist* nodep) {
@@ -2440,7 +2514,7 @@ void V3Const::constifyAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ConstVisitor visitor (ConstVisitor::PROC_V_EXPENSIVE);
(void)visitor.mainAcceptEdit(nodep);
V3Global::dumpCheckGlobalTree("const.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("const", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
AstNode* V3Const::constifyExpensiveEdit(AstNode* nodep) {
+1 -1
View File
@@ -395,5 +395,5 @@ public:
void V3Coverage::coverage(AstNetlist* rootp) {
UINFO(2,__FUNCTION__<<": "<<endl);
CoverageVisitor visitor (rootp);
V3Global::dumpCheckGlobalTree("coverage.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("coverage", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -135,5 +135,5 @@ public:
void V3CoverageJoin::coverageJoin(AstNetlist* rootp) {
UINFO(2,__FUNCTION__<<": "<<endl);
CoverageJoinVisitor visitor (rootp);
V3Global::dumpCheckGlobalTree("coveragejoin.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("coveragejoin", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+7 -7
View File
@@ -338,8 +338,8 @@ private:
if (vscp->user1() == 0) {
UINFO(4," Dead "<<vscp<<endl);
pair <AssignMap::iterator,AssignMap::iterator> eqrange = m_assignMap.equal_range(vscp);
for (AssignMap::iterator it = eqrange.first; it != eqrange.second; ++it) {
AstNodeAssign* assp = it->second;
for (AssignMap::iterator itr = eqrange.first; itr != eqrange.second; ++itr) {
AstNodeAssign* assp = itr->second;
UINFO(4," Dead assign "<<assp<<endl);
assp->dtypep()->user1Inc(-1);
assp->unlinkFrBack()->deleteTree(); VL_DANGLING(assp);
@@ -422,29 +422,29 @@ public:
void V3Dead::deadifyModules(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DeadVisitor visitor (nodep, false, false, false, false);
V3Global::dumpCheckGlobalTree("deadModules.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
V3Global::dumpCheckGlobalTree("deadModules", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
void V3Dead::deadifyDTypes(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DeadVisitor visitor (nodep, false, true, false, false);
V3Global::dumpCheckGlobalTree("deadDtypes.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("deadDtypes", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Dead::deadifyDTypesScoped(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DeadVisitor visitor (nodep, false, true, true, false);
V3Global::dumpCheckGlobalTree("deadDtypesScoped.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("deadDtypesScoped", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Dead::deadifyAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DeadVisitor visitor (nodep, true, true, false, true);
V3Global::dumpCheckGlobalTree("deadAll.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("deadAll", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Dead::deadifyAllScoped(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DeadVisitor visitor (nodep, true, true, true, true);
V3Global::dumpCheckGlobalTree("deadAllScoped.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("deadAllScoped", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -471,5 +471,5 @@ public:
void V3Delayed::delayedAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DelayedVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("delayed.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("delayed", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -175,5 +175,5 @@ public:
void V3Depth::depthAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DepthVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("depth.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
V3Global::dumpCheckGlobalTree("depth", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
+1 -1
View File
@@ -140,5 +140,5 @@ public:
void V3DepthBlock::depthBlockAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DepthBlockVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("deepblock.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("deepblock", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -263,5 +263,5 @@ public:
void V3Descope::descopeAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
DescopeVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("descope.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("descope", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+102 -52
View File
@@ -36,6 +36,8 @@
#define VL_VALUE_STRING_MAX_WIDTH 8192 // We use a static char array in VL_VALUE_STRING
#define EMITC_NUM_CONSTW 8 // Number of VL_CONST_W_*X's in verilated.h (IE VL_CONST_W_8X is last)
//######################################################################
// Emit statements and math operators
@@ -603,9 +605,9 @@ public:
puts(nodep->hiername());
puts(nodep->varp()->name());
}
void emitCvtPackStr(AstNode* nodep) {
void emitCvtPackStr(AstNode* nodep) {
if (AstConst* constp = nodep->castConst()) {
putbs("string(");
putbs("std::string(");
putsQuoted(constp->num().toString());
puts(")");
} else {
@@ -625,28 +627,68 @@ public:
if (nodep->num().isFourState()) {
nodep->v3error("Unsupported: 4-state numbers in this context");
} else if (nodep->num().isString()) {
putbs("string(");
putbs("std::string(");
putsQuoted(nodep->num().toString());
puts(")");
} else if (nodep->isWide()) {
putbs("VL_CONST_W_");
puts(cvtToStr(VL_WORDS_I(nodep->num().widthMin())));
puts("X(");
puts(cvtToStr(nodep->widthMin()));
puts(",");
if (!assigntop) {
puts(assignString);
} else if (assigntop->castVarRef()) {
puts(assigntop->hiername());
puts(assigntop->varp()->name());
} else {
assigntop->iterateAndNext(*this);
int upWidth = nodep->num().widthMin();
int chunks = 0;
if (upWidth > EMITC_NUM_CONSTW*VL_WORDSIZE) {
// Output e.g. 8 words in groups of e.g. 8
chunks = (upWidth-1) / (EMITC_NUM_CONSTW*VL_WORDSIZE);
upWidth %= (EMITC_NUM_CONSTW*VL_WORDSIZE);
if (upWidth == 0) upWidth = (EMITC_NUM_CONSTW*VL_WORDSIZE);
}
for (int word=VL_WORDS_I(nodep->num().widthMin())-1; word>0; word--) {
// Only 32 bits - llx + long long here just to appease CPP format warning
ofp()->printf(",0x%08" VL_PRI64 "x", (vluint64_t)(nodep->num().dataWord(word)));
{ // Upper e.g. 8 words
if (chunks) {
putbs("VL_CONSTHI_W_");
puts(cvtToStr(VL_WORDS_I(upWidth)));
puts("X(");
puts(cvtToStr(nodep->widthMin()));
puts(",");
puts(cvtToStr(chunks*EMITC_NUM_CONSTW*VL_WORDSIZE));
} else {
putbs("VL_CONST_W_");
puts(cvtToStr(VL_WORDS_I(upWidth)));
puts("X(");
puts(cvtToStr(nodep->widthMin()));
}
puts(",");
if (!assigntop) {
puts(assignString);
} else if (assigntop->castVarRef()) {
puts(assigntop->hiername());
puts(assigntop->varp()->name());
} else {
assigntop->iterateAndNext(*this);
}
for (int word=VL_WORDS_I(upWidth)-1; word>=0; word--) {
// Only 32 bits - llx + long long here just to appease CPP format warning
ofp()->printf(",0x%08" VL_PRI64 "x", (vluint64_t)(nodep->num().dataWord(word+chunks*EMITC_NUM_CONSTW)));
}
puts(")");
}
for (chunks--; chunks >= 0; chunks--) {
puts(";\n");
putbs("VL_CONSTLO_W_");
puts(cvtToStr(EMITC_NUM_CONSTW));
puts("X(");
puts(cvtToStr(chunks*EMITC_NUM_CONSTW*VL_WORDSIZE));
puts(",");
if (!assigntop) {
puts(assignString);
} else if (assigntop->castVarRef()) {
puts(assigntop->hiername());
puts(assigntop->varp()->name());
} else {
assigntop->iterateAndNext(*this);
}
for (int word=EMITC_NUM_CONSTW-1; word>=0; word--) {
// Only 32 bits - llx + long long here just to appease CPP format warning
ofp()->printf(",0x%08" VL_PRI64 "x", (vluint64_t)(nodep->num().dataWord(word+chunks*EMITC_NUM_CONSTW)));
}
puts(")");
}
ofp()->printf(",0x%08" VL_PRI64 "x)", (vluint64_t)(nodep->num().dataWord(0)));
} else if (nodep->isDouble()) {
if (int(nodep->num().toDouble()) == nodep->num().toDouble()
&& nodep->num().toDouble() < 1000
@@ -1516,8 +1558,8 @@ void EmitCImp::emitCoverageImp(AstNodeModule* modp) {
puts( " \"filename\",filenamep,");
puts( " \"lineno\",lineno,");
puts( " \"column\",column,\n");
//puts( "\"hier\",string(__VlSymsp->name())+hierp,"); // Need to move hier into scopes and back out if do this
puts( "\"hier\",string(name())+hierp,");
//puts( "\"hier\",std::string(__VlSymsp->name())+hierp,"); // Need to move hier into scopes and back out if do this
puts( "\"hier\",std::string(name())+hierp,");
puts( " \"page\",pagep,");
puts( " \"comment\",commentp);\n");
puts("}\n");
@@ -1686,7 +1728,7 @@ void EmitCImp::emitSensitives() {
void EmitCImp::emitWrapEval(AstNodeModule* modp) {
puts("\nvoid "+modClassName(modp)+"::eval() {\n");
puts(EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp; // Setup global symbol table\n");
puts(EmitCBaseVisitor::symClassVar()+" = this->__VlSymsp; // Setup global symbol table\n");
puts(EmitCBaseVisitor::symTopAssign()+"\n");
putsDecoration("// Initialize\n");
puts("if (VL_UNLIKELY(!vlSymsp->__Vm_didInit)) _eval_initial_loop(vlSymsp);\n");
@@ -1696,14 +1738,16 @@ void EmitCImp::emitWrapEval(AstNodeModule* modp) {
putsDecoration("// Evaluate till stable\n");
puts("VL_DEBUG_IF(VL_PRINTF(\"\\n----TOP Evaluate "+modClassName(modp)+"::eval\\n\"); );\n");
puts("int __VclockLoop = 0;\n");
puts("QData __Vchange=1;\n");
puts("QData __Vchange = 1;\n");
puts("while (VL_LIKELY(__Vchange)) {\n");
puts( "VL_DEBUG_IF(VL_PRINTF(\" Clock loop\\n\"););\n");
puts( "vlSymsp->__Vm_activity = true;\n");
if (v3Global.opt.trace()) {
puts("vlSymsp->__Vm_activity = true;\n");
}
puts( "_eval(vlSymsp);\n");
puts( "__Vchange = _change_request(vlSymsp);\n");
puts( "if (++__VclockLoop > "+cvtToStr(v3Global.opt.convergeLimit())
+") vl_fatal(__FILE__,__LINE__,__FILE__,\"Verilated model didn't converge\");\n");
puts( "if (VL_UNLIKELY(++__VclockLoop > "+cvtToStr(v3Global.opt.convergeLimit())
+")) vl_fatal(__FILE__,__LINE__,__FILE__,\"Verilated model didn't converge\");\n");
puts("}\n");
puts("}\n");
splitSizeInc(10);
@@ -1712,15 +1756,17 @@ void EmitCImp::emitWrapEval(AstNodeModule* modp) {
puts("\nvoid "+modClassName(modp)+"::_eval_initial_loop("+EmitCBaseVisitor::symClassVar()+") {\n");
puts("vlSymsp->__Vm_didInit = true;\n");
puts("_eval_initial(vlSymsp);\n");
puts( "vlSymsp->__Vm_activity = true;\n");
if (v3Global.opt.trace()) {
puts("vlSymsp->__Vm_activity = true;\n");
}
puts( "int __VclockLoop = 0;\n");
puts( "QData __Vchange=1;\n");
puts( "QData __Vchange = 1;\n");
puts( "while (VL_LIKELY(__Vchange)) {\n");
puts( "_eval_settle(vlSymsp);\n");
puts( "_eval(vlSymsp);\n");
puts( "__Vchange = _change_request(vlSymsp);\n");
puts( "if (++__VclockLoop > "+cvtToStr(v3Global.opt.convergeLimit())
+") vl_fatal(__FILE__,__LINE__,__FILE__,\"Verilated model didn't DC converge\");\n");
puts( "if (VL_UNLIKELY(++__VclockLoop > "+cvtToStr(v3Global.opt.convergeLimit())
+")) vl_fatal(__FILE__,__LINE__,__FILE__,\"Verilated model didn't DC converge\");\n");
puts( "}\n");
puts("}\n");
splitSizeInc(10);
@@ -1797,7 +1843,7 @@ void EmitCImp::emitIntFuncDecls(AstNodeModule* modp) {
if (!funcp->dpiImport()) { // DPI is prototyped in __Dpi.h
ofp()->putsPrivate(funcp->declPrivate());
if (funcp->isStatic()) puts("static ");
puts(funcp->rtnTypeVoid()); puts("\t");
puts(funcp->rtnTypeVoid()); puts(" ");
puts(funcp->name()); puts("("+cFuncArgs(funcp)+");\n");
}
}
@@ -1829,8 +1875,8 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
// do this before including our main .h file so that any references to
// types defined in svdpi.h are available
puts("#include \""+ topClassName() +"__Dpi.h\"\n");
puts("\n");
}
puts("\n");
// Declare foreign instances up front to make C++ happy
puts("class "+symClassName()+";\n");
@@ -1854,13 +1900,17 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
ofp()->resetPrivate();
ofp()->putsPrivate(false); // public:
// Instantiated modules
putsDecoration("// CELLS\n");
if (modp->isTop()) puts("// Public to allow access to /*verilator_public*/ items;\n");
if (modp->isTop()) puts("// otherwise the application code can consider these internals.\n");
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (AstCell* cellp=nodep->castCell()) {
ofp()->putsCellDecl(modClassName(cellp->modp()), cellp->name());
{ // Instantiated cells
bool did = false;
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (AstCell* cellp=nodep->castCell()) {
if (!did++) {
putsDecoration("// CELLS\n");
if (modp->isTop()) puts("// Public to allow access to /*verilator_public*/ items;\n");
if (modp->isTop()) puts("// otherwise the application code can consider these internals.\n");
}
ofp()->putsCellDecl(modClassName(cellp->modp()), cellp->name());
}
}
}
@@ -1882,11 +1932,11 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
puts("\n// INTERNAL VARIABLES\n");
if (modp->isTop()) puts("// Internals; generally not touched by application code\n");
ofp()->putsPrivate(!modp->isTop()); // private: unless top
puts(symClassName()+"*\t__VlSymsp;\t\t// Symbol table\n");
puts(symClassName()+"* __VlSymsp; // Symbol table\n");
ofp()->putsPrivate(false); // public:
if (modp->isTop()) {
if (v3Global.opt.inhibitSim()) {
puts("bool\t__Vm_inhibitSim;\t///< Set true to disable evaluation of module\n");
puts("bool __Vm_inhibitSim; ///< Set true to disable evaluation of module\n");
}
}
emitCoverageDecl(modp); // may flip public/private
@@ -1921,8 +1971,8 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
ofp()->resetPrivate();
// We don't need a private copy constructor, as VerilatedModule has one for us.
ofp()->putsPrivate(true);
puts(modClassName(modp)+"& operator= (const "+modClassName(modp)+"&);\t///< Copying not allowed\n");
puts(modClassName(modp)+"(const "+modClassName(modp)+"&);\t///< Copying not allowed\n");
puts(modClassName(modp)+"& operator= (const "+modClassName(modp)+"&); ///< Copying not allowed\n");
puts(modClassName(modp)+"(const "+modClassName(modp)+"&); ///< Copying not allowed\n");
ofp()->putsPrivate(false); // public:
if (optSystemC() && modp->isTop()) {
@@ -1950,7 +2000,6 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
}
}
puts("\n// USER METHODS\n");
emitTextSection(AstType::atScInt);
puts("\n// API METHODS\n");
@@ -1962,7 +2011,7 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
if (!optSystemC()) puts("/// Simulation complete, run final blocks. Application must call on completion.\n");
puts("void final();\n");
if (v3Global.opt.inhibitSim()) {
puts("void inhibitSim(bool flag) { __Vm_inhibitSim=flag; }\t///< Set true to disable evaluation of module\n");
puts("void inhibitSim(bool flag) { __Vm_inhibitSim=flag; } ///< Set true to disable evaluation of module\n");
}
}
@@ -1995,13 +2044,13 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
// Save/restore
if (v3Global.opt.savable() && modp->isTop()) {
puts("inline VerilatedSerialize& operator<<(VerilatedSerialize& os, "+modClassName(modp)+"& rhs) {rhs.__Vserialize(os); return os;}\n");
puts("inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, "+modClassName(modp)+"& rhs) {rhs.__Vdeserialize(os); return os;}\n");
puts("inline VerilatedSerialize& operator<<(VerilatedSerialize& os, "+modClassName(modp)+"& rhs) { rhs.__Vserialize(os); return os; }\n");
puts("inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, "+modClassName(modp)+"& rhs) { rhs.__Vdeserialize(os); return os; }\n");
puts("\n");
}
// finish up h-file
puts("#endif /*guard*/\n");
puts("#endif // guard\n");
}
//----------------------------------------------------------------------
@@ -2017,6 +2066,7 @@ void EmitCImp::emitImp(AstNodeModule* modp) {
puts("\n");
puts("#include \"verilated_dpi.h\"\n");
}
puts("\n");
emitTextSection(AstType::atScImpHdr);
@@ -2152,7 +2202,7 @@ class EmitCTrace : EmitCStmts {
+v3Global.opt.traceClassBase()+"* vcdp, void* userthis, uint32_t code) {\n");
putsDecoration("// Callback from vcd->open()\n");
puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n");
puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n");
puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n");
puts("if (!Verilated::calcUnusedSigs()) vl_fatal(__FILE__,__LINE__,__FILE__,\"Turning on wave traces requires Verilated::traceEverOn(true) call before time 0.\");\n");
puts("vcdp->scopeEscape(' ');\n");
@@ -2165,7 +2215,7 @@ class EmitCTrace : EmitCStmts {
+v3Global.opt.traceClassBase()+"* vcdp, void* userthis, uint32_t code) {\n");
putsDecoration("// Callback from vcd->dump()\n");
puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n");
puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n");
puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n");
puts("t->traceFullThis (vlSymsp, vcdp, code);\n");
puts("}\n");
splitSizeInc(10);
@@ -2180,7 +2230,7 @@ class EmitCTrace : EmitCStmts {
+v3Global.opt.traceClassBase()+"* vcdp, void* userthis, uint32_t code) {\n");
putsDecoration("// Callback from vcd->dump()\n");
puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n");
puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n");
puts(EmitCBaseVisitor::symClassVar()+" = t->__VlSymsp; // Setup global symbol table\n");
puts("if (vlSymsp->getClearActivity()) {\n");
puts("t->traceChgThis (vlSymsp, vcdp, code);\n");
puts("}\n");
@@ -2324,7 +2374,7 @@ class EmitCTrace : EmitCStmts {
puts("int c=code;\n");
puts("if (0 && vcdp && c) {} // Prevent unused\n");
if (nodep->funcType() == AstCFuncType::TRACE_INIT) {
puts("vcdp->module(vlSymsp->name()); // Setup signal names\n");
puts("vcdp->module(vlSymsp->name()); // Setup signal names\n");
} else if (nodep->funcType() == AstCFuncType::TRACE_INIT_SUB) {
} else if (nodep->funcType() == AstCFuncType::TRACE_FULL) {
} else if (nodep->funcType() == AstCFuncType::TRACE_FULL_SUB) {
+2 -40
View File
@@ -32,30 +32,15 @@
#include "V3EmitCBase.h"
#include "V3Stats.h"
#define EMITCINLINES_NUM_CONSTW 10 // Number of VL_CONST_W_*X's in verilated.h (IE VL_CONST_W_9X is last)
//######################################################################
class EmitCInlines : EmitCBaseVisitor {
// STATE
vector<V3Double0> m_wordWidths; // What sizes are used?
// METHODS
void emitInt();
// VISITORS
virtual void visit(AstVar* nodep) {
// All wide constants load into variables, so we can just hunt for them
nodep->iterateChildren(*this);
int words = nodep->widthWords();
if (words >= EMITCINLINES_NUM_CONSTW ) {
if (int(m_wordWidths.size()) <= words) {
m_wordWidths.resize(words+5);
}
++ m_wordWidths.at(words);
v3Global.needHInlines(true);
}
}
virtual void visit(AstBasicDType* nodep) {
if (nodep->keyword() == AstBasicDTypeKwd::STRING) {
v3Global.needHeavy(true); // #include <string> via verilated_heavy.h when we create symbol file
@@ -94,33 +79,10 @@ void EmitCInlines::emitInt() {
puts("\n//======================\n\n");
for (unsigned words=0; words<m_wordWidths.size(); words++) {
if (m_wordWidths.at(words)) {
puts("#ifndef VL_HAVE_CONST_W_"+cvtToStr(words)+"X\n");
puts("# define VL_HAVE_CONST_W_"+cvtToStr(words)+"X\n");
puts("static inline WDataOutP VL_CONST_W_"+cvtToStr(words)+"X(int obits, WDataOutP o\n");
puts("\t");
for (int i=words-1; i>=0; --i) {
puts(",IData d"+cvtToStr(i));
if (i && (i % 8 == 0)) puts("\n\t");
}
puts(") {\n");
puts(" ");
for (int i=words-1; i>=0; --i) {
puts(" o["+cvtToStr(i)+"]=d"+cvtToStr(i)+";");
if (i && (i % 8 == 0)) puts("\n ");
}
puts("\n");
puts(" for(int i="+cvtToStr(words)+";i<VL_WORDS_I(obits);i++) o[i] = (IData)0x0;\n");
puts(" return o;\n");
puts("}\n");
puts("#endif\n");
puts("\n");
}
}
// Placeholder - v3Global.needHInlines(true) currently not used
puts("//======================\n\n");
puts("#endif /*guard*/\n");
puts("#endif // guard\n");
}
//######################################################################
+36 -22
View File
@@ -112,8 +112,8 @@ class EmitCSyms : EmitCBaseVisitor {
// We didn'e have all m_scopes loaded when we encountered variables, so expand them now
// It would be less code if each module inserted its own variables.
// Someday. For now public isn't common.
for (vector<ScopeModPair>::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) {
AstScope* scopep = it->first; AstNodeModule* smodp = it->second;
for (vector<ScopeModPair>::iterator itsc = m_scopes.begin(); itsc != m_scopes.end(); ++itsc) {
AstScope* scopep = itsc->first; AstNodeModule* smodp = itsc->second;
for (vector<ModVarPair>::iterator it = m_modVars.begin(); it != m_modVars.end(); ++it) {
AstNodeModule* modp = it->first;
AstVar* varp = it->second;
@@ -124,10 +124,10 @@ class EmitCSyms : EmitCBaseVisitor {
string scpName;
string varBase;
if (whole.substr(0,10) == "__DOT__TOP") whole.replace(0,10,"");
string::size_type pos = whole.rfind("__DOT__");
if (pos != string::npos) {
scpName = whole.substr(0,pos);
varBase = whole.substr(pos+strlen("__DOT__"));
string::size_type dpos = whole.rfind("__DOT__");
if (dpos != string::npos) {
scpName = whole.substr(0,dpos);
varBase = whole.substr(dpos+strlen("__DOT__"));
} else {
varBase = whole;
}
@@ -303,8 +303,10 @@ void EmitCSyms::emitSymHdr() {
puts("\n// LOCAL STATE\n");
puts("const char* __Vm_namep;\n"); // Must be before subcells, as constructor order needed before _vlCoverInsert.
puts("bool\t__Vm_activity;\t\t///< Used by trace routines to determine change occurred\n");
puts("bool\t__Vm_didInit;\n");
if (v3Global.opt.trace()) {
puts("bool __Vm_activity; ///< Used by trace routines to determine change occurred\n");
}
puts("bool __Vm_didInit;\n");
puts("\n// SUBCELL STATE\n");
for (vector<ScopeModPair>::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) {
@@ -319,14 +321,17 @@ void EmitCSyms::emitSymHdr() {
}
}
puts("\n// COVERAGE\n");
if (m_coverBins) {
puts("uint32_t\t__Vcoverage["); puts(cvtToStr(m_coverBins)); puts("];\n");
puts("\n// COVERAGE\n");
puts("uint32_t __Vcoverage["); puts(cvtToStr(m_coverBins)); puts("];\n");
}
puts("\n// SCOPE NAMES\n");
for (ScopeNames::iterator it = m_scopeNames.begin(); it != m_scopeNames.end(); ++it) {
puts("VerilatedScope __Vscope_"+it->second.m_symName+";\n");
{ // Scope names
bool did = false;
for (ScopeNames::iterator it = m_scopeNames.begin(); it != m_scopeNames.end(); ++it) {
if (!did++) puts("\n// SCOPE NAMES\n");
puts("VerilatedScope __Vscope_"+it->second.m_symName+";\n");
}
}
puts("\n// CREATORS\n");
@@ -335,7 +340,9 @@ void EmitCSyms::emitSymHdr() {
puts("\n// METHODS\n");
puts("inline const char* name() { return __Vm_namep; }\n");
puts("inline bool getClearActivity() { bool r=__Vm_activity; __Vm_activity=false; return r;}\n");
if (v3Global.opt.trace()) {
puts("inline bool getClearActivity() { bool r=__Vm_activity; __Vm_activity=false; return r; }\n");
}
if (v3Global.opt.savable() ) {
puts("void __Vserialize(VerilatedSerialize& os);\n");
puts("void __Vdeserialize(VerilatedDeserialize& os);\n");
@@ -343,7 +350,7 @@ void EmitCSyms::emitSymHdr() {
puts("\n");
puts("} VL_ATTR_ALIGNED(64);\n");
puts("\n");
puts("#endif /*guard*/\n");
puts("#endif // guard\n");
}
void EmitCSyms::emitSymImp() {
@@ -369,7 +376,9 @@ void EmitCSyms::emitSymImp() {
puts(symClassName()+"::"+symClassName()+"("+topClassName()+"* topp, const char* namep)\n");
puts("\t// Setup locals\n");
puts("\t: __Vm_namep(namep)\n"); // No leak, as we get destroyed when the top is destroyed
puts("\t, __Vm_activity(false)\n");
if (v3Global.opt.trace()) {
puts("\t, __Vm_activity(false)\n");
}
puts("\t, __Vm_didInit(false)\n");
puts("\t// Setup submodule names\n");
char comma=',';
@@ -420,11 +429,14 @@ void EmitCSyms::emitSymImp() {
}
}
puts("// Setup scope names\n");
for (ScopeNames::iterator it = m_scopeNames.begin(); it != m_scopeNames.end(); ++it) {
puts("__Vscope_"+it->second.m_symName+".configure(this,name(),");
putsQuoted(it->second.m_prettyName);
puts(");\n");
{ // Setup scope names
bool did = false;
for (ScopeNames::iterator it = m_scopeNames.begin(); it != m_scopeNames.end(); ++it) {
if (!did++) puts("// Setup scope names\n");
puts("__Vscope_"+it->second.m_symName+".configure(this,name(),");
putsQuoted(it->second.m_prettyName);
puts(");\n");
}
}
if (v3Global.dpi()) {
@@ -512,7 +524,9 @@ void EmitCSyms::emitSymImp() {
puts("void "+symClassName()+"::"+funcname+"("+classname+"& os) {\n");
puts( "// LOCAL STATE\n");
// __Vm_namep presumably already correct
puts( "os"+op+"__Vm_activity;\n");
if (v3Global.opt.trace()) {
puts( "os"+op+"__Vm_activity;\n");
}
puts( "os"+op+"__Vm_didInit;\n");
puts( "// SUBCELL STATE\n");
for (vector<ScopeModPair>::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) {
+1 -1
View File
@@ -215,7 +215,7 @@ void V3Error::v3errorEnd (ostringstream& sstr) {
}
#ifndef _V3ERROR_NO_GLOBAL_
if (debug()) {
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("final.tree",990));
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("final",990));
if (s_errorExitCb) s_errorExitCb();
V3Stats::statsFinalAll(v3Global.rootp());
V3Stats::statsReport();
+1 -2
View File
@@ -254,8 +254,7 @@ class V3Error {
// Global versions, so that if the class doesn't define a operator, we get the functions anyways.
inline int debug() { return V3Error::debugDefault(); }
inline void v3errorEnd(ostringstream& sstr) { V3Error::v3errorEnd(sstr); }
inline void v3errorEndFatal(ostringstream& sstr) VL_ATTR_NORETURN;
inline void v3errorEndFatal(ostringstream& sstr) { V3Error::v3errorEnd(sstr); assert(0); }
inline void v3errorEndFatal(ostringstream& sstr) { V3Error::v3errorEnd(sstr); assert(0); VL_UNREACHABLE }
// Theses allow errors using << operators: v3error("foo"<<"bar");
// Careful, you can't put () around msg, as you would in most macro definitions
+1 -1
View File
@@ -937,5 +937,5 @@ public:
void V3Expand::expandAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ExpandVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("expand.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("expand", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+14 -13
View File
@@ -608,21 +608,22 @@ bool V3OutFormatter::tokenEnd(const char* cp) {
int V3OutFormatter::endLevels (const char *strg) {
int levels=m_indentLevel;
const char* cp=strg;
while (isspace(*cp)) cp++;
switch (*cp) {
case '\n': // Newlines.. No need for whitespace before it
return (0);
case '#': // Preproc directive
return (0);
}
{
// label/public/private: Deindent by 2 spaces
const char* mp=cp;
for (; isalnum(*mp); mp++) ;
if (mp[0]==':' && mp[1]!=':') return (levels-m_blockIndent/2);
const char* cp=strg;
while (isspace(*cp)) cp++;
switch (*cp) {
case '\n': // Newlines.. No need for whitespace before it
return (0);
case '#': // Preproc directive
return (0);
}
{
// label/public/private: Deindent by 2 spaces
const char* mp=cp;
for (; isalnum(*mp); mp++) ;
if (mp[0]==':' && mp[1]!=':') return (levels-m_blockIndent/2);
}
}
// We want "} else {" to be one level to the left of normal
for (const char* cp=strg; *cp; cp++) {
switch (*cp) {
+3 -1
View File
@@ -161,11 +161,13 @@ public:
// OPERATORS
void v3errorEnd(ostringstream& str);
void v3errorEndFatal(ostringstream& str) VL_ATTR_NORETURN;
void v3errorEndFatal(ostringstream& str);
string warnMore() const;
inline bool operator==(FileLine rhs) const {
return (m_lineno==rhs.m_lineno && m_filenameno==rhs.m_filenameno && m_warnOn==rhs.m_warnOn);
}
private:
void v3errorEndFatalGuts(ostringstream& str);
};
ostream& operator<<(ostream& os, FileLine* fileline);
+6 -6
View File
@@ -437,9 +437,9 @@ private:
if (m_inSenItem) varscp->user2(true);
else if (m_activep && m_activep->hasClocked() && !nodep->lvalue()) {
if (varscp->user2()) {
if (!vvertexp->rstSyncNodep()) vvertexp->rstSyncNodep(nodep);
} else {
if (!vvertexp->rstAsyncNodep()) vvertexp->rstAsyncNodep(nodep);
} else {
if (!vvertexp->rstSyncNodep()) vvertexp->rstSyncNodep(nodep);
}
}
// We use weight of one; if we ref the var more than once, when we simplify,
@@ -1133,7 +1133,7 @@ void GateVisitor::dedupe() {
//######################################################################
// Recurse through the graph, try to merge assigns
// Recurse through the graph, try to merge assigns
class GateMergeAssignsGraphVisitor : public GateGraphBaseVisitor {
private:
@@ -1145,7 +1145,7 @@ private:
V3Double0 m_numMergedAssigns; // Statistic tracking
// assemble two Sel into one if possible
// assemble two Sel into one if possible
AstSel* merge(AstSel* pre, AstSel* cur) {
AstVarRef* preVarRefp = pre->fromp()->castVarRef();
AstVarRef* curVarRefp = cur->fromp()->castVarRef();
@@ -1201,7 +1201,7 @@ private:
// update the graph
{
// delete all inedges to lvertexp
if (!lvertexp->inEmpty()) {
if (!lvertexp->inEmpty()) {
for (V3GraphEdge* ledgep = lvertexp->inBeginp(); ledgep; ) {
V3GraphEdge* oedgep = ledgep;
ledgep = ledgep->inNextp();
@@ -1488,5 +1488,5 @@ void V3Gate::gateAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
GateVisitor visitor (nodep);
GateDeassignVisitor deassign (nodep);
V3Global::dumpCheckGlobalTree("gate.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("gate", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -228,5 +228,5 @@ public:
void V3GenClk::genClkAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
GenClkReadVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("genclk.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("genclk", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -97,7 +97,7 @@ public:
// METHODS
void readFiles();
void checkTree();
static void dumpCheckGlobalTree(const string& filename, 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; }
+4 -4
View File
@@ -257,11 +257,11 @@ private:
// Find epsilon closure of this nfa node, and destinations to work list
for (V3GraphEdge* nfaEdgep = nfaStatep->outBeginp(); nfaEdgep; nfaEdgep=nfaEdgep->outNextp()) {
DfaEdge* cNfaEdgep = static_cast<DfaEdge*>(nfaEdgep);
DfaVertex* nfaStatep = static_cast<DfaVertex*>(nfaEdgep->top());
DfaVertex* ecNfaStatep = static_cast<DfaVertex*>(nfaEdgep->top());
//UINFO(9," Consider "<<nfaEdgep->top()<<" EP "<<cNfaEdgep->epsilon()<<endl);
if (cNfaEdgep->epsilon()
&& unseenNfaThisStep(nfaStatep)) { // Not processed?
workps.push_back(nfaStatep);
&& unseenNfaThisStep(ecNfaStatep)) { // Not processed?
workps.push_back(ecNfaStatep);
}
}
}
@@ -453,7 +453,7 @@ private:
DfaVertex* fromvertexp = static_cast<DfaVertex*>(edgep->fromp());
if (fromvertexp != vertexp
&& !fromvertexp->user()) {
workps.push(static_cast<DfaVertex*>(fromvertexp));
workps.push(fromvertexp);
fromvertexp->user(1);
}
}
+1 -1
View File
@@ -251,7 +251,7 @@ public:
// Outbound are cutable, as we may need to evaluate multiple times
{
V3GraphTestVertex* n = new V3GraphTestVertex(gp,"c=a|b|i");
n = new V3GraphTestVertex(gp,"c=a|b|i");
new V3GraphEdge(gp, n, c, 1, true);
new V3GraphEdge(gp, a, n, 1, false);
new V3GraphEdge(gp, b, n, 1, false);
+1 -1
View File
@@ -587,5 +587,5 @@ void V3Inline::inlineAll(AstNetlist* nodep) {
modp->unlinkFrBack()->deleteTree(); VL_DANGLING(modp);
}
}
V3Global::dumpCheckGlobalTree("inline.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("inline", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+21 -18
View File
@@ -203,7 +203,7 @@ public:
public:
// CONSTUCTORS
explicit InstDeModVarVisitor() {}
void accept(AstNodeModule* nodep) {
void main(AstNodeModule* nodep) {
UINFO(8," dmMODULE "<<nodep<<endl);
m_modVarNameMap.clear();
nodep->accept(*this);
@@ -218,8 +218,7 @@ class InstDeVisitor : public AstNVisitor {
private:
// STATE
AstRange* m_cellRangep; // Range for arrayed instantiations, NULL for normal instantiations
int m_instNum; // Current instantiation number
int m_instLsb; // Current instantiation number
int m_instSelNum; // Current instantiation count 0..N-1
InstDeModVarVisitor m_deModVars; // State of variables for current cell module
typedef map<string,AstVar*> VarNameMap;
@@ -267,7 +266,7 @@ private:
UINFO(4," CELL "<<nodep<<endl);
// Find submodule vars
if (!nodep->modp()) nodep->v3fatalSrc("Unlinked");
m_deModVars.accept(nodep->modp());
m_deModVars.main(nodep->modp());
//
if (nodep->rangep()) {
m_cellRangep = nodep->rangep();
@@ -278,8 +277,10 @@ private:
&& ifaceVarp->dtypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
// Make all of the required clones
m_instLsb = m_cellRangep->lsbConst();
for (m_instNum = m_instLsb; m_instNum<=m_cellRangep->msbConst(); m_instNum++) {
for (int i = 0; i < m_cellRangep->elementsConst(); i++) {
m_instSelNum = m_cellRangep->littleEndian() ? (m_cellRangep->elementsConst() - 1 - i) : i;
int instNum = m_cellRangep->lsbConst() + i;
AstCell* newp = nodep->cloneTree(false);
nodep->addNextHere(newp);
// Remove ranging and fix name
@@ -287,8 +288,8 @@ private:
// Somewhat illogically, we need to rename the orignal name of the cell too.
// as that is the name users expect for dotting
// The spec says we add [x], but that won't work in C...
newp->name(newp->name()+"__BRA__"+cvtToStr(m_instNum)+"__KET__");
newp->origName(newp->origName()+"__BRA__"+cvtToStr(m_instNum)+"__KET__");
newp->name(newp->name()+"__BRA__"+cvtToStr(instNum)+"__KET__");
newp->origName(newp->origName()+"__BRA__"+cvtToStr(instNum)+"__KET__");
UINFO(8," CELL loop "<<newp<<endl);
// If this AstCell is actually an interface instantiation, also clone the IfaceRef
@@ -302,8 +303,8 @@ private:
arrdtype->addNextHere(ifaceRefp);
ifaceRefp->cellp(newp);
ifaceRefp->cellName(newp->name());
varNewp->name(varNewp->name() + "__BRA__" + cvtToStr(m_instNum) + "__KET__");
varNewp->origName(varNewp->origName() + "__BRA__" + cvtToStr(m_instNum) + "__KET__");
varNewp->name(varNewp->name() + "__BRA__" + cvtToStr(instNum) + "__KET__");
varNewp->origName(varNewp->origName() + "__BRA__" + cvtToStr(instNum) + "__KET__");
varNewp->dtypep(ifaceRefp);
newp->addNextHere(varNewp);
if (debug()==9) { varNewp->dumpTree(cout, "newintf: "); cout << endl; }
@@ -343,12 +344,16 @@ private:
// Connection to array, where array dimensions match the instant dimension
AstNode* exprp = nodep->exprp()->unlinkFrBack();
exprp = new AstArraySel (exprp->fileline(), exprp,
(m_instNum-m_instLsb));
m_instSelNum);
nodep->exprp(exprp);
} else if (expwidth == pinwidth) {
// NOP: Arrayed instants: widths match so connect to each instance
} else if (expwidth == pinwidth*m_cellRangep->elementsConst()) {
// Arrayed instants: one bit for each of the instants (each assign is 1 pinwidth wide)
if (m_cellRangep->littleEndian()) {
nodep->v3warn(LITENDIAN,"Little endian cell range connecting to vector: MSB < LSB of cell range: "
<<m_cellRangep->lsbConst()<<":"<<m_cellRangep->msbConst());
}
AstNode* exprp = nodep->exprp()->unlinkFrBack();
bool inputPin = nodep->modVarp()->isInput();
if (!inputPin && !exprp->castVarRef()
@@ -358,7 +363,7 @@ private:
// Note spec allows more complicated matches such as slices and such
}
exprp = new AstSel (exprp->fileline(), exprp,
pinwidth*(m_instNum-m_instLsb),
pinwidth*m_instSelNum,
pinwidth);
nodep->exprp(exprp);
} else {
@@ -457,8 +462,7 @@ public:
// CONSTUCTORS
explicit InstDeVisitor(AstNetlist* nodep) {
m_cellRangep=NULL;
m_instNum=0;
m_instLsb=0;
m_instSelNum=0;
//
nodep->accept(*this);
}
@@ -526,8 +530,7 @@ public:
&& connBasicp->width() == pinBasicp->width()
&& connBasicp->lsb() == pinBasicp->lsb()
&& !connectRefp->varp()->isSc() // Need the signal as a 'shell' to convert types
&& connBasicp->width() == pinVarp->width()
&& 1) {
&& connBasicp->width() == pinVarp->width()) {
// Done. One to one interconnect won't need a temporary variable.
} else if (!alwaysCvt && !forTristate && pinp->exprp()->castConst()) {
// Done. Constant.
@@ -580,11 +583,11 @@ AstAssignW* V3Inst::pinReconnectSimple(AstPin* pinp, AstCell* cellp, AstNodeModu
void V3Inst::instAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
InstVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("inst.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("inst", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Inst::dearrayAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
InstDeVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("dearray.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
V3Global::dumpCheckGlobalTree("dearray", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
+1 -1
View File
@@ -515,5 +515,5 @@ void V3Life::lifeAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
LifeState state;
LifeTopVisitor visitor (nodep, &state);
V3Global::dumpCheckGlobalTree("life.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("life", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -193,5 +193,5 @@ void V3LifePost::lifepostAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
// Mark redundant AssignPost
LifePostDlyVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("life_post.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("life_post", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+33 -5
View File
@@ -161,7 +161,7 @@ public:
if (!diddump && v3Global.opt.dumpTree()) {
diddump = true;
dump("linkdot-preerr",true);
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("linkdot-preerr.tree"));
v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("linkdot-preerr"));
}
}
@@ -1017,6 +1017,24 @@ class LinkDotFindVisitor : public AstNVisitor {
UINFO(9," Link Done: "<<nodep<<endl);
// No longer needed, but can't delete until any multi-instantiated modules are expanded
}
virtual void visit(AstPackageExport* nodep) {
UINFO(9," Link: "<<nodep<<endl);
VSymEnt* srcp = m_statep->getNodeSym(nodep->packagep());
if (nodep->name()!="*") {
VSymEnt* impp = srcp->findIdFlat(nodep->name());
if (!impp) {
nodep->v3error("Export object not found: "<<nodep->packagep()->prettyName()<<"::"<<nodep->prettyName());
}
}
m_curSymp->exportFromPackage(m_statep->symsp(), srcp, nodep->name());
UINFO(9," Link Done: "<<nodep<<endl);
// No longer needed, but can't delete until any multi-instantiated modules are expanded
}
virtual void visit(AstPackageExportStarStar* nodep) {
UINFO(2," Link: "<<nodep<<endl);
m_curSymp->exportStarStar(m_statep->symsp());
// No longer needed, but can't delete until any multi-instantiated modules are expanded
}
virtual void visit(AstNode* nodep) {
// Default: Just iterate
@@ -2216,6 +2234,16 @@ private:
checkNoDot(nodep);
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
virtual void visit(AstPackageExport* nodep) {
// No longer needed
checkNoDot(nodep);
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
virtual void visit(AstPackageExportStarStar* nodep) {
// No longer needed
checkNoDot(nodep);
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
virtual void visit(AstCellRef* nodep) {
UINFO(5," AstCellRef: "<<nodep<<" "<<m_ds.ascii()<<endl);
nodep->iterateChildren(*this);
@@ -2258,21 +2286,21 @@ public:
int V3LinkDot::debug() { return LinkDotState::debug(); }
void V3LinkDot::linkDotGuts(AstNetlist* rootp, VLinkDotStep step) {
if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot.tree"));
if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot"));
LinkDotState state (rootp, step);
LinkDotFindVisitor visitor(rootp,&state);
if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-find.tree"));
if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-find"));
if (step == LDS_PRIMARY || step == LDS_PARAMED) {
// Initial link stage, resolve parameters
LinkDotParamVisitor visitors(rootp,&state);
if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-param.tree"));
if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-param"));
}
else if (step == LDS_ARRAYED) {}
else if (step == LDS_SCOPED) {
// Well after the initial link when we're ready to operate on the flat design,
// process AstScope's. This needs to be separate pass after whole hierarchy graph created.
LinkDotScopeVisitor visitors(rootp,&state);
if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-scoped.tree"));
if (LinkDotState::debug()>=5 || v3Global.opt.dumpTree()>=9) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("prelinkdot-scoped"));
}
else v3fatalSrc("Bad case");
state.dump();
+4 -4
View File
@@ -36,19 +36,19 @@ private:
public:
static void linkDotPrimary(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl); linkDotGuts(nodep,LDS_PRIMARY);
V3Global::dumpCheckGlobalTree("linkdot.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
V3Global::dumpCheckGlobalTree("linkdot", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
static void linkDotParamed(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl); linkDotGuts(nodep,LDS_PARAMED);
V3Global::dumpCheckGlobalTree("paramlink.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("paramlink", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
static void linkDotArrayed(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl); linkDotGuts(nodep,LDS_ARRAYED);
V3Global::dumpCheckGlobalTree("linkdot.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
V3Global::dumpCheckGlobalTree("linkdot", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
static void linkDotScope(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl); linkDotGuts(nodep,LDS_SCOPED);
V3Global::dumpCheckGlobalTree("linkdot.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("linkdot", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
};
+1 -1
View File
@@ -263,5 +263,5 @@ public:
void V3LinkJump::linkJump(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
LinkJumpVisitor bvisitor (nodep);
V3Global::dumpCheckGlobalTree("link.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("link", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -279,7 +279,7 @@ public:
void V3LinkLValue::linkLValue(AstNetlist* rootp) {
UINFO(4,__FUNCTION__<<": "<<endl);
LinkLValueVisitor visitor(rootp, false);
V3Global::dumpCheckGlobalTree("linklvalue.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
V3Global::dumpCheckGlobalTree("linklvalue", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
void V3LinkLValue::linkLValueSet(AstNode* nodep) {
// Called by later link functions when it is known a node needs
+1 -1
View File
@@ -80,7 +80,7 @@ void V3LinkLevel::modSortByLevel() {
v3Global.rootp()->addModulep(nodep);
}
UINFO(9,"modSortByLevel() done\n"); // Comment required for gcc4.6.3 / bug666
V3Global::dumpCheckGlobalTree("cells.tree", false, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("cells", false, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
//######################################################################
+1 -1
View File
@@ -431,5 +431,5 @@ public:
void V3LinkParse::linkParse(AstNetlist* rootp) {
UINFO(4,__FUNCTION__<<": "<<endl);
LinkParseVisitor visitor(rootp);
V3Global::dumpCheckGlobalTree("linkparse.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
V3Global::dumpCheckGlobalTree("linkparse", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
+1 -1
View File
@@ -516,5 +516,5 @@ void V3LinkResolve::linkResolve(AstNetlist* rootp) {
UINFO(4,__FUNCTION__<<": "<<endl);
LinkResolveVisitor visitor(rootp);
LinkBotupVisitor visitorb(rootp);
V3Global::dumpCheckGlobalTree("linkresolve.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
V3Global::dumpCheckGlobalTree("linkresolve", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
+1 -1
View File
@@ -250,5 +250,5 @@ void V3Localize::localizeAll(AstNetlist* nodep) {
LocalizeVisitor visitor (nodep);
// Fix up hiernames
LocalizeDehierVisitor dvisitor (nodep);
V3Global::dumpCheckGlobalTree("localize.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
V3Global::dumpCheckGlobalTree("localize", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
+1 -1
View File
@@ -149,5 +149,5 @@ public:
void V3Name::nameAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
NameVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("name.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
V3Global::dumpCheckGlobalTree("name", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
+7 -1
View File
@@ -139,6 +139,12 @@ V3Number::V3Number (FileLine* fileline, const char* sourcep) {
this->opAdd(product,addend);
if (product.bitsValue(width(), 4)) { // Overflowed
m_fileline->v3error("Too many digits for "<<width()<<" bit number: "<<sourcep);
if (!m_sized) {
static int warned = false;
if (!warned++) {
m_fileline->v3error("As that number was unsized ('d...) it is limited to 32 bits (IEEE 2012 5.7.1)");
}
}
while (*(cp+1)) cp++; // Skip ahead so don't get multiple warnings
}
}
@@ -446,7 +452,7 @@ bool V3Number::displayedFmtLegal(char format) {
case 's': return true;
case 't': return true;
case 'u': return true; // Packed 2-state
case 'v': return true; // Strength
case 'v': return true; // Strength
case 'x': return true;
case 'z': return true; // Packed 4-state
case '@': return true; // Packed string
+1 -1
View File
@@ -799,7 +799,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
}
else if ( !strcmp (sw, "-Mdir") && (i+1)<argc ) {
shift; m_makeDir = argv[i];
addIncDirFallback (string (m_makeDir)); // Need to find generated files there too
addIncDirFallback (m_makeDir); // Need to find generated files there too
}
else if ( !strcmp (sw, "-o") && (i+1)<argc ) {
shift; m_exeName = argv[i];
+1 -1
View File
@@ -145,7 +145,7 @@ class V3Options {
bool m_oCombine; // main switch: -Ob: common icode packing
bool m_oConst; // main switch: -Oc: constant folding
bool m_oDedupe; // main switch: -Od: logic deduplication
bool m_oAssemble; // main switch: -Om: assign assemble
bool m_oAssemble; // main switch: -Om: assign assemble
bool m_oExpand; // main switch: -Ox: expansion of C macros
bool m_oFlopGater; // main switch: -Of: flop gater detection
bool m_oGate; // main switch: -Og: gate wire elimination
+5 -47
View File
@@ -242,7 +242,7 @@ struct OrderVarFanoutCmp {
};
//######################################################################
// The class is used for propagating the clocker attribute for further
// The class is used for propagating the clocker attribute for further
// avoiding marking clock signals as circular.
// Transformation:
// while (newClockerMarked)
@@ -251,7 +251,7 @@ struct OrderVarFanoutCmp {
// mark LHS as clocker as well.
// newClockerMarked = true;
//
// In addition it also check whether clock and data signals are mixed, and
// In addition it also check whether clock and data signals are mixed, and
// produce a CLKDATA warning if so.
//
class OrderClkMarkVisitor : public AstNVisitor {
@@ -465,9 +465,6 @@ private:
OrderLogicVertex* m_activeSenVxp; // Sensitivity vertex
deque<OrderUser*> m_orderUserps; // All created OrderUser's for later deletion.
// STATE... for inside process
OrderLoopId m_loopIdMax; // Maximum BeginLoop id number assigned
vector<OrderLoopEndVertex*> m_pmlLoopEndps; // processInsLoop: End vertex for each color
vector<OrderLoopBeginVertex*> m_pomLoopMoveps;// processMoveLoop: Loops next nodes are under
AstCFunc* m_pomNewFuncp; // Current function being created
int m_pomNewStmts; // Statements in function being created
V3Graph m_pomGraph; // Graph of logic elements to move
@@ -565,10 +562,6 @@ private:
void processMoveReadyOne(OrderMoveVertex* vertexp);
void processMoveDoneOne(OrderMoveVertex* vertexp);
void processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* domScopep, int level);
void processMoveLoopPush(OrderLoopBeginVertex* beginp);
void processMoveLoopPop(OrderLoopBeginVertex* beginp);
void processMoveLoopStmt(AstNode* newSubnodep);
OrderLoopId processMoveLoopCurrent();
string cfuncName(AstNodeModule* modp, AstSenTree* domainp, AstScope* scopep, AstNode* forWhatp) {
modp->user3Inc();
@@ -1016,7 +1009,6 @@ public:
m_activeSenVxp = NULL;
m_logicVxp = NULL;
m_pomNewFuncp = NULL;
m_loopIdMax = LOOPID_FIRST;
m_pomNewStmts = 0;
if (debug()) m_graph.debug(5); // 3 is default if global debug; we want acyc debugging
}
@@ -1518,7 +1510,7 @@ void OrderVisitor::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* d
scopep->addActivep(m_pomNewFuncp);
// Where will we be adding the call?
AstActive* callunderp = new AstActive(nodep->fileline(), name, domainp);
processMoveLoopStmt(callunderp);
m_scopetopp->addActivep(callunderp);
// Add a top call to it
AstCCall* callp = new AstCCall(nodep->fileline(), m_pomNewFuncp);
callp->argTypes("vlSymsp");
@@ -1543,40 +1535,6 @@ void OrderVisitor::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* d
processMoveDoneOne (vertexp);
}
inline void OrderVisitor::processMoveLoopPush(OrderLoopBeginVertex* beginp) {
UINFO(6," LoopPush "<<beginp<<endl);
m_pomLoopMoveps.push_back(beginp);
}
inline void OrderVisitor::processMoveLoopPop(OrderLoopBeginVertex* beginp) {
UINFO(6," LoopPop "<<beginp<<endl);
if (m_pomLoopMoveps.empty()) beginp->nodep()->v3fatalSrc("processMoveLoopPop with no push'ed loops");
OrderLoopBeginVertex* topBeginp = m_pomLoopMoveps.back();
if (topBeginp != beginp) beginp->nodep()->v3fatalSrc("processMoveLoopPop had different vertex then one expected, got="<<topBeginp<<" exp="<<beginp<<endl);
m_pomLoopMoveps.pop_back();
}
inline void OrderVisitor::processMoveLoopStmt(AstNode* newSubnodep) {
if (m_pomLoopMoveps.empty()) {
// Not in any loops, statements go into main body
m_scopetopp->addActivep(newSubnodep);
} else {
// In a loop, put statements under appropriate loop body
OrderLoopBeginVertex* topBeginp = m_pomLoopMoveps.back();
topBeginp->untilp()->addBodysp(newSubnodep);
}
}
inline OrderLoopId OrderVisitor::processMoveLoopCurrent() {
// Return loopID we're currently processing
if (m_pomLoopMoveps.empty()) {
return LOOPID_NOTLOOPED;
} else {
OrderLoopBeginVertex* topBeginp = m_pomLoopMoveps.back();
return topBeginp->loopId(); // Not inLoop, the begin is in the upper subloop.
}
}
inline void OrderMoveDomScope::ready(OrderVisitor* ovp) { // Check the domScope is on ready list, add if not
if (!m_onReadyList) {
m_onReadyList = true;
@@ -1645,7 +1603,7 @@ void OrderVisitor::process() {
// Dump data
m_graph.dumpDotFilePrefixed("orderg_done");
if (0 && debug()) {
string dfilename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"_INT_order.tree";
string dfilename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"_INT_order";
const VL_UNIQUE_PTR<ofstream> logp (V3File::new_ofstream(dfilename));
if (logp->fail()) v3fatalSrc("Can't write "<<dfilename);
m_graph.dump(*logp);
@@ -1660,5 +1618,5 @@ void V3Order::orderAll(AstNetlist* nodep) {
OrderClkMarkVisitor markVisitor(nodep);
OrderVisitor visitor;
visitor.main(nodep);
V3Global::dumpCheckGlobalTree("order.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("order", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+35 -1
View File
@@ -22,6 +22,7 @@
#include "verilatedos.h"
#include <cstdarg>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
@@ -68,7 +69,7 @@ void V3Os::setenvStr(const string& envvar, const string& value, const string& wh
}
//######################################################################
// Generic filename utilities
// Generic filename utilities
string V3Os::filenameFromDirBase (const string& dir, const string& basename) {
// Don't return ./{filename} because if filename was absolute, that makes it relative
@@ -186,3 +187,36 @@ void V3Os::unlinkRegexp(const string& dir, const string& regexp) {
closedir(dirp);
}
}
//######################################################################
// METHODS (performance)
uint64_t V3Os::timeUsecs() {
#if defined(_WIN32) || defined(__MINGW32__)
return 0;
#else
timeval tv;
if (gettimeofday(&tv, NULL) < 0) return 0;
return static_cast<uint64_t>(tv.tv_sec)*1000000 + tv.tv_usec;
#endif
}
uint64_t V3Os::memUsageBytes() {
#if defined(_WIN32) || defined(__MINGW32__)
return 0;
#else
// Highly unportable. Sorry
const char* statmFilename = "/proc/self/statm";
FILE* fp = fopen(statmFilename,"r");
if (!fp) {
return 0;
}
uint64_t size, resident, share, text, lib, data, dt; // All in pages
if (7 != fscanf(fp, "%" VL_PRI64 "d %" VL_PRI64 "d %" VL_PRI64 "d %"
VL_PRI64 "d %" VL_PRI64 "d %" VL_PRI64 "d %" VL_PRI64 "d",
&size, &resident, &share, &text, &lib, &data, &dt)) {
return 0;
}
return (text + data) * getpagesize();
#endif
}
+4
View File
@@ -47,6 +47,10 @@ public:
// METHODS (directory utilities)
static void createDir(const string& dirname);
static void unlinkRegexp(const string& dir, const string& regexp);
// METHODS (performance)
static uint64_t timeUsecs(); ///< Return wall time since epoch in microseconds, or 0 if not implemented
static uint64_t memUsageBytes(); ///< Return memory usage in bytes, or 0 if not implemented
};
#endif // Guard
+2 -2
View File
@@ -744,7 +744,7 @@ void ParamVisitor::visitCell(AstCell* nodep) {
// Delete the parameters from the cell; they're not relevant any longer.
if (nodep->paramsp()) nodep->paramsp()->unlinkFrBackWithNext()->deleteTree();
UINFO(8," Done with "<<nodep<<endl);
//if (debug()>=10) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("param-out.tree"));
//if (debug()>=10) v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("param-out"));
}
// Now remember to process the child module at the end of the module
@@ -757,5 +757,5 @@ void ParamVisitor::visitCell(AstCell* nodep) {
void V3Param::param(AstNetlist* rootp) {
UINFO(2,__FUNCTION__<<": "<<endl);
ParamVisitor visitor (rootp);
V3Global::dumpCheckGlobalTree("param.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
V3Global::dumpCheckGlobalTree("param", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
+11 -5
View File
@@ -42,11 +42,13 @@ typedef enum { uniq_NONE, uniq_UNIQUE, uniq_UNIQUE0, uniq_PRIORITY } V3UniqState
typedef enum { iprop_NONE, iprop_CONTEXT, iprop_PURE } V3ImportProperty;
//============================================================================
// Parser YYSType, e.g. for parser's yylval
// We can't use bison's %union as we want to pass the fileline with all tokens
struct V3ParseBisonYYSType {
FileLine* fl;
AstNode* scp; // Symbol table scope for future lookups
int token; // Read token, aka tok
union {
V3Number* nump;
string* strp;
@@ -107,9 +109,10 @@ class V3ParseImp {
int m_lastVerilogState; // Last LEX state in `begin_keywords
int m_prevLexToken; // previous parsed token (for lexer)
bool m_ahead; // aheadToken is valid
int m_aheadToken; // Token we read ahead
V3ParseBisonYYSType m_aheadVal; // aheadToken's value
bool m_ahead; // aheadval is valid
V3ParseBisonYYSType m_aheadVal; // ahead token value
V3ParseBisonYYSType m_curBisonVal; // current token for error reporting
V3ParseBisonYYSType m_prevBisonVal; // previous token for error reporting
deque<string*> m_stringps; // Created strings for later cleanup
deque<V3Number*> m_numberps; // Created numbers for later cleanup
@@ -194,6 +197,8 @@ public:
static int stateVerilogRecent(); // Parser -> lexer communication
int prevLexToken() { return m_prevLexToken; } // Parser -> lexer communication
size_t flexPpInputToLex(char* buf, size_t max_size) { return ppInputToLex(buf,max_size); }
const V3ParseBisonYYSType curBisonVal() const { return m_curBisonVal; }
const V3ParseBisonYYSType prevBisonVal() const { return m_prevBisonVal; }
//==== Symbol tables
V3ParseSym* symp() { return m_symp; }
@@ -210,7 +215,8 @@ public:
m_lastVerilogState = stateVerilogRecent();
m_prevLexToken = 0;
m_ahead = false;
m_aheadToken = 0;
m_curBisonVal.token = 0;
m_prevBisonVal.token = 0;
// m_aheadVal not used as m_ahead = false
}
~V3ParseImp();
@@ -227,7 +233,7 @@ public:
private:
void lexFile(const string& modname);
int yylexReadTok();
int lexToken(); // Internal; called from lexToBison
void lexToken(); // Internal; called from lexToBison
};
#endif // Guard
+14 -1
View File
@@ -122,7 +122,7 @@ public:
if (foundp) return foundp->nodep();
else return NULL;
}
void import(AstNode* packagep, const string& id_or_star) {
void importItem(AstNode* packagep, const string& id_or_star) {
// Import from package::id_or_star to this
VSymEnt* symp = getTable(packagep);
if (!symp) { // Internal problem, because we earlier found pkg to label it an ID__aPACKAGE
@@ -133,6 +133,19 @@ public:
// We let V3LinkDot report the error instead of us
symCurrentp()->importFromPackage(&m_syms, symp, id_or_star);
}
void exportItem(AstNode* packagep, const string& id_or_star) {
// Export from this the remote package::id_or_star
VSymEnt* symp = getTable(packagep);
if (!symp) { // Internal problem, because we earlier found pkg to label it an ID__aPACKAGE
packagep->v3fatalSrc("Export package not found");
return;
}
symCurrentp()->exportFromPackage(&m_syms, symp, id_or_star);
}
void exportStarStar(AstNode* packagep) {
// Export *::* from remote packages
symCurrentp()->exportStarStar(&m_syms);
}
public:
// CREATORS
explicit V3ParseSym(AstNetlist* rootp)
+14 -11
View File
@@ -323,8 +323,10 @@ void V3PreProcImp::define(FileLine* fl, const string& name, const string& value,
UINFO(4,"DEFINE '"<<name<<"' as '"<<value<<"' params '"<<params<<"'"<<endl);
if (defExists(name)) {
if (!(defValue(name)==value && defParams(name)==params)) { // Duplicate defs are OK
fl->v3warn(REDEFMACRO,"Redefining existing define: "<<name<<", with different value: "<<value<<" "<<params);
defFileline(name)->v3warn(REDEFMACRO,"Previous definition is here, with value: "<<defValue(name)<<" "<<defParams(name));
fl->v3warn(REDEFMACRO,"Redefining existing define: "<<name<<", with different value: "
<<value<<(params=="" ? "":" ")<<params);
defFileline(name)->v3warn(REDEFMACRO,"Previous definition is here, with value: "
<<defValue(name)<<(defParams(name)=="" ? "":" ")<<defParams(name));
}
undef(name);
}
@@ -559,31 +561,31 @@ string V3PreProcImp::defineSubst(V3DefineRef* refp) {
bool quote = false;
bool haveDefault = false;
// Note there's a leading ( and trailing ), so parens==1 is the base parsing level
string params = refp->params(); // Must keep in scope
string params = refp->params(); // Must keep str in scope to get pointer
const char* cp=params.c_str();
if (*cp == '(') cp++;
for (; *cp; cp++) {
//UINFO(4," Parse Paren="<<paren<<" Arg="<<numArgs<<" token='"<<token<<"' Parse="<<cp<<endl);
if (!quote && paren==1) {
if (*cp==')' || *cp==',') {
string value;
if (haveDefault) { value=token; } else { argName=token; }
string valueDef;
if (haveDefault) { valueDef=token; } else { argName=token; }
argName = trimWhitespace(argName,true);
UINFO(4," Got Arg="<<numArgs<<" argName='"<<argName<<"' default='"<<value<<"'"<<endl);
UINFO(4," Got Arg="<<numArgs<<" argName='"<<argName<<"' default='"<<valueDef<<"'"<<endl);
// Parse it
if (argName!="") {
if (refp->args().size() > numArgs) {
// A call `def( a ) must be equivelent to `def(a ), so trimWhitespace
// At one point we didn't trim trailing whitespace, but this confuses `"
string arg = trimWhitespace(refp->args()[numArgs], true);
if (arg != "") value = arg;
if (arg != "") valueDef = arg;
} else if (!haveDefault) {
error("Define missing argument '"+argName+"' for: "+refp->name()+"\n");
return " `"+refp->name()+" ";
}
numArgs++;
}
argValueByName[argName] = value;
argValueByName[argName] = valueDef;
// Prepare for next
argName = "";
token = "";
@@ -1095,7 +1097,7 @@ int V3PreProcImp::getStateToken() {
// Value of building argument is data before the lower defref
// we'll append it when we push the argument.
break;
} else if (tok==VP_SYMBOL || tok==VP_STRING || VP_TEXT || VP_WHITE) {
} else if (tok==VP_SYMBOL || tok==VP_STRING || tok==VP_TEXT || tok==VP_WHITE) {
string rtn; rtn.assign(yyourtext(),yyourleng());
refp->nextarg(refp->nextarg()+rtn);
goto next_tok;
@@ -1263,7 +1265,7 @@ int V3PreProcImp::getStateToken() {
error("Recursive `define substitution: `"+name);
goto next_tok;
}
// substitute
// Substitute
if (!defExists(name)) { // Not found, return original string as-is
m_defDepth = 0;
UINFO(4,"Defref `"<<name<<" => not_defined"<<endl);
@@ -1308,7 +1310,8 @@ int V3PreProcImp::getStateToken() {
goto next_tok;
}
}
fatalSrc("Bad case\n");
fatalSrc("Bad case\n"); // FALLTHRU
goto next_tok; // but not really, above fatal catches it, but if add goto, static analysis complains
}
case VP_ERROR: {
statePush(ps_ERRORNAME);
+24 -8
View File
@@ -135,7 +135,7 @@ private:
// ARRAYSEL(*here*, ...) (No wides can be in any argument but first, so we don't check which arg is wide)
// ASSIGN(x, SEL*HERE*(ARRAYSEL()...) (m_assignLhs==true handles this.)
//UINFO(9, " Check: "<<nodep<<endl);
//UINFO(9, " Detail stmtp="<<(m_stmtp?"Y":"N")<<" U="<<(nodep->user1()?"Y":"N")<<" IW "<<(nodep->isWide()?"Y":"N")<<endl);
//UINFO(9, " Detail stmtp="<<(m_stmtp?"Y":"N")<<" U="<<(nodep->user1()?"Y":"N")<<" IW="<<(nodep->isWide()?"Y":"N")<<endl);
if (m_stmtp
&& !nodep->user1()) { // Not already done
if (nodep->isWide()) {
@@ -321,13 +321,17 @@ private:
}
// Operators
virtual void visit(AstNodeTermop* nodep) {
nodep->iterateChildren(*this); checkNode(nodep); }
nodep->iterateChildren(*this); checkNode(nodep);
}
virtual void visit(AstNodeUniop* nodep) {
nodep->iterateChildren(*this); checkNode(nodep); }
nodep->iterateChildren(*this); checkNode(nodep);
}
virtual void visit(AstNodeBiop* nodep) {
nodep->iterateChildren(*this); checkNode(nodep); }
nodep->iterateChildren(*this); checkNode(nodep);
}
virtual void visit(AstUCFunc* nodep) {
nodep->iterateChildren(*this); checkNode(nodep); }
nodep->iterateChildren(*this); checkNode(nodep);
}
virtual void visit(AstSel* nodep) {
nodep->fromp()->iterateAndNext(*this);
{ // Only the 'from' is part of the assignment LHS
@@ -337,9 +341,21 @@ private:
nodep->widthp()->iterateAndNext(*this);
m_assignLhs = prevAssign;
}
checkNode(nodep); }
checkNode(nodep);
}
virtual void visit(AstArraySel* nodep) {
nodep->fromp()->iterateAndNext(*this);
{ // Only the 'from' is part of the assignment LHS
bool prevAssign = m_assignLhs;
m_assignLhs = false;
nodep->bitp()->iterateAndNext(*this);
m_assignLhs = prevAssign;
}
checkNode(nodep);
}
virtual void visit(AstConst* nodep) {
nodep->iterateChildren(*this); checkNode(nodep); }
nodep->iterateChildren(*this); checkNode(nodep);
}
virtual void visit(AstNodeCond* nodep) {
nodep->iterateChildren(*this);
if (nodep->expr1p()->isWide()
@@ -412,5 +428,5 @@ public:
void V3Premit::premitAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
PremitVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("premit.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("premit", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+3 -3
View File
@@ -60,7 +60,7 @@ private:
// STATE, for passing down one level of hierarchy (may need save/restore)
AstCell* m_aboveCellp; // Cell that instantiates this module
AstScope* m_aboveScopep; // Scope that instantiates this scope
PackageScopeMap m_packageScopes; // Scopes for each package
VarScopeMap m_varScopes; // Varscopes created for each scope and var
VarRefScopeSet m_varRefScopes; // Varrefs-in-scopes needing fixup when donw
@@ -265,7 +265,7 @@ private:
// the var's referenced package etc might not be created yet.
// So push to a list and post-correct
m_varRefScopes.insert(make_pair(nodep, m_scopep));
}
}
}
virtual void visit(AstScopeName* nodep) {
// If there's a %m in the display text, we add a special node that will contain the name()
@@ -418,5 +418,5 @@ void V3Scope::scopeAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
ScopeVisitor visitor (nodep);
ScopeCleanupVisitor cleanVisitor (nodep);
V3Global::dumpCheckGlobalTree("scope.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("scope", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -548,5 +548,5 @@ public:
void V3Slice::sliceAll(AstNetlist* rootp) {
UINFO(2,__FUNCTION__<<": "<<endl);
SliceVisitor visitor(rootp);
V3Global::dumpCheckGlobalTree("slice.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("slice", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+2 -2
View File
@@ -579,10 +579,10 @@ public:
void V3Split::splitReorderAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
SplitVisitor visitor (nodep, true);
V3Global::dumpCheckGlobalTree("reorder.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("reorder", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
void V3Split::splitAlwaysAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
SplitVisitor visitor (nodep, false);
V3Global::dumpCheckGlobalTree("split.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
V3Global::dumpCheckGlobalTree("split", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 6);
}
+1 -1
View File
@@ -216,5 +216,5 @@ public:
void V3SplitAs::splitAsAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
SplitAsVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("splitas.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("splitas", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+8 -2
View File
@@ -56,6 +56,7 @@ class V3Statistic {
double m_count; ///< Count of occurrences/ value
string m_stage; ///< Runtime stage
bool m_sumit; ///< Do summation of similar stats
bool m_perf; ///< Performance section
bool m_printit; ///< Print the results
public:
// METHODS
@@ -63,6 +64,7 @@ public:
string name() const { return m_name; }
double count() const { return m_count; }
bool sumit() const { return m_sumit; }
bool perf() const { return m_perf; }
bool printit() const { return m_printit; }
virtual void dump(ofstream& os) const;
void combineWith(V3Statistic* otherp) {
@@ -70,8 +72,8 @@ public:
otherp->m_printit = false;
}
// CONSTRUCTORS
V3Statistic(const string& stage, const string& name, double count, bool sumit=false)
: m_name(name), m_count(count), m_stage(stage), m_sumit(sumit)
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() {}
};
@@ -87,6 +89,10 @@ public:
addStat(V3Statistic("*",name,count)); }
static void addStatSum(const string& name, double count) {
addStat(V3Statistic("*",name,count,true)); }
static void addStatPerf(const string& name, double count) {
addStat(V3Statistic("*",name,count,true,true)); }
/// Called each stage
static void statsStage(const string& name);
/// Called by the top level to collect statistics
static void statsStageAll(AstNetlist* nodep, const string& stage, bool fast=false);
static void statsFinalAll(AstNetlist* nodep);
+38 -4
View File
@@ -30,6 +30,7 @@
#include "V3Stats.h"
#include "V3Ast.h"
#include "V3File.h"
#include "V3Os.h"
//######################################################################
// Stats dumping
@@ -75,9 +76,6 @@ class StatsReport {
}
void stars() {
os<<"Global Statistics:\n";
os<<endl;
// Find all stages
size_t maxWidth = 0;
typedef multimap<string,const V3Statistic*> ByName;
@@ -92,8 +90,23 @@ class StatsReport {
}
// Print organized by stage
os<<"Global Statistics:\n";
os<<endl;
for (ByName::iterator it = byName.begin(); it!=byName.end(); ++it) {
const V3Statistic* repp = it->second;
if (repp->perf()) continue;
os<<" "<<left<<setw(maxWidth)<<repp->name();
repp->dump(os);
os<<endl;
}
os<<endl;
// Print organized by stage
os<<"Peformance Statistics:\n";
os<<endl;
for (ByName::iterator it = byName.begin(); it!=byName.end(); ++it) {
const V3Statistic* repp = it->second;
if (!repp->perf()) continue;
os<<" "<<left<<setw(maxWidth)<<repp->name();
repp->dump(os);
os<<endl;
@@ -193,7 +206,11 @@ StatsReport::StatColl StatsReport::s_allStats;
// V3Statstic class
void V3Statistic::dump (ofstream& os) const {
os<<" "<<right<<fixed<<setprecision(0)<<setw(9)<<count();
if (perf()) {
os<<" "<<right<<fixed<<setprecision(6)<<setw(9)<<count();
} else {
os<<" "<<right<<fixed<<setprecision(0)<<setw(9)<<count();
}
}
//######################################################################
@@ -203,6 +220,23 @@ 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);
const string digitName = string(digits)+"_"+name;
double wallTime = V3Os::timeUsecs() / 1.0e6;
if (lastWallTime<0) lastWallTime = wallTime;
double wallTimeDelta = wallTime - lastWallTime;
lastWallTime = wallTime;
V3Stats::addStatPerf("Stage, Elapsed time (sec), "+digitName, wallTimeDelta);
double memory = V3Os::memUsageBytes()/1024.0/1024.0;
V3Stats::addStatPerf("Stage, Memory (MB), "+digitName, memory);
}
void V3Stats::statsReport() {
UINFO(2,__FUNCTION__<<": "<<endl);
+1 -1
View File
@@ -401,5 +401,5 @@ public:
void V3Subst::substituteAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
SubstVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("subst.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("subst", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+36 -15
View File
@@ -41,6 +41,7 @@ class VSymEnt;
// Symbol table
typedef set<VSymEnt*> VSymMap;
typedef set<const VSymEnt*> VSymConstMap;
class VSymEnt {
// Symbol table that can have a "superior" table for resolving upper references
@@ -65,7 +66,7 @@ private:
static inline int debug() { return 0; } // NOT runtime, too hot of a function
#endif
public:
void dumpIterate(ostream& os, VSymMap& doneSymsr, const string& indent, int numLevels, const string& searchName) {
void dumpIterate(ostream& os, VSymConstMap& doneSymsr, const string& indent, int numLevels, const string& searchName) const {
os<<indent<<"+ "<<left<<setw(30)<<(searchName==""?"\"\"":searchName)<<setw(0)<<right;
os<<" se"<<(void*)(this)<<setw(0);
os<<" fallb=se"<<(void*)(m_fallbackp);
@@ -82,8 +83,8 @@ public:
}
}
}
void dump(ostream& os, const string& indent="", int numLevels=1) {
VSymMap doneSyms;
void dump(ostream& os, const string& indent="", int numLevels=1) const {
VSymConstMap doneSyms;
dumpIterate(os, doneSyms, indent, numLevels, "TOP");
}
@@ -153,35 +154,55 @@ public:
return NULL;
}
private:
bool importOneSymbol(VSymGraph* graphp, const string& name, const VSymEnt* srcp) {
void importOneSymbol(VSymGraph* graphp, const string& name, const VSymEnt* srcp) {
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);
reinsert(name, symp);
return true;
} else {
return false;
}
}
void exportOneSymbol(VSymGraph* graphp, const string& name, const VSymEnt* srcp) {
if (srcp->exported()) {
if (VSymEnt* symp = findIdFlat(name)) { // Should already exist in current table
if (!symp->exported()) symp->exported(true);
}
}
}
public:
bool importFromPackage(VSymGraph* graphp, const VSymEnt* srcp, const string& id_or_star) {
void importFromPackage(VSymGraph* graphp, const VSymEnt* srcp, const string& id_or_star) {
// Import tokens from source symbol table into this symbol table
// Returns true if successful
bool any = false;
if (id_or_star != "*") {
IdNameMap::const_iterator it = srcp->m_idNameMap.find(id_or_star);
if (it != m_idNameMap.end()) {
if (it != srcp->m_idNameMap.end()) {
importOneSymbol(graphp, it->first, it->second);
}
any = true; // Legal, though perhaps lint questionable to import nothing
} else {
for (IdNameMap::const_iterator it=srcp->m_idNameMap.begin(); it!=srcp->m_idNameMap.end(); ++it) {
if (importOneSymbol(graphp, it->first, it->second)) any = true;
importOneSymbol(graphp, it->first, it->second);
}
}
return any;
}
void exportFromPackage(VSymGraph* graphp, const VSymEnt* srcp, const string& id_or_star) {
// 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);
}
} else {
for (IdNameMap::const_iterator it=srcp->m_idNameMap.begin(); it!=srcp->m_idNameMap.end(); ++it) {
exportOneSymbol(graphp, it->first, it->second);
}
}
}
void exportStarStar(VSymGraph* graphp) {
// Export *:*: Export all tokens from imported packages
for (IdNameMap::const_iterator it=m_idNameMap.begin(); it!=m_idNameMap.end(); ++it) {
VSymEnt* symp = it->second;
if (!symp->exported()) symp->exported(true);
}
}
void importFromIface(VSymGraph* graphp, const VSymEnt* srcp, bool onlyUnmodportable = false) {
// Import interface tokens from source symbol table into this symbol table, recursively
@@ -239,7 +260,7 @@ public:
VSymEnt* rootp() const { return m_symRootp; }
// Debug
void dump(ostream& os, const string& indent="") {
VSymMap doneSyms;
VSymConstMap doneSyms;
os<<"SymEnt Dump:\n";
m_symRootp->dumpIterate(os, doneSyms, indent, 9999, "$root");
bool first = true;
+1 -1
View File
@@ -466,5 +466,5 @@ void TableSimulateVisitor::varRefCb(AstVarRef* nodep) {
void V3Table::tableAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
TableVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("table.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("table", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+16 -6
View File
@@ -35,6 +35,7 @@
#include <map>
#include "V3Global.h"
#include "V3Const.h"
#include "V3Task.h"
#include "V3Inst.h"
#include "V3Ast.h"
@@ -1260,11 +1261,20 @@ V3TaskConnects V3Task::taskConnects(AstNodeFTaskRef* nodep, AstNode* taskStmtsp)
<<"' in function call to "<<nodep->taskp()->prettyTypeName());
newvaluep = new AstConst(nodep->fileline(), AstConst::Unsized32(), 0);
} else if (!portp->valuep()->castConst()) {
// Problem otherwise is we might have a varref, task call, or something else that only
// makes sense in the domain of the function, not the callee.
nodep->v3error("Unsupported: Non-constant default value in missing argument '"<<portp->prettyName()
<<"' in function call to "<<nodep->taskp()->prettyTypeName());
newvaluep = new AstConst(nodep->fileline(), AstConst::Unsized32(), 0);
// The default value for this port might be a constant
// expression that hasn't been folded yet. Try folding it
// now; we don't have much to lose if it fails.
newvaluep = V3Const::constifyParamsEdit(portp->valuep());
if (!newvaluep->castConst()) {
// Problem otherwise is we might have a varref, task call, or something else that only
// makes sense in the domain of the function, not the callee.
nodep->v3error("Unsupported: Non-constant default value in missing argument '"<<portp->prettyName()
<<"' in function call to "<<nodep->taskp()->prettyTypeName());
newvaluep = new AstConst(nodep->fileline(), AstConst::Unsized32(), 0);
}
else {
newvaluep = newvaluep->cloneTree(true);
}
} else {
newvaluep = portp->valuep()->cloneTree(true);
}
@@ -1301,5 +1311,5 @@ void V3Task::taskAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
TaskStateVisitor visitors (nodep);
TaskVisitor visitor (nodep, &visitors);
V3Global::dumpCheckGlobalTree("task.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("task", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -713,5 +713,5 @@ public:
void V3Trace::traceAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
TraceVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("trace.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("trace", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}
+1 -1
View File
@@ -326,5 +326,5 @@ public:
void V3TraceDecl::traceDeclAll(AstNetlist* nodep) {
UINFO(2,__FUNCTION__<<": "<<endl);
TraceDeclVisitor visitor (nodep);
V3Global::dumpCheckGlobalTree("tracedecl.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
V3Global::dumpCheckGlobalTree("tracedecl", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
}

Some files were not shown because too many files have changed in this diff Show More