mirror of
https://github.com/verilator/verilator.git
synced 2026-10-03 16:44:11 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
379177d2f4 | ||
|
|
fb193d6172 | ||
|
|
16234bb713 | ||
|
|
3f14e649b5 | ||
|
|
c2e8062f84 | ||
|
|
5d3fef21b0 | ||
|
|
b64e1b4a49 | ||
|
|
89f414b185 | ||
|
|
47e13cfdf4 | ||
|
|
48d3ce46d8 | ||
|
|
89c8449ec0 | ||
|
|
331fcb633e | ||
|
|
bffc2233a0 | ||
|
|
393b5d48b2 | ||
|
|
6006cdff2c | ||
|
|
d6b10465f3 | ||
|
|
b3cf5c4f5f | ||
|
|
3862f2f022 | ||
|
|
38ab22bf1d | ||
|
|
ce16f7689d | ||
|
|
b06a329466 | ||
|
|
c5b24f3850 | ||
|
|
103b956581 | ||
|
|
63361fc56e | ||
|
|
1e9e334929 | ||
|
|
f30d71b0c5 | ||
|
|
fee4aba9ec | ||
|
|
f1960273a0 | ||
|
|
778564e63b | ||
|
|
cf6a69da27 | ||
|
|
960b2ed023 | ||
|
|
74420550e6 | ||
|
|
cb5887b376 | ||
|
|
41b40157d8 | ||
|
|
b11b693c08 | ||
|
|
256eb4bba0 | ||
|
|
77804b4d38 | ||
|
|
8c9ca7a1b3 | ||
|
|
9d055f8c13 | ||
|
|
3dacd87dfb | ||
|
|
691fbb0c42 | ||
|
|
c28a6eef3b | ||
|
|
17fed3fedd | ||
|
|
1448cc56fc | ||
|
|
074689b5de | ||
|
|
8dd612a0a0 | ||
|
|
22fdbba0b5 | ||
|
|
39b787670b | ||
|
|
a221278c05 | ||
|
|
5f26b9ec66 | ||
|
|
48778d0a77 | ||
|
|
42d2cbad41 | ||
|
|
cb82c42e35 | ||
|
|
f13fb330ed | ||
|
|
d4bae48ca2 | ||
|
|
590ad964b1 | ||
|
|
d4595df8a4 | ||
|
|
7b642bcbb4 | ||
|
|
ca26596695 | ||
|
|
88cf5e5d98 | ||
|
|
13f790360d | ||
|
|
70daadf987 | ||
|
|
9d5004db1c | ||
|
|
ea82bfcced | ||
|
|
00a502942e | ||
|
|
2031bc7fc4 | ||
|
|
3adb22e971 | ||
|
|
331ea5116f |
@@ -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/*
|
||||
|
||||
@@ -2,6 +2,61 @@ 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.
|
||||
|
||||
**** Update keyword warnings to include C++11 and others.
|
||||
|
||||
|
||||
* Verilator 3.908 2017-08-28
|
||||
|
||||
**** Support x in $readmem, bug1180. [Arthur Kahlich]
|
||||
|
||||
**** Support packed struct DPI imports, bug1190. [Rob Stoddard]
|
||||
|
||||
**** Fix GCC 6 warnings.
|
||||
|
||||
**** Fix compile error on unused VL_VALUEPLUSARGS_IW, bug1181. [Thomas J Whatson]
|
||||
|
||||
**** Fix undefined VL_POW_WWI. [Clifford Wolf]
|
||||
|
||||
**** Fix internal error on unconnected inouts, bug1187. [Rob Stoddard]
|
||||
|
||||
|
||||
* Verilator 3.906 2017-06-22
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+24
-15
@@ -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
|
||||
@@ -483,7 +486,7 @@ interest in adding more traditional CDC checks, please contact the authors.
|
||||
Sometimes it is quite difficult for Verilator to distinguish clock signals from
|
||||
other data signals. Occasionally the clock signals can end up in the checking
|
||||
list of signals which determines if further evaluation is needed. This will
|
||||
heavily degrade the performance of verilated model.
|
||||
heavily degrade the performance of a Verilated model.
|
||||
|
||||
With --clk <signal-name>, user can specified root clock into the model, then
|
||||
Verilator will mark the signal as clocker and propagate the clocker attribute
|
||||
@@ -513,7 +516,7 @@ breaking deep structures as for msvc as described below.
|
||||
|
||||
=item gcc
|
||||
|
||||
Tune for Gnu C++, although generated code should work on almost any
|
||||
Tune for GNU C++, although generated code should work on almost any
|
||||
compliant C++ compiler. Currently the default.
|
||||
|
||||
=item msvc
|
||||
@@ -911,7 +914,7 @@ developers.
|
||||
|
||||
=item --output-split I<bytes>
|
||||
|
||||
Enables splitting the output .cpp/.sp files into multiple outputs. When a
|
||||
Enables splitting the output .cpp files into multiple outputs. When a
|
||||
C++ file exceeds the specified number of operations, a new file will be
|
||||
created at the next function boundary. In addition, any slow routines will
|
||||
be placed into __Slow files. This accelerates compilation by as
|
||||
@@ -923,7 +926,7 @@ one-minute-compile chunks.
|
||||
|
||||
=item --output-split-cfuncs I<statements>
|
||||
|
||||
Enables splitting functions in the output .cpp/.sp files into multiple
|
||||
Enables splitting functions in the output .cpp files into multiple
|
||||
functions. When a generated function exceeds the specified number of
|
||||
operations, a new function will be created. With --output-split, this will
|
||||
enable GCC to compile faster, at a small loss in performance that gets
|
||||
@@ -933,7 +936,7 @@ function.
|
||||
|
||||
=item --output-split-ctrace I<statements>
|
||||
|
||||
Enables splitting trace functions in the output .cpp/.sp files into
|
||||
Enables splitting trace functions in the output .cpp files into
|
||||
multiple functions. Defaults to same setting as --output-split-cfuncs.
|
||||
|
||||
=item -P
|
||||
@@ -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>
|
||||
|
||||
@@ -1430,8 +1434,8 @@ This is an example similar to the above, but using SystemC.
|
||||
Verilated::commandArgs(argc, argv);
|
||||
sc_clock clk ("clk",10, 0.5, 3, true);
|
||||
Vour* top;
|
||||
top = new Vour("top"); // SP_CELL (top, Vour);
|
||||
top->clk(clk); // SP_PIN (top, clk, clk);
|
||||
top = new Vour("top");
|
||||
top->clk(clk);
|
||||
while (!Verilated::gotFinish()) { sc_start(1, SC_NS); }
|
||||
delete top;
|
||||
exit(0);
|
||||
@@ -1510,7 +1514,7 @@ OPT, OPT_FAST, or OPT_SLOW lib/verilated.mk. Or, use the -CFLAGS and/or
|
||||
the compiler or linker. Or, just for one run, pass them on the command
|
||||
line to make:
|
||||
|
||||
make OPT_FAST="-O2" -f Vour.mk Vour__ALL.a
|
||||
make OPT_FAST="-O2 -fno-stack-protector" -f Vour.mk Vour__ALL.a
|
||||
|
||||
OPT_FAST specifies optimizations for those programs that are part of the
|
||||
fast path, mostly code that is executed every cycle. OPT_SLOW specifies
|
||||
@@ -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.
|
||||
|
||||
@@ -3878,7 +3887,7 @@ From the sc_main.cpp file, you'd then:
|
||||
|
||||
#include "Vour.h"
|
||||
#include "Vour_our.h"
|
||||
cout << "clock is " << top->v->clk << endl;
|
||||
cout << "clock is " << top->our->clk << endl;
|
||||
|
||||
In this example, clk is a bool you can read or set as any other variable.
|
||||
The value of normal signals may be set, though clocks shouldn't be changed
|
||||
|
||||
+22
-12
@@ -6,8 +6,9 @@
|
||||
|
||||
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
|
||||
#AC_INIT([Verilator],[#.### devel])
|
||||
AC_INIT([Verilator],[3.906 2017-06-22])
|
||||
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,35 +140,44 @@ AC_DEFUN([_MY_CXX_CHECK_OPT],
|
||||
CXXFLAGS="$ACO_SAVE_CXXFLAGS"
|
||||
])# _MY_CXX_CHECK_OPT
|
||||
|
||||
# Flags for compiling Verilator internals including parser
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-unused-parameter)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-char-subscripts)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-undefined-bool-conversion)
|
||||
# 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
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-unused)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-parentheses-equality)
|
||||
# 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)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-unused)
|
||||
AC_SUBST(CFG_CXXFLAGS_PARSER)
|
||||
|
||||
# Flags for Verilated makefile
|
||||
# For example, -Wno-div-by-zero isn't in 4.1.2
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-char-subscripts)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-parentheses-equality)
|
||||
# Random code often does / 0. Unfortunately VL_DIV_I(0,0) will warn
|
||||
# without this flag, even though there's a conditional to prevent the divide.
|
||||
# We still don't add no-div-by-zero as it throws message to stdout, though doesn't die.
|
||||
#_MY_CXX_CHECK_OPT(-Wno-div-by-zero)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-faligned-new)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-fbracket-depth=4096)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Qunused-arguments)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-parentheses-equality)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-sign-compare)
|
||||
_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,-fbracket-depth=4096)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Qunused-arguments)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-shadow)
|
||||
AC_SUBST(CFG_CXXFLAGS_NO_UNUSED)
|
||||
|
||||
# Checks for library functions.
|
||||
|
||||
+94
-57
@@ -283,6 +283,7 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, boo
|
||||
}
|
||||
|
||||
WDataOutP VL_POW_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDataInP rwp) {
|
||||
// obits==lbits, rbits can be different
|
||||
owp[0] = 1;
|
||||
for (int i=1; i < VL_WORDS_I(obits); i++) owp[i] = 0;
|
||||
// cppcheck-suppress variableScope
|
||||
@@ -303,8 +304,24 @@ WDataOutP VL_POW_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDa
|
||||
}
|
||||
return owp;
|
||||
}
|
||||
WDataOutP VL_POW_WWQ(int obits, int lbits, int rbits, WDataOutP owp, WDataInP lwp, QData rhs) {
|
||||
WData rhsw[2]; VL_SET_WQ(rhsw, rhs);
|
||||
return VL_POW_WWW(obits,lbits,rbits,owp,lwp,rhsw);
|
||||
}
|
||||
QData VL_POW_QQW(int, int, int rbits, QData lhs, WDataInP rwp) {
|
||||
// Skip check for rhs == 0, as short-circuit doesn't save time
|
||||
if (VL_UNLIKELY(lhs==0)) return 0;
|
||||
QData power = lhs;
|
||||
QData out = VL_ULL(1);
|
||||
for (int bit=0; bit<rbits; ++bit) {
|
||||
if (bit>0) power = power*power;
|
||||
if (VL_BITISSET_W(rwp,bit)) out *= power;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, bool lsign, bool rsign) {
|
||||
// obits==lbits, rbits can be different
|
||||
if (rsign && VL_SIGN_W(rbits, rwp)) {
|
||||
int words = VL_WORDS_I(obits);
|
||||
VL_ZERO_W(obits, owp);
|
||||
@@ -323,6 +340,23 @@ WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, W
|
||||
}
|
||||
return VL_POW_WWW(obits, rbits, rbits, owp, lwp, rwp);
|
||||
}
|
||||
WDataOutP VL_POWSS_WWQ(int obits, int lbits, int rbits, WDataOutP owp, WDataInP lwp, QData rhs, bool lsign, bool rsign) {
|
||||
WData rhsw[2]; VL_SET_WQ(rhsw, rhs);
|
||||
return VL_POWSS_WWW(obits,lbits,rbits,owp,lwp,rhsw,lsign,rsign);
|
||||
}
|
||||
QData VL_POWSS_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp, bool lsign, bool rsign) {
|
||||
// Skip check for rhs == 0, as short-circuit doesn't save time
|
||||
if (rsign && VL_SIGN_W(rbits, rwp)) {
|
||||
if (lhs==0) return 0; // "X"
|
||||
else if (lhs==1) return 1;
|
||||
else if (lsign && lhs==VL_MASK_I(obits)) { // -1
|
||||
if (rwp[0] & 1) return VL_MASK_I(obits); // -1^odd=-1
|
||||
else return 1; // -1^even=1
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return VL_POW_QQW(obits, rbits, rbits, lhs, rwp);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Formatting
|
||||
@@ -330,7 +364,7 @@ WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, W
|
||||
// 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
|
||||
@@ -386,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;
|
||||
}
|
||||
@@ -495,25 +529,28 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
|
||||
case 'u': // Packed 2-state
|
||||
output.reserve(output.size() + 4*VL_WORDS_I(lbits));
|
||||
for (int i=0; i<VL_WORDS_I(lbits); ++i) {
|
||||
output += (char)((lwp[i] >> 0) & 0xff);
|
||||
output += (char)((lwp[i] ) & 0xff);
|
||||
output += (char)((lwp[i] >> 8) & 0xff);
|
||||
output += (char)((lwp[i] >> 16) & 0xff);
|
||||
output += (char)((lwp[i] >> 24) & 0xff);
|
||||
}
|
||||
break;
|
||||
case 'z': // Packed 4-state
|
||||
output.reserve(output.size() + 8*VL_WORDS_I(lbits));
|
||||
for (int i=0; i<VL_WORDS_I(lbits); ++i) {
|
||||
output += (char)((lwp[i] >> 0) & 0xff);
|
||||
output += (char)((lwp[i] ) & 0xff);
|
||||
output += (char)((lwp[i] >> 8) & 0xff);
|
||||
output += (char)((lwp[i] >> 16) & 0xff);
|
||||
output += (char)((lwp[i] >> 24) & 0xff);
|
||||
output += "\0\0\0\0"; // No tristate
|
||||
}
|
||||
break;
|
||||
case 'v': // Strength; assume always strong
|
||||
for (lsb=lbits-1; lsb>=0; --lsb) {
|
||||
if ((lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 1) output += "St1 ";
|
||||
else output += "St0 ";
|
||||
}
|
||||
break;
|
||||
case 'x':
|
||||
for (; lsb>=0; --lsb) {
|
||||
lsb = (lsb / 4) * 4; // Next digit
|
||||
@@ -522,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
|
||||
@@ -540,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);
|
||||
@@ -557,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;
|
||||
@@ -614,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
|
||||
@@ -651,7 +688,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||
// Deal with all read-and-scan somethings
|
||||
// Note LSBs are preserved if there's an overflow
|
||||
const int obits = va_arg(ap, int);
|
||||
WData qowp[2];
|
||||
WData qowp[2] = {0, 0};
|
||||
WDataOutP owp = qowp;
|
||||
if (obits > VL_QUADSIZE) {
|
||||
owp = va_arg(ap,WDataOutP);
|
||||
@@ -669,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;
|
||||
}
|
||||
@@ -729,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
|
||||
@@ -815,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);
|
||||
@@ -843,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);
|
||||
@@ -854,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);
|
||||
@@ -865,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);
|
||||
@@ -876,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);
|
||||
@@ -887,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);
|
||||
@@ -897,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;
|
||||
@@ -906,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);
|
||||
@@ -918,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);
|
||||
@@ -930,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;
|
||||
@@ -979,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);
|
||||
@@ -997,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)) {
|
||||
@@ -1038,9 +1075,9 @@ void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords,
|
||||
else if (c=='_') {}
|
||||
else if (c=='@') { reading_addr = true; innum=false; needinc=false; }
|
||||
// Check for hex or binary digits as file format requests
|
||||
else if (isxdigit(c)) {
|
||||
else if (isxdigit(c) || (!reading_addr && (c=='x' || c=='X'))) {
|
||||
c = tolower(c);
|
||||
int value = (c >= 'a' ? (c-'a'+10) : (c-'0'));
|
||||
int value = (c >= 'a' ? (c=='x' ? VL_RAND_RESET_I(4) : (c-'a'+10)) : (c-'0'));
|
||||
if (!innum) { // Prep for next number
|
||||
if (needinc) { addr++; needinc=false; }
|
||||
}
|
||||
@@ -1092,7 +1129,7 @@ void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwords,
|
||||
}
|
||||
lastc = c;
|
||||
}
|
||||
if (needinc) { addr++; needinc=false; }
|
||||
if (needinc) { addr++; }
|
||||
|
||||
// Final checks
|
||||
fclose(fp);
|
||||
@@ -1113,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 = ' ';
|
||||
@@ -1142,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));
|
||||
@@ -1177,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) {
|
||||
@@ -1198,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 "+"
|
||||
@@ -1218,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;
|
||||
@@ -1235,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);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@@ -1247,7 +1284,7 @@ const char* Verilated::catName(const char* n1, const char* n2) {
|
||||
static char* strp = NULL;
|
||||
static size_t len = 0;
|
||||
size_t newlen = strlen(n1)+strlen(n2)+2;
|
||||
if (newlen > len) {
|
||||
if (!strp || newlen > len) {
|
||||
if (strp) delete [] strp;
|
||||
strp = new char[newlen];
|
||||
len = newlen;
|
||||
@@ -1274,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);
|
||||
@@ -1405,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);
|
||||
}
|
||||
}
|
||||
@@ -1426,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;
|
||||
}
|
||||
|
||||
+64
-41
@@ -40,13 +40,12 @@
|
||||
// <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
|
||||
|
||||
#if VM_TRACE // Verilator tracing requested
|
||||
# define WAVES 1 // Set backward compatibility flag as in systemperl.h
|
||||
# define WAVES 1 // Set backward compatibility flag
|
||||
#endif
|
||||
|
||||
//=========================================================================
|
||||
@@ -392,7 +391,6 @@ extern IData VL_SYSTEM_IQ(QData lhs);
|
||||
inline IData VL_SYSTEM_II(IData lhs) { return VL_SYSTEM_IQ(lhs); }
|
||||
|
||||
extern IData VL_TESTPLUSARGS_I(const char* formatp);
|
||||
extern IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rwp);
|
||||
extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish
|
||||
|
||||
//=========================================================================
|
||||
@@ -405,6 +403,7 @@ extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish
|
||||
#define VL_BITISSETLIMIT_W(data,width,bit) (((bit)<(width)) && data[VL_BITWORD_I(bit)] & (VL_UL(1)<<VL_BITBIT_I(bit)))
|
||||
|
||||
/// Create two 32-bit words from quadword
|
||||
/// WData is always at least 2 words; does not clean upper bits
|
||||
#define VL_SET_WQ(owp,data) { owp[0]=(IData)(data); owp[1]=(IData)((data)>>VL_WORDSIZE); }
|
||||
#define VL_SET_WI(owp,data) { owp[0]=(IData)(data); owp[1]=0; }
|
||||
#define VL_SET_QW(lwp) ( ((QData)(lwp[0])) | ((QData)(lwp[1])<<((QData)(VL_WORDSIZE)) ))
|
||||
@@ -524,7 +523,7 @@ static inline WDataOutP VL_ALLONES_W(int obits, WDataOutP owp) {
|
||||
// EMIT_RULE: VL_ASSIGN: oclean=rclean; obits==lbits;
|
||||
// For now, we always have a clean rhs.
|
||||
// Note: If a ASSIGN isn't clean, use VL_ASSIGNCLEAN instead to do the same thing.
|
||||
static inline WDataOutP VL_ASSIGN_W(int obits, WDataOutP owp,WDataInP lwp){
|
||||
static inline WDataOutP VL_ASSIGN_W(int obits, WDataOutP owp, WDataInP lwp) {
|
||||
int words = VL_WORDS_I(obits);
|
||||
for (int i=0; i < words; ++i) owp[i] = lwp[i];
|
||||
return(owp);
|
||||
@@ -1191,7 +1190,10 @@ static inline WDataOutP VL_MODDIVS_WWW(int lbits, WDataOutP owp,WDataInP lwp,WDa
|
||||
}
|
||||
}
|
||||
|
||||
#define VL_POW_IIQ(obits,lbits,rbits,lhs,rhs) VL_POW_QQQ(obits,lbits,rbits,lhs,rhs)
|
||||
#define VL_POW_IIW(obits,lbits,rbits,lhs,rwp) VL_POW_QQW(obits,lbits,rbits,lhs,rwp)
|
||||
#define VL_POW_QQI(obits,lbits,rbits,lhs,rhs) VL_POW_QQQ(obits,lbits,rbits,lhs,rhs)
|
||||
#define VL_POW_WWI(obits,lbits,rbits,owp,lwp,rhs) VL_POW_WWQ(obits,lbits,rbits,owp,lwp,rhs)
|
||||
|
||||
static inline IData VL_POW_III(int, int, int rbits, IData lhs, IData rhs) {
|
||||
if (VL_UNLIKELY(rhs==0)) return 1;
|
||||
@@ -1216,8 +1218,14 @@ static inline QData VL_POW_QQQ(int, int, int rbits, QData lhs, QData rhs) {
|
||||
return out;
|
||||
}
|
||||
WDataOutP VL_POW_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDataInP rwp);
|
||||
WDataOutP VL_POW_WWQ(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, QData rhs);
|
||||
QData VL_POW_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp);
|
||||
|
||||
#define VL_POWSS_IIQ(obits,lbits,rbits,lhs,rhs,lsign,rsign) VL_POWSS_QQQ(obits,lbits,rbits,lhs,rhs,lsign,rsign)
|
||||
#define VL_POWSS_IIQ(obits,lbits,rbits,lhs,rhs,lsign,rsign) VL_POWSS_QQQ(obits,lbits,rbits,lhs,rhs,lsign,rsign)
|
||||
#define VL_POWSS_IIW(obits,lbits,rbits,lhs,rwp,lsign,rsign) VL_POWSS_QQW(obits,lbits,rbits,lhs,rwp,lsign,rsign)
|
||||
#define VL_POWSS_QQI(obits,lbits,rbits,lhs,rhs,lsign,rsign) VL_POWSS_QQQ(obits,lbits,rbits,lhs,rhs,lsign,rsign)
|
||||
#define VL_POWSS_WWI(obits,lbits,rbits,owp,lwp,rhs,lsign,rsign) VL_POWSS_WWQ(obits,lbits,rbits,owp,lwp,rhs,lsign,rsign)
|
||||
|
||||
static inline IData VL_POWSS_III(int obits, int, int rbits, IData lhs, IData rhs, bool lsign, bool rsign) {
|
||||
if (VL_UNLIKELY(rhs==0)) return 1;
|
||||
@@ -1246,6 +1254,8 @@ static inline QData VL_POWSS_QQQ(int obits, int, int rbits, QData lhs, QData rhs
|
||||
return VL_POW_QQQ(obits, rbits, rbits, lhs, rhs);
|
||||
}
|
||||
WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, WDataInP rwp, bool lsign, bool rsign);
|
||||
WDataOutP VL_POWSS_WWQ(int obits, int, int rbits, WDataOutP owp, WDataInP lwp, QData rhs, bool lsign, bool rsign);
|
||||
QData VL_POWSS_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp, bool lsign, bool rsign);
|
||||
|
||||
//===================================================================
|
||||
// Concat/replication
|
||||
@@ -1715,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;
|
||||
}
|
||||
@@ -1880,88 +1890,101 @@ static inline WDataOutP VL_COND_WIWW(int obits, int, int, int,
|
||||
return(owp);
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// System Functions
|
||||
|
||||
inline IData VL_VALUEPLUSARGS_IQ(int rbits, const char* prefixp, char fmt, QData& ldr) {
|
||||
WData wd[2]; IData v=VL_VALUEPLUSARGS_IW(rbits,prefixp,fmt,wd); if (v) ldr=VL_SET_QW(wd);
|
||||
return v;
|
||||
}
|
||||
inline IData VL_VALUEPLUSARGS_II(int rbits, const char* prefixp, char fmt, CData& ldr) {
|
||||
QData qd; IData v=VL_VALUEPLUSARGS_IQ(rbits,prefixp,fmt,qd); if (v) ldr=(CData)qd;
|
||||
return v;
|
||||
}
|
||||
inline IData VL_VALUEPLUSARGS_II(int rbits, const char* prefixp, char fmt, SData& ldr) {
|
||||
QData qd; IData v=VL_VALUEPLUSARGS_IQ(rbits,prefixp,fmt,qd); if (v) ldr=(SData)qd;
|
||||
return v;
|
||||
}
|
||||
inline IData VL_VALUEPLUSARGS_II(int rbits, const char* prefixp, char fmt, IData& ldr) {
|
||||
QData qd; IData v=VL_VALUEPLUSARGS_IQ(rbits,prefixp,fmt,qd); if (v) ldr=(IData)qd;
|
||||
return v;
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// 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_*/
|
||||
|
||||
+7
-21
@@ -18,11 +18,12 @@ 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
|
||||
|
||||
SP_PREPROC = sp_preproc
|
||||
SP_INCLUDER = $(VERILATOR_INCLUDER)
|
||||
VERILATOR_COVERAGE = $(PERL) $(VERILATOR_ROOT)/bin/verilator_coverage
|
||||
VERILATOR_INCLUDER = $(PERL) $(VERILATOR_ROOT)/bin/verilator_includer
|
||||
@@ -49,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)
|
||||
@@ -93,9 +93,9 @@ VM_CLASSES += $(VM_CLASSES_FAST) $(VM_CLASSES_SLOW)
|
||||
VM_SUPPORT += $(VM_SUPPORT_FAST) $(VM_SUPPORT_SLOW)
|
||||
|
||||
#######################################################################
|
||||
##### SystemC or SystemPerl builds
|
||||
##### SystemC builds
|
||||
|
||||
ifeq ($(VM_SP_OR_SC),1)
|
||||
ifeq ($(VM_SC),1)
|
||||
CPPFLAGS += $(SYSTEMC_CXX_FLAGS) -I$(SYSTEMC_INCLUDE)
|
||||
LDFLAGS += $(SYSTEMC_CXX_FLAGS) -L$(SYSTEMC_LIBDIR)
|
||||
SC_LIBS = -lsystemc
|
||||
@@ -106,23 +106,9 @@ ifeq ($(VM_SP_OR_SC),1)
|
||||
endif
|
||||
|
||||
#######################################################################
|
||||
##### SystemPerl builds
|
||||
##### Stub
|
||||
|
||||
ifeq ($(VM_SP),1)
|
||||
CPPFLAGS += -I$(SYSTEMPERL_INCLUDE) -DSYSTEMPERL
|
||||
VPATH += $(SYSTEMPERL_INCLUDE)
|
||||
LIBS += -lm -lstdc++
|
||||
|
||||
VK_CLASSES_SP = $(addsuffix .sp, $(VM_CLASSES))
|
||||
|
||||
# This rule is called manually by the upper level makefile
|
||||
preproc:
|
||||
@echo " SP Preprocess" $(basename $(VM_CLASSES)) ...
|
||||
$(SP_PREPROC) -M sp_preproc.d --tree $(VM_PREFIX).sp_tree \
|
||||
--preproc $(VK_CLASSES_SP)
|
||||
else
|
||||
preproc:
|
||||
endif
|
||||
preproc:
|
||||
|
||||
#######################################################################
|
||||
##### C/H builds
|
||||
|
||||
+43
-42
@@ -72,6 +72,7 @@ private:
|
||||
T* m_countp; ///< Count value
|
||||
public:
|
||||
// METHODS
|
||||
// cppcheck-suppress truncLongCastReturn
|
||||
virtual vluint64_t count() const { return *m_countp; }
|
||||
virtual void zero() const { *m_countp = 0; }
|
||||
// CONSTRUCTORS
|
||||
@@ -89,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
|
||||
@@ -118,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]);
|
||||
@@ -140,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...
|
||||
@@ -149,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.*
|
||||
@@ -177,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;
|
||||
@@ -186,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;
|
||||
}
|
||||
}
|
||||
@@ -262,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];
|
||||
@@ -293,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());
|
||||
}
|
||||
}
|
||||
@@ -317,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;
|
||||
}
|
||||
@@ -362,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;
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -440,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),
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
+11
-11
@@ -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() \
|
||||
@@ -58,31 +58,31 @@ const char* svDpiVersion() {
|
||||
//======================================================================
|
||||
// Bit-select utility functions.
|
||||
|
||||
svBit svGetBitselBit(const svBitVecVal* s, int i) {
|
||||
_VL_SVDPI_UNIMP(); return 0;
|
||||
svBit svGetBitselBit(const svBitVecVal* sp, int bit) {
|
||||
return VL_BITISSET_W(sp,bit);
|
||||
}
|
||||
svLogic svGetBitselLogic(const svLogicVecVal* s, int i) {
|
||||
svLogic svGetBitselLogic(const svLogicVecVal* sp, int bit) {
|
||||
_VL_SVDPI_UNIMP(); return 0;
|
||||
}
|
||||
|
||||
void svPutBitselBit(svBitVecVal* d, int i, svBit s) {
|
||||
_VL_SVDPI_UNIMP();
|
||||
void svPutBitselBit(svBitVecVal* dp, int bit, svBit s) {
|
||||
VL_ASSIGNBIT_WI(32, bit, dp, s);
|
||||
}
|
||||
void svPutBitselLogic(svLogicVecVal* d, int i, svLogic s) {
|
||||
void svPutBitselLogic(svLogicVecVal* dp, int bit, svLogic s) {
|
||||
_VL_SVDPI_UNIMP();
|
||||
}
|
||||
|
||||
void svGetPartselBit(svBitVecVal* d, const svBitVecVal* s, int i, int w) {
|
||||
void svGetPartselBit(svBitVecVal* dp, const svBitVecVal* sp, int i, int w) {
|
||||
_VL_SVDPI_UNIMP();
|
||||
}
|
||||
void svGetPartselLogic(svLogicVecVal* d, const svLogicVecVal* s, int i, int w) {
|
||||
void svGetPartselLogic(svLogicVecVal* dp, const svLogicVecVal* sp, int i, int w) {
|
||||
_VL_SVDPI_UNIMP();
|
||||
}
|
||||
|
||||
void svPutPartselBit(svBitVecVal* d, const svBitVecVal s, int i, int w) {
|
||||
void svPutPartselBit(svBitVecVal* dp, const svBitVecVal s, int i, int w) {
|
||||
_VL_SVDPI_UNIMP();
|
||||
}
|
||||
void svPutPartselLogic(svLogicVecVal* d, const svLogicVecVal* s, int i, int w) {
|
||||
void svPutPartselLogic(svLogicVecVal* dp, const svLogicVecVal* sp, int i, int w) {
|
||||
_VL_SVDPI_UNIMP();
|
||||
}
|
||||
|
||||
|
||||
+18
-18
@@ -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) {
|
||||
WData rwp[1];
|
||||
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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
+28
-31
@@ -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");
|
||||
|
||||
@@ -412,13 +407,13 @@ void VerilatedVcd::dumpHeader () {
|
||||
// We detect the spaces in module names to determine hierarchy. This
|
||||
// allows signals to be declared without fixed ordering, which is
|
||||
// required as Verilog signals might be separately declared from
|
||||
// "SP_TRACE" signals.
|
||||
// SC module signals.
|
||||
|
||||
// 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)
|
||||
@@ -570,6 +565,7 @@ void VerilatedVcd::declDouble (vluint32_t code, const char* name, int arraynum
|
||||
//=============================================================================
|
||||
|
||||
void VerilatedVcd::fullDouble (vluint32_t code, const double newval) {
|
||||
// cppcheck-suppress invalidPointerCast
|
||||
(*((double*)&m_sigs_oldvalp[code])) = newval;
|
||||
// Buffer can't overflow before sprintf; we sized during declaration
|
||||
sprintf(m_writep, "r%.16g", newval);
|
||||
@@ -578,6 +574,7 @@ void VerilatedVcd::fullDouble (vluint32_t code, const double newval) {
|
||||
bufferCheck();
|
||||
}
|
||||
void VerilatedVcd::fullFloat (vluint32_t code, const float newval) {
|
||||
// cppcheck-suppress invalidPointerCast
|
||||
(*((float*)&m_sigs_oldvalp[code])) = newval;
|
||||
// Buffer can't overflow before sprintf; we sized during declaration
|
||||
sprintf(m_writep, "r%.16g", (double)newval);
|
||||
@@ -594,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());
|
||||
@@ -645,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();
|
||||
}
|
||||
}
|
||||
|
||||
+23
-17
@@ -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);
|
||||
@@ -382,11 +386,13 @@ public:
|
||||
}
|
||||
}
|
||||
inline void chgDouble (vluint32_t code, const double newval) {
|
||||
// cppcheck-suppress invalidPointerCast
|
||||
if (VL_UNLIKELY((*((double*)&m_sigs_oldvalp[code])) != newval)) {
|
||||
fullDouble (code, newval);
|
||||
}
|
||||
}
|
||||
inline void chgFloat (vluint32_t code, const float newval) {
|
||||
// cppcheck-suppress invalidPointerCast
|
||||
if (VL_UNLIKELY((*((float*)&m_sigs_oldvalp[code])) != newval)) {
|
||||
fullFloat (code, newval);
|
||||
}
|
||||
@@ -431,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; };
|
||||
|
||||
@@ -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;
|
||||
@@ -946,11 +946,10 @@ void vpi_get_value(vpiHandle object, p_vpi_value value_p) {
|
||||
case VLVT_UINT32:
|
||||
value_p->value.integer = *((IData*)(vop->varDatap()));
|
||||
return;
|
||||
case VLVT_WDATA:
|
||||
case VLVT_UINT64:
|
||||
// Not legal
|
||||
value_p->value.integer = 0;
|
||||
case VLVT_WDATA: // FALLTHRU
|
||||
case VLVT_UINT64: // FALLTHRU
|
||||
default:
|
||||
value_p->value.integer = 0;
|
||||
_VL_VPI_ERROR(__FILE__, __LINE__, "%s: Unsupported format (%s) for %s",
|
||||
VL_FUNC, VerilatedVpiError::strFromVpiVal(value_p->format), vop->fullname());
|
||||
return;
|
||||
|
||||
+29
-28
@@ -99,8 +99,8 @@ public:
|
||||
virtual const char* name() { return "<null>"; }
|
||||
virtual const char* fullname() { return "<null>"; }
|
||||
virtual const char* defname() { return "<null>"; }
|
||||
virtual const vluint32_t type() { return 0; }
|
||||
virtual const vluint32_t size() const { return 0; }
|
||||
virtual vluint32_t type() { return 0; }
|
||||
virtual vluint32_t size() const { return 0; }
|
||||
virtual const VerilatedRange* rangep() const { return NULL; }
|
||||
virtual vpiHandle dovpi_scan() { return 0; }
|
||||
};
|
||||
@@ -120,7 +120,7 @@ public:
|
||||
}
|
||||
virtual ~VerilatedVpioCb() {}
|
||||
static inline VerilatedVpioCb* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioCb*>((VerilatedVpio*)h); }
|
||||
virtual const vluint32_t type() { return vpiCallback; }
|
||||
virtual vluint32_t type() { return vpiCallback; }
|
||||
vluint32_t reason() const { return m_cbData.reason; }
|
||||
VerilatedPliCb cb_rtnp() const { return m_cbData.cb_rtn; }
|
||||
t_cb_data* cb_datap() { return &(m_cbData); }
|
||||
@@ -133,7 +133,7 @@ public:
|
||||
explicit VerilatedVpioConst(vlsint32_t num) : m_num(num) {}
|
||||
virtual ~VerilatedVpioConst() {}
|
||||
static inline VerilatedVpioConst* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioConst*>((VerilatedVpio*)h); }
|
||||
virtual const vluint32_t type() { return vpiUndefined; }
|
||||
virtual vluint32_t type() { return vpiUndefined; }
|
||||
vlsint32_t num() const { return m_num; }
|
||||
};
|
||||
|
||||
@@ -144,8 +144,8 @@ public:
|
||||
explicit VerilatedVpioRange(const VerilatedRange* range) : m_range(range), m_iteration(0) {}
|
||||
virtual ~VerilatedVpioRange() {}
|
||||
static inline VerilatedVpioRange* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioRange*>((VerilatedVpio*)h); }
|
||||
virtual const vluint32_t type() { return vpiRange; }
|
||||
virtual const vluint32_t size() const { return m_range->elements(); }
|
||||
virtual vluint32_t type() { return vpiRange; }
|
||||
virtual vluint32_t size() const { return m_range->elements(); }
|
||||
virtual const VerilatedRange* rangep() const { return m_range; }
|
||||
int iteration() const { return m_iteration; }
|
||||
void iterationInc() { ++m_iteration; }
|
||||
@@ -167,7 +167,7 @@ public:
|
||||
: m_scopep(scopep) {}
|
||||
virtual ~VerilatedVpioScope() {}
|
||||
static inline VerilatedVpioScope* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioScope*>((VerilatedVpio*)h); }
|
||||
virtual const vluint32_t type() { return vpiScope; }
|
||||
virtual vluint32_t type() { return vpiScope; }
|
||||
const VerilatedScope* scopep() const { return m_scopep; }
|
||||
virtual const char* name() { return m_scopep->name(); }
|
||||
virtual const char* fullname() { return m_scopep->name(); }
|
||||
@@ -206,17 +206,17 @@ public:
|
||||
vluint32_t mask() const { return m_mask.u32; }
|
||||
vluint8_t mask_byte(int idx) { return m_mask.u8[idx & 3]; }
|
||||
vluint32_t entSize() const { return m_entSize; }
|
||||
const vluint32_t index() { return m_index; }
|
||||
virtual const vluint32_t type() {
|
||||
vluint32_t index() { return m_index; }
|
||||
virtual vluint32_t type() {
|
||||
if (varp()->vldir() != vpiNoDirection) return vpiPort;
|
||||
return (varp()->dims()>1) ? vpiMemory : vpiReg; /* but might be wire, logic */
|
||||
}
|
||||
virtual const vluint32_t size() const { return get_range().elements(); }
|
||||
virtual vluint32_t size() const { return get_range().elements(); }
|
||||
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; }
|
||||
@@ -239,13 +239,13 @@ public:
|
||||
}
|
||||
virtual ~VerilatedVpioMemoryWord() {}
|
||||
static inline VerilatedVpioMemoryWord* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioMemoryWord*>((VerilatedVpio*)h); }
|
||||
virtual const vluint32_t type() { return vpiMemoryWord; }
|
||||
virtual const vluint32_t size() const { return varp()->range().elements(); }
|
||||
virtual vluint32_t type() { return vpiMemoryWord; }
|
||||
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();
|
||||
}
|
||||
};
|
||||
@@ -259,7 +259,7 @@ public:
|
||||
: m_scopep(scopep), m_started(false) { }
|
||||
virtual ~VerilatedVpioVarIter() {}
|
||||
static inline VerilatedVpioVarIter* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioVarIter*>((VerilatedVpio*)h); }
|
||||
virtual const vluint32_t type() { return vpiIterator; }
|
||||
virtual vluint32_t type() { return vpiIterator; }
|
||||
virtual vpiHandle dovpi_scan() {
|
||||
if (VL_LIKELY(m_scopep->varsp())) {
|
||||
VerilatedVarNameMap* varsp = m_scopep->varsp();
|
||||
@@ -286,7 +286,7 @@ public:
|
||||
: m_handle(handle), m_varp(varp), m_iteration(varp->array().right()), m_direction(VL_LIKELY(varp->array().left()>varp->array().right())?1:-1), m_done(false) { }
|
||||
virtual ~VerilatedVpioMemoryWordIter() {}
|
||||
static inline VerilatedVpioMemoryWordIter* castp(vpiHandle h) { return dynamic_cast<VerilatedVpioMemoryWordIter*>((VerilatedVpio*)h); }
|
||||
virtual const vluint32_t type() { return vpiIterator; }
|
||||
virtual vluint32_t type() { return vpiIterator; }
|
||||
void iterationInc() { if (!(m_done = (m_iteration == m_varp->array().left()))) m_iteration+=m_direction; }
|
||||
virtual vpiHandle dovpi_scan() {
|
||||
vpiHandle result;
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
@@ -95,7 +98,7 @@
|
||||
// This is not necessarily the same as #UL, depending on what the IData typedef is.
|
||||
#define VL_UL(c) ((IData)(c##UL)) ///< Add appropriate suffix to 32-bit constant
|
||||
|
||||
#ifdef VL_CPPCHECK
|
||||
#if defined(VL_CPPCHECK) || defined(__clang_analyzer__)
|
||||
# define VL_DANGLING(v)
|
||||
#else
|
||||
# define VL_DANGLING(v) do { (v) = NULL; } while(0) ///< After e.g. delete, set variable to NULL to indicate must not use later
|
||||
|
||||
+7
-7
@@ -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
@@ -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
@@ -8,7 +8,7 @@ use strict;
|
||||
#======================================================================
|
||||
# main
|
||||
|
||||
eval `modulecmd perl add synopsys-vcs_mx`;
|
||||
eval `modulecmd perl add synopsys-sim`;
|
||||
exec('vcs',@ARGV);
|
||||
|
||||
#######################################################################
|
||||
|
||||
+4
-10
@@ -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)
|
||||
@@ -105,12 +107,6 @@ endif
|
||||
CPPFLAGSWALL = $(CPPFLAGS)
|
||||
CPPFLAGSPARSER = $(CPPFLAGS) $(CFG_CXXFLAGS_PARSER)
|
||||
|
||||
ifneq ($(SYSTEMPERL),) # Intuit SYSTEMPERL_INCLUDE as it's new
|
||||
SYSTEMPERL_INCLUDE ?= $(SYSTEMPERL)/src
|
||||
#else if set, leave as-is.
|
||||
#else if SYSTEMPERL="" don't set _INCLUDE so source will figure it out
|
||||
endif
|
||||
|
||||
# Allow RPM builds to specify hardcoded data directories
|
||||
# To do this:
|
||||
ifeq ($(CFG_WITH_DEFENV),yes)
|
||||
@@ -118,8 +114,6 @@ ifeq ($(CFG_WITH_DEFENV),yes)
|
||||
CPPFLAGS += -DDEFENV_SYSTEMC_ARCH=\"$(SYSTEMC_ARCH)\"
|
||||
CPPFLAGS += -DDEFENV_SYSTEMC_INCLUDE=\"$(SYSTEMC_INCLUDE)\"
|
||||
CPPFLAGS += -DDEFENV_SYSTEMC_LIBDIR=\"$(SYSTEMC_LIBDIR)\"
|
||||
CPPFLAGS += -DDEFENV_SYSTEMPERL=\"$(SYSTEMPERL)\"
|
||||
CPPFLAGS += -DDEFENV_SYSTEMPERL_INCLUDE=\"$(SYSTEMPERL_INCLUDE)\"
|
||||
ifeq ($(VERILATOR_ROOT),) # Use what we're given, or intuit
|
||||
CPPFLAGS += -DDEFENV_VERILATOR_ROOT=\"$(pkgdatadir)\"
|
||||
else
|
||||
|
||||
+3
-3
@@ -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 (=).");
|
||||
}
|
||||
@@ -323,7 +323,7 @@ private:
|
||||
// Read sensitivitues
|
||||
m_itemCombo = false;
|
||||
m_itemSequent = false;
|
||||
oldsensesp->iterateAndNext(*this);
|
||||
if (oldsensesp) oldsensesp->iterateAndNext(*this);
|
||||
bool combo = m_itemCombo;
|
||||
bool sequent = m_itemSequent;
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
+7
-7
@@ -119,7 +119,7 @@ private:
|
||||
} else {
|
||||
nodep->v3fatalSrc("Unknown node type");
|
||||
}
|
||||
if (stmtsp) bodysp = bodysp->addNext(stmtsp);
|
||||
if (bodysp && stmtsp) bodysp = bodysp->addNext(stmtsp);
|
||||
AstIf* ifp = new AstIf (nodep->fileline(), propp, bodysp, NULL);
|
||||
bodysp = ifp;
|
||||
if (nodep->castVAssert()) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
+9
-3
@@ -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);
|
||||
@@ -902,7 +906,7 @@ bool AstNode::sameTreeIter(AstNode* node1p, AstNode* node2p, bool ignNext, bool
|
||||
//======================================================================
|
||||
// Static utilities
|
||||
|
||||
ostream& operator<<(ostream& os, V3Hash rhs) {
|
||||
ostream& operator<<(ostream& os, const V3Hash& rhs) {
|
||||
return os<<hex<<setw(2)<<setfill('0')<<rhs.depth()
|
||||
<<"_"<<setw(6)<<setfill('0')<<rhs.hshval();
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -1057,6 +1061,8 @@ void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump) {
|
||||
editCountSetLast();
|
||||
}
|
||||
|
||||
void AstNode::v3errorEndFatal(ostringstream& str) const { v3errorEnd(str); assert(0); }
|
||||
|
||||
void AstNode::v3errorEnd(ostringstream& str) const {
|
||||
if (!dynamic_cast<const AstNode*>(this)) {
|
||||
// No known cases cause this, but better than a core dump
|
||||
|
||||
+17
-13
@@ -61,7 +61,7 @@ public:
|
||||
inline bool operator== (AstType lhs, AstType rhs) { return (lhs.m_e == rhs.m_e); }
|
||||
inline bool operator== (AstType lhs, AstType::en rhs) { return (lhs.m_e == rhs); }
|
||||
inline bool operator== (AstType::en lhs, AstType rhs) { return (lhs == rhs.m_e); }
|
||||
inline ostream& operator<<(ostream& os, AstType rhs) { return os<<rhs.ascii(); }
|
||||
inline ostream& operator<<(ostream& os, const AstType& rhs) { return os<<rhs.ascii(); }
|
||||
|
||||
//######################################################################
|
||||
|
||||
@@ -107,7 +107,7 @@ public:
|
||||
inline bool operator== (AstNumeric lhs, AstNumeric rhs) { return (lhs.m_e == rhs.m_e); }
|
||||
inline bool operator== (AstNumeric lhs, AstNumeric::en rhs) { return (lhs.m_e == rhs); }
|
||||
inline bool operator== (AstNumeric::en lhs, AstNumeric rhs) { return (lhs == rhs.m_e); }
|
||||
inline ostream& operator<<(ostream& os, AstNumeric rhs) { return os<<rhs.ascii(); }
|
||||
inline ostream& operator<<(ostream& os, const AstNumeric& rhs) { return os<<rhs.ascii(); }
|
||||
|
||||
//######################################################################
|
||||
|
||||
@@ -396,7 +396,7 @@ public:
|
||||
return (m_e==LOGIC || m_e==BIT);
|
||||
}
|
||||
bool isDpiUnsupported() const {
|
||||
return (m_e==LOGIC || m_e==TIME);
|
||||
return (m_e==TIME);
|
||||
}
|
||||
bool isDpiUnsignable() const { // Can add "unsigned" to DPI
|
||||
return (m_e==BYTE || m_e==SHORTINT || m_e==INT || m_e==LONGINT || m_e==INTEGER);
|
||||
@@ -464,7 +464,7 @@ public:
|
||||
inline bool operator== (AstVarType lhs, AstVarType rhs) { return (lhs.m_e == rhs.m_e); }
|
||||
inline bool operator== (AstVarType lhs, AstVarType::en rhs) { return (lhs.m_e == rhs); }
|
||||
inline bool operator== (AstVarType::en lhs, AstVarType rhs) { return (lhs == rhs.m_e); }
|
||||
inline ostream& operator<<(ostream& os, AstVarType rhs) { return os<<rhs.ascii(); }
|
||||
inline ostream& operator<<(ostream& os, const AstVarType& rhs) { return os<<rhs.ascii(); }
|
||||
|
||||
//######################################################################
|
||||
|
||||
@@ -496,7 +496,7 @@ public:
|
||||
inline bool operator== (AstBranchPred lhs, AstBranchPred rhs) { return (lhs.m_e == rhs.m_e); }
|
||||
inline bool operator== (AstBranchPred lhs, AstBranchPred::en rhs) { return (lhs.m_e == rhs); }
|
||||
inline bool operator== (AstBranchPred::en lhs, AstBranchPred rhs) { return (lhs == rhs.m_e); }
|
||||
inline ostream& operator<<(ostream& os, AstBranchPred rhs) { return os<<rhs.ascii(); }
|
||||
inline ostream& operator<<(ostream& os, const AstBranchPred& rhs) { return os<<rhs.ascii(); }
|
||||
|
||||
//######################################################################
|
||||
|
||||
@@ -529,7 +529,7 @@ public:
|
||||
inline bool operator== (AstVarAttrClocker lhs, AstVarAttrClocker rhs) { return (lhs.m_e == rhs.m_e); }
|
||||
inline bool operator== (AstVarAttrClocker lhs, AstVarAttrClocker::en rhs) { return (lhs.m_e == rhs); }
|
||||
inline bool operator== (AstVarAttrClocker::en lhs, AstVarAttrClocker rhs) { return (lhs == rhs.m_e); }
|
||||
inline ostream& operator<<(ostream& os, AstVarAttrClocker rhs) { return os<<rhs.ascii(); }
|
||||
inline ostream& operator<<(ostream& os, const AstVarAttrClocker& rhs) { return os<<rhs.ascii(); }
|
||||
|
||||
//######################################################################
|
||||
|
||||
@@ -628,7 +628,7 @@ public:
|
||||
inline bool operator== (AstParseRefExp lhs, AstParseRefExp rhs) { return (lhs.m_e == rhs.m_e); }
|
||||
inline bool operator== (AstParseRefExp lhs, AstParseRefExp::en rhs) { return (lhs.m_e == rhs); }
|
||||
inline bool operator== (AstParseRefExp::en lhs, AstParseRefExp rhs) { return (lhs == rhs.m_e); }
|
||||
inline ostream& operator<<(ostream& os, AstParseRefExp rhs) { return os<<rhs.ascii(); }
|
||||
inline ostream& operator<<(ostream& os, const AstParseRefExp& rhs) { return os<<rhs.ascii(); }
|
||||
|
||||
//######################################################################
|
||||
// VNumRange - Structure containing numberic range information
|
||||
@@ -680,7 +680,7 @@ struct VNumRange {
|
||||
{ return (!m_ranged || (m_lo==0 && m_hi>=1 && !m_littleEndian)); }
|
||||
void dump(ostream& str) const { if (ranged()) str<<"["<<left()<<":"<<right()<<"]"; else str<<"[norg]"; }
|
||||
};
|
||||
inline ostream& operator<<(ostream& os, VNumRange rhs) { rhs.dump(os); return os; }
|
||||
inline ostream& operator<<(ostream& os, const VNumRange& rhs) { rhs.dump(os); return os; }
|
||||
|
||||
//######################################################################
|
||||
|
||||
@@ -709,7 +709,7 @@ struct VBasicTypeKey {
|
||||
if (!(m_nrange == rhs.m_nrange)) return false; // lhs > rhs
|
||||
return false; }
|
||||
VBasicTypeKey(int width, int widthMin, AstNumeric numeric, AstBasicDTypeKwd kwd,
|
||||
VNumRange nrange)
|
||||
const VNumRange& nrange)
|
||||
: m_width(width), m_widthMin(widthMin), m_numeric(numeric),
|
||||
m_keyword(kwd), m_nrange(nrange) {}
|
||||
~VBasicTypeKey() {}
|
||||
@@ -733,8 +733,9 @@ class VNUser {
|
||||
} m_u;
|
||||
public:
|
||||
VNUser() {}
|
||||
// non-explicit:
|
||||
VNUser(int i) { m_u.up = 0; m_u.ui = i; }
|
||||
VNUser(void* p) { m_u.up = p; }
|
||||
explicit VNUser(void* p) { m_u.up = p; }
|
||||
~VNUser() {}
|
||||
// Casters
|
||||
WidthVP* c() { return ((WidthVP*)m_u.up); }
|
||||
@@ -891,7 +892,7 @@ public:
|
||||
AstNode* oldp() const { return m_oldp; }
|
||||
void dump(ostream& str=cout) const;
|
||||
};
|
||||
inline ostream& operator<<(ostream& os, AstNRelinker& rhs) { rhs.dump(os); return os;}
|
||||
inline ostream& operator<<(ostream& os, const AstNRelinker& rhs) { rhs.dump(os); return os;}
|
||||
|
||||
//######################################################################
|
||||
// V3Hash -- Node hashing for V3Combine
|
||||
@@ -903,7 +904,8 @@ class V3Hash {
|
||||
uint32_t m_both;
|
||||
static const uint32_t M24 = ((1<<24)-1);
|
||||
void setBoth(uint32_t depth, uint32_t hshval) {
|
||||
if (depth==0) depth=1; if (depth>255) depth=255;
|
||||
if (depth==0) depth=1;
|
||||
if (depth>255) depth=255;
|
||||
m_both = (depth<<24) | (hshval & M24);
|
||||
}
|
||||
public:
|
||||
@@ -940,7 +942,7 @@ public:
|
||||
V3Hash(V3Hash h1, V3Hash h2, V3Hash h3, V3Hash h4) {
|
||||
setBoth(1,((h1.hshval()*31+h2.hshval())*31+h3.hshval())*31+h4.hshval()); }
|
||||
};
|
||||
ostream& operator<<(ostream& os, V3Hash rhs);
|
||||
ostream& operator<<(ostream& os, const V3Hash& rhs);
|
||||
|
||||
//######################################################################
|
||||
// AstNode -- Base type of all Ast types
|
||||
@@ -1230,6 +1232,7 @@ public:
|
||||
|
||||
// METHODS - dump and error
|
||||
void v3errorEnd(ostringstream& str) const;
|
||||
void v3errorEndFatal(ostringstream& str) const VL_ATTR_NORETURN;
|
||||
string warnMore() const;
|
||||
virtual void dump(ostream& str=cout);
|
||||
void dumpGdb(); // For GDB only
|
||||
@@ -1509,6 +1512,7 @@ public:
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(AstNode*) const { return true; }
|
||||
virtual string verilogKwd() const { return "="; }
|
||||
virtual bool brokeLhsMustBeLvalue() const = 0;
|
||||
};
|
||||
|
||||
class AstNodeFor : public AstNodeStmt {
|
||||
|
||||
+5
-1
@@ -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();
|
||||
|
||||
+52
-17
@@ -121,21 +121,24 @@ public:
|
||||
m_littleEndian = false;
|
||||
setOp2p(new AstConst(fl,msb)); setOp3p(new AstConst(fl,lsb));
|
||||
}
|
||||
AstRange(FileLine* fl, VNumRange range)
|
||||
AstRange(FileLine* fl, const VNumRange& range)
|
||||
:AstNode(fl) {
|
||||
m_littleEndian = range.littleEndian();
|
||||
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
|
||||
@@ -743,7 +746,7 @@ class AstParseTypeDType : public AstNodeDType {
|
||||
// During parsing, this indicates the type of a parameter is a "parameter type"
|
||||
// e.g. the data type is a container of any data type
|
||||
public:
|
||||
AstParseTypeDType(FileLine* fl)
|
||||
explicit AstParseTypeDType(FileLine* fl)
|
||||
: AstNodeDType(fl) {}
|
||||
ASTNODE_NODE_FUNCS(ParseTypeDType)
|
||||
AstNodeDType* dtypep() const { return NULL; }
|
||||
@@ -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
|
||||
@@ -1655,7 +1683,7 @@ private:
|
||||
string m_name; // Cell name
|
||||
public:
|
||||
AstCellRef(FileLine* fl,
|
||||
string name, AstNode* cellp, AstNode* exprp)
|
||||
const string& name, AstNode* cellp, AstNode* exprp)
|
||||
: AstNode(fl)
|
||||
, m_name(name) {
|
||||
addNOp1p(cellp); addNOp2p(exprp); }
|
||||
@@ -1672,7 +1700,7 @@ private:
|
||||
string m_name; // Array name
|
||||
public:
|
||||
AstCellArrayRef(FileLine* fl,
|
||||
string name, AstNode* selectExprp)
|
||||
const string& name, AstNode* selectExprp)
|
||||
: AstNode(fl)
|
||||
, m_name(name) {
|
||||
addNOp1p(selectExprp); }
|
||||
@@ -1688,7 +1716,7 @@ private:
|
||||
string m_name; // Var name
|
||||
public:
|
||||
AstUnlinkedRef(FileLine* fl,
|
||||
AstNode* refp, string name, AstNode* crp)
|
||||
AstNode* refp, const string& name, AstNode* crp)
|
||||
: AstNode(fl)
|
||||
, m_name(name) {
|
||||
addNOp1p(refp); addNOp2p(crp); }
|
||||
@@ -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
|
||||
@@ -2039,6 +2067,7 @@ public:
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(Assign)
|
||||
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssign(this->fileline(), lhsp, rhsp); }
|
||||
virtual bool brokeLhsMustBeLvalue() const { return true; }
|
||||
};
|
||||
|
||||
class AstAssignAlias : public AstNodeAssign {
|
||||
@@ -2049,6 +2078,7 @@ public:
|
||||
: AstNodeAssign(fileline, lhsp, rhsp) {}
|
||||
ASTNODE_NODE_FUNCS(AssignAlias)
|
||||
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { V3ERROR_NA; return NULL; }
|
||||
virtual bool brokeLhsMustBeLvalue() const { return false; }
|
||||
};
|
||||
|
||||
class AstAssignDly : public AstNodeAssign {
|
||||
@@ -2059,6 +2089,7 @@ public:
|
||||
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignDly(this->fileline(), lhsp, rhsp); }
|
||||
virtual bool isGateOptimizable() const { return false; }
|
||||
virtual string verilogKwd() const { return "<="; }
|
||||
virtual bool brokeLhsMustBeLvalue() const { return true; }
|
||||
};
|
||||
|
||||
class AstAssignW : public AstNodeAssign {
|
||||
@@ -2068,6 +2099,7 @@ public:
|
||||
: AstNodeAssign(fileline, lhsp, rhsp) { }
|
||||
ASTNODE_NODE_FUNCS(AssignW)
|
||||
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignW(this->fileline(), lhsp, rhsp); }
|
||||
virtual bool brokeLhsMustBeLvalue() const { return true; }
|
||||
AstAlways* convertToAlways() {
|
||||
AstNode* lhs1p = lhsp()->unlinkFrBack();
|
||||
AstNode* rhs1p = rhsp()->unlinkFrBack();
|
||||
@@ -2087,6 +2119,7 @@ public:
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(AssignVarScope)
|
||||
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignVarScope(this->fileline(), lhsp, rhsp); }
|
||||
virtual bool brokeLhsMustBeLvalue() const { return false; }
|
||||
};
|
||||
|
||||
class AstPull : public AstNode {
|
||||
@@ -2113,6 +2146,7 @@ public:
|
||||
: AstNodeAssign(fileline, lhsp, rhsp) {}
|
||||
ASTNODE_NODE_FUNCS(AssignPre)
|
||||
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignPre(this->fileline(), lhsp, rhsp); }
|
||||
virtual bool brokeLhsMustBeLvalue() const { return true; }
|
||||
};
|
||||
|
||||
class AstAssignPost : public AstNodeAssign {
|
||||
@@ -2122,6 +2156,7 @@ public:
|
||||
: AstNodeAssign(fileline, lhsp, rhsp) {}
|
||||
ASTNODE_NODE_FUNCS(AssignPost)
|
||||
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp) { return new AstAssignPost(this->fileline(), lhsp, rhsp); }
|
||||
virtual bool brokeLhsMustBeLvalue() const { return true; }
|
||||
};
|
||||
|
||||
class AstComment : public AstNodeStmt {
|
||||
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
|
||||
+14
-1
@@ -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
|
||||
@@ -236,6 +240,15 @@ private:
|
||||
nodep->iterateChildrenConst(*this);
|
||||
BrokenTable::setUnder(nodep,false);
|
||||
}
|
||||
virtual void visit(AstNodeAssign* nodep) {
|
||||
processAndIterate(nodep);
|
||||
if (v3Global.assertDTypesResolved()
|
||||
&& nodep->brokeLhsMustBeLvalue()
|
||||
&& nodep->lhsp()->castNodeVarRef()
|
||||
&& !nodep->lhsp()->castNodeVarRef()->lvalue()) {
|
||||
nodep->v3fatalSrc("Assignment LHS is not an lvalue");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNode* nodep) {
|
||||
processAndIterate(nodep);
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ public:
|
||||
m_funcp = m_tlFuncp;
|
||||
m_modp->addStmtp(m_tlFuncp);
|
||||
}
|
||||
~V3CCtorsVisitor() {}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
||||
+2
-2
@@ -423,7 +423,7 @@ private:
|
||||
// Handle any assertions
|
||||
replaceCaseParallel(nodep, false);
|
||||
// Replace the CASE... with IF...
|
||||
if (debug()>=9) grouprootp->dumpTree(cout," _new: ");
|
||||
if (debug()>=9 && grouprootp) grouprootp->dumpTree(cout," _new: ");
|
||||
if (grouprootp) nodep->replaceWith(grouprootp);
|
||||
else nodep->unlinkFrBack();
|
||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
+2
-2
@@ -591,14 +591,14 @@ private:
|
||||
vertexp->dstDomainp(senoutp);
|
||||
if (debug()>=9) {
|
||||
UINFO(9,spaces(level)+" Tracedst "<<vertexp);
|
||||
if (senoutp) V3EmitV::verilogForTree(senoutp, cout); cout<<endl;
|
||||
if (senoutp) { V3EmitV::verilogForTree(senoutp, cout); cout<<endl; }
|
||||
}
|
||||
} else {
|
||||
vertexp->srcDomainSet(true); // Note it's set - domainp may be null, so can't use that
|
||||
vertexp->srcDomainp(senoutp);
|
||||
if (debug()>=9) {
|
||||
UINFO(9,spaces(level)+" Tracesrc "<<vertexp);
|
||||
if (senoutp) V3EmitV::verilogForTree(senoutp, cout); cout<<endl;
|
||||
if (senoutp) { V3EmitV::verilogForTree(senoutp, cout); cout<<endl; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
+4
-3
@@ -611,7 +611,8 @@ class GaterVisitor : public GaterBaseVisitor {
|
||||
// Edges from IFs represent a real IF branch in the equation tree
|
||||
//UINFO(9," ifver "<<(void*)(edgep)<<" cc"<<edgep->dotColor()<<endl);
|
||||
eqnp = cVxp->nodep()->condp()->cloneTree(true);
|
||||
if (eqnp && cedgep->ifelseFalse()) {
|
||||
if (!eqnp) cVxp->nodep()->v3fatalSrc("null condition");
|
||||
if (cedgep->ifelseFalse()) {
|
||||
eqnp = new AstNot(eqnp->fileline(),eqnp);
|
||||
}
|
||||
// We need to AND this term onto whatever was found below it
|
||||
@@ -878,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);
|
||||
@@ -914,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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
+1
-1
@@ -104,7 +104,7 @@ class V3ConfigIgnores {
|
||||
public:
|
||||
inline static V3ConfigIgnores& singleton() { return s_singleton; }
|
||||
|
||||
void addIgnore(V3ErrorCode code, string wildname, int lineno, bool on) {
|
||||
void addIgnore(V3ErrorCode code, const string& wildname, int lineno, bool on) {
|
||||
// Insert
|
||||
IgnLines* linesp = findWilds(wildname);
|
||||
UINFO(9,"config addIgnore "<<wildname<<":"<<lineno<<", "<<code<<", "<<on<<endl);
|
||||
|
||||
+89
-14
@@ -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,21 +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();
|
||||
@@ -2241,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");
|
||||
@@ -2252,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)
|
||||
@@ -2408,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) {
|
||||
@@ -2431,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) {
|
||||
@@ -2439,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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
+2
-2
@@ -158,7 +158,7 @@ private:
|
||||
if (oldactivep->sensesp() != m_activep->sensesp()) {
|
||||
if (!varrefp->varp()->fileline()->warnIsOff(V3ErrorCode::MULTIDRIVEN)
|
||||
&& !varrefp->varp()->user2()) {
|
||||
varrefp->varp()->v3warn(MULTIDRIVEN,"Signal has multiple driving blocks: "<<varrefp->varp()->prettyName()<<endl
|
||||
varrefp->varp()->v3warn(MULTIDRIVEN,"Signal has multiple driving blocks with different clocking: "<<varrefp->varp()->prettyName()<<endl
|
||||
<<varrefp->warnMore()<<"... Location of first driving block"<<endl
|
||||
<<oldactivep->warnMore()<<"... Location of other driving block");
|
||||
varrefp->varp()->user2(true);
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
+4
-3
@@ -138,8 +138,9 @@ private:
|
||||
for (AstNode* stmtp = newfuncp->argsp(); stmtp; stmtp=stmtp->nextp()) {
|
||||
if (AstVar* portp = stmtp->castVar()) {
|
||||
if (portp->isIO() && !portp->isFuncReturn()) {
|
||||
argsp = argsp->addNextNull(new AstVarRef(portp->fileline(), portp,
|
||||
portp->isOutput()));
|
||||
AstNode* newp = new AstVarRef(portp->fileline(), portp, portp->isOutput());
|
||||
if (argsp) argsp = argsp->addNextNull(newp);
|
||||
else argsp = newp;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -262,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);
|
||||
}
|
||||
|
||||
+112
-129
@@ -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
|
||||
|
||||
@@ -69,7 +71,7 @@ public:
|
||||
const string& vformat, AstNode* exprsp, bool isScan);
|
||||
void displayEmit(AstNode* nodep, bool isScan);
|
||||
void displayArg(AstNode* dispp, AstNode** elistp, bool isScan,
|
||||
string vfmt, char fmtLetter);
|
||||
const string& vfmt, char fmtLetter);
|
||||
|
||||
void emitVarDecl(AstVar* nodep, const string& prefixIfImp);
|
||||
typedef enum {EVL_IO, EVL_SIG, EVL_TEMP, EVL_PAR, EVL_ALL} EisWhich;
|
||||
@@ -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
|
||||
@@ -782,12 +824,7 @@ class EmitCImp : EmitCStmts {
|
||||
// We should move them to a different stage.
|
||||
string filename = VL_DEV_NULL;
|
||||
newCFile(filename, slow, source);
|
||||
ofp = new V3OutSpFile (filename);
|
||||
}
|
||||
else if (optSystemPerl()) {
|
||||
string filename = filenameNoExt+".sp";
|
||||
newCFile(filename, slow, source);
|
||||
ofp = new V3OutSpFile (filename);
|
||||
ofp = new V3OutCFile (filename);
|
||||
}
|
||||
else if (optSystemC()) {
|
||||
string filename = filenameNoExt+(source?".cpp":".h");
|
||||
@@ -847,16 +884,13 @@ class EmitCImp : EmitCStmts {
|
||||
if (nodep->symProlog()) puts(EmitCBaseVisitor::symTopAssign()+"\n");
|
||||
|
||||
if (nodep->initsp()) putsDecoration("// Variables\n");
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, 4);
|
||||
for (AstNode* subnodep=nodep->argsp(); subnodep; subnodep = subnodep->nextp()) {
|
||||
if (AstVar* varp=subnodep->castVar()) {
|
||||
if (varp->isFuncReturn()) emitVarDecl(varp, "");
|
||||
}
|
||||
}
|
||||
emitVarList(nodep->initsp(), EVL_ALL, "");
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, 4);
|
||||
emitVarList(nodep->stmtsp(), EVL_ALL, "");
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, 4);
|
||||
|
||||
nodep->initsp()->iterateAndNext(*this);
|
||||
|
||||
@@ -964,7 +998,6 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
||||
if (nodep->isIO()) {
|
||||
if (nodep->isSc()) {
|
||||
m_ctorVarsVec.push_back(nodep);
|
||||
ofp()->putAlign(nodep->isStatic(), 4); // sc stuff is a structure, so bigger alignment
|
||||
if (nodep->attrScClocked() && nodep->isInput()) {
|
||||
puts("sc_in_clk\t");
|
||||
} else {
|
||||
@@ -985,8 +1018,6 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
||||
emitDeclArrayBrackets(nodep);
|
||||
puts(";\n");
|
||||
} else { // C++ signals
|
||||
ofp()->putAlign(nodep->isStatic(), nodep->dtypeSkipRefp()->widthAlignBytes(),
|
||||
nodep->dtypeSkipRefp()->widthTotalBytes());
|
||||
if (nodep->isInout()) puts("VL_INOUT");
|
||||
else if (nodep->isInput()) puts("VL_IN");
|
||||
else if (nodep->isOutput()) puts("VL_OUT");
|
||||
@@ -1013,8 +1044,6 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
||||
} else {
|
||||
// Arrays need a small alignment, but may need different padding after.
|
||||
// For example three VL_SIG8's needs alignment 1 but size 3.
|
||||
ofp()->putAlign(nodep->isStatic(), nodep->dtypeSkipRefp()->widthAlignBytes(),
|
||||
nodep->dtypeSkipRefp()->widthTotalBytes());
|
||||
if (nodep->isStatic() && prefixIfImp=="") puts("static ");
|
||||
if (nodep->isStatic()) puts("VL_ST_"); else puts("VL_");
|
||||
if (nodep->widthMin() <= 8) {
|
||||
@@ -1237,7 +1266,6 @@ void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) {
|
||||
if (dispp) {}
|
||||
puts("VL_SFORMATF_NX(");
|
||||
} else {
|
||||
isStmt = true;
|
||||
nodep->v3fatalSrc("Unknown displayEmit node type");
|
||||
}
|
||||
ofp()->putsQuoted(emitDispState.m_format);
|
||||
@@ -1269,7 +1297,7 @@ void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) {
|
||||
}
|
||||
|
||||
void EmitCStmts::displayArg(AstNode* dispp, AstNode** elistp, bool isScan,
|
||||
string vfmt, char fmtLetter) {
|
||||
const string& vfmt, char fmtLetter) {
|
||||
// Print display argument, edits elistp
|
||||
AstNode* argp = *elistp;
|
||||
if (!argp) {
|
||||
@@ -1484,9 +1512,7 @@ void EmitCImp::emitCoverageDecl(AstNodeModule* modp) {
|
||||
|
||||
void EmitCImp::emitCtorImp(AstNodeModule* modp) {
|
||||
puts("\n");
|
||||
if (optSystemPerl() && modp->isTop()) {
|
||||
puts("SP_CTOR_IMP("+modClassName(modp)+")");
|
||||
} else if (optSystemC() && modp->isTop()) {
|
||||
if (optSystemC() && modp->isTop()) {
|
||||
puts("VL_SC_CTOR_IMP("+modClassName(modp)+")");
|
||||
} else {
|
||||
puts("VL_CTOR_IMP("+modClassName(modp)+")");
|
||||
@@ -1504,7 +1530,6 @@ void EmitCImp::emitCtorImp(AstNodeModule* modp) {
|
||||
putsDecoration("// Reset structure values\n");
|
||||
puts("_ctor_var_reset();\n");
|
||||
emitTextSection(AstType::atScCtor);
|
||||
if (optSystemPerl()) puts("SP_AUTO_CTOR;\n");
|
||||
puts("}\n");
|
||||
}
|
||||
|
||||
@@ -1523,9 +1548,7 @@ void EmitCImp::emitCoverageImp(AstNodeModule* modp) {
|
||||
if (v3Global.opt.coverage() ) {
|
||||
puts("\n// Coverage\n");
|
||||
// Rather than putting out VL_COVER_INSERT calls directly, we do it via this function
|
||||
// This gets around gcc slowness constructing all of the template arguments
|
||||
// SystemPerl 1.301 is much faster, but it's nice to remain back
|
||||
// compatible, and have a common wrapper.
|
||||
// This gets around gcc slowness constructing all of the template arguments.
|
||||
puts("void "+modClassName(m_modp)+"::__vlCoverInsert(uint32_t* countp, bool enable, const char* filenamep, int lineno, int column,\n");
|
||||
puts( "const char* hierp, const char* pagep, const char* commentp) {\n");
|
||||
puts( "static uint32_t fake_zero_count = 0;\n"); // static doesn't need save-restore as constant
|
||||
@@ -1535,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");
|
||||
@@ -1705,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");
|
||||
@@ -1715,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);
|
||||
@@ -1731,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);
|
||||
@@ -1789,7 +1816,6 @@ void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& pref
|
||||
}
|
||||
}
|
||||
}
|
||||
ofp()->putAlign(isstatic, 4, 0, prefixIfImp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1817,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");
|
||||
}
|
||||
}
|
||||
@@ -1825,11 +1851,9 @@ void EmitCImp::emitIntFuncDecls(AstNodeModule* modp) {
|
||||
|
||||
void EmitCImp::emitInt(AstNodeModule* modp) {
|
||||
// Always have this first; gcc has short circuiting if #ifdef is first in a file
|
||||
if (!optSystemPerl()) { // else done for us automatically
|
||||
puts("#ifndef _"+modClassName(modp)+"_H_\n");
|
||||
puts("#define _"+modClassName(modp)+"_H_\n");
|
||||
puts("\n");
|
||||
}
|
||||
puts("#ifndef _"+modClassName(modp)+"_H_\n");
|
||||
puts("#define _"+modClassName(modp)+"_H_\n");
|
||||
puts("\n");
|
||||
|
||||
ofp()->putsIntTopInclude();
|
||||
if (v3Global.needHeavy()) {
|
||||
@@ -1851,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");
|
||||
@@ -1873,19 +1897,18 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
|
||||
} else {
|
||||
puts("VL_MODULE("+modClassName(modp)+") {\n");
|
||||
}
|
||||
if (optSystemPerl()) puts("/*AUTOATTR(verilated)*/\n\n");
|
||||
ofp()->resetPrivate();
|
||||
ofp()->putsPrivate(false); // public:
|
||||
|
||||
// Instantiated modules
|
||||
if (optSystemPerl()) {
|
||||
puts("/*AUTOSUBCELLS*/\n\n");
|
||||
} else {
|
||||
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");
|
||||
{ // 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());
|
||||
}
|
||||
}
|
||||
@@ -1909,18 +1932,14 @@ 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
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, 8);
|
||||
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()) {
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
|
||||
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");
|
||||
}
|
||||
}
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, 8);
|
||||
emitCoverageDecl(modp); // may flip public/private
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, 8);
|
||||
|
||||
puts("\n// PARAMETERS\n");
|
||||
if (modp->isTop()) puts("// Parameters marked /*verilator public*/ for use by application code\n");
|
||||
@@ -1952,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()) {
|
||||
@@ -1972,7 +1991,7 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
|
||||
if (modp->isTop()) puts("/// Destroy the model; called (often implicitly) by application code\n");
|
||||
puts("~"+modClassName(modp)+"();\n");
|
||||
}
|
||||
if (v3Global.opt.trace() && !optSystemPerl()) {
|
||||
if (v3Global.opt.trace()) {
|
||||
if (modp->isTop()) puts("/// Trace signals in the model; called by application code\n");
|
||||
puts("void trace (VerilatedVcdC* tfp, int levels, int options=0);\n");
|
||||
if (modp->isTop() && optSystemC()) {
|
||||
@@ -1981,8 +2000,6 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
|
||||
}
|
||||
}
|
||||
|
||||
puts("\n// USER METHODS\n");
|
||||
if (optSystemPerl()) puts("/*AUTOMETHODS*/\n");
|
||||
emitTextSection(AstType::atScInt);
|
||||
|
||||
puts("\n// API METHODS\n");
|
||||
@@ -1994,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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2009,7 +2026,7 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
|
||||
|
||||
emitIntFuncDecls(modp);
|
||||
|
||||
if (!optSystemPerl() && v3Global.opt.trace()) {
|
||||
if (v3Global.opt.trace()) {
|
||||
ofp()->putsPrivate(false); // public:
|
||||
puts("static void traceInit ("+v3Global.opt.traceClassBase()+"* vcdp, void* userthis, uint32_t code);\n");
|
||||
puts("static void traceFull ("+v3Global.opt.traceClassBase()+"* vcdp, void* userthis, uint32_t code);\n");
|
||||
@@ -2027,24 +2044,18 @@ 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
|
||||
if (!optSystemPerl()) {
|
||||
puts("#endif /*guard*/\n");
|
||||
}
|
||||
puts("#endif // guard\n");
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void EmitCImp::emitImp(AstNodeModule* modp) {
|
||||
if (optSystemPerl()) {
|
||||
puts("//############################################################\n");
|
||||
puts("#sp implementation\n");
|
||||
}
|
||||
ofp()->printf("#include \"%-20s // For This\n",
|
||||
(modClassName(modp)+".h\"").c_str());
|
||||
|
||||
@@ -2055,11 +2066,7 @@ void EmitCImp::emitImp(AstNodeModule* modp) {
|
||||
puts("\n");
|
||||
puts("#include \"verilated_dpi.h\"\n");
|
||||
}
|
||||
|
||||
if (optSystemPerl() && (splitFilenum() || !m_fast)) {
|
||||
puts("\n");
|
||||
puts("SP_MODULE_CONTINUED("+modClassName(modp)+");\n");
|
||||
}
|
||||
puts("\n");
|
||||
|
||||
emitTextSection(AstType::atScImpHdr);
|
||||
|
||||
@@ -2092,13 +2099,6 @@ void EmitCImp::emitImp(AstNodeModule* modp) {
|
||||
}
|
||||
}
|
||||
|
||||
if (m_fast && splitFilenum()==0) {
|
||||
if (v3Global.opt.trace() && optSystemPerl() && m_modp->isTop()) {
|
||||
puts("\n");
|
||||
puts("\n/*AUTOTRACE(__MODULE__,recurse,activity,exists)*/\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Blocks
|
||||
puts("\n//--------------------\n");
|
||||
puts("// Internal Methods\n");
|
||||
@@ -2116,15 +2116,7 @@ void EmitCImp::main(AstNodeModule* modp, bool slow, bool fast) {
|
||||
UINFO(0," Emitting "<<modClassName(modp)<<endl);
|
||||
}
|
||||
|
||||
if (optSystemPerl()) {
|
||||
m_ofp = newOutCFile(modp, !m_fast, true);
|
||||
|
||||
if (m_fast) {
|
||||
puts("#sp interface\n");
|
||||
emitInt (modp);
|
||||
}
|
||||
}
|
||||
else if (optSystemC()) {
|
||||
if (optSystemC()) {
|
||||
if (m_fast) {
|
||||
m_ofp = newOutCFile (modp, !m_fast, false/*source*/);
|
||||
emitInt (modp);
|
||||
@@ -2189,11 +2181,7 @@ class EmitCTrace : EmitCStmts {
|
||||
|
||||
void emitTraceHeader() {
|
||||
// Includes
|
||||
if (optSystemPerl()) {
|
||||
puts("#include \"SpTraceVcd.h\"\n");
|
||||
} else {
|
||||
puts("#include \"verilated_vcd_c.h\"\n");
|
||||
}
|
||||
puts("#include \"verilated_vcd_c.h\"\n");
|
||||
puts("#include \""+ symClassName() +".h\"\n");
|
||||
puts("\n");
|
||||
}
|
||||
@@ -2202,11 +2190,7 @@ class EmitCTrace : EmitCStmts {
|
||||
puts("\n//======================\n\n");
|
||||
|
||||
puts("void "+topClassName()+"::trace (");
|
||||
if (optSystemPerl()) {
|
||||
puts("SpTraceFile* tfp, int, int) {\n");
|
||||
} else {
|
||||
puts("VerilatedVcdC* tfp, int, int) {\n");
|
||||
}
|
||||
puts("VerilatedVcdC* tfp, int, int) {\n");
|
||||
puts( "tfp->spTrace()->addCallback ("
|
||||
"&"+topClassName()+"::traceInit"
|
||||
+", &"+topClassName()+"::traceFull"
|
||||
@@ -2218,12 +2202,12 @@ 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");
|
||||
puts("t->traceInitThis (vlSymsp, vcdp, code);\n");
|
||||
puts("vcdp->scopeEscape('.');\n"); // Restore so SystemPerl traced files won't break
|
||||
puts("vcdp->scopeEscape('.');\n"); // Restore so later traced files won't break
|
||||
puts("}\n");
|
||||
splitSizeInc(10);
|
||||
|
||||
@@ -2231,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);
|
||||
@@ -2246,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");
|
||||
@@ -2390,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) {
|
||||
@@ -2401,7 +2385,6 @@ class EmitCTrace : EmitCStmts {
|
||||
if (nodep->initsp()) putsDecoration("// Variables\n");
|
||||
emitVarList(nodep->initsp(), EVL_ALL, "");
|
||||
nodep->initsp()->iterateAndNext(*this);
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, 4);
|
||||
|
||||
putsDecoration("// Body\n");
|
||||
puts("{\n");
|
||||
|
||||
@@ -46,7 +46,6 @@ public:
|
||||
void putsDecoration(const string& str) { if (v3Global.opt.decoration()) puts(str); }
|
||||
void putsQuoted(const string& str) { ofp()->putsQuoted(str); }
|
||||
bool optSystemC() { return v3Global.opt.systemC(); }
|
||||
bool optSystemPerl() { return v3Global.opt.systemPerl(); }
|
||||
static string symClassName() { return v3Global.opt.prefix()+"__Syms"; }
|
||||
static string symClassVar() { return symClassName()+"* __restrict vlSymsp"; }
|
||||
static string symTopAssign() { return v3Global.opt.prefix()+"* __restrict vlTOPp VL_ATTR_UNUSED = vlSymsp->TOPp;"; }
|
||||
|
||||
+2
-40
@@ -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
-28
@@ -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;
|
||||
}
|
||||
@@ -238,7 +238,6 @@ class EmitCSyms : EmitCBaseVisitor {
|
||||
virtual void visit(AstConst*) {}
|
||||
// Default
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nameCheck(nodep);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
//---------------------------------------
|
||||
@@ -303,14 +302,12 @@ void EmitCSyms::emitSymHdr() {
|
||||
ofp()->putsPrivate(false); // public:
|
||||
|
||||
puts("\n// LOCAL STATE\n");
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(vluint64_t));
|
||||
puts("const char* __Vm_namep;\n"); // Must be before subcells, as constructor order needed before _vlCoverInsert.
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
|
||||
puts("bool\t__Vm_activity;\t\t///< Used by trace routines to determine change occurred\n");
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(bool));
|
||||
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");
|
||||
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(vluint64_t));
|
||||
puts("\n// SUBCELL STATE\n");
|
||||
for (vector<ScopeModPair>::iterator it = m_scopes.begin(); it != m_scopes.end(); ++it) {
|
||||
AstScope* scopep = it->first; AstNodeModule* modp = it->second;
|
||||
@@ -324,15 +321,17 @@ void EmitCSyms::emitSymHdr() {
|
||||
}
|
||||
}
|
||||
|
||||
puts("\n// COVERAGE\n");
|
||||
if (m_coverBins) {
|
||||
ofp()->putAlign(V3OutFile::AL_AUTO, sizeof(uint32_t));
|
||||
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");
|
||||
@@ -341,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");
|
||||
@@ -349,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() {
|
||||
@@ -375,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=',';
|
||||
@@ -426,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()) {
|
||||
@@ -518,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) {
|
||||
|
||||
+8
-19
@@ -90,15 +90,10 @@ public:
|
||||
if (v3Global.opt.coverage()) {
|
||||
putMakeClassEntry(of, "verilated_cov.cpp");
|
||||
}
|
||||
if (v3Global.opt.systemPerl()) {
|
||||
putMakeClassEntry(of, "Sp.cpp"); // Note Sp.cpp includes SpTraceVcdC
|
||||
}
|
||||
else {
|
||||
if (v3Global.opt.trace()) {
|
||||
putMakeClassEntry(of, "verilated_vcd_c.cpp");
|
||||
if (v3Global.opt.systemC()) {
|
||||
putMakeClassEntry(of, "verilated_vcd_sc.cpp");
|
||||
}
|
||||
if (v3Global.opt.trace()) {
|
||||
putMakeClassEntry(of, "verilated_vcd_c.cpp");
|
||||
if (v3Global.opt.systemC()) {
|
||||
putMakeClassEntry(of, "verilated_vcd_sc.cpp");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,7 +101,7 @@ public:
|
||||
}
|
||||
else {
|
||||
for (AstCFile* nodep = v3Global.rootp()->filesp(); nodep; nodep=nodep->nextp()->castCFile()) {
|
||||
if (nodep->source() && nodep->slow()==slow && nodep->support()==support) {
|
||||
if (nodep->source() && nodep->slow()==(slow!=0) && nodep->support()==(support!=0)) {
|
||||
putMakeClassEntry(of, nodep->name());
|
||||
}
|
||||
}
|
||||
@@ -139,22 +134,16 @@ public:
|
||||
of.puts("PERL = "+V3Options::getenvPERL()+"\n");
|
||||
of.puts("# Path to Verilator kit (from $VERILATOR_ROOT)\n");
|
||||
of.puts("VERILATOR_ROOT = "+V3Options::getenvVERILATOR_ROOT()+"\n");
|
||||
of.puts("# Path to SystemPerl kit top (from $SYSTEMPERL)\n");
|
||||
of.puts("SYSTEMPERL = "+V3Options::getenvSYSTEMPERL()+"\n");
|
||||
of.puts("# Path to SystemPerl kit includes (from $SYSTEMPERL_INCLUDE)\n");
|
||||
of.puts("SYSTEMPERL_INCLUDE = "+V3Options::getenvSYSTEMPERL_INCLUDE()+"\n");
|
||||
of.puts("# SystemC include directory with systemc.h (from $SYSTEMC_INCLUDE)\n");
|
||||
of.puts(string("SYSTEMC_INCLUDE ?= ")+V3Options::getenvSYSTEMC_INCLUDE()+"\n");
|
||||
of.puts("# SystemC library directory with libsystemc.a (from $SYSTEMC_LIBDIR)\n");
|
||||
of.puts(string("SYSTEMC_LIBDIR ?= ")+V3Options::getenvSYSTEMC_LIBDIR()+"\n");
|
||||
|
||||
of.puts("\n### Switches...\n");
|
||||
of.puts("# SystemPerl output mode? 0/1 (from --sp)\n");
|
||||
of.puts(string("VM_SP = ")+(v3Global.opt.systemPerl()?"1":"0")+"\n");
|
||||
of.puts("# SystemC output mode? 0/1 (from --sc)\n");
|
||||
of.puts(string("VM_SC = ")+((v3Global.opt.systemC()&&!v3Global.opt.systemPerl())?"1":"0")+"\n");
|
||||
of.puts("# SystemPerl or SystemC output mode? 0/1 (from --sp/--sc)\n");
|
||||
of.puts(string("VM_SP_OR_SC = ")+(v3Global.opt.systemC()?"1":"0")+"\n");
|
||||
of.puts(string("VM_SC = ")+((v3Global.opt.systemC())?"1":"0")+"\n");
|
||||
of.puts("# Legacy or SystemC output mode? 0/1 (from --sc)\n");
|
||||
of.puts(string("VM_SP_OR_SC = $(VM_SC)\n"));
|
||||
of.puts("# Deprecated\n");
|
||||
of.puts(string("VM_PCLI = ")+(v3Global.opt.systemC()?"0":"1")+"\n");
|
||||
of.puts("# Deprecated: SystemC architecture to find link library path (from $SYSTEMC_ARCH)\n");
|
||||
|
||||
+1
-1
@@ -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();
|
||||
|
||||
+8
-5
@@ -29,6 +29,7 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <deque>
|
||||
#include <cassert>
|
||||
|
||||
//######################################################################
|
||||
|
||||
@@ -253,18 +254,20 @@ 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) { 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
|
||||
// Note the commas are the comma operator, not separating arguments. These are needed to insure
|
||||
// evaluation order as otherwise we couldn't insure v3errorPrep is called first.
|
||||
#define v3warnCode(code,msg) v3errorEnd((V3Error::v3errorPrep(code), (V3Error::v3errorStr()<<msg), V3Error::v3errorStr()));
|
||||
#define v3warn(code,msg) v3warnCode(V3ErrorCode::code,msg)
|
||||
#define v3info(msg) v3warn(EC_INFO,msg)
|
||||
#define v3fatal(msg) v3warn(EC_FATAL,msg)
|
||||
#define v3error(msg) v3warn(EC_ERROR,msg)
|
||||
#define v3warnCodeFatal(code,msg) v3errorEndFatal((V3Error::v3errorPrep(code), (V3Error::v3errorStr()<<msg), V3Error::v3errorStr()));
|
||||
#define v3warn(code,msg) v3warnCode(V3ErrorCode::code, msg)
|
||||
#define v3info(msg) v3warnCode(V3ErrorCode::EC_INFO, msg)
|
||||
#define v3error(msg) v3warnCode(V3ErrorCode::EC_ERROR, msg)
|
||||
#define v3fatal(msg) v3warnCodeFatal(V3ErrorCode::EC_FATAL, msg)
|
||||
// Use this instead of fatal() to mention the source code line.
|
||||
#define v3fatalSrc(msg) v3warn(EC_FATALSRC,__FILE__<<":"<<dec<<__LINE__<<": "<<msg)
|
||||
#define v3fatalSrc(msg) v3warnCodeFatal(V3ErrorCode::EC_FATALSRC, __FILE__<<":"<<dec<<__LINE__<<": "<<msg)
|
||||
|
||||
#define UINFO(level,stmsg) {if(VL_UNLIKELY(debug()>=(level))) { cout<<"- "<<V3Error::lineStr(__FILE__,__LINE__)<<stmsg; }}
|
||||
#define UINFONL(level,stmsg) {if(VL_UNLIKELY(debug()>=(level))) { cout<<stmsg; } }
|
||||
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
|
||||
+15
-33
@@ -553,8 +553,7 @@ bool V3InFilter::readWholefile(const string& filename, V3InFilter::StrList& outl
|
||||
V3OutFormatter::V3OutFormatter(const string& filename, V3OutFormatter::Language lang)
|
||||
: m_filename(filename), m_lang(lang)
|
||||
, m_lineno(1), m_column(0)
|
||||
, m_nobreak(false), m_prependIndent(true), m_indentLevel(0)
|
||||
, m_declSAlign(0), m_declNSAlign(0), m_declPadNum(0) {
|
||||
, m_nobreak(false), m_prependIndent(true), m_indentLevel(0) {
|
||||
m_blockIndent = v3Global.opt.decoration() ? 4 : 1;
|
||||
m_commaWidth = v3Global.opt.decoration() ? 50 : 150;
|
||||
}
|
||||
@@ -609,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) {
|
||||
@@ -797,24 +797,6 @@ void V3OutFormatter::putcNoTracking (char chr) {
|
||||
putcOutput (chr);
|
||||
}
|
||||
|
||||
void V3OutFormatter::putAlign (bool/*AlignClass*/ isStatic, int align, int size, const string& prefix) {
|
||||
if (size==0) size=align;
|
||||
int alignSize = size; if (alignSize>8) alignSize=8;
|
||||
int& alignr = isStatic ? m_declSAlign : m_declNSAlign;
|
||||
int padsize = alignSize - (alignr % alignSize);
|
||||
if (padsize && padsize!=alignSize) {
|
||||
// Modern versions of GCC no longer need this, they'll pad for us, so
|
||||
// we'll save the work and danger of getting it wrong.
|
||||
puts("//char\t");
|
||||
puts(prefix);
|
||||
puts("__VpadToAlign"+cvtToStr(alignr)
|
||||
+"["+cvtToStr(padsize)+"];\n");
|
||||
alignr += padsize;
|
||||
m_declPadNum++;
|
||||
}
|
||||
alignr += size;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Simple wrappers
|
||||
|
||||
|
||||
@@ -120,9 +120,6 @@ private:
|
||||
int m_nobreak; // Basic operator or begin paren, don't break next
|
||||
bool m_prependIndent;
|
||||
int m_indentLevel; // Current {} indentation
|
||||
int m_declSAlign; // Byte alignment of next declaration, statics
|
||||
int m_declNSAlign; // Byte alignment of next declaration, nonstatics
|
||||
int m_declPadNum; // Pad variable number
|
||||
stack<int> m_parenVec; // Stack of columns where last ( was
|
||||
|
||||
int endLevels(const char* strg);
|
||||
@@ -144,7 +141,6 @@ public:
|
||||
void putsQuoted(const string& strg);
|
||||
void putBreak(); // Print linebreak if line is too wide
|
||||
void putBreakExpr(); // Print linebreak in expression if line is too wide
|
||||
void putAlign(bool isstatic/*AlignClass*/, int align, int size=0/*=align*/, const string& prefix=""); // Declare a variable, with natural alignment
|
||||
void putbs(const char* strg) { putBreakExpr(); puts(strg); }
|
||||
void putbs(const string& strg) { putBreakExpr(); puts(strg); }
|
||||
bool exceededWidth() const { return m_column > m_commaWidth; }
|
||||
@@ -222,18 +218,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class V3OutSpFile : public V3OutCFile {
|
||||
public:
|
||||
explicit V3OutSpFile(const string& filename) : V3OutCFile(filename) {}
|
||||
virtual ~V3OutSpFile() {}
|
||||
virtual void putsHeader() { puts("// Verilated -*- SystemC -*-\n"); }
|
||||
virtual void putsIntTopInclude() {
|
||||
putsForceIncs();
|
||||
puts("#include \"systemperl.h\"\n");
|
||||
puts("#include \"verilated_sc.h\"\n");
|
||||
}
|
||||
};
|
||||
|
||||
class V3OutVFile : public V3OutFile {
|
||||
public:
|
||||
explicit V3OutVFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_VERILOG) {}
|
||||
|
||||
@@ -161,11 +161,16 @@ public:
|
||||
|
||||
// OPERATORS
|
||||
void v3errorEnd(ostringstream& str);
|
||||
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);
|
||||
|
||||
inline void FileLine::v3errorEndFatal(ostringstream& str) { v3errorEnd(str); assert(0); }
|
||||
|
||||
#endif // Guard
|
||||
|
||||
+7
-7
@@ -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();
|
||||
@@ -1409,7 +1409,7 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
GateClkDecompGraphVisitor(V3Graph* graphp) {
|
||||
explicit GateClkDecompGraphVisitor(V3Graph* graphp) {
|
||||
m_graphp = graphp;
|
||||
m_seen_clk_vectors = 0;
|
||||
m_clk_vsp = NULL;
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -124,7 +124,7 @@ public:
|
||||
static DfaInput EPSILON() { return VNUser::fromInt(0); }
|
||||
static DfaInput NA() { return VNUser::fromInt(1); } // as in not-applicable
|
||||
// CONSTRUCTORS
|
||||
DfaEdge(DfaGraph* graphp, DfaVertex* fromp, DfaVertex* top, DfaInput input)
|
||||
DfaEdge(DfaGraph* graphp, DfaVertex* fromp, DfaVertex* top, const DfaInput& input)
|
||||
: V3GraphEdge(graphp, fromp, top, 1)
|
||||
, m_input(input), m_complement(false) {}
|
||||
DfaEdge(DfaGraph* graphp, DfaVertex* fromp, DfaVertex* top, const DfaEdge* copyfrom)
|
||||
|
||||
+4
-4
@@ -72,7 +72,7 @@ public:
|
||||
class V3GraphTestVertex : public V3GraphVertex {
|
||||
string m_name;
|
||||
public:
|
||||
V3GraphTestVertex(V3Graph* graphp, string name) : V3GraphVertex(graphp), m_name(name) {}
|
||||
V3GraphTestVertex(V3Graph* graphp, const string& name) : V3GraphVertex(graphp), m_name(name) {}
|
||||
virtual ~V3GraphTestVertex() {}
|
||||
// Accessors
|
||||
virtual string name() const { return m_name; }
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
|
||||
class V3GraphTestVarVertex : public V3GraphTestVertex {
|
||||
public:
|
||||
V3GraphTestVarVertex(V3Graph* graphp, string name) : V3GraphTestVertex(graphp, name) {}
|
||||
V3GraphTestVarVertex(V3Graph* graphp, const string& name) : V3GraphTestVertex(graphp, name) {}
|
||||
virtual ~V3GraphTestVarVertex() {}
|
||||
// Accessors
|
||||
virtual string dotColor() const { return "blue"; }
|
||||
@@ -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);
|
||||
@@ -270,7 +270,7 @@ public:
|
||||
class DfaTestVertex : public DfaVertex {
|
||||
string m_name;
|
||||
public:
|
||||
DfaTestVertex(DfaGraph* graphp, string name) : DfaVertex(graphp), m_name(name) {}
|
||||
DfaTestVertex(DfaGraph* graphp, const string& name) : DfaVertex(graphp), m_name(name) {}
|
||||
virtual ~DfaTestVertex() {}
|
||||
// Accessors
|
||||
virtual string name() const { return m_name; }
|
||||
|
||||
+1
-1
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
+104
-43
@@ -45,70 +45,132 @@ class V3LanguageWords {
|
||||
public:
|
||||
V3LanguageWords() {
|
||||
// C++ keywords
|
||||
addKwd("asm", "C++ reserved word");
|
||||
addKwd("auto", "C++ reserved word");
|
||||
addKwd("catch", "C++ reserved word");
|
||||
addKwd("cdecl", "C++ reserved word");
|
||||
addKwd("char", "C++ reserved word");
|
||||
addKwd("const_cast", "C++ reserved word");
|
||||
addKwd("delete", "C++ reserved word");
|
||||
addKwd("double", "C++ reserved word");
|
||||
addKwd("dynamic_cast", "C++ reserved word");
|
||||
addKwd("explicit", "C++ reserved word");
|
||||
addKwd("far", "C++ reserved word");
|
||||
addKwd("float", "C++ reserved word");
|
||||
addKwd("friend", "C++ reserved word");
|
||||
addKwd("goto", "C++ reserved word");
|
||||
addKwd("huge", "C++ reserved word");
|
||||
addKwd("inline", "C++ reserved word");
|
||||
addKwd("interrupt", "C++ reserved word");
|
||||
addKwd("long", "C++ reserved word");
|
||||
addKwd("mutable", "C++ reserved word");
|
||||
addKwd("near", "C++ reserved word");
|
||||
addKwd("operator", "C++ reserved word");
|
||||
addKwd("pascal", "C++ reserved word");
|
||||
addKwd("private", "C++ reserved word");
|
||||
addKwd("public", "C++ reserved word");
|
||||
addKwd("register", "C++ reserved word");
|
||||
addKwd("reinterpret_cast ", "C++ reserved word");
|
||||
addKwd("restrict", "C++ reserved word");
|
||||
addKwd("short", "C++ reserved word");
|
||||
addKwd("sizeof", "C++ reserved word");
|
||||
addKwd("static_cast", "C++ reserved word");
|
||||
addKwd("switch", "C++ reserved word");
|
||||
addKwd("template", "C++ reserved word");
|
||||
addKwd("throw", "C++ reserved word");
|
||||
addKwd("try", "C++ reserved word");
|
||||
addKwd("typeid", "C++ reserved word");
|
||||
addKwd("typename", "C++ reserved word");
|
||||
addKwd("unsigned", "C++ reserved word");
|
||||
addKwd("using", "C++ reserved word");
|
||||
addKwd("volatile", "C++ reserved word");
|
||||
// C++
|
||||
addKwd("NULL", "C++ common word");
|
||||
addKwd("abort", "C++ common word");
|
||||
addKwd("alignas", "C++11 keyword");
|
||||
addKwd("alignof", "C++11 keyword");
|
||||
addKwd("and", "C++11 keyword");
|
||||
addKwd("and_eq", "C++11 keyword");
|
||||
addKwd("asm", "C++ common word");
|
||||
addKwd("atomic_cancel", "C++ TM TS keyword");
|
||||
addKwd("atomic_commit", "C++ TM TS keyword");
|
||||
addKwd("atomic_noexcept", "C++ TM TS keyword");
|
||||
addKwd("auto", "C++ keyword");
|
||||
addKwd("bit_vector", "C++ common word");
|
||||
addKwd("bool", "C++ common word");
|
||||
addKwd("bitand", "C++ keyword");
|
||||
addKwd("bitor", "C++ keyword");
|
||||
addKwd("bool", "C++ keyword");
|
||||
addKwd("break", "C++ keyword");
|
||||
addKwd("case", "C++ keyword");
|
||||
addKwd("catch", "C++ keyword");
|
||||
addKwd("cdecl", "C++ common word");
|
||||
addKwd("char", "C++ keyword");
|
||||
addKwd("char16_t", "C++11 keyword");
|
||||
addKwd("char32_t", "C++11 keyword");
|
||||
addKwd("class", "C++11 keyword");
|
||||
addKwd("compl", "C++11 keyword");
|
||||
addKwd("complex", "C++ common word");
|
||||
addKwd("concept", "C++20 keyword");
|
||||
addKwd("const", "C++ keyword");
|
||||
addKwd("const_cast", "C++ common word");
|
||||
addKwd("const_iterator", "C++ common word");
|
||||
addKwd("const_reference ", "C++ common word");
|
||||
addKwd("constexpr", "C++11 keyword");
|
||||
addKwd("continue", "C++ keyword");
|
||||
addKwd("decltype", "C++11 keyword");
|
||||
addKwd("default", "C++ keyword");
|
||||
addKwd("delete", "C++ keyword");
|
||||
addKwd("deque", "C++ common word");
|
||||
addKwd("false", "C++ common word");
|
||||
addKwd("do", "C++ keyword");
|
||||
addKwd("double", "C++ keyword");
|
||||
addKwd("dynamic_cast", "C++ keyword");
|
||||
addKwd("else", "C++ keyword");
|
||||
addKwd("enum", "C++ keyword");
|
||||
addKwd("explicit", "C++ keyword");
|
||||
addKwd("export", "C++ keyword");
|
||||
addKwd("extern", "C++ keyword");
|
||||
addKwd("false", "C++ keyword");
|
||||
addKwd("far", "C++ common word");
|
||||
addKwd("float", "C++ keyword");
|
||||
addKwd("for", "C++ keyword");
|
||||
addKwd("friend", "C++ keyword");
|
||||
addKwd("goto", "C++ keyword");
|
||||
addKwd("huge", "C++ keyword");
|
||||
addKwd("if", "C++ keyword");
|
||||
addKwd("import", "C++ modules TS keyword");
|
||||
addKwd("inline", "C++ keyword");
|
||||
addKwd("int", "C++ keyword");
|
||||
addKwd("interrupt", "C++ common word");
|
||||
addKwd("iterator", "C++ common word");
|
||||
addKwd("list", "C++ common word");
|
||||
addKwd("long", "C++ keyword");
|
||||
addKwd("map", "C++ common word");
|
||||
addKwd("module", "C++ modules TS keyword");
|
||||
addKwd("multimap", "C++ common word");
|
||||
addKwd("multiset", "C++ common word");
|
||||
addKwd("mutable", "C++ keyword");
|
||||
addKwd("namespace", "C++ keyword");
|
||||
addKwd("near", "C++ common word");
|
||||
addKwd("new", "C++ keyword");
|
||||
addKwd("noexcept", "C++11 keyword");
|
||||
addKwd("not", "C++ keyword");
|
||||
addKwd("not_eq", "C++ keyword");
|
||||
addKwd("nullptr", "C++11 keyword");
|
||||
addKwd("operator", "C++ keyword");
|
||||
addKwd("or", "C++ keyword");
|
||||
addKwd("or_eq", "C++ keyword");
|
||||
addKwd("override", "C++ common word");
|
||||
addKwd("pascal", "C++ keyword");
|
||||
addKwd("private", "C++ keyword");
|
||||
addKwd("protected", "C++ keyword");
|
||||
addKwd("public", "C++ keyword");
|
||||
addKwd("queue", "C++ common word");
|
||||
addKwd("reference", "C++ common word");
|
||||
addKwd("register", "C++ keyword");
|
||||
addKwd("reinterpret_cast ", "C++ keyword");
|
||||
addKwd("requires", "C++20 keyword");
|
||||
addKwd("restrict", "C++ keyword");
|
||||
addKwd("return", "C++ keyword");
|
||||
addKwd("set", "C++ common word");
|
||||
addKwd("short", "C++ keyword");
|
||||
addKwd("signed", "C++ keyword");
|
||||
addKwd("sizeof", "C++ keyword");
|
||||
addKwd("stack", "C++ common word");
|
||||
addKwd("true", "C++ common word");
|
||||
addKwd("static", "C++ keyword");
|
||||
addKwd("static_assert", "C++11 keyword");
|
||||
addKwd("static_cast", "C++ keyword");
|
||||
addKwd("struct", "C++ keyword");
|
||||
addKwd("switch", "C++ keyword");
|
||||
addKwd("synchronized", "C++ TM TS keyword");
|
||||
addKwd("template", "C++ keyword");
|
||||
addKwd("this", "C++ keyword");
|
||||
addKwd("thread_local", "C++11 keyword");
|
||||
addKwd("throw", "C++ keyword");
|
||||
addKwd("transaction_safe", "C++ common word");
|
||||
addKwd("transaction_safe_dynamic", "C++ common word");
|
||||
addKwd("true", "C++ keyword");
|
||||
addKwd("try", "C++ keyword");
|
||||
addKwd("type_info", "C++ common word");
|
||||
addKwd("typedef", "C++ keyword");
|
||||
addKwd("typeid", "C++ keyword");
|
||||
addKwd("typename", "C++ keyword");
|
||||
addKwd("uint16_t", "C++ common word");
|
||||
addKwd("uint32_t", "C++ common word");
|
||||
addKwd("uint8_t", "C++ common word");
|
||||
addKwd("union", "C++ keyword");
|
||||
addKwd("unsigned", "C++ keyword");
|
||||
addKwd("using", "C++ keyword");
|
||||
addKwd("vector", "C++ common word");
|
||||
addKwd("virtual", "C++ keyword");
|
||||
addKwd("void", "C++ keyword");
|
||||
addKwd("volatile", "C++ keyword");
|
||||
addKwd("wchar_t", "C++ keyword");
|
||||
addKwd("while", "C++ keyword");
|
||||
addKwd("xor", "C++ keyword");
|
||||
addKwd("xor_eq", "C++ keyword");
|
||||
// This conflicts with header functions, so is ignored
|
||||
//dKwd("final", "C++11 keyword"); // Member function or class head, otherwise not reserved
|
||||
// SystemC
|
||||
addKwd("sc_clock", "SystemC common word");
|
||||
addKwd("sc_in", "SystemC common word");
|
||||
@@ -123,4 +185,3 @@ class V3LanguageWords {
|
||||
|
||||
#endif // Guard
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
|
||||
+4
-2
@@ -131,7 +131,9 @@ private:
|
||||
AstNode* valuep = NULL;
|
||||
if (nodep->valuep()) valuep = new AstAdd(nodep->fileline(), nodep->valuep()->cloneTree(true),
|
||||
new AstConst(nodep->fileline(), AstConst::Unsized32(), offset_from_init));
|
||||
addp = addp->addNextNull(new AstEnumItem(nodep->fileline(), name, NULL, valuep));
|
||||
AstNode* newp = new AstEnumItem(nodep->fileline(), name, NULL, valuep);
|
||||
if (addp) addp = addp->addNextNull(newp);
|
||||
else addp = newp;
|
||||
}
|
||||
nodep->replaceWith(addp);
|
||||
nodep->deleteTree();
|
||||
@@ -429,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);
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
+8
-2
@@ -71,7 +71,7 @@ V3Number::V3Number (FileLine* fileline, const char* sourcep) {
|
||||
if (*cp != '_') *wp++ = *cp;
|
||||
}
|
||||
*wp++ = '\0';
|
||||
while (*cp && *cp == '_') cp++;
|
||||
while (*cp == '_') cp++;
|
||||
if (*cp && tolower(*cp)=='s') {
|
||||
cp++; isSigned(true);
|
||||
}
|
||||
@@ -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
@@ -327,6 +327,6 @@ public:
|
||||
V3Number& opLtN (const V3Number& lhs, const V3Number& rhs);
|
||||
V3Number& opLteN (const V3Number& lhs, const V3Number& rhs);
|
||||
};
|
||||
inline ostream& operator<<(ostream& os, V3Number rhs) { return os<<rhs.ascii(); }
|
||||
inline ostream& operator<<(ostream& os, const V3Number& rhs) { return os<<rhs.ascii(); }
|
||||
|
||||
#endif // Guard
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include <algorithm>
|
||||
#include "V3Number.h"
|
||||
|
||||
void test(string lhss, string op, string rhss, string exps) {
|
||||
void test(const string& lhss, const string& op, const string& rhss, const string& exps) {
|
||||
char* l1 = strdup(lhss.c_str());
|
||||
char* r1 = strdup(rhss.c_str());
|
||||
char* e1 = strdup(exps.c_str());
|
||||
|
||||
+5
-56
@@ -491,52 +491,6 @@ string V3Options::getenvSYSTEMC_LIBDIR() {
|
||||
return var;
|
||||
}
|
||||
|
||||
string V3Options::getenvSYSTEMPERL() {
|
||||
// Must be careful to set SYSTEMPERL_INCLUDE first else we'd setenv
|
||||
// SYSTEMPERL which would override a DEFENVed SYSTEMPERL_INCLUDE.
|
||||
V3Options::getenvSYSTEMPERL_INCLUDE();
|
||||
return V3Options::getenvSYSTEMPERLGuts();
|
||||
}
|
||||
|
||||
string V3Options::getenvSYSTEMPERLGuts() {
|
||||
// Get SYSTEMPERL when SYSTEMPERL_INCLUDE has already been tested
|
||||
string var = V3Os::getenvStr("SYSTEMPERL","");
|
||||
if (var == "" && string(DEFENV_SYSTEMPERL) != "") {
|
||||
var = DEFENV_SYSTEMPERL;
|
||||
V3Os::setenvStr("SYSTEMPERL", var, "Hardcoded at build time");
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
string V3Options::getenvSYSTEMPERL_INCLUDE() {
|
||||
string var = V3Os::getenvStr("SYSTEMPERL_INCLUDE","");
|
||||
if (var == "") {
|
||||
string sp_src = V3Options::getenvSYSTEMPERLGuts()+"/src";
|
||||
if (V3Options::fileStatNormal(sp_src+"/systemperl.h")) {
|
||||
var = sp_src;
|
||||
V3Os::setenvStr ("SYSTEMPERL_INCLUDE", var, "From $SYSTEMPERL/src");
|
||||
} else if (string(DEFENV_SYSTEMPERL_INCLUDE) != "") {
|
||||
// Note if SYSTEMPERL is DEFENVed, then SYSTEMPERL_INCLUDE is also DEFENVed
|
||||
// So we don't need to sweat testing DEFENV_SYSTEMPERL also
|
||||
var = DEFENV_SYSTEMPERL_INCLUDE;
|
||||
V3Os::setenvStr("SYSTEMPERL_INCLUDE", var, "Hardcoded at build time");
|
||||
}
|
||||
}
|
||||
// Only correct or check it if we really need the value
|
||||
if (v3Global.opt.usingSystemPerlLibs()) {
|
||||
// We warn about $SYSTEMPERL instead of _INCLUDE since that's more likely
|
||||
// what users will want to set.
|
||||
if (var == "") {
|
||||
v3fatal("Need $SYSTEMPERL and $SYSTEMPERL_INCLUDE in environment for --sp or --coverage\n"
|
||||
"Probably System-Perl isn't installed, see http://www.veripool.org/systemperl\n");
|
||||
}
|
||||
else if (var != "" && !V3Options::fileStatNormal(var+"/systemperl.h")) {
|
||||
v3fatal("Neither $SYSTEMPERL nor $SYSTEMPERL_INCLUDE environment vars to point to System-Perl kit: "<<var<<endl);
|
||||
}
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
string V3Options::getenvVERILATOR_ROOT() {
|
||||
string var = V3Os::getenvStr("VERILATOR_ROOT","");
|
||||
if (var == "" && string(DEFENV_VERILATOR_ROOT) != "") {
|
||||
@@ -559,8 +513,9 @@ string V3Options::version() {
|
||||
}
|
||||
|
||||
void V3Options::throwSigsegv() {
|
||||
// cppcheck-suppress nullPointer
|
||||
#if !(defined(VL_CPPCHECK) || defined(__clang_analyzer__))
|
||||
char* zp=NULL; *zp=0; // Intentional core dump, ignore warnings here
|
||||
#endif
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
@@ -682,7 +637,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||
else if ( onoff (sw, "-autoflush", flag/*ref*/) ) { m_autoflush = flag; }
|
||||
else if ( onoff (sw, "-bbox-sys", flag/*ref*/) ) { m_bboxSys = flag; }
|
||||
else if ( onoff (sw, "-bbox-unsup", flag/*ref*/) ) { m_bboxUnsup = flag; }
|
||||
else if ( !strcmp (sw, "-cc") ) { m_outFormatOk = true; m_systemC = false; m_systemPerl = false; }
|
||||
else if ( !strcmp (sw, "-cc") ) { m_outFormatOk = true; m_systemC = false; }
|
||||
else if ( onoff (sw, "-cdc", flag/*ref*/) ) { m_cdc = flag; }
|
||||
else if ( onoff (sw, "-coverage", flag/*ref*/) ) { coverage(flag); }
|
||||
else if ( onoff (sw, "-coverage-line", flag/*ref*/) ){ m_coverageLine = flag; }
|
||||
@@ -713,9 +668,8 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
|
||||
else if ( onoff (sw, "-report-unoptflat", flag/*ref*/) ) { m_reportUnoptflat = flag; }
|
||||
else if ( onoff (sw, "-relative-includes", flag/*ref*/) ) { m_relativeIncludes = flag; }
|
||||
else if ( onoff (sw, "-savable", flag/*ref*/) ) { m_savable = flag; }
|
||||
else if ( !strcmp (sw, "-sc") ) { m_outFormatOk = true; m_systemC = true; m_systemPerl = false; }
|
||||
else if ( !strcmp (sw, "-sc") ) { m_outFormatOk = true; m_systemC = true; }
|
||||
else if ( onoff (sw, "-skip-identical", flag/*ref*/) ) { m_skipIdentical = flag; }
|
||||
else if ( !strcmp (sw, "-sp-deprecated") ) { m_outFormatOk = true; m_systemC = true; m_systemPerl = true; } // Undocumented, old
|
||||
else if ( onoff (sw, "-stats", flag/*ref*/) ) { m_stats = flag; }
|
||||
else if ( onoff (sw, "-stats-vars", flag/*ref*/) ) { m_statsVars = flag; m_stats |= flag; }
|
||||
else if ( !strcmp (sw, "-sv") ) { m_defaultLanguage = V3LangCode::L1800_2005; }
|
||||
@@ -845,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];
|
||||
@@ -1178,8 +1132,6 @@ void V3Options::showVersion(bool verbose) {
|
||||
cout << " SYSTEMC_ARCH = " << DEFENV_SYSTEMC_ARCH<<endl;
|
||||
cout << " SYSTEMC_INCLUDE = " << DEFENV_SYSTEMC_INCLUDE<<endl;
|
||||
cout << " SYSTEMC_LIBDIR = " << DEFENV_SYSTEMC_LIBDIR<<endl;
|
||||
cout << " SYSTEMPERL = " << DEFENV_SYSTEMPERL<<endl;
|
||||
cout << " SYSTEMPERL_INCLUDE = " << DEFENV_SYSTEMPERL_INCLUDE<<endl;
|
||||
cout << " VERILATOR_ROOT = " << DEFENV_VERILATOR_ROOT<<endl;
|
||||
|
||||
cout <<endl;
|
||||
@@ -1189,8 +1141,6 @@ void V3Options::showVersion(bool verbose) {
|
||||
cout << " SYSTEMC_ARCH = " << V3Os::getenvStr("SYSTEMC_ARCH","")<<endl;
|
||||
cout << " SYSTEMC_INCLUDE = " << V3Os::getenvStr("SYSTEMC_INCLUDE","")<<endl;
|
||||
cout << " SYSTEMC_LIBDIR = " << V3Os::getenvStr("SYSTEMC_LIBDIR","")<<endl;
|
||||
cout << " SYSTEMPERL = " << V3Os::getenvStr("SYSTEMPERL","")<<endl;
|
||||
cout << " SYSTEMPERL_INCLUDE = " << V3Os::getenvStr("SYSTEMPERL_INCLUDE","")<<endl;
|
||||
cout << " VERILATOR_ROOT = " << V3Os::getenvStr("VERILATOR_ROOT","")<<endl;
|
||||
cout << " VERILATOR_BIN = " << V3Os::getenvStr("VERILATOR_BIN","")<<endl; // wrapper uses this
|
||||
}
|
||||
@@ -1234,7 +1184,6 @@ V3Options::V3Options() {
|
||||
m_stats = false;
|
||||
m_statsVars = false;
|
||||
m_systemC = false;
|
||||
m_systemPerl = false;
|
||||
m_trace = false;
|
||||
m_traceDups = false;
|
||||
m_traceParams = true;
|
||||
|
||||
+3
-10
@@ -93,7 +93,6 @@ class V3Options {
|
||||
bool m_savable; // main switch: --savable
|
||||
bool m_systemC; // main switch: --sc: System C instead of simple C++
|
||||
bool m_skipIdentical;// main switch: --skip-identical
|
||||
bool m_systemPerl; // main switch: --sp: System Perl instead of SystemC (m_systemC also set)
|
||||
bool m_stats; // main switch: --stats
|
||||
bool m_statsVars; // main switch: --stats-vars
|
||||
bool m_trace; // main switch: --trace
|
||||
@@ -146,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
|
||||
@@ -179,8 +178,6 @@ class V3Options {
|
||||
bool parseLangExt(const char* swp, const char* langswp, const V3LangCode& lc);
|
||||
string filePathCheckOneDir(const string& modname, const string& dirname);
|
||||
|
||||
static string getenvSYSTEMPERLGuts();
|
||||
|
||||
V3Options(const V3Options&); ///< N/A, no copy constructor
|
||||
|
||||
public:
|
||||
@@ -212,9 +209,7 @@ class V3Options {
|
||||
string bin() const { return m_bin; }
|
||||
string flags() const { return m_flags; }
|
||||
bool systemC() const { return m_systemC; }
|
||||
bool systemPerl() const { return m_systemPerl; }
|
||||
bool usingSystemCLibs() const { return !lintOnly() && (systemPerl() || systemC()); }
|
||||
bool usingSystemPerlLibs() const { return !lintOnly() && systemPerl(); }
|
||||
bool usingSystemCLibs() const { return !lintOnly() && systemC(); }
|
||||
bool savable() const { return m_savable; }
|
||||
bool skipIdentical() const { return m_skipIdentical; }
|
||||
bool stats() const { return m_stats; }
|
||||
@@ -319,7 +314,7 @@ class V3Options {
|
||||
bool oTable() const { return m_oTable; }
|
||||
|
||||
// METHODS (uses above)
|
||||
string traceClassBase() const { return systemPerl() ? "SpTraceVcd" : "VerilatedVcd"; }
|
||||
string traceClassBase() const { return "VerilatedVcd"; }
|
||||
|
||||
// METHODS (from main)
|
||||
static string version();
|
||||
@@ -339,8 +334,6 @@ class V3Options {
|
||||
static string getenvSYSTEMC_ARCH();
|
||||
static string getenvSYSTEMC_INCLUDE();
|
||||
static string getenvSYSTEMC_LIBDIR();
|
||||
static string getenvSYSTEMPERL();
|
||||
static string getenvSYSTEMPERL_INCLUDE();
|
||||
static string getenvVERILATOR_ROOT();
|
||||
|
||||
// METHODS (file utilities using these options)
|
||||
|
||||
+5
-47
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
+15
-11
@@ -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;
|
||||
@@ -1188,6 +1190,7 @@ int V3PreProcImp::getStateToken() {
|
||||
}
|
||||
else if (tok==VP_EOF) {
|
||||
error("`\" not terminated at EOF\n");
|
||||
break;
|
||||
}
|
||||
else if (tok==VP_BACKQUOTE) {
|
||||
m_strify += "\\\"";
|
||||
@@ -1262,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);
|
||||
@@ -1307,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);
|
||||
|
||||
+2
-2
@@ -90,8 +90,8 @@ public:
|
||||
virtual string removeDefines(const string& text)=0; // Remove defines in a text string
|
||||
|
||||
// UTILITIES
|
||||
void error(string msg) { fileline()->v3error(msg); } ///< Report a error
|
||||
void fatal(string msg) { fileline()->v3fatalSrc(msg); } ///< Report a fatal error
|
||||
void error(const string& msg) { fileline()->v3error(msg); } ///< Report a error
|
||||
void fatal(const string& msg) { fileline()->v3fatalSrc(msg); } ///< Report a fatal error
|
||||
|
||||
protected:
|
||||
// CONSTUCTORS
|
||||
|
||||
+24
-8
@@ -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);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user