Compare commits

...
61 Commits
Author SHA1 Message Date
Wilson Snyder 0a1b55c296 Version bump 2015-11-01 08:18:54 -05:00
Wilson Snyder 14b8efe4bb Version bump 2015-11-01 08:14:44 -05:00
Wilson Snyder 64162efebd Fix commit 379bfd06, crash in commandArgsPlusMatch 2015-11-01 08:14:18 -05:00
Wilson Snyder faf5e1de51 Internals: Remove some unneeded c_str() calls. No functional change. 2015-10-29 22:19:51 -04:00
Wilson Snyder 0d7b1a7dc7 Remove VlCovCvtToCStr to avoid scary scope issues. 2015-10-29 21:58:00 -04:00
Wilson Snyder fa63bc6b78 Fix error message on missing interface, bug985. 2015-10-29 21:44:02 -04:00
Wilson Snyder 379bfd062f Fix crash in commandArgsPlusMatch, bug987. 2015-10-29 21:07:49 -04:00
Jamey Hicks 49108c23f0 Support with non-format arguments, bug467.
Signed-off-by: Wilson Snyder <[email protected]>
2015-10-27 20:58:31 -04:00
Wilson Snyder 4475060268 Ignore %l in , bug983. 2015-10-27 20:37:52 -04:00
Wilson Snyder 4f269e336d With --bbox-ignore, don't warn about always order. 2015-10-24 07:24:53 -04:00
Wilson Snyder 4464b13163 Fix dot indexing into arrayed inferfaces, bug978. 2015-10-23 23:06:24 -04:00
Wilson Snyder 215d5f68b0 Fix struct.enum.name method calls, bug855. 2015-10-23 22:57:15 -04:00
Wilson Snyder 281f4e04ee Fix $fwrite to constant stderr/stdout, bug961. 2015-10-23 21:53:16 -04:00
Wilson Snyder 17a3f9691d Fix package:scope.scope variable references. 2015-10-23 21:03:35 -04:00
Wilson Snyder 4fde6ee7af Support elaboration assertions, bug973. 2015-10-23 18:13:25 -04:00
Wilson Snyder 040b1b06d5 Support genvar indexes into arrayed cells, bug517. 2015-10-22 20:13:49 -04:00
Wilson Snyder b16ea8b719 Tests: With --benchmark, don't time directory change. 2015-10-21 06:54:03 -04:00
Wilson Snyder cc22847bc3 For --xml, decrease block indent to 2 spaces. 2015-10-20 21:22:00 -04:00
Johan Bjork 3702e17b2e Backout bug978 fix as is incomplete.
Signed-off-by: Wilson Snyder <[email protected]>
2015-10-10 07:54:45 -04:00
Wilson Snyder 7abc220fb3 Fix C++ 2014 compile warnings. No functional change. 2015-10-04 13:41:45 -04:00
Wilson Snyder 4fc9a906f6 Internals: Fix cppcheck warnings; add VL_DANGLING. No functional change. 2015-10-04 13:16:35 -04:00
Wilson Snyder 5de83c9805 Internals: Fix cppcheck warnings. No functional change. 2015-10-04 13:11:32 -04:00
Johan Bjork f71d904a9b Fix internal error on interface array, bug978.
Signed-off-by: Wilson Snyder <[email protected]>
2015-10-04 11:17:58 -04:00
Wilson Snyder 318ded4198 Internals: Cleanup cppcheck warnings. 2015-10-03 22:33:06 -04:00
Wilson Snyder f1874b211f Support , bug977. 2015-10-03 07:12:56 -04:00
Wilson Snyder c60ffd7fd9 Fix enum constant propagation, bug970. 2015-10-01 21:15:01 -04:00
Todd Strader dc57282168 Internal: Fix setBit from earlier commit, bug971.
Signed-off-by: Wilson Snyder <[email protected]>
2015-09-30 07:02:39 -04:00
Todd Strader 3c336e179f Fix structure parameter constant propagation, bug968.
Signed-off-by: Wilson Snyder <[email protected]>
2015-09-29 21:02:33 -04:00
Todd Strader 6bda57da5d Internals: Fix setBit not clearing X mask.
Signed-off-by: Wilson Snyder <[email protected]>
2015-09-29 20:59:17 -04:00
Wilson Snyder 9a16001e51 Add --vpi flag, and fix VPI linkage, bug969. 2015-09-25 22:57:28 -04:00
Todd Strader 34870e899f Add VerilatedScopeNameMap for introspection, bug966.
Signed-off-by: Wilson Snyder <[email protected]>
2015-09-24 21:08:58 -04:00
Wilson Snyder d0653f72e2 Fix very long module names, bug937. 2015-09-19 20:12:35 -04:00
Wilson Snyder 64748b7b1d Internals: Replace FNV hashes with SHA1 2015-09-19 18:49:54 -04:00
Wilson Snyder 7163c8d048 Fix internal error on dotted refs into generates, bug958. 2015-09-18 20:57:27 -04:00
Wilson Snyder d0ec991bb2 Fix mis-optimizing public DPI functions, bug963. 2015-09-18 19:06:15 -04:00
Wilson Snyder d458af4454 Commentary, bug965. 2015-09-11 20:18:41 -04:00
Wilson Snyder 9e9e7c33ae Install commentary, msg1678. 2015-09-03 21:20:19 -04:00
Wilson Snyder ce7de5ed30 Commentary, bug951 2015-08-16 11:48:05 -04:00
Wilson Snyder 776d8edf52 devel release 2015-08-12 21:42:08 -04:00
Wilson Snyder 5f21385e41 Version bump - commentary fix 2015-08-12 21:40:55 -04:00
Wilson Snyder 94fed93f54 Version bump 2015-08-12 21:34:59 -04:00
Wilson Snyder a950e4816d Support extraction of enum bits, bug951. 2015-08-12 21:33:40 -04:00
Wilson Snyder c87c66efb1 Fix size casts as second argument of cast item, bug950. 2015-08-12 19:37:25 -04:00
Jie Xu 5a5a0006fe Fix parameters with function parameter arguments, bug952.
Signed-off-by: Wilson Snyder <[email protected]>
2015-08-12 19:29:06 -04:00
Wilson Snyder 60b48a6830 Fix coverage documentation, bug954. 2015-08-12 19:18:58 -04:00
Wilson Snyder 5e41350588 Fix makefile with --coverage, bug953. 2015-08-12 19:06:15 -04:00
Wilson Snyder ff9f5b62ac bug951 testcase 2015-08-12 08:36:23 -04:00
Wilson Snyder 882913f0ca Add tracing_on, etc to vlt files, bug932. 2015-07-22 20:14:58 -04:00
Wilson Snyder 2062f7e97b Fix hashed error with typedef inside block, bug948. 2015-07-22 19:52:11 -04:00
Wilson Snyder 445c83a60d Fix with SV string, bug947. 2015-07-21 18:36:27 -04:00
Wilson Snyder 1891cfd79a Fix rounding in trace , bug946. 2015-07-21 13:22:08 -04:00
Wilson Snyder 06d5a7b2bf Internals: Allow hashing nulls; misc cleanup 2015-07-06 19:37:20 -04:00
Wilson Snyder 5af8a8aa4c Internals: Hash nulls 2015-07-05 20:31:30 -04:00
Wilson Snyder dc6b085d8b Fix MinGW compiler error, bug927. 2015-06-21 21:01:02 -04:00
Wilson Snyder 00759f777e Fix dpi imports inside generates. 2015-06-16 19:27:18 -04:00
Wilson Snyder 95ac0e61b2 Fix MinGW compiler error, bug927. 2015-06-16 07:13:45 -04:00
Wilson Snyder 6c5884853f Fix string-to-int space conversion, bug931. 2015-06-12 07:28:44 -04:00
Wilson Snyder 7578ef889f Fix .c files to be treated as .cpp, bug930. 2015-06-09 07:28:51 -04:00
Wilson Snyder da254af8d5 Fix MinGW compiler error, bug929. 2015-06-08 07:24:04 -04:00
Wilson Snyder 98123dc422 Verison fix 2015-06-06 14:02:06 -04:00
Wilson Snyder 466909b3d9 devel release 2015-06-06 14:00:23 -04:00
190 changed files with 4319 additions and 1939 deletions
+69 -1
View File
@@ -3,7 +3,75 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. [by ...]
indicates the contributor was also the author of the fix; Thanks!
* Verilator 3.873 2015-06-06
* Verilator 3.878 2015-11-01
** Add --vpi flag, and fix VPI linkage, bug969. [Arthur Kahlich]
** Support genvar indexes into arrayed cells, bug517. [Todd Strader]
** Support $sformatf, bug977. [Johan Bjork]
*** Support elaboration assertions, bug973. [Johan Bjork]
*** Support $display with non-format arguments, bug467. [Jamey Hicks]
**** Add VerilatedScopeNameMap for introspection, bug966. [Todd Strader]
**** Ignore %l in $display, bug983. [Todd Strader]
**** Fix very long module names, bug937. [Todd Strader]
**** Fix internal error on dotted refs into generates, bug958. [Jie Xu]
**** Fix structure parameter constant propagation, bug968. [Todd Strader]
**** Fix enum constant propagation, bug970. [Todd Strader]
**** Fix mis-optimizing public DPI functions, bug963. [Wei Song]
**** Fix package:scope.scope variable references.
**** Fix $fwrite to constant stderr/stdout, bug961. [Wei Song]
**** Fix struct.enum.name method calls, bug855. [Jonathon Donaldson]
**** Fix dot indexing into arrayed inferfaces, bug978. [Johan Bjork]
**** Fix crash in commandArgsPlusMatch, bug987. [Jamie Iles]
**** Fix error message on missing interface, bug985. [Todd Strader]
* Verilator 3.876 2015-08-12
*** Add tracing_on, etc to vlt files, bug932. [Frederic Requin]
**** Support extraction of enum bits, bug951. [Jonathon Donaldson]
**** Fix MinGW compiler error, bug927, bug929. [Hans Tichelaar]
**** Fix .c files to be treated as .cpp, bug930. [Jonathon Donaldson]
**** Fix string-to-int space conversion, bug931. [Fabrizio Ferrandi]
**** Fix dpi imports inside generates. [Michael Tresidder]
**** Fix rounding in trace $timescale, bug946. [Frederic Requin]
**** Fix $fopen with SV string, bug947. [Sven Stucki]
**** Fix hashed error with typedef inside block, bug948. [Sven Stucki]
**** Fix makefile with --coverage, bug953. [Eivind Liland]
**** Fix coverage documentation, bug954. [Thomas J Whatson]
**** Fix parameters with function parameter arguments, bug952. [Jie Xu]
**** Fix size casts as second argument of cast item, bug950. [Jonathon Donaldson]
* Verilator 3.874 2015-06-06
*** Add pkg-config .pc file, bug919. [Stefan Wallentowitz]
+2 -1
View File
@@ -117,9 +117,10 @@ and add it to path using Modules/modulecmd:
After installing you'll want a module file like the following:
set install_root /CAD_DISK/verilator/{version-number-used-above}
setenv VERILATOR_ROOT $install_root
unsetenv VERILATOR_ROOT
prepend-path PATH $install_root/bin
prepend-path MANPATH $install_root/man
prepend-path PKG_CONFIG_PATH $install_root/share/pkgconfig
=item 3.
+79 -37
View File
@@ -331,6 +331,7 @@ descriptions in the next sections for more information.
-v <filename> Verilog library
+verilog1995ext+<ext> Synonym for +1364-1995ext+<ext>
+verilog2001ext+<ext> Synonym for +1364-2001ext+<ext>
--vpi Enable VPI compiles
-Werror-<message> Convert warning to error
-Wfuture-<message> Disable unknown message warnings
-Wno-<message> Disable warning
@@ -471,7 +472,7 @@ Verilator will mark the signal as clocker and propagate the clocker attribute
automatically to other signals derived from that. In this way, Verilator will
try to avoid taking the clocker signal into checking list.
Note signal-name is specified by the RTL hiearchy path. For example, v.foo.bar.
Note signal-name is specified by the RTL hierarchy path. For example, v.foo.bar.
If the signal is the input to top-module, the directly the signal name. If you
find it difficult to find the exact name, try to use C</*verilator clocker*/> in
RTL file to mark the signal directly.
@@ -1103,6 +1104,10 @@ Note -v is fairly standard across Verilog tools.
Synonyms for C<+1364-1995ext+>I<ext> and C<+1364-2001ext+>I<ext> respectively
=item --vpi
Enable use of VPI and linking against the verilated_vpi.cpp files.
=item -Wall
Enable all warnings, including code style warnings that are normally
@@ -1802,6 +1807,8 @@ Verilator supports a very limited subset of the VPI. This subset allows
inspection, examination, value change callbacks, and depositing of values
to public signals only.
VPI is enabled with the verilator --vpi switch.
To access signals via the VPI, Verilator must be told exactly which signals
are to be accessed. This is done using the Verilator public pragmas
documented below.
@@ -1835,17 +1842,28 @@ changed on the specified clock edge.
There are many online tutorials and books on the VPI, but an example that
accesses the above would be:
void read_and_check() {
vpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)"t.readme", NULL);
if (!vh1) { error... }
const char* name = vpi_get_str(vpiName, vh1);
printf("Module name: %s\n"); // Prints "readme"
void read_and_check() {
vpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)"t.readme", NULL);
if (!vh1) { error... }
const char* name = vpi_get_str(vpiName, vh1);
printf("Module name: %s\n"); // Prints "readme"
s_vpi_value v;
v.format = vpiIntVal;
vpi_get_value(vh1, &v);
printf("Value of v: %d\n", v.value.integer); // Prints "readme"
}
s_vpi_value v;
v.format = vpiIntVal;
vpi_get_value(vh1, &v);
printf("Value of v: %d\n", v.value.integer); // Prints "readme"
}
For signal callbacks to work the main loop of the program must call
VerilatedVpi::callValueCbs().
#include "verilated_vpi.h" // Required to get definitions
...
while (time passes) {
...
topp->eval();
VerilatedVpi::callValueCbs();
}
=head1 CROSS COMPILATION
@@ -1923,30 +1941,40 @@ The grammar of configuration commands is as follows:
Take remaining text up the the next `verilog mode switch and treat it as
Verilator configuration commands.
=item coverage_on [-file "<filename>" [-lines <line> [ - <line> ]]]
=item coverage_off [-file "<filename>" [-lines <line> [ - <line> ]]]
Disable coverage for the specified filename (or wildcard with '*' or '?',
or all files if omitted) and range of line numbers (or all lines if
Enable/disable coverage for the specified filename (or wildcard with '*' or
'?', or all files if omitted) and range of line numbers (or all lines if
omitted). Often used to ignore an entire module for coverage analysis
purposes.
=item lint_on [-msg <message>] [-file "<filename>" [-lines <line> [ - <line>]]]
=item lint_off [-msg <message>] [-file "<filename>" [-lines <line> [ - <line>]]]
Disables the specified lint warning, in the specified filename (or wildcard
with '*' or '?', or all files if omitted) and range of line numbers (or all
lines if omitted).
Enable/disables the specified lint warning, in the specified filename (or
wildcard with '*' or '?', or all files if omitted) and range of line
numbers (or all lines if omitted).
Using '*' will override any lint_on directives in the source, i.e. the
warning will still not be printed.
With lint_off using '*' will override any lint_on directives in the source,
i.e. the warning will still not be printed.
If the -msg is omitted, all lint warnings are disabled. This will override
all later lint warning enables for the specified region.
If the -msg is omitted, all lint warnings are enabled/disabled. This will
override all later lint warning enables for the specified region.
=item tracing_on [-file "<filename>" [-lines <line> [ - <line> ]]]
=item tracing_off [-file "<filename>" [-lines <line> [ - <line> ]]]
Disable waveform tracing for all future signals declared in the specified
filename (or wildcard with '*' or '?', or all files if omitted) and range
of line numbers (or all lines if omitted).
Enable/disable waveform tracing for all future signals declared in the
specified filename (or wildcard with '*' or '?', or all files if omitted)
and range of line numbers (or all lines if omitted).
For tracing_off, cells below any module in the files/ranges specified will
also not be traced.
=back
@@ -2075,45 +2103,52 @@ per the C standard (it's unspecified in Verilog).
=item `coverage_block_off
Specifies the entire begin/end block should be ignored for coverage analysis.
Specifies the entire begin/end block should be ignored for coverage
analysis. Must be inside a basic block, e.g. within a begin/end pair.
Same as /* verilator coverage_block_off */.
=item `systemc_header
Take remaining text up to the next `verilog or `systemc_... mode switch and
place it verbatim into the output .h file's header. Despite the name of this
macro, this also works in pure C++ code.
place it verbatim into the output .h file's header. Must be placed as a
module item, e.g. directly inside a module/endmodule pair. Despite the name
of this macro, this also works in pure C++ code.
=item `systemc_ctor
Take remaining text up to the next `verilog or `systemc_... mode switch and
place it verbatim into the C++ class constructor. Despite the name of this
macro, this also works in pure C++ code.
place it verbatim into the C++ class constructor. Must be placed as a
module item, e.g. directly inside a module/endmodule pair. Despite the name
of this macro, this also works in pure C++ code.
=item `systemc_dtor
Take remaining text up to the next `verilog or `systemc_... mode switch and
place it verbatim into the C++ class destructor. Despite the name of this
macro, this also works in pure C++ code.
place it verbatim into the C++ class destructor. Must be placed as a
module item, e.g. directly inside a module/endmodule pair. Despite the name
of this macro, this also works in pure C++ code.
=item `systemc_interface
Take remaining text up to the next `verilog or `systemc_... mode switch and
place it verbatim into the C++ class interface. Despite the name of this
macro, this also works in pure C++ code.
place it verbatim into the C++ class interface. Must be placed as a module
item, e.g. directly inside a module/endmodule pair. Despite the name of
this macro, this also works in pure C++ code.
=item `systemc_imp_header
Take remaining text up to the next `verilog or `systemc_... mode switch and
place it verbatim into the header of all files for this C++ class
implementation. Despite the name of this macro, this also works in pure
C++ code.
implementation. Must be placed as a module item, e.g. directly inside a
module/endmodule pair. Despite the name of this macro, this also works in
pure C++ code.
=item `systemc_implementation
Take remaining text up to the next `verilog or `systemc_... mode switch and
place it verbatim into a single file of the C++ class implementation.
Despite the name of this macro, this also works in pure C++ code.
place it verbatim into a single file of the C++ class implementation. Must
be placed as a module item, e.g. directly inside a module/endmodule
pair. Despite the name of this macro, this also works in pure C++ code.
If you will be reading or writing any Verilog variables in the C++
functions, the Verilog signals must be declared with /*verilator public*/.
@@ -3305,6 +3340,10 @@ with "unused" in the name, or put the appropriate lint_off around the wire.
Having unused signals in one place makes it easy to find what is unused,
and reduces the number of lint_off pragmas, reducing bugs.
=item USERINFO, USERWARN, USERERROR, USERFATAL
A SystemVerilog elaboration-time assertion print was executed.
=item VARHIDDEN
Warns that a task, function, or begin/end block is declaring a variable by
@@ -3563,7 +3602,10 @@ First, run verilator with the --coverage option. If you're using your own
makefile, compile the model with the GCC flag -DVM_COVERAGE (if using
Verilator's, it will do this for you.)
Run your tests in different directories. Each test will create a
At the end of your test, call VerilatedCov::write passing the name of the
coverage data file (typically "logs/coverage.dat").
Run each of your tests in different directories. Each test will create a
logs/coverage.pl file.
After running all of your tests, verilator_coverage is executed.
+3 -1
View File
@@ -6,7 +6,9 @@
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
#AC_INIT([Verilator],[#.### devel])
AC_INIT([Verilator],[3.874 2015-06-06])
AC_INIT([Verilator],[3.878 2015-11-01])
# When releasing, also update header of Changes file
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)
+17 -3
View File
@@ -708,8 +708,8 @@ void _VL_VINT_TO_STRING(int obits, char* destoutp, WDataInP sourcep) {
start = false; // Drop leading 0s
}
}
*destp++ = '\0'; // Terminate
while (isspace(*(destp-1)) && destp>destoutp) *--destp = '\0'; // Drop trailing spaces
*destp = '\0'; // Terminate
if (!start) while (isspace(*(destp-1)) && destp>destoutp) *--destp = '\0'; // Drop trailing spaces
}
void _VL_STRING_TO_VINT(int obits, void* destp, int srclen, const char* srcp) {
@@ -750,6 +750,11 @@ IData VL_FGETS_IXI(int obits, void* destp, IData fpi) {
return got;
}
IData VL_FOPEN_NI(const string& filename, IData mode) {
char modez[5];
_VL_VINT_TO_STRING(VL_WORDSIZE, modez, &mode);
return VL_FOPEN_S(filename.c_str(), modez);
}
IData VL_FOPEN_QI(QData filename, IData mode) {
IData fnw[2]; VL_SET_WQ(fnw, filename);
return VL_FOPEN_WI(2, fnw, mode);
@@ -1146,7 +1151,12 @@ void Verilated::commandArgs(int argc, const char** argv) {
}
const char* Verilated::commandArgsPlusMatch(const char* prefixp) {
return VerilatedImp::argPlusMatch(prefixp).c_str();
const 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);
outstr[VL_VALUE_STRING_MAX_WIDTH-1] = '\0';
return outstr;
}
void Verilated::internalsDump() {
@@ -1165,6 +1175,10 @@ int Verilated::exportFuncNum(const char* namep) {
return VerilatedImp::exportFind(namep);
}
const VerilatedScopeNameMap* Verilated::scopeNameMap() {
return VerilatedImp::scopeNameMap();
}
//===========================================================================
// VerilatedModule:: Methods
+7 -2
View File
@@ -38,6 +38,7 @@
#include <cstring>
#include <cmath>
// <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;
@@ -68,6 +69,7 @@ typedef void (*VerilatedVoidCb)(void);
class SpTraceVcd;
class SpTraceVcdCFile;
class VerilatedScopeNameMap;
class VerilatedVar;
class VerilatedVarNameMap;
class VerilatedVcd;
@@ -102,9 +104,9 @@ class VerilatedModule {
private:
const char* m_namep; ///< Module name
VerilatedModule(); ///< N/A, always use named constructor below
VerilatedModule(const VerilatedModule& ); ///< N/A, no copying modules
VerilatedModule(const VerilatedModule& ); ///< N/A, no copy constructor
public:
VerilatedModule(const char* namep); ///< Create module with given hierarchy name
explicit VerilatedModule(const char* namep); ///< Create module with given hierarchy name
~VerilatedModule();
const char* name() const { return m_namep; } ///< Return name of module
};
@@ -287,6 +289,7 @@ public:
static void commandArgs(int argc, const char** argv);
static void commandArgs(int argc, char** argv) { commandArgs(argc,(const char**)argv); }
static CommandArgValues* getCommandArgs() {return &s_args;}
/// Match plusargs with a given prefix. Returns static char* valid only for a single call
static const char* commandArgsPlusMatch(const char* prefixp);
/// Produce name & version for (at least) VPI
@@ -308,6 +311,7 @@ public:
static const char* catName(const char* n1, const char* n2); // Returns new'ed data
// Internal: Find scope
static const VerilatedScope* scopeFind(const char* namep);
static const VerilatedScopeNameMap* scopeNameMap();
// Internal: Get and set DPI context
static const VerilatedScope* dpiScope() { return t_dpiScopep; }
static void dpiScope(const VerilatedScope* scopep) { t_dpiScopep=scopep; }
@@ -357,6 +361,7 @@ extern IData VL_FOPEN_WI(int fnwords, WDataInP ofilename, IData mode);
extern IData VL_FOPEN_QI(QData ofilename, IData mode);
inline IData VL_FOPEN_II(IData ofilename, IData mode) { return VL_FOPEN_QI(ofilename,mode); }
extern void VL_FCLOSE_I(IData fdi);
extern void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
-4
View File
@@ -120,10 +120,6 @@ ifeq ($(VM_SP),1)
$(SP_PREPROC) -M sp_preproc.d --tree $(VM_PREFIX).sp_tree \
--preproc $(VK_CLASSES_SP)
else
ifeq ($(VM_COVERAGE),1)
CPPFLAGS += -I$(SYSTEMPERL_INCLUDE)
VPATH += $(SYSTEMPERL_INCLUDE)
endif
preproc:
endif
+6 -3
View File
@@ -75,6 +75,7 @@ public:
virtual vluint64_t count() const { return *m_countp; }
virtual void zero() const { *m_countp = 0; }
// CONSTRUCTORS
// cppcheck-suppress noExplicitConstructor
VerilatedCoverItemSpec(T* countp) : m_countp(countp) { zero(); }
virtual ~VerilatedCoverItemSpec() {}
};
@@ -261,8 +262,8 @@ public:
assert(m_insertp);
// First two key/vals are filename
ckeyps[0]="filename"; valps[0]=m_insertFilenamep;
VlCovCvtToCStr linestrp (m_insertLineno);
ckeyps[1]="lineno"; valps[1]=linestrp;
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;
@@ -440,8 +441,10 @@ 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);
_insertp(C(0),C(1),
key2,VlCovCvtToCStr(val2), key3,VlCovCvtToCStr(val3), key4, val4.c_str(),
key2,val2str.c_str(), key3,val3str.c_str(), key4, val4.c_str(),
C(5),C(6),N(7),N(8),N(9),
N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19),
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
-13
View File
@@ -78,19 +78,6 @@ template< class T> std::string vlCovCvtToStr (const T& t) {
ostringstream os; os<<t; return os.str();
}
/// Usage: something(VlCovCvtToCStr(i))
/// Note the pointer will only be valid for as long as the object remains
/// in scope!
struct VlCovCvtToCStr {
string m_str;
// Casters
template< class T> VlCovCvtToCStr (const T& t) {
ostringstream os; os<<t; m_str=os.str();
}
~VlCovCvtToCStr() {}
operator const char* () const { return m_str.c_str(); };
};
//=============================================================================
// VerilatedCov
/// Verilator coverage global class
+1
View File
@@ -60,6 +60,7 @@ inline string VL_REPLICATEN_NNI(int obits,int lbits,int rbits, const string& lhs
return VL_REPLICATEN_NNQ(obits,lbits,rbits,lhs,rep);
}
extern IData VL_FOPEN_NI(const string& filename, IData mode);
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, ...);
+8 -6
View File
@@ -49,7 +49,6 @@ class VerilatedImp {
// TYPES
typedef vector<string> ArgVec;
typedef map<pair<const void*,void*>,void*> UserMap;
typedef map<const char*, const VerilatedScope*, VerilatedCStrCmp> ScopeNameMap;
typedef map<const char*, int, VerilatedCStrCmp> ExportNameMap;
// MEMBERS
@@ -60,7 +59,7 @@ class VerilatedImp {
ArgVec m_argVec; ///< Argument list (NOT save-restored, may want different results)
bool m_argVecLoaded; ///< Ever loaded argument list
UserMap m_userMap; ///< Map of <(scope,userkey), userData>
ScopeNameMap m_nameMap; ///< Map of <scope_name, scope pointer>
VerilatedScopeNameMap m_nameMap; ///< Map of <scope_name, scope pointer>
// Slow - somewhat static:
ExportNameMap m_exportMap; ///< Map of <export_func_proto, func number>
int m_exportNext; ///< Next export funcnum
@@ -154,30 +153,33 @@ public: // But only for verilated*.cpp
// METHODS - scope name
static void scopeInsert(const VerilatedScope* scopep) {
// Slow ok - called once/scope at construction
ScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
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));
}
}
static inline const VerilatedScope* scopeFind(const char* namep) {
ScopeNameMap::iterator it=s_s.m_nameMap.find(namep);
VerilatedScopeNameMap::iterator it=s_s.m_nameMap.find(namep);
if (VL_LIKELY(it != s_s.m_nameMap.end())) return it->second;
else return NULL;
}
static void scopeErase(const VerilatedScope* scopep) {
// Slow ok - called once/scope at destruction
userEraseScope(scopep);
ScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
VerilatedScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
if (it != s_s.m_nameMap.end()) s_s.m_nameMap.erase(it);
}
static void scopesDump() {
VL_PRINTF(" scopesDump:\n");
for (ScopeNameMap::iterator it=s_s.m_nameMap.begin(); it!=s_s.m_nameMap.end(); ++it) {
for (VerilatedScopeNameMap::iterator it=s_s.m_nameMap.begin(); it!=s_s.m_nameMap.end(); ++it) {
const VerilatedScope* scopep = it->second;
scopep->scopeDump();
}
VL_PRINTF("\n");
}
static const VerilatedScopeNameMap* scopeNameMap() {
return &s_s.m_nameMap;
}
public: // But only for verilated*.cpp
// METHODS - export names
+3 -1
View File
@@ -48,6 +48,8 @@ protected:
m_bufp = new vluint8_t [bufferSize()];
m_cp = m_bufp;
}
private:
VerilatedSerialBase(const VerilatedSerialBase& ); ///< N/A, no copy constructor
public:
// CREATORS
virtual ~VerilatedSerialBase() {
@@ -223,7 +225,7 @@ inline VerilatedSerialize& operator<<(VerilatedSerialize& os, string& rhs) {
return os.write(rhs.data(), len);
}
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, string& rhs) {
vluint32_t len;
vluint32_t len=0;
os>>len;
rhs.resize(len);
return os.read((void*)rhs.data(), len);
+14 -10
View File
@@ -32,16 +32,6 @@
#include <map>
//======================================================================
// Types
struct VerilatedCStrCmp {
/// Ordering maps keyed by const char*'s
bool operator() (const char *a, const char *b) const {
return std::strcmp(a, b) < 0;
}
};
//===========================================================================
/// Verilator range
@@ -93,6 +83,20 @@ public:
//======================================================================
/// Types
struct VerilatedCStrCmp {
/// Ordering maps keyed by const char*'s
bool operator() (const char *a, const char *b) const {
return std::strcmp(a, b) < 0;
}
};
class VerilatedScopeNameMap
: public map<const char*, const VerilatedScope*, VerilatedCStrCmp> {
public:
VerilatedScopeNameMap() {}
~VerilatedScopeNameMap() {}
};
class VerilatedVarNameMap : public map<const char*, VerilatedVar, VerilatedCStrCmp> {
public:
VerilatedVarNameMap() {}
+1 -1
View File
@@ -378,7 +378,7 @@ string VerilatedVcd::doubleToTimescale (double value) {
else if (value>=1e-12) { suffixp="ps"; value *= 1e12; }
else if (value>=1e-15) { suffixp="fs"; value *= 1e15; }
else if (value>=1e-18) { suffixp="as"; value *= 1e18; }
char valuestr[100]; sprintf(valuestr,"%d%s",(int)(value), suffixp);
char valuestr[100]; sprintf(valuestr,"%3.0f%s", value, suffixp);
return valuestr; // Gets converted to string, so no ref to stack
}
+4 -2
View File
@@ -144,13 +144,15 @@ private:
return out + ((char)((code)%94+33));
}
VerilatedVcd(const VerilatedVcd& ); ///< N/A, no copy constructor
protected:
// METHODS
void evcd(bool flag) { m_evcd = flag; }
public:
// CREATORS
VerilatedVcd(VerilatedVcdFile* filep=NULL);
explicit VerilatedVcd(VerilatedVcdFile* filep=NULL);
~VerilatedVcd();
// ACCESSORS
@@ -399,7 +401,7 @@ class VerilatedVcdC {
VerilatedVcd m_sptrace; ///< Trace file being created
public:
// CONSTRUCTORS
VerilatedVcdC(VerilatedVcdFile* filep=NULL) : m_sptrace(filep) {}
explicit VerilatedVcdC(VerilatedVcdFile* filep=NULL) : m_sptrace(filep) {}
~VerilatedVcdC() {}
// ACCESSORS
/// Is file open?
+3
View File
@@ -30,6 +30,7 @@
//--------------------------------------------------
#if (SYSTEMC_VERSION>=20050714)
// SystemC 2.1.v1
// cppcheck-suppress unusedFunction
void VerilatedVcdSc::write_comment (const std::string &) {}
void VerilatedVcdSc::trace (const unsigned int &, const std::string &, const char **) {}
@@ -74,6 +75,7 @@ void VerilatedVcdSc::trace (const unsigned int &, const std::string &, const cha
//--------------------------------------------------
#elif (SYSTEMC_VERSION>20011000)
// SystemC 2.0.1
// cppcheck-suppress unusedFunction
void VerilatedVcdSc::write_comment (const sc_string &) {}
void VerilatedVcdSc::trace (const unsigned int &, const sc_string &, const char **) {}
@@ -116,6 +118,7 @@ void VerilatedVcdSc::trace (const unsigned int &, const sc_string &, const char
//--------------------------------------------------
#else
// SystemC 1.2.1beta
// cppcheck-suppress unusedFunction
void VerilatedVcdSc::write_comment (const sc_string &) {}
void VerilatedVcdSc::trace (const unsigned int &, const sc_string &, const char **) {}
File diff suppressed because it is too large Load Diff
+17 -993
View File
File diff suppressed because it is too large Load Diff
+14 -12
View File
@@ -95,6 +95,12 @@
// 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
# 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
#endif
//=========================================================================
// C++-2011
@@ -207,19 +213,15 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
# endif
#endif
#ifdef _WIN32
# define VL_VSNPRINTF vl_vsnprintf
inline int vl_vsnprintf(char* str, size_t size, const char* format, va_list ap) {
int count = -1;
if (size != 0) {
count = _vsnprintf_s(str, size, _TRUNCATE, format, ap);
}
if (count == -1) {
count = _vscprintf(format, ap);
}
return count;
}
#if defined(_WIN32) && defined(_MSC_VER)
# if (_MSC_VER < 1900)
# define VL_SNPRINTF _snprintf
# else
# define VL_SNPRINTF snprintf
# endif
# define VL_VSNPRINTF vsnprintf
#else
# define VL_SNPRINTF snprintf
# define VL_VSNPRINTF vsnprintf
#endif
+9 -9
View File
@@ -83,7 +83,7 @@ private:
}
virtual void visit(AstSenTree* nodep, AstNUser*) {
// Simplify sensitivity list
V3Const::constifyExpensiveEdit(nodep); nodep=NULL;
V3Const::constifyExpensiveEdit(nodep); VL_DANGLING(nodep);
}
// Empty visitors, speed things up
virtual void visit(AstNodeStmt* nodep, AstNUser*) { }
@@ -184,7 +184,7 @@ private:
nodep->lhsp()->unlinkFrBack(),
nodep->rhsp()->unlinkFrBack());
nodep->replaceWith(newp);
nodep->deleteTree(); nodep = NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
}
virtual void visit(AstAssign* nodep, AstNUser*) {
@@ -288,7 +288,7 @@ private:
// Relink to CFUNC for the final
UINFO(4," FINAL "<<nodep<<endl);
if (!nodep->bodysp()) { // Empty, Kill it.
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
return;
}
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_INITIAL);
@@ -304,7 +304,7 @@ private:
nodep->unlinkFrBack();
m_scopeFinalp->addStmtsp(new AstComment(nodep->fileline(), nodep->typeName()));
m_scopeFinalp->addStmtsp(nodep->bodysp()->unlinkFrBackWithNext());
nodep->deleteTree(); nodep = NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
// METHODS
@@ -316,7 +316,7 @@ private:
&& oldsensesp->sensesp()->castSenItem()->isNever()) {
// Never executing. Kill it.
if (oldsensesp->sensesp()->nextp()) nodep->v3fatalSrc("Never senitem should be alone, else the never should be eliminated.");
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
return;
}
@@ -351,7 +351,7 @@ private:
// Delete sensitivity list
if (oldsensesp) {
oldsensesp->unlinkFrBackWithNext()->deleteTree(); oldsensesp=NULL;
oldsensesp->unlinkFrBackWithNext()->deleteTree(); VL_DANGLING(oldsensesp);
}
// Move node to new active
@@ -377,7 +377,7 @@ private:
if (!nodep->bodysp()) {
// Empty always. Kill it.
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
return;
}
visitAlways(nodep, nodep->sensesp(), nodep->keyword());
@@ -402,7 +402,7 @@ private:
m_itemCombo = true;
// Delete the sensitivity
// We'll add it as a generic COMBO SenItem in a moment.
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
} else if (nodep->varrefp()) {
// V3LinkResolve should have cleaned most of these up
if (!nodep->varrefp()->width1()) nodep->v3error("Unsupported: Non-single bit wide signal pos/negedge sensitivity: "
@@ -421,7 +421,7 @@ private:
}
public:
// CONSTUCTORS
ActiveVisitor(AstNetlist* nodep) {
explicit ActiveVisitor(AstNetlist* nodep) {
m_scopeFinalp = NULL;
m_itemCombo = false;
m_itemSequent = false;
+2 -2
View File
@@ -87,7 +87,7 @@ private:
&& sensesp->sensesp()->castSenItem()->isNever()) {
// Never executing. Kill it.
if (sensesp->sensesp()->nextp()) nodep->v3fatalSrc("Never senitem should be alone, else the never should be eliminated.");
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
return;
}
// Copy combo tree to settlement tree with duplicated statements
@@ -147,7 +147,7 @@ private:
}
public:
// CONSTUCTORS
ActiveTopVisitor(AstNetlist* nodep) {
explicit ActiveTopVisitor(AstNetlist* nodep) {
m_topscopep = NULL;
nodep->accept(*this);
}
+5 -5
View File
@@ -138,7 +138,7 @@ private:
nodep->replaceWith(newp);
}
// Bye
pushDeletep(nodep); nodep=NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
}
void newVAssertion(AstVAssert* nodep, AstNode* propp) {
@@ -160,7 +160,7 @@ private:
// Install it
nodep->replaceWith(newp);
// Bye
pushDeletep(nodep); nodep=NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
}
virtual void visit(AstIf* nodep, AstNUser*) {
@@ -285,12 +285,12 @@ private:
nodep->iterateChildren(*this);
if (m_beginp && nodep->name() == "") nodep->name(m_beginp->name());
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(),
nodep->stmtsp(), nodep->name()); nodep=NULL;
nodep->stmtsp(), nodep->name()); VL_DANGLING(nodep);
++m_statAsCover;
}
virtual void visit(AstVAssert* nodep, AstNUser*) {
nodep->iterateChildren(*this);
newVAssertion(nodep, nodep->propp()); nodep=NULL;
newVAssertion(nodep, nodep->propp()); VL_DANGLING(nodep);
++m_statAsSV;
}
@@ -317,7 +317,7 @@ private:
}
public:
// CONSTRUCTORS
AssertVisitor(AstNetlist* nodep) {
explicit AssertVisitor(AstNetlist* nodep) {
m_beginp = NULL;
m_modp = NULL;
// Process
+3 -3
View File
@@ -83,7 +83,7 @@ private:
} else {
nodep->unlinkFrBack();
}
pushDeletep(nodep); nodep=NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
}
virtual void visit(AstPslCover* nodep, AstNUser*) {
@@ -109,7 +109,7 @@ private:
// Unlink and just keep a pointer to it, convert to sentree as needed
m_senip = nodep->sensesp();
nodep->replaceWith(blockp);
pushDeletep(nodep); nodep=NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
}
virtual void visit(AstNodeModule* nodep, AstNUser*) {
nodep->iterateChildren(*this);
@@ -122,7 +122,7 @@ private:
public:
// CONSTRUCTORS
AssertPreVisitor(AstNetlist* nodep) {
explicit AssertPreVisitor(AstNetlist* nodep) {
m_seniDefaultp = NULL;
clearAssertInfo();
// Process
+19 -4
View File
@@ -28,6 +28,7 @@
#include "V3File.h"
#include "V3Global.h"
#include "V3Broken.h"
#include "V3String.h"
//======================================================================
// Statics
@@ -115,6 +116,10 @@ string AstNode::encodeName(const string& namein) {
out += hex;
}
}
// Shorten names
// TODO long term use VName in place of "string name"
VName vname(out);
out = vname.hashedName();
return out;
}
@@ -823,10 +828,10 @@ AstNode* AstNode::acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup) {
// Calling on standalone tree; insert a shim node so we can keep track, then delete it on completion
AstBegin* tempp = new AstBegin(nodep->fileline(),"[EditWrapper]",nodep);
{
tempp->stmtsp()->accept(v, vup); nodep=NULL; // nodep to null as may be replaced
tempp->stmtsp()->accept(v, vup); VL_DANGLING(nodep); // nodep to null as may be replaced
}
nodep = tempp->stmtsp()->unlinkFrBackWithNext();
tempp->deleteTree(); tempp=NULL;
tempp->deleteTree(); VL_DANGLING(tempp);
} else {
// Use back to determine who's pointing at us (IE assume new node grafts into same place as old one)
AstNode** nextnodepp = NULL;
@@ -837,7 +842,7 @@ AstNode* AstNode::acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup) {
else if (this->m_backp->m_nextp == this) nextnodepp = &(this->m_backp->m_nextp);
if (!nextnodepp) this->v3fatalSrc("Node's back doesn't point to forward to node itself");
{
nodep->accept(v, vup); nodep=NULL; // nodep to null as may be replaced
nodep->accept(v, vup); VL_DANGLING(nodep); // nodep to null as may be replaced
}
nodep = *nextnodepp; // Grab new node from point where old was connected
}
@@ -863,6 +868,16 @@ void AstNode::cloneRelinkTree() {
//======================================================================
// Comparison
bool AstNode::gateTreeIter() {
// Return true if the two trees are identical
if (this==NULL) return true;
if (!isGateOptimizable()) return false;
return (this->op1p()->gateTreeIter()
&& this->op2p()->gateTreeIter()
&& this->op3p()->gateTreeIter()
&& this->op4p()->gateTreeIter());
}
bool AstNode::sameTreeIter(AstNode* node2p, bool ignNext, bool gateOnly) {
// Return true if the two trees are identical
if (this==NULL && node2p==NULL) return true;
@@ -1016,7 +1031,7 @@ void AstNode::dumpTreeFile(const string& filename, bool append, bool doDump) {
if (doDump) {
{ // Write log & close
UINFO(2,"Dumping "<<filename<<endl);
const auto_ptr<ofstream> logsp (V3File::new_ofstream(filename, append));
const VL_UNIQUE_PTR<ofstream> logsp (V3File::new_ofstream(filename, append));
if (logsp->fail()) v3fatalSrc("Can't write "<<filename);
*logsp<<"Verilator Tree Dump (format 0x3900) from <e"<<dec<<editCountLast()<<">";
*logsp<<" to <e"<<dec<<editCountGbl()<<">"<<endl;
+35 -10
View File
@@ -53,6 +53,7 @@ public:
enum en m_e;
// cppcheck-suppress uninitVar // responsiblity of each subclass
inline AstType () {}
// cppcheck-suppress noExplicitConstructor
inline AstType (en _e) : m_e(_e) {}
explicit inline AstType (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -87,7 +88,9 @@ public:
return names[m_e];
};
inline AstNumeric () : m_e(UNSIGNED) {}
// cppcheck-suppress noExplicitConstructor
inline AstNumeric (en _e) : m_e(_e) {}
// cppcheck-suppress noExplicitConstructor
inline AstNumeric (VSignedState signst) {
if (signst==signedst_UNSIGNED) m_e=UNSIGNED;
else if (signst==signedst_SIGNED) m_e=SIGNED;
@@ -121,6 +124,7 @@ public:
};
enum en m_e;
inline AstPragmaType () : m_e(ILLEGAL) {}
// cppcheck-suppress noExplicitConstructor
inline AstPragmaType (en _e) : m_e(_e) {}
explicit inline AstPragmaType (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -144,6 +148,7 @@ public:
};
enum en m_e;
inline AstCFuncType () : m_e(FT_NORMAL) {}
// cppcheck-suppress noExplicitConstructor
inline AstCFuncType (en _e) : m_e(_e) {}
explicit inline AstCFuncType (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -212,6 +217,7 @@ public:
return names[m_e];
};
inline AstEdgeType () : m_e(ET_ILLEGAL) {}
// cppcheck-suppress noExplicitConstructor
inline AstEdgeType (en _e) : m_e(_e) {}
explicit inline AstEdgeType (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -239,6 +245,7 @@ public:
//
DT_PUBLIC, // V3LinkParse moves to AstTypedef::attrPublic
//
ENUM_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes
ENUM_FIRST, // V3Width processes
ENUM_LAST, // V3Width processes
ENUM_NUM, // V3Width processes
@@ -268,7 +275,7 @@ public:
"DIM_BITS", "DIM_DIMENSIONS", "DIM_HIGH", "DIM_INCREMENT", "DIM_LEFT",
"DIM_LOW", "DIM_RIGHT", "DIM_SIZE", "DIM_UNPK_DIMENSIONS",
"DT_PUBLIC",
"ENUM_FIRST", "ENUM_LAST", "ENUM_NUM", "ENUM_NEXT", "ENUM_PREV", "ENUM_NAME",
"ENUM_BASE", "ENUM_FIRST", "ENUM_LAST", "ENUM_NUM", "ENUM_NEXT", "ENUM_PREV", "ENUM_NAME",
"MEMBER_BASE",
"VAR_BASE", "VAR_CLOCK", "VAR_CLOCK_ENABLE", "VAR_PUBLIC",
"VAR_PUBLIC_FLAT", "VAR_PUBLIC_FLAT_RD","VAR_PUBLIC_FLAT_RW",
@@ -278,6 +285,7 @@ public:
return names[m_e];
};
inline AstAttrType () : m_e(ILLEGAL) {}
// cppcheck-suppress noExplicitConstructor
inline AstAttrType (en _e) : m_e(_e) {}
explicit inline AstAttrType (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -337,6 +345,7 @@ public:
UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).dpiType()," MAX"),"Enum array mismatch");
}
inline AstBasicDTypeKwd () : m_e(UNKNOWN) {}
// cppcheck-suppress noExplicitConstructor
inline AstBasicDTypeKwd (en _e) : m_e(_e) {}
explicit inline AstBasicDTypeKwd (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -431,6 +440,7 @@ public:
};
enum en m_e;
inline AstVarType () : m_e(UNKNOWN) {}
// cppcheck-suppress noExplicitConstructor
inline AstVarType (en _e) : m_e(_e) {}
explicit inline AstVarType (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -468,6 +478,7 @@ public:
enum en m_e;
// CONSTRUCTOR - note defaults to *UNKNOWN*
inline AstBranchPred () : m_e(BP_UNKNOWN) {}
// cppcheck-suppress noExplicitConstructor
inline AstBranchPred (en _e) : m_e(_e) {}
explicit inline AstBranchPred (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -499,6 +510,7 @@ public:
enum en m_e;
// CONSTRUCTOR - note defaults to *UNKNOWN*
inline AstVarAttrClocker () : m_e(CLOCKER_UNKNOWN) {}
// cppcheck-suppress noExplicitConstructor
inline AstVarAttrClocker (en _e) : m_e(_e) {}
explicit inline AstVarAttrClocker (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -529,6 +541,7 @@ public:
};
enum en m_e;
inline VAlwaysKwd () : m_e(ALWAYS) {}
// cppcheck-suppress noExplicitConstructor
inline VAlwaysKwd (en _e) : m_e(_e) {}
explicit inline VAlwaysKwd (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -553,6 +566,7 @@ public:
};
enum en m_e;
inline VCaseType () : m_e(CT_CASE) {}
// cppcheck-suppress noExplicitConstructor
inline VCaseType (en _e) : m_e(_e) {}
explicit inline VCaseType (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -575,6 +589,7 @@ public:
};
enum en m_e;
inline AstDisplayType () : m_e(DT_DISPLAY) {}
// cppcheck-suppress noExplicitConstructor
inline AstDisplayType (en _e) : m_e(_e) {}
explicit inline AstDisplayType (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -599,6 +614,7 @@ public:
};
enum en m_e;
inline AstParseRefExp() : m_e(PX_NONE) {}
// cppcheck-suppress noExplicitConstructor
inline AstParseRefExp (en _e) : m_e(_e) {}
explicit inline AstParseRefExp (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -896,16 +912,19 @@ public:
// CREATORS
class Illegal {}; // for creator type-overload selection
class FullValue {}; // for creator type-overload selection
V3Hash(Illegal) { m_both=0; }
explicit V3Hash(Illegal) { m_both=0; }
// Saving and restoring inside a userp
V3Hash(AstNUser* up) { m_both=up->castInt(); }
explicit V3Hash(AstNUser* up) { m_both=up->castInt(); }
V3Hash operator+= (const V3Hash& rh) {
setBoth(depth()+rh.depth(), (hshval()*31+rh.hshval()));
return *this; };
// Creating from raw data (sameHash functions)
V3Hash() { setBoth(1,0); }
// cppcheck-suppress noExplicitConstructor
V3Hash(uint32_t val) { setBoth(1,val); }
// cppcheck-suppress noExplicitConstructor
V3Hash(const void* vp) { setBoth(1,cvtToHash(vp)); }
// cppcheck-suppress noExplicitConstructor
V3Hash(const string& name);
V3Hash(V3Hash h1, V3Hash h2) {
setBoth(1,h1.hshval()*31+h2.hshval()); }
@@ -973,12 +992,15 @@ class AstNode {
void init(); // initialize value of AstNode
void iterateListBackwards(AstNVisitor& v, AstNUser* vup=NULL);
private:
AstNode* cloneTreeIter();
AstNode* cloneTreeIterList();
void checkTreeIter(AstNode* backp);
void checkTreeIterList(AstNode* backp);
bool gateTreeIter();
bool sameTreeIter(AstNode* node2p, bool ignNext, bool gateOnly);
void deleteTreeIter();
public:
void deleteNode();
static void relinkOneLink(AstNode*& pointpr, AstNode* newp);
// cppcheck-suppress functionConst
@@ -987,7 +1009,7 @@ class AstNode {
protected:
// CONSTUCTORS
AstNode() {init(); }
AstNode(FileLine* fileline) {init(); m_fileline = fileline; }
explicit AstNode(FileLine* fileline) {init(); m_fileline = fileline; }
virtual AstNode* clone() = 0; // Generally, cloneTree is what you want instead
virtual void cloneRelink() {}
void cloneRelinkTree();
@@ -1206,6 +1228,7 @@ public:
// METHODS - Iterate on a tree
AstNode* cloneTree(bool cloneNextLink);
bool gateTree() { return gateTreeIter(); } // Is tree gateOptimizable?
bool sameTree(AstNode* node2p); // Does tree of this == node2p?
bool sameGateTree(AstNode* node2p); // Does tree of this == node2p?, not allowing non-isGateOptimizable
void deleteTree(); // Always deletes the next link
@@ -1269,7 +1292,7 @@ inline void AstNRelinker::relink(AstNode* newp) { newp->AstNode::relink(this); }
class AstNodeMath : public AstNode {
// Math -- anything that's part of an expression tree
public:
AstNodeMath(FileLine* fl)
explicit AstNodeMath(FileLine* fl)
: AstNode(fl) {}
ASTNODE_BASE_FUNCS(NodeMath)
// METHODS
@@ -1286,7 +1309,7 @@ public:
class AstNodeTermop : public AstNodeMath {
// Terminal operator -- a operator with no "inputs"
public:
AstNodeTermop(FileLine* fl)
explicit AstNodeTermop(FileLine* fl)
: AstNodeMath(fl) {}
ASTNODE_BASE_FUNCS(NodeTermop)
// Know no children, and hot function, so skip iterator for speed
@@ -1430,7 +1453,7 @@ public:
class AstNodeStmt : public AstNode {
// Statement -- anything that's directly under a function
public:
AstNodeStmt(FileLine* fl)
explicit AstNodeStmt(FileLine* fl)
: AstNode(fl) {}
ASTNODE_BASE_FUNCS(NodeStmt)
// METHODS
@@ -1520,7 +1543,7 @@ public:
class AstNodeSenItem : public AstNode {
// An AstSenItem or AstSenGate
public:
AstNodeSenItem(FileLine* fl) : AstNode(fl) {}
explicit AstNodeSenItem(FileLine* fl) : AstNode(fl) {}
ASTNODE_BASE_FUNCS(NodeSenItem)
virtual bool isClocked() const = 0;
virtual bool isCombo() const = 0;
@@ -1607,7 +1630,7 @@ private:
static int s_uniqueNum; // Unique number assigned to each dtype during creation for IEEE matching
public:
// CONSTRUCTORS
AstNodeDType(FileLine* fl) : AstNode(fl) {
explicit AstNodeDType(FileLine* fl) : AstNode(fl) {
m_width=0; m_widthMin=0; m_generic=false;
}
ASTNODE_BASE_FUNCS(NodeDType)
@@ -1696,7 +1719,7 @@ private:
AstNodeDType* m_refDTypep; // Elements of this type (after widthing)
AstNode* rangenp() const { return op2p(); } // op2 = Array(s) of variable
public:
AstNodeArrayDType(FileLine* fl) : AstNodeDType(fl) {
explicit AstNodeArrayDType(FileLine* fl) : AstNodeDType(fl) {
m_refDTypep = NULL;
}
ASTNODE_BASE_FUNCS(NodeArrayDType)
@@ -1789,6 +1812,7 @@ public:
virtual void dump(ostream& str=cout);
virtual string name() const { return m_name; } // * = Var name
virtual bool maybePointedTo() const { return true; }
virtual bool isGateOptimizable() const { return !((m_dpiExport || m_dpiImport) && !m_pure); }
// {AstFunc only} op1 = Range output variable
virtual void name(const string& name) { m_name = name; }
string cname() const { return m_cname; }
@@ -1847,6 +1871,7 @@ public:
}}
virtual void dump(ostream& str=cout);
virtual string name() const { return m_name; } // * = Var name
virtual bool isGateOptimizable() const { return m_taskp && m_taskp->isGateOptimizable(); }
string dotted() const { return m_dotted; } // * = Scope name or ""
string prettyDotted() const { return prettyName(dotted()); }
string inlinedDots() const { return m_inlinedDots; }
+4 -22
View File
@@ -506,9 +506,9 @@ string AstScope::nameDotless() const {
return out;
}
string AstScopeName::scopePrettyName() const {
string AstScopeName::scopePrettyNameFormatter(AstText* scopeTextp) const {
string out;
for (AstText* textp=scopeAttrp(); textp; textp=textp->nextp()->castText()) {
for (AstText* textp=scopeTextp; textp; textp=textp->nextp()->castText()) {
out += textp->text();
}
// TOP will be replaced by top->name()
@@ -518,27 +518,9 @@ string AstScopeName::scopePrettyName() const {
return AstNode::prettyName(out);
}
string AstScopeName::scopeSymName() const {
string AstScopeName::scopeNameFormatter(AstText* scopeTextp) const {
string out;
for (AstText* textp=scopeAttrp(); textp; textp=textp->nextp()->castText()) {
out += textp->text();
}
if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,"");
if (out.substr(0,7) == "__DOT__") out.replace(0,7,"");
if (out.substr(0,1) == ".") out.replace(0,1,"");
string::size_type pos;
while ((pos=out.find(".")) != string::npos) {
out.replace(pos, 1, "__");
}
while ((pos=out.find("__DOT__")) != string::npos) {
out.replace(pos, 7, "__");
}
return out;
}
string AstScopeName::scopeDpiName() const {
string out;
for (AstText* textp=scopeEntrp(); textp; textp=textp->nextp()->castText()) {
for (AstText* textp=scopeTextp; textp; textp=textp->nextp()->castText()) {
out += textp->text();
}
if (out.substr(0,10) == "__DOT__TOP") out.replace(0,10,"");
+69 -12
View File
@@ -1311,6 +1311,7 @@ public:
ASTNODE_NODE_FUNCS(VarXRef, VARXREF)
virtual void dump(ostream& str);
string dotted() const { return m_dotted; }
void dotted(const string& dotted) { m_dotted = dotted; }
string prettyDotted() const { return prettyName(dotted()); }
string inlinedDots() const { return m_inlinedDots; }
void inlinedDots(const string& flag) { m_inlinedDots = flag; }
@@ -1570,6 +1571,56 @@ public:
virtual void name(const string& name) { m_name = name; }
};
class AstCellRef : public AstNode {
// As-of-yet unlinkable reference into a cell
private:
string m_name; // Cell name
public:
AstCellRef(FileLine* fl,
string name, AstNode* cellp, AstNode* exprp)
: AstNode(fl)
, m_name(name) {
addNOp1p(cellp); addNOp2p(exprp); }
ASTNODE_NODE_FUNCS(CellRef, CELLREF)
// ACCESSORS
virtual string name() const { return m_name; } // * = Array name
AstNode* cellp() const { return op1p(); } // op1 = Cell
AstNode* exprp() const { return op2p(); } // op2 = Expression
};
class AstCellArrayRef : public AstNode {
// As-of-yet unlinkable reference into an array of cells
private:
string m_name; // Array name
public:
AstCellArrayRef(FileLine* fl,
string name, AstNode* selectExprp)
: AstNode(fl)
, m_name(name) {
addNOp1p(selectExprp); }
ASTNODE_NODE_FUNCS(CellArrayRef, CELLARRAYREF)
// ACCESSORS
virtual string name() const { return m_name; } // * = Array name
AstNode* selp() const { return op1p(); } // op1 = Select expression
};
class AstUnlinkedVarXRef : public AstNode {
// As-of-yet unlinkable VarXRef
private:
string m_name; // Var name
public:
AstUnlinkedVarXRef(FileLine* fl,
AstVarXRef* vxrp, string name, AstNode* crp)
: AstNode(fl)
, m_name(name) {
addNOp1p(vxrp); addNOp2p(crp); }
ASTNODE_NODE_FUNCS(UnlinkedVarXRef, UNLINKEDVARXREF)
// ACCESSORS
virtual string name() const { return m_name; } // * = Var name
AstVarXRef* varxrefp() const { return op1p()->castVarXRef(); } // op1 = VarXRef
AstNode* cellrefp() const { return op2p(); } // op1 = CellArrayRef or CellRef
};
class AstBind : public AstNode {
// Parents: MODULE
// Children: CELL
@@ -2208,11 +2259,13 @@ class AstSFormatF : public AstNode {
public:
AstSFormatF(FileLine* fl, const string& text, bool hidden, AstNode* exprsp)
: AstNode(fl), m_text(text), m_hidden(hidden) {
dtypeSetString();
addNOp1p(exprsp); addNOp2p(NULL); }
ASTNODE_NODE_FUNCS(SFormatF, SFORMATF)
virtual string name() const { return m_text; }
virtual int instrCount() const { return instrCountPli(); }
virtual V3Hash sameHash() const { return V3Hash(text()); }
virtual bool hasDType() const { return true; }
virtual bool same(AstNode* samep) const { return text()==samep->castSFormatF()->text(); }
virtual string verilogKwd() const { return "$sformatf"; }
void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output
@@ -2602,7 +2655,7 @@ public:
class AstBreak : public AstNodeStmt {
public:
AstBreak(FileLine* fileline)
explicit AstBreak(FileLine* fileline)
: AstNodeStmt (fileline) {}
ASTNODE_NODE_FUNCS(Break, BREAK)
virtual string verilogKwd() const { return "break"; };
@@ -2612,7 +2665,7 @@ public:
class AstContinue : public AstNodeStmt {
public:
AstContinue(FileLine* fileline)
explicit AstContinue(FileLine* fileline)
: AstNodeStmt (fileline) {}
ASTNODE_NODE_FUNCS(Continue, CONTINUE)
virtual string verilogKwd() const { return "continue"; };
@@ -2905,7 +2958,7 @@ public:
class AstStop : public AstNodeStmt {
public:
AstStop(FileLine* fl)
explicit AstStop(FileLine* fl)
: AstNodeStmt(fl) {}
ASTNODE_NODE_FUNCS(Stop, STOP)
virtual bool isGateOptimizable() const { return false; }
@@ -2921,7 +2974,7 @@ public:
class AstFinish : public AstNodeStmt {
public:
AstFinish(FileLine* fl)
explicit AstFinish(FileLine* fl)
: AstNodeStmt(fl) {}
ASTNODE_NODE_FUNCS(Finish, FINISH)
virtual bool isGateOptimizable() const { return false; }
@@ -3067,8 +3120,10 @@ class AstScopeName : public AstNodeMath {
// Children: TEXT
private:
bool m_dpiExport; // Is for dpiExport
string scopeNameFormatter(AstText* textp) const;
string scopePrettyNameFormatter(AstText* textp) const;
public:
AstScopeName(FileLine* fl) : AstNodeMath(fl), m_dpiExport(false) {
explicit AstScopeName(FileLine* fl) : AstNodeMath(fl), m_dpiExport(false) {
dtypeSetUInt64(); }
ASTNODE_NODE_FUNCS(ScopeName, SCOPENAME)
virtual V3Hash sameHash() const { return V3Hash(); }
@@ -3080,9 +3135,10 @@ public:
void scopeAttrp(AstNode* nodep) { addOp1p(nodep); }
AstText* scopeEntrp() const { return op2p()->castText(); }
void scopeEntrp(AstNode* nodep) { addOp2p(nodep); }
string scopeSymName() const; // Name for __Vscope variable including children
string scopeDpiName() const; // Name for DPI import scope
string scopePrettyName() const; // Name for __Vscope printing
string scopeSymName() const { return scopeNameFormatter(scopeAttrp()); } // Name for __Vscope variable including children
string scopeDpiName() const { return scopeNameFormatter(scopeEntrp()); } // Name for DPI import scope
string scopePrettySymName() const { return scopePrettyNameFormatter(scopeAttrp()); } // Name for __Vscope variable including children
string scopePrettyDpiName() const { return scopePrettyNameFormatter(scopeEntrp()); } // Name for __Vscope variable including children
bool dpiExport() const { return m_dpiExport; }
void dpiExport(bool flag) { m_dpiExport=flag; }
};
@@ -3117,7 +3173,7 @@ private:
public:
AstRand(FileLine* fl, AstNodeDType* dtp, bool reset) : AstNodeTermop(fl) {
dtypep(dtp); m_reset=reset; }
AstRand(FileLine* fl) : AstNodeTermop(fl), m_reset(false) { }
explicit AstRand(FileLine* fl) : AstNodeTermop(fl), m_reset(false) { }
ASTNODE_NODE_FUNCS(Rand, RAND)
virtual string emitVerilog() { return "%f$random"; }
virtual string emitC() {
@@ -3134,7 +3190,7 @@ public:
class AstTime : public AstNodeTermop {
public:
AstTime(FileLine* fl) : AstNodeTermop(fl) {
explicit AstTime(FileLine* fl) : AstNodeTermop(fl) {
dtypeSetUInt64(); }
ASTNODE_NODE_FUNCS(Time, TIME)
virtual string emitVerilog() { return "%f$time"; }
@@ -3149,7 +3205,7 @@ public:
class AstTimeD : public AstNodeTermop {
public:
AstTimeD(FileLine* fl) : AstNodeTermop(fl) {
explicit AstTimeD(FileLine* fl) : AstNodeTermop(fl) {
dtypeSetDouble(); }
ASTNODE_NODE_FUNCS(TimeD, TIMED)
virtual string emitVerilog() { return "%f$realtime"; }
@@ -3511,6 +3567,7 @@ public:
setOp1p(lhsp); setOp2p(rhsp);
}
ASTNODE_NODE_FUNCS(CastSize, CASTSIZE)
// No hasDType because widthing removes this node before the hasDType check
virtual string emitVerilog() { return "((%r)'(%l))"; }
virtual string emitC() { V3ERROR_NA; return ""; }
virtual bool cleanOut() { V3ERROR_NA; return true;} virtual bool cleanLhs() {return true;}
@@ -5076,7 +5133,7 @@ class AstTypeTable : public AstNode {
typedef map<VBasicTypeKey,AstBasicDType*> DetailedMap;
DetailedMap m_detailedMap;
public:
AstTypeTable(FileLine* fl) : AstNode(fl) {
explicit AstTypeTable(FileLine* fl) : AstNode(fl) {
for (int i=0; i<AstBasicDTypeKwd::_ENUM_MAX; ++i) m_basicps[i] = NULL;
}
ASTNODE_NODE_FUNCS(TypeTable, TYPETABLE)
+1 -1
View File
@@ -160,7 +160,7 @@ private:
} else {
nodep->unlinkFrBack();
}
pushDeletep(nodep); nodep=NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
}
virtual void visit(AstVar* nodep, AstNUser*) {
if (m_unnamedScope != "") {
+1 -1
View File
@@ -128,7 +128,7 @@ private:
public:
// CONSTUCTORS
BranchVisitor(AstNetlist* nodep) {
explicit BranchVisitor(AstNetlist* nodep) {
reset();
nodep->iterateChildren(*this);
calc_tasks();
+12 -5
View File
@@ -186,14 +186,18 @@ private:
// NODE STATE
// Nothing! // This may be called deep inside other routines
// // so userp and friends may not be used
// VISITORS
virtual void visit(AstNode* nodep, AstNUser*) {
// METHODS
void processAndIterate(AstNode* nodep) {
BrokenTable::addInTree(nodep, nodep->maybePointedTo());
nodep->iterateChildrenConst(*this);
}
// VISITORS
virtual void visit(AstNode* nodep, AstNUser*) {
processAndIterate(nodep);
}
public:
// CONSTUCTORS
BrokenMarkVisitor(AstNetlist* nodep) {
explicit BrokenMarkVisitor(AstNetlist* nodep) {
nodep->accept(*this);
}
virtual ~BrokenMarkVisitor() {}
@@ -210,7 +214,7 @@ private:
nodep->v3fatalSrc("Width != WidthMin");
}
}
virtual void visit(AstNode* nodep, AstNUser*) {
void processAndIterate(AstNode* nodep) {
BrokenTable::setUnder(nodep,true);
if (const char* whyp=nodep->broken()) {
nodep->v3fatalSrc("Broken link in node (or something without maybePointedTo): "<<whyp);
@@ -232,9 +236,12 @@ private:
nodep->iterateChildrenConst(*this);
BrokenTable::setUnder(nodep,false);
}
virtual void visit(AstNode* nodep, AstNUser*) {
processAndIterate(nodep);
}
public:
// CONSTUCTORS
BrokenCheckVisitor(AstNetlist* nodep) {
explicit BrokenCheckVisitor(AstNetlist* nodep) {
nodep->accept(*this);
}
virtual ~BrokenCheckVisitor() {}
+13 -15
View File
@@ -112,7 +112,7 @@ private:
}
public:
// CONSTUCTORS
CaseLintVisitor(AstNodeCase* nodep) {
explicit CaseLintVisitor(AstNodeCase* nodep) {
m_caseExprp = NULL;
nodep->accept(*this);
}
@@ -246,7 +246,7 @@ private:
if (m_valueItem[a] != m_valueItem[b]) { same=false; break; }
}
if (same) {
tree1p->deleteTree(); tree1p=NULL;
tree1p->deleteTree(); VL_DANGLING(tree1p);
return tree0p;
}
@@ -295,8 +295,8 @@ private:
if (ifrootp) nodep->replaceWith(ifrootp);
else nodep->unlinkFrBack();
nodep->deleteTree(); nodep=NULL;
cexprp->deleteTree(); cexprp=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
cexprp->deleteTree(); VL_DANGLING(cexprp);
if (debug()>=9) ifrootp->dumpTree(cout," _simp: ");
}
@@ -327,7 +327,7 @@ private:
AstConst* iconstp = icondp->castConst();
if (iconstp && neverItem(nodep, iconstp)) {
// X in casez can't ever be executed
icondp->deleteTree(); icondp=NULL; iconstp=NULL;
icondp->deleteTree(); VL_DANGLING(icondp); VL_DANGLING(iconstp);
// For simplicity, make expression that is not equal, and let later
// optimizations remove it
condp = new AstConst(itemp->fileline(), AstConst::LogicFalse());
@@ -351,7 +351,7 @@ private:
AstNode* and2p = new AstAnd(itemp->fileline(),
new AstConst(itemp->fileline(), numval),
new AstConst(itemp->fileline(), nummask));
icondp->deleteTree(); icondp=NULL; iconstp=NULL;
icondp->deleteTree(); VL_DANGLING(icondp); VL_DANGLING(iconstp);
condp = AstEq::newTyped(itemp->fileline(), and1p, and2p);
} else {
// Not a caseX mask, we can simply build CASEEQ(cexpr icond)
@@ -369,7 +369,7 @@ private:
itemp->condsp(ifexprp);
}
}
cexprp->deleteTree(); cexprp=NULL;
cexprp->deleteTree(); VL_DANGLING(cexprp);
if (!hadDefault) {
// If there was no default, add a empty one, this greatly simplifies below code
// and constant propagation will just eliminate it for us later.
@@ -408,10 +408,9 @@ private:
}
}
{ // Make the new lower IF and attach in the tree
AstNode* itemexprp = ifexprp; ifexprp=NULL;
AstNode* itemexprp = ifexprp; VL_DANGLING(ifexprp);
if (depth == (CASE_ENCODER_GROUP_DEPTH)) { // End of group - can skip the condition
itemexprp->deleteTree(); itemexprp=NULL;
// cppcheck-suppress redundantAssignment
itemexprp->deleteTree(); VL_DANGLING(itemexprp);
itemexprp = new AstConst(itemp->fileline(), AstConst::LogicTrue());
}
AstIf* newp = new AstIf(itemp->fileline(), itemexprp, istmtsp, NULL);
@@ -427,7 +426,7 @@ private:
if (debug()>=9) grouprootp->dumpTree(cout," _new: ");
if (grouprootp) nodep->replaceWith(grouprootp);
else nodep->unlinkFrBack();
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
void replaceCaseParallel(AstCase* nodep, bool noOverlapsAllCovered) {
@@ -460,11 +459,10 @@ private:
// It's a simple priority encoder or complete statement
// we can make a tree of statements to avoid extra comparisons
++m_statCaseFast;
replaceCaseFast(nodep); nodep=NULL;
replaceCaseFast(nodep); VL_DANGLING(nodep);
} else {
++m_statCaseSlow;
// cppcheck-supporess uselessAssignmentPtrArg
replaceCaseComplicated(nodep); nodep=NULL;
replaceCaseComplicated(nodep); VL_DANGLING(nodep);
}
}
//--------------------
@@ -475,7 +473,7 @@ private:
public:
// CONSTUCTORS
CaseVisitor(AstNetlist* nodep) {
explicit CaseVisitor(AstNetlist* nodep) {
m_caseNoOverlapsAllCovered = false;
nodep->accept(*this);
}
+1 -1
View File
@@ -176,7 +176,7 @@ private:
public:
// CONSTUCTORS
CastVisitor(AstNetlist* nodep) {
explicit CastVisitor(AstNetlist* nodep) {
nodep->accept(*this);
}
virtual ~CastVisitor() {}
+3 -3
View File
@@ -184,7 +184,7 @@ private:
}
public:
// CONSTUCTORS
CdcWidthVisitor(AstNode* nodep) {
explicit CdcWidthVisitor(AstNode* nodep) {
m_maxLineno = 0;
m_maxFilenameLen = 0;
nodep->accept(*this);
@@ -496,7 +496,7 @@ private:
}
string filename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"__cdc_edges.txt";
const auto_ptr<ofstream> ofp (V3File::new_ofstream(filename));
const VL_UNIQUE_PTR<ofstream> ofp (V3File::new_ofstream(filename));
if (ofp->fail()) v3fatalSrc("Can't write "<<filename);
*ofp<<"Edge Report for "<<v3Global.opt.prefix()<<endl;
@@ -726,7 +726,7 @@ private:
public:
// CONSTUCTORS
CdcVisitor(AstNode* nodep) {
explicit CdcVisitor(AstNode* nodep) {
m_logicVertexp = NULL;
m_scopep = NULL;
m_modp = NULL;
+1 -1
View File
@@ -280,7 +280,7 @@ private:
public:
// CONSTUCTORS
CleanVisitor(AstNetlist* nodep) {
explicit CleanVisitor(AstNetlist* nodep) {
nodep->accept(*this);
}
virtual ~CleanVisitor() {}
+11 -11
View File
@@ -66,7 +66,7 @@ class GaterVarVertex;
class GaterVertex : public V3GraphVertex {
static uint32_t s_rankNum;
public:
GaterVertex(V3Graph* graphp)
explicit GaterVertex(V3Graph* graphp)
: V3GraphVertex(graphp) {
s_rankNum++; rank(s_rankNum);
}
@@ -79,7 +79,7 @@ uint32_t GaterVertex::s_rankNum = 0;
class GaterHeadVertex : public GaterVertex {
public:
GaterHeadVertex(V3Graph* graphp)
explicit GaterHeadVertex(V3Graph* graphp)
: GaterVertex(graphp) {}
virtual ~GaterHeadVertex() {}
virtual int typeNum() const { return __LINE__; } // C++ typeof() equivelent
@@ -89,7 +89,7 @@ public:
class GaterPliVertex : public GaterVertex {
public:
GaterPliVertex(V3Graph* graphp)
explicit GaterPliVertex(V3Graph* graphp)
: GaterVertex(graphp) {}
virtual ~GaterPliVertex() {}
virtual int typeNum() const { return __LINE__; } // C++ typeof() equivelent
@@ -217,7 +217,7 @@ private:
}
public:
// CONSTUCTORS
GaterCondVisitor(AstNode* nodep) {
explicit GaterCondVisitor(AstNode* nodep) {
m_isSimple = true;
nodep->accept(*this);
}
@@ -296,7 +296,7 @@ class GaterBodyVisitor : public GaterBaseVisitor {
}
if ((childstate & STATE_DELETE) && !(childstate & STATE_KEEP)) {
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
// Pass upwards we did delete
m_state |= STATE_DELETE;
} else {
@@ -427,7 +427,7 @@ class GaterVisitor : public GaterBaseVisitor {
for (V3GraphEdge* nextp,* edgep = m_pliVertexp->outBeginp(); edgep; edgep = nextp) {
nextp = edgep->outNextp(); // We may edit the list
if (GaterVarVertex* vVxp = dynamic_cast<GaterVarVertex*>(edgep->top())) {
vVxp->unlinkDelete(&m_graph); vVxp=NULL; edgep=NULL;
vVxp->unlinkDelete(&m_graph); VL_DANGLING(vVxp); VL_DANGLING(edgep);
} else {
m_graph.dump();
v3fatalSrc("PLI vertex points to non-signal");
@@ -463,7 +463,7 @@ class GaterVisitor : public GaterBaseVisitor {
V3GraphVertex* toVxp = edgep->top();
//UINFO(9," to "<<toVxp->user()<<" "<<toVxp<<endl);
if ((toVxp->user() & VU_IF) && (toVxp->user() & VU_ELSE)) {
edgep->unlinkDelete(); edgep = NULL;
edgep->unlinkDelete(); VL_DANGLING(edgep);
if (!(toVxp->user() & VU_MADE)) { // Make an edge only once
toVxp->user(toVxp->user() | VU_MADE);
GaterEdge* inedgep = static_cast<GaterEdge*>(vertexp->inBeginp());
@@ -487,7 +487,7 @@ class GaterVisitor : public GaterBaseVisitor {
if (toVxp->user() && toVxp->user() < depth) {
// A recursion "above" us marked it,
// Remove this edge, it's redundant with the upper edge
edgep->unlinkDelete(); edgep=NULL;
edgep->unlinkDelete(); VL_DANGLING(edgep);
} else {
GaterEdge* cedgep = static_cast<GaterEdge*>(edgep);
if (cedgep->ifelseBoth()) {
@@ -515,7 +515,7 @@ class GaterVisitor : public GaterBaseVisitor {
if (GaterIfVertex* toVxp = dynamic_cast<GaterIfVertex*>(edgep->top())) {
if (!toVxp->outBeginp()) {
if (!nextp || nextp->top() != edgep->top()) { // Else next would disappear; we'll do it next loop
toVxp->unlinkDelete(&m_graph); toVxp=NULL; edgep=NULL;
toVxp->unlinkDelete(&m_graph); VL_DANGLING(toVxp); VL_DANGLING(edgep);
}
}
}
@@ -529,7 +529,7 @@ class GaterVisitor : public GaterBaseVisitor {
nextp = edgep->outNextp(); // We may edit the list
if (GaterVarVertex* toVxp = dynamic_cast<GaterVarVertex*>(edgep->top())) {
if (!nextp || nextp->top() != edgep->top()) { // Else next would disappear; we'll do it next loop
toVxp->unlinkDelete(&m_graph); toVxp=NULL; edgep=NULL;
toVxp->unlinkDelete(&m_graph); VL_DANGLING(toVxp); VL_DANGLING(edgep);
}
}
}
@@ -878,7 +878,7 @@ class GaterVisitor : public GaterBaseVisitor {
public:
// CONSTUCTORS
GaterVisitor(AstNode* nodep) {
explicit GaterVisitor(AstNode* nodep) {
// AstAlways visitor does the real work, so most zeroing needs to be in clear()
clear();
nodep->accept(*this);
+7 -7
View File
@@ -268,7 +268,7 @@ private:
stmtsp->unlinkFrBackWithNext();
cmtp->addNextHere(stmtsp);
}
nodep->deleteTree(); nodep = NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
virtual void visit(AstAlwaysPost* nodep, AstNUser*) {
AstNode* cmtp = new AstComment(nodep->fileline(), nodep->typeName());
@@ -277,7 +277,7 @@ private:
stmtsp->unlinkFrBackWithNext();
cmtp->addNextHere(stmtsp);
}
nodep->deleteTree(); nodep = NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
virtual void visit(AstCoverToggle* nodep, AstNUser*) {
//nodep->dumpTree(cout,"ct:");
@@ -297,7 +297,7 @@ private:
newp->addIfsp(new AstAssign(nodep->fileline(),
changep->cloneTree(false),
origp->cloneTree(false)));
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
}
virtual void visit(AstInitial* nodep, AstNUser*) {
AstNode* cmtp = new AstComment(nodep->fileline(), nodep->typeName());
@@ -306,7 +306,7 @@ private:
stmtsp->unlinkFrBackWithNext();
cmtp->addNextHere(stmtsp);
}
nodep->deleteTree(); nodep = NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
virtual void visit(AstCFunc* nodep, AstNUser*) {
nodep->iterateChildren(*this);
@@ -342,7 +342,7 @@ private:
// Not at the top or empty block...
// Only empty blocks should be leftover on the non-top. Killem.
if (nodep->stmtsp()) nodep->v3fatalSrc("Non-empty lower active");
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
} else {
UINFO(4," ACTIVE "<<nodep<<endl);
AstNode* stmtsp = nodep->stmtsp()->unlinkFrBackWithNext();
@@ -374,7 +374,7 @@ private:
// Move statements to function
addToEvalLoop(stmtsp);
}
nodep->unlinkFrBack()->deleteTree(); nodep = NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
}
@@ -386,7 +386,7 @@ private:
public:
// CONSTUCTORS
ClockVisitor(AstNetlist* nodep) {
explicit ClockVisitor(AstNetlist* nodep) {
m_modp=NULL; m_activep=NULL;
m_evalFuncp = NULL;
m_topScopep=NULL;
+8 -8
View File
@@ -111,7 +111,7 @@ public:
callp->unlinkFrBack();
}
callp->user3(true); // Dead now
pushDeletep(callp); callp=NULL;
pushDeletep(callp); VL_DANGLING(callp);
m_callMmap.erase(eqit); // Fix the table
}
}
@@ -169,7 +169,7 @@ private:
}
public:
// CONSTRUCTORS
CombMarkVisitor(AstNode* nodep) {
explicit CombMarkVisitor(AstNode* nodep) {
nodep->accept(*this);
}
virtual ~CombMarkVisitor() {}
@@ -230,7 +230,7 @@ private:
CombMarkVisitor visitor(oldfuncp);
m_call.replaceFunc(oldfuncp, NULL);
oldfuncp->unlinkFrBack();
pushDeletep(oldfuncp); oldfuncp=NULL;
pushDeletep(oldfuncp); VL_DANGLING(oldfuncp);
}
}
}
@@ -262,7 +262,7 @@ private:
CombMarkVisitor visitor(oldfuncp);
m_call.replaceFunc(oldfuncp, newfuncp);
oldfuncp->unlinkFrBack();
pushDeletep(oldfuncp); oldfuncp=NULL;
pushDeletep(oldfuncp); VL_DANGLING(oldfuncp);
}
void replaceOnlyCallFunc(AstCCall* nodep) {
if (AstCFunc* oldfuncp = nodep->backp()->castCFunc()) {
@@ -274,7 +274,7 @@ private:
UINFO(9," Function only has call "<<oldfuncp<<endl);
m_call.deleteCall(nodep);
CombMarkVisitor visitor(oldfuncp);
replaceFuncWFunc(oldfuncp, nodep->funcp()); nodep=NULL;
replaceFuncWFunc(oldfuncp, nodep->funcp()); VL_DANGLING(nodep);
}
}
}
@@ -384,8 +384,8 @@ private:
m_call.addCall(call2p);
// If either new statement makes a func with only a single call, replace
// the above callers to call it directly
replaceOnlyCallFunc(call1p); call1p=NULL;
replaceOnlyCallFunc(call2p); call2p=NULL;
replaceOnlyCallFunc(call1p); VL_DANGLING(call1p);
replaceOnlyCallFunc(call2p); VL_DANGLING(call2p);
}
// VISITORS
@@ -457,7 +457,7 @@ private:
public:
// CONSTUCTORS
CombineVisitor(AstNetlist* nodep) {
explicit CombineVisitor(AstNetlist* nodep) {
m_modp=NULL;
m_funcp = NULL;
m_state = STATE_IDLE;
+4 -4
View File
@@ -144,12 +144,12 @@ V3ConfigIgnores V3ConfigIgnores::s_singleton;
//######################################################################
// V3Config
void V3Config::addIgnore(V3ErrorCode code, string filename, int min, int max) {
void V3Config::addIgnore(V3ErrorCode code, bool on, string filename, int min, int max) {
if (filename=="*") {
FileLine::globalWarnOff(code,true);
FileLine::globalWarnOff(code,!on);
} else {
V3ConfigIgnores::singleton().addIgnore(code, filename, min, false);
if (max) V3ConfigIgnores::singleton().addIgnore(code, filename, max, true);
V3ConfigIgnores::singleton().addIgnore(code, filename, min, on);
if (max) V3ConfigIgnores::singleton().addIgnore(code, filename, max, !on);
}
}
+1 -1
View File
@@ -30,7 +30,7 @@
class V3Config {
public:
static void addIgnore(V3ErrorCode code, string filename, int min, int max);
static void addIgnore(V3ErrorCode code, bool on, string filename, int min, int max);
static void applyIgnores(FileLine* filelinep);
};
+81 -77
View File
@@ -54,7 +54,7 @@ private:
}
public:
// CONSTUCTORS
ConstVarMarkVisitor(AstNode* nodep) {
explicit ConstVarMarkVisitor(AstNode* nodep) {
AstNode::user4ClearTree(); // Check marked InUse before we're called
nodep->accept(*this);
}
@@ -76,7 +76,7 @@ private:
}
public:
// CONSTUCTORS
ConstVarFindVisitor(AstNode* nodep) {
explicit ConstVarFindVisitor(AstNode* nodep) {
m_found = false;
nodep->iterateAndNext(*this, NULL);
}
@@ -214,7 +214,7 @@ private:
if (!operandsSame(ap, bp)) return false;
// Do it
cp->unlinkFrBack();
andp->unlinkFrBack()->deleteTree(); andp=NULL; notp=NULL;
andp->unlinkFrBack()->deleteTree(); VL_DANGLING(andp); VL_DANGLING(notp);
// Replace whichever branch is now dangling
if (nodep->rhsp()) nodep->lhsp(cp);
else nodep->rhsp(cp);
@@ -319,7 +319,7 @@ private:
&& nodep->lsbConst()==0
&& (int)nodep->widthConst()==extendp->lhsp()->width()
)) return false;
replaceWChild(nodep, extendp->lhsp()); nodep=NULL;
replaceWChild(nodep, extendp->lhsp()); VL_DANGLING(nodep);
return true;
}
bool operandSelBiLower(AstSel* nodep) {
@@ -338,7 +338,7 @@ private:
bip->lhsp(new AstSel(nodep->fileline(), bilhsp, 0, nodep->widthConst()));
bip->rhsp(new AstSel(nodep->fileline(), birhsp, 0, nodep->widthConst()));
if (debug()>=9) bip->dumpTree(cout,"SEL(BI)-ou:");
replaceWChild(nodep, bip); nodep=NULL;
replaceWChild(nodep, bip); VL_DANGLING(nodep);
return true;
}
@@ -364,7 +364,7 @@ private:
V3Number num (constp->fileline(), subsize);
num.opAssign(constp->num());
nodep->lhsp(new AstConst(constp->fileline(), num));
constp->deleteTree(); constp=NULL;
constp->deleteTree(); VL_DANGLING(constp);
if (debug()>=9) nodep->dumpTree(cout,"BI(EXTEND)-ou:");
return true;
}
@@ -450,6 +450,9 @@ private:
if (!ifvarp || !elsevarp) return false;
if (ifvarp->isWide()) return false; // Would need temporaries, so not worth it
if (!ifvarp->sameGateTree(elsevarp)) return false;
UINFO(1,"HERE "<<nodep<<endl);
if (!ifp->rhsp()->gateTree()) return false;
if (!elsep->rhsp()->gateTree()) return false;
return true;
}
bool operandIfIf(AstNodeIf* nodep) {
@@ -559,58 +562,58 @@ private:
if (debug()>5) oldp->dumpTree(cout," const_old: ");
if (debug()>5) newp->dumpTree(cout," _new: ");
oldp->replaceWith(newp);
oldp->deleteTree(); oldp=NULL;
oldp->deleteTree(); VL_DANGLING(oldp);
}
void replaceNum (AstNode* nodep, uint32_t val) {
V3Number num (nodep->fileline(), nodep->width(), val);
replaceNum(nodep, num); nodep=NULL;
replaceNum(nodep, num); VL_DANGLING(nodep);
}
void replaceNumSigned(AstNodeBiop* nodep, uint32_t val) {
// We allow both sides to be constant, as one may have come from parameter propagation, etc.
if (m_warn && !(nodep->lhsp()->castConst() && nodep->rhsp()->castConst())) {
nodep->v3warn(UNSIGNED,"Comparison is constant due to unsigned arithmetic");
}
replaceNum(nodep, val); nodep=NULL;
replaceNum(nodep, val); VL_DANGLING(nodep);
}
void replaceNumLimited(AstNodeBiop* nodep, uint32_t val) {
// Avoids gcc warning about same
if (m_warn) nodep->v3warn(CMPCONST,"Comparison is constant due to limited range");
replaceNum(nodep, val); nodep=NULL;
replaceNum(nodep, val); VL_DANGLING(nodep);
}
void replaceZero(AstNode* nodep) {
replaceNum(nodep, 0); nodep=NULL;
replaceNum(nodep, 0); VL_DANGLING(nodep);
}
void replaceZeroChkPure(AstNode* nodep, AstNode* checkp) {
// For example, "0 * n" -> 0 if n has no side effects
// Else strength reduce it to 0 & n.
// If ever change the operation note AstAnd rule specially ignores this created pattern
if (isTPure(checkp)) {
replaceNum(nodep, 0); nodep=NULL;
replaceNum(nodep, 0); VL_DANGLING(nodep);
} else {
AstNode* newp = new AstAnd(nodep->fileline(),
new AstConst(nodep->fileline(), 0),
checkp->unlinkFrBack());
newp->dtypeFrom(nodep);
nodep->replaceWith(newp);
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
}
void replaceAllOnes (AstNode* nodep) {
V3Number ones (nodep->fileline(), nodep->width(), 0);
ones.setMask(nodep->width());
replaceNum(nodep, ones); nodep=NULL;
replaceNum(nodep, ones); VL_DANGLING(nodep);
}
void replaceConst(AstNodeUniop* nodep) {
V3Number num (nodep->fileline(), nodep->width());
nodep->numberOperate(num, nodep->lhsp()->castConst()->num());
UINFO(4,"UNICONST -> "<<num<<endl);
replaceNum(nodep, num); nodep=NULL;
replaceNum(nodep, num); VL_DANGLING(nodep);
}
void replaceConst(AstNodeBiop* nodep) {
V3Number num (nodep->fileline(), nodep->width());
nodep->numberOperate(num, nodep->lhsp()->castConst()->num(), nodep->rhsp()->castConst()->num());
UINFO(4,"BICONST -> "<<num<<endl);
replaceNum(nodep, num); nodep=NULL;
replaceNum(nodep, num); VL_DANGLING(nodep);
}
void replaceConst(AstNodeTriop* nodep) {
V3Number num (nodep->fileline(), nodep->width());
@@ -618,7 +621,7 @@ private:
nodep->rhsp()->castConst()->num(),
nodep->thsp()->castConst()->num());
UINFO(4,"TRICONST -> "<<num<<endl);
replaceNum(nodep, num); nodep=NULL;
replaceNum(nodep, num); VL_DANGLING(nodep);
}
void replaceConstString (AstNode* oldp, const string& num) {
@@ -628,7 +631,7 @@ private:
if (debug()>5) oldp->dumpTree(cout," const_old: ");
if (debug()>5) newp->dumpTree(cout," _new: ");
oldp->replaceWith(newp);
oldp->deleteTree(); oldp=NULL;
oldp->deleteTree(); VL_DANGLING(oldp);
}
//----------------------------------------
// Replacement functions.
@@ -641,7 +644,7 @@ private:
// This may adversly affect the operation of the node being replaced.
childp->dtypeFrom(nodep);
nodep->replaceWith(childp);
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
//! Replace a ternary node with its RHS after iterating
@@ -775,9 +778,9 @@ private:
UINFO(5, "merged two adjacent sel "<<lselp <<" and "<<rselp<< " to one "<<newselp<<endl);
nodep->replaceWith(newselp);
lselp->deleteTree(); lselp = NULL;
rselp->deleteTree(); rselp = NULL;
nodep->deleteTree(); nodep = NULL;
lselp->deleteTree(); VL_DANGLING(lselp);
rselp->deleteTree(); VL_DANGLING(rselp);
nodep->deleteTree(); VL_DANGLING(nodep);
}
void replaceConcatMerge(AstConcat* nodep) {
AstNodeBiop* lp = nodep->lhsp()->castNodeBiop();
@@ -794,8 +797,8 @@ private:
lp->rhsp()->replaceWith(newrp);
lp->dtypeChgWidthSigned(newlp->width(), newlp->width(), AstNumeric::fromBool(true));
UINFO(5, "merged "<< nodep <<endl);
rp->unlinkFrBack()->deleteTree(); rp = NULL;
nodep->replaceWith(lp->unlinkFrBack()); nodep->deleteTree(); nodep = NULL;
rp->unlinkFrBack()->deleteTree(); VL_DANGLING(rp);
nodep->replaceWith(lp->unlinkFrBack()); nodep->deleteTree(); VL_DANGLING(nodep);
lp->lhsp()->accept(*this);
lp->rhsp()->accept(*this);
} else nodep->v3fatalSrc("tried to merge two Concat which are not adjacent");
@@ -808,7 +811,7 @@ private:
? (new AstExtendS(nodep->fileline(), arg0p))->castNode()
: (new AstExtend (nodep->fileline(), arg0p))->castNode());
newp->dtypeFrom(nodep);
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
}
void replacePowShift (AstNodeBiop* nodep) { // Pow or PowS
UINFO(5,"POW(2,b)->SHIFTL(1,b) "<<nodep<<endl);
@@ -818,7 +821,7 @@ private:
rhsp);
newp->dtypeFrom(nodep);
newp->lhsp()->dtypeFrom(nodep);
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
}
void replaceMulShift (AstMul* nodep) { // Mul, but not MulS as not simple shift
UINFO(5,"MUL(2^n,b)->SHIFTL(b,n) "<<nodep<<endl);
@@ -827,7 +830,7 @@ private:
AstShiftL* newp = new AstShiftL(nodep->fileline(),
opp, new AstConst(nodep->fileline(), amount));
newp->dtypeFrom(nodep);
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
}
void replaceDivShift (AstDiv* nodep) { // Mul, but not MulS as not simple shift
UINFO(5,"DIV(b,2^n)->SHIFTR(b,n) "<<nodep<<endl);
@@ -836,7 +839,7 @@ private:
AstShiftR* newp = new AstShiftR(nodep->fileline(),
opp, new AstConst(nodep->fileline(), amount));
newp->dtypeFrom(nodep);
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
}
void replaceShiftOp (AstNodeBiop* nodep) {
UINFO(5,"SHIFT(AND(a,b),CONST)->AND(SHIFT(a,CONST),SHIFT(b,CONST)) "<<nodep<<endl);
@@ -867,8 +870,8 @@ private:
int shift1 = shift1p->castConst()->toUInt();
int shift2 = shift2p->castConst()->toUInt();
int newshift = shift1+shift2;
shift1p->deleteTree(); shift1p=NULL;
shift2p->deleteTree(); shift2p=NULL;
shift1p->deleteTree(); VL_DANGLING(shift1p);
shift2p->deleteTree(); VL_DANGLING(shift2p);
nodep->lhsp(ap);
nodep->rhsp(new AstConst(nodep->fileline(), newshift));
nodep->accept(*this); // Further reduce, either node may have more reductions.
@@ -877,8 +880,8 @@ private:
int shift1 = shift1p->castConst()->toUInt(); if (lhsp->castShiftR()) shift1=-shift1;
int shift2 = shift2p->castConst()->toUInt(); if (nodep->castShiftR()) shift2=-shift2;
int newshift = shift1+shift2;
shift1p->deleteTree(); shift1p=NULL;
shift2p->deleteTree(); shift2p=NULL;
shift1p->deleteTree(); VL_DANGLING(shift1p);
shift2p->deleteTree(); VL_DANGLING(shift2p);
AstNode* newp;
V3Number mask1 (nodep->fileline(), nodep->width());
V3Number ones (nodep->fileline(), nodep->width());
@@ -906,11 +909,11 @@ private:
newp,
new AstConst (nodep->fileline(), mask));
newp->dtypeFrom(nodep);
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
//newp->dumpTree(cout, " repShiftShift_new: ");
newp->accept(*this); // Further reduce, either node may have more reductions.
}
lhsp->deleteTree(); lhsp=NULL;
lhsp->deleteTree(); VL_DANGLING(lhsp);
}
bool replaceAssignMultiSel(AstNodeAssign* nodep) {
@@ -983,7 +986,7 @@ private:
nodep->v3error("Wire inputs its own output, creating circular logic (wire x=x)");
return false; // Don't delete the assign, or V3Gate will freak out
} else {
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
return true;
}
}
@@ -1079,8 +1082,8 @@ private:
if (debug()>=9 && newp) newp->dumpTreeAndNext(cout," _new: ");
nodep->addNextHere(newp);
// Cleanup
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
conp->deleteTree(); conp=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
conp->deleteTree(); VL_DANGLING(conp);
// Further reduce, either node may have more reductions.
return true;
}
@@ -1093,8 +1096,8 @@ private:
AstNode* streamp = nodep->rhsp()->castStreamR()->unlinkFrBack();
nodep->rhsp(srcp);
// Cleanup
sizep->deleteTree(); sizep=NULL;
streamp->deleteTree(); streamp=NULL;
sizep->deleteTree(); VL_DANGLING(sizep);
streamp->deleteTree(); VL_DANGLING(streamp);
// Further reduce, any of the nodes may have more reductions.
return true;
}
@@ -1137,8 +1140,8 @@ private:
nodep->lhsp(dstp);
nodep->rhsp(srcp);
// Cleanup
sizep->deleteTree(); sizep=NULL;
streamp->deleteTree(); streamp=NULL;
sizep->deleteTree(); VL_DANGLING(sizep);
streamp->deleteTree(); VL_DANGLING(streamp);
// Further reduce, any of the nodes may have more reductions.
return true;
}
@@ -1171,7 +1174,7 @@ private:
fromp);
newp->dtypeSetLogicSized(nodep->width(), nodep->width(), AstNumeric::UNSIGNED); // widthMin no longer applicable if different C-expanded width
nodep->replaceWith(newp);
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
if (debug()>=9) newp->dumpTree(cout," _new: ");
}
@@ -1185,13 +1188,13 @@ private:
<<nodep->prettyTypeName()<<endl
<<errorp->warnMore()<<"... Location of non-constant "
<<errorp->prettyTypeName()<<": "<<simvis.whyNotMessage());
replaceZero(nodep); nodep=NULL;
replaceZero(nodep); VL_DANGLING(nodep);
} else {
// Fetch the result
V3Number* outnump = simvis.fetchNumberNull(nodep);
if (!outnump) nodep->v3fatalSrc("No number returned from simulation");
// Replace it
replaceNum(nodep,*outnump); nodep=NULL;
replaceNum(nodep,*outnump); VL_DANGLING(nodep);
}
}
@@ -1271,7 +1274,7 @@ private:
// If bp was a concat, then we have this exact same form again!
// Recurse rather then calling node->iterate to prevent 2^n recursion!
if (operandConcatMove(abConcp)) moveConcat(abConcp);
bcConcp->deleteTree(); bcConcp=NULL;
bcConcp->deleteTree(); VL_DANGLING(bcConcp);
} else {
AstConcat* abConcp = nodep->lhsp()->castConcat(); abConcp->unlinkFrBack();
AstNode* ap = abConcp->lhsp()->unlinkFrBack();
@@ -1282,7 +1285,7 @@ private:
nodep->lhsp(ap);
nodep->rhsp(bcConcp);
if (operandConcatMove(bcConcp)) moveConcat(bcConcp);
abConcp->deleteTree(); abConcp=NULL;
abConcp->deleteTree(); VL_DANGLING(abConcp);
}
}
@@ -1313,8 +1316,8 @@ private:
if (lsb1p->castConst() && lsb2p->castConst()) {
newlsbp = new AstConst(lsb1p->fileline(),
lsb1p->castConst()->toUInt() + lsb2p->castConst()->toUInt());
lsb1p->deleteTree(); lsb1p=NULL;
lsb2p->deleteTree(); lsb2p=NULL;
lsb1p->deleteTree(); VL_DANGLING(lsb1p);
lsb2p->deleteTree(); VL_DANGLING(lsb2p);
} else {
// Width is important, we need the width of the fromp's
// expression, not the potentially smaller lsb1p's width
@@ -1328,7 +1331,7 @@ private:
newlsbp,
widthp);
nodep->replaceWith(newp);
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
void replaceSelConcat(AstSel* nodep) {
@@ -1368,7 +1371,7 @@ private:
conRhsp->width()-nodep->lsbConst()));
nodep->replaceWith(newp);
}
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
void replaceSelReplicate(AstSel* nodep) {
@@ -1382,7 +1385,7 @@ private:
new AstConst(lsbp->fileline(), lsbp->toUInt() % fromp->width()),
widthp);
newp->dtypeFrom(nodep);
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
}
void replaceSelIntoBiop(AstSel* nodep) {
@@ -1400,7 +1403,7 @@ private:
fromp->rhsp(new AstSel(nodep->fileline(),
birhsp, lsbp, widthp));
fromp->dtypeFrom(nodep);
nodep->replaceWith(fromp); nodep->deleteTree(); nodep=NULL;
nodep->replaceWith(fromp); nodep->deleteTree(); VL_DANGLING(nodep);
}
void replaceSelIntoUniop(AstSel* nodep) {
// SEL(NOT(a),1,bit) => NOT(SEL(a,bit))
@@ -1414,7 +1417,7 @@ private:
fromp->lhsp(new AstSel(nodep->fileline(),
bilhsp, lsbp, widthp));
fromp->dtypeFrom(nodep);
nodep->replaceWith(fromp); nodep->deleteTree(); nodep=NULL;
nodep->replaceWith(fromp); nodep->deleteTree(); VL_DANGLING(nodep);
}
virtual void visit(AstAttrOf* nodep, AstNUser*) {
@@ -1443,7 +1446,7 @@ private:
}
m_selp = NULL;
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
virtual void visit(AstNodeVarRef* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (!nodep->varp()) nodep->v3fatalSrc("Not linked");
bool did=false;
@@ -1463,7 +1466,7 @@ private:
if (operandConst(valuep)) {
const V3Number& num = valuep->castConst()->num();
//UINFO(2,"constVisit "<<(void*)valuep<<" "<<num<<endl);
replaceNum(nodep, num); nodep=NULL;
replaceNum(nodep, num); VL_DANGLING(nodep);
did=true;
}
else if (m_selp && valuep->castInitArray()) {
@@ -1473,7 +1476,7 @@ private:
if (itemp->castConst()) {
const V3Number& num = itemp->castConst()->num();
//UINFO(2,"constVisit "<<(void*)valuep<<" "<<num<<endl);
replaceNum(nodep, num); nodep=NULL;
replaceNum(nodep, num); VL_DANGLING(nodep);
did=true;
}
}
@@ -1492,7 +1495,7 @@ private:
nodep->itemp()->valuep()->iterateAndNext(*this);
if (AstConst* valuep = nodep->itemp()->valuep()->castConst()) {
const V3Number& num = valuep->num();
replaceNum(nodep, num); nodep=NULL;
replaceNum(nodep, num); VL_DANGLING(nodep);
did=true;
}
}
@@ -1519,13 +1522,13 @@ private:
if (nodep->isClocked()) { // A constant can never get a pos/negexge
if (onlySenItemInSenTree(nodep)) {
nodep->replaceWith(new AstSenItem(nodep->fileline(), AstSenItem::Never()));
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
} else {
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
} else { // Otherwise it may compute a result that needs to settle out
nodep->replaceWith(new AstSenItem(nodep->fileline(), AstSenItem::Combo()));
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
} else if (m_doNConst && nodep->sensp()->castNot()) {
// V3Gate may propagate NOTs into clocks... Just deal with it
@@ -1541,7 +1544,7 @@ private:
AstNodeVarRef* senvarp = lastSensp->unlinkFrBack()->castNodeVarRef();
if (!senvarp) sensp->v3fatalSrc("Non-varref sensitivity variable");
sensp->replaceWith(senvarp);
sensp->deleteTree(); sensp=NULL;
sensp->deleteTree(); VL_DANGLING(sensp);
} else if (!m_doNConst // Deal with later when doNConst missing
&& (nodep->sensp()->castEnumItemRef()
|| nodep->sensp()->castConst())) {
@@ -1556,15 +1559,15 @@ private:
UINFO(4,"SENGATE(...,0)->NEVER"<<endl);
if (onlySenItemInSenTree(nodep)) {
nodep->replaceWith(new AstSenItem(nodep->fileline(), AstSenItem::Never()));
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
} else {
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
} else {
UINFO(4,"SENGATE(SENITEM,0)->ALWAYS SENITEM"<<endl);
AstNode* senitemp = nodep->sensesp()->unlinkFrBack();
nodep->replaceWith(senitemp);
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
}
}
@@ -1630,7 +1633,7 @@ private:
// Found, push this item up to the top
itemp->unlinkFrBack();
nodep->addSensesp(itemp);
gatep->unlinkFrBack()->deleteTree(); gatep=NULL; senp=NULL;
gatep->unlinkFrBack()->deleteTree(); VL_DANGLING(gatep); VL_DANGLING(senp);
}
}
}
@@ -1686,7 +1689,7 @@ private:
&& ritemp->edgeType()==AstEdgeType::ET_NEGEDGE)
litemp->edgeType(AstEdgeType::ET_BOTHEDGE);
// Remove redundant node
ritemp->unlinkFrBack()->deleteTree(); ritemp=NULL; cmpp=NULL;
ritemp->unlinkFrBack()->deleteTree(); VL_DANGLING(ritemp); VL_DANGLING(cmpp);
// Try to collapse again
nextp=litemp;
}
@@ -1729,7 +1732,7 @@ private:
new AstAssign(nodep->fileline(),
varrefp, exprp));
m_modp->addStmtp(newinitp);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
// Set the initial value right in the variable so we can constant propagate
AstNode* initvaluep = exprp->cloneTree(false);
varrefp->varp()->valuep(initvaluep);
@@ -1754,12 +1757,12 @@ private:
} else {
nodep->unlinkFrBack();
}
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
else if (!afterComment(nodep->ifsp()) && !afterComment(nodep->elsesp())) {
// Empty block, remove it
// Note if we support more C++ then there might be side effects in the condition itself
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (!afterComment(nodep->ifsp())) {
UINFO(4,"IF({x}) NULL {...} => IF(NOT{x}}: "<<nodep<<endl);
@@ -1781,7 +1784,7 @@ private:
AstIf* ifp = new AstIf(nodep->fileline(), condp, elsesp, ifsp);
ifp->branchPred(nodep->branchPred().invert());
nodep->replaceWith(ifp);
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
else if (ifSameAssign(nodep)) {
UINFO(4,"IF({a}) ASSIGN({b},{c}) else ASSIGN({b},{d}) => ASSIGN({b}, {a}?{c}:{d})"<<endl);
@@ -1794,7 +1797,7 @@ private:
ifp->rhsp(new AstCond(truep->fileline(),
condp, truep, falsep));
nodep->replaceWith(ifp);
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
else if (0 // Disabled, as vpm assertions are faster without due to short-circuiting
&& operandIfIf(nodep)) {
@@ -1806,7 +1809,7 @@ private:
nodep->condp(new AstLogAnd(lowerIfp->fileline(),
condp, lowerCondp));
lowerIfp->replaceWith(lowerIfsp);
lowerIfp->deleteTree(); lowerIfp=NULL;
lowerIfp->deleteTree(); VL_DANGLING(lowerIfp);
}
else if (operandBoolShift(nodep->condp())) {
replaceBoolShift(nodep->condp());
@@ -1843,6 +1846,7 @@ private:
switch (tolower(ch)) {
case '%': break; // %% - just output a %
case 'm': break; // %m - auto insert "name"
case 'l': break; // %m - auto insert "library"
default: // Most operators, just move to next argument
if (argp) {
AstNode* nextp=argp->nextp();
@@ -1874,7 +1878,7 @@ private:
&& nodep->name().find("%") == string::npos
&& !nodep->hidden()) {
// Just a simple constant string - the formatting is pointless
replaceConstString(nodep, nodep->name()); nodep=NULL;
replaceConstString(nodep, nodep->name()); VL_DANGLING(nodep);
}
}
@@ -1895,7 +1899,7 @@ private:
UINFO(4,"WHILE(0) => nop "<<nodep<<endl);
if (nodep->precondsp()) nodep->replaceWith(nodep->precondsp());
else nodep->unlinkFrBack();
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
else if (operandBoolShift(nodep->condp())) {
replaceBoolShift(nodep->condp());
@@ -1915,7 +1919,7 @@ private:
virtual void visit(AstSysIgnore* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (m_doNConst) {
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
}
@@ -1945,7 +1949,7 @@ private:
if (nodep->stmtsp()) underp = nodep->stmtsp()->unlinkFrBackWithNext();
if (underp) nodep->replaceWith(underp);
else nodep->unlinkFrBack();
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
}
@@ -2289,7 +2293,7 @@ public:
};
// CONSTUCTORS
ConstVisitor(ProcMode pmode) {
explicit ConstVisitor(ProcMode pmode) {
m_params = false;
m_required = false;
m_doExpensive = false;
+3 -3
View File
@@ -87,7 +87,7 @@ private:
if (!nodep->isToggleCoverable())
return "Not relevant signal type";
if (!v3Global.opt.coverageUnderscore()) {
if (prettyName.c_str()[0] == '_')
if (prettyName[0] == '_')
return "Leading underscore";
if (prettyName.find("._") != string::npos)
return "Inlined leading underscore";
@@ -343,7 +343,7 @@ private:
// Skip all NEXT nodes under this block, and skip this if/case branch
UINFO(4," OFF: "<<nodep<<endl);
m_checkBlock = false;
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
} else {
if (m_checkBlock) nodep->iterateChildren(*this);
}
@@ -378,7 +378,7 @@ private:
public:
// CONSTUCTORS
CoverageVisitor(AstNetlist* rootp) {
explicit CoverageVisitor(AstNetlist* rootp) {
// Operate on all modules
m_checkBlock = true;
m_beginHier = "";
+2 -2
View File
@@ -93,7 +93,7 @@ private:
UINFO(8," new "<<removep->incp()->declp()<<endl);
// Mark the found node as a duplicate of the first node
// (Not vice-versa as we have the iterator for the found node)
removep->unlinkFrBack(); pushDeletep(removep); removep=NULL;
removep->unlinkFrBack(); pushDeletep(removep); VL_DANGLING(removep);
// Remove node from comparison so don't hit it again
hashed.erase(dupit);
++m_statToggleJoins;
@@ -121,7 +121,7 @@ private:
public:
// CONSTUCTORS
CoverageJoinVisitor(AstNetlist* nodep) {
explicit CoverageJoinVisitor(AstNetlist* nodep) {
nodep->accept(*this);
}
virtual ~CoverageJoinVisitor() {
+4 -4
View File
@@ -58,7 +58,7 @@ private:
}
public:
// CONSTRUCTORS
DeadModVisitor(AstNodeModule* nodep) {
explicit DeadModVisitor(AstNodeModule* nodep) {
nodep->accept(*this);
}
virtual ~DeadModVisitor() {}
@@ -229,7 +229,7 @@ private:
// And its children may now be killable too; correct counts
// Recurse, as cells may not be directly under the module but in a generate
DeadModVisitor visitor(modp);
modp->unlinkFrBack()->deleteTree(); modp=NULL;
modp->unlinkFrBack()->deleteTree(); VL_DANGLING(modp);
retry = true;
}
}
@@ -252,9 +252,9 @@ private:
for (AssignMap::iterator it = eqrange.first; it != eqrange.second; ++it) {
AstNodeAssign* assp = it->second;
UINFO(4," Dead assign "<<assp<<endl);
assp->unlinkFrBack()->deleteTree(); assp=NULL;
assp->unlinkFrBack()->deleteTree(); VL_DANGLING(assp);
}
vscp->unlinkFrBack()->deleteTree(); vscp=NULL;
vscp->unlinkFrBack()->deleteTree(); VL_DANGLING(vscp);
}
}
for (vector<AstNode*>::iterator it = m_varEtcsp.begin(); it!=m_varEtcsp.end(); ++it) {
+4 -4
View File
@@ -374,9 +374,9 @@ private:
if (newlhsp) {
nodep->lhsp(newlhsp);
} else {
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
lhsp->deleteTree(); lhsp=NULL;
lhsp->deleteTree(); VL_DANGLING(lhsp);
}
else {
nodep->iterateChildren(*this);
@@ -420,7 +420,7 @@ private:
}
AstVarRef* newrefp = new AstVarRef(nodep->fileline(), dlyvscp, true);
newrefp->user2(true); // No reason to do it again
nodep->replaceWith(newrefp); nodep->deleteTree(); nodep=NULL;
nodep->replaceWith(newrefp); nodep->deleteTree(); VL_DANGLING(nodep);
}
else if (!m_inDly && nodep->lvalue()) {
//UINFO(9,"NBA "<<nodep<<endl);
@@ -450,7 +450,7 @@ private:
public:
// CONSTUCTORS
DelayedVisitor(AstNetlist* nodep) {
explicit DelayedVisitor(AstNetlist* nodep) {
m_inDly = false;
m_activep=NULL;
m_cfuncp=NULL;
+1 -1
View File
@@ -157,7 +157,7 @@ private:
public:
// CONSTUCTORS
DepthVisitor(AstNetlist* nodep) {
explicit DepthVisitor(AstNetlist* nodep) {
m_modp=NULL;
m_funcp=NULL;
m_stmtp=NULL;
+1 -1
View File
@@ -125,7 +125,7 @@ private:
public:
// CONSTUCTORS
DepthBlockVisitor(AstNetlist* nodep) {
explicit DepthBlockVisitor(AstNetlist* nodep) {
m_modp=NULL;
m_depth=0;
//
+1 -1
View File
@@ -247,7 +247,7 @@ private:
}
public:
// CONSTRUCTORS
DescopeVisitor(AstNetlist* nodep) {
explicit DescopeVisitor(AstNetlist* nodep) {
m_modp = NULL;
m_scopep = NULL;
m_needThis = false;
+12 -8
View File
@@ -656,7 +656,7 @@ public:
}
} else if (nodep->isQuad()) {
vluint64_t num = nodep->toUQuad();
if (num<10) ofp()->printf("VL_ULL(%" VL_PRI64 "d)", num);
if (num<10) ofp()->printf("VL_ULL(%" VL_PRI64 "u)", num);
else ofp()->printf("VL_ULL(0x%" VL_PRI64 "x)", num);
} else {
uint32_t num = nodep->toUInt();
@@ -1351,16 +1351,20 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep,
case 'g': displayArg(nodep,&elistp,isScan, vfmt,'g'); break;
case 'm': {
if (!scopenamep) nodep->v3fatalSrc("Display with %m but no AstScopeName");
string suffix = scopenamep->scopePrettyName();
string suffix = scopenamep->scopePrettySymName();
if (suffix=="") emitDispState.pushFormat("%S");
else emitDispState.pushFormat("%N"); // Add a . when needed
emitDispState.pushArg(' ',NULL, "vlSymsp->name()");
emitDispState.pushFormat(suffix);
break;
}
case 'l': {
// Better than not compiling
emitDispState.pushFormat("----");
break;
}
case 'u':
case 'z':
case 'l':
case 'v':
nodep->v3error("Unsupported: $display-like format code: %"<<pos[0]);
break;
@@ -1560,15 +1564,15 @@ void EmitCImp::emitSavableImp(AstNodeModule* modp) {
puts("void "+modClassName(modp)+"::"+funcname+"("+classname+"& os) {\n");
// Place a computed checksum to insure proper structure save/restore formatting
// OK if this hash includes some things we won't dump, since just looking for loading the wrong model
VHashFnv hash;
VHashSha1 hash;
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
if (AstVar* varp = nodep->castVar()) {
hash.hash(varp->name());
hash.hash(varp->dtypep()->width());
hash.insert(varp->name());
hash.insert(varp->dtypep()->width());
}
}
ofp()->printf( "vluint64_t __Vcheckval = VL_ULL(0x%" VL_PRI64 "x);\n",
hash.value());
hash.digestUInt64());
if (de) {
puts("os.readAssert(__Vcheckval);\n");
} else {
@@ -2434,7 +2438,7 @@ class EmitCTrace : EmitCStmts {
}
public:
EmitCTrace(bool slow) {
explicit EmitCTrace(bool slow) {
m_funcp = NULL;
m_slow = slow;
}
+1 -1
View File
@@ -106,7 +106,7 @@ private:
}
public:
// CONSTUCTORS
EmitCBaseCounterVisitor(AstNode* nodep) {
explicit EmitCBaseCounterVisitor(AstNode* nodep) {
m_count = 0;
nodep->accept(*this);
}
+1 -1
View File
@@ -71,7 +71,7 @@ class EmitCInlines : EmitCBaseVisitor {
//---------------------------------------
// ACCESSORS
public:
EmitCInlines(AstNetlist* nodep) {
explicit EmitCInlines(AstNetlist* nodep) {
nodep->accept(*this);
if (v3Global.needHInlines()) {
emitInt();
+7 -3
View File
@@ -193,14 +193,18 @@ class EmitCSyms : EmitCBaseVisitor {
}
virtual void visit(AstScopeName* nodep, AstNUser*) {
string name = nodep->scopeSymName();
//UINFO(9,"scnameins sp "<<nodep->name()<<" sp "<<nodep->scopePrettyName()<<" ss "<<name<<endl);
//UINFO(9,"scnameins sp "<<nodep->name()<<" sp "<<nodep->scopePrettySymName()<<" ss "<<name<<endl);
if (m_scopeNames.find(name) == m_scopeNames.end()) {
m_scopeNames.insert(make_pair(name, ScopeNameData(name, nodep->scopePrettyName())));
m_scopeNames.insert(make_pair(name, ScopeNameData(name, nodep->scopePrettySymName())));
}
if (nodep->dpiExport()) {
if (!m_funcp) nodep->v3fatalSrc("ScopeName not under DPI function");
m_scopeFuncs.insert(make_pair(name + " " + m_funcp->name(),
ScopeFuncData(nodep, m_funcp, m_modp)));
} else {
if (m_scopeNames.find(nodep->scopeDpiName()) == m_scopeNames.end()) {
m_scopeNames.insert(make_pair(nodep->scopeDpiName(), ScopeNameData(nodep->scopeDpiName(), nodep->scopePrettyDpiName())));
}
}
}
virtual void visit(AstVar* nodep, AstNUser*) {
@@ -240,7 +244,7 @@ class EmitCSyms : EmitCBaseVisitor {
//---------------------------------------
// ACCESSORS
public:
EmitCSyms(AstNetlist* nodep) {
explicit EmitCSyms(AstNetlist* nodep) {
m_funcp = NULL;
m_modp = NULL;
m_coverBins = 0;
+4 -1
View File
@@ -81,6 +81,9 @@ public:
if (v3Global.dpi()) {
putMakeClassEntry(of, "verilated_dpi.cpp");
}
if (v3Global.opt.vpi()) {
putMakeClassEntry(of, "verilated_vpi.cpp");
}
if (v3Global.opt.savable()) {
putMakeClassEntry(of, "verilated_save.cpp");
}
@@ -231,7 +234,7 @@ public:
}
public:
EmitMkVisitor(AstNetlist*) {
explicit EmitMkVisitor(AstNetlist*) {
emitClassMake();
emitOverallMake();
}
+1 -1
View File
@@ -589,7 +589,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
}
public:
EmitVBaseVisitor(AstSenTree* domainp=NULL) { // Domain for printing one a ALWAYS under a ACTIVE
explicit EmitVBaseVisitor(AstSenTree* domainp=NULL) { // Domain for printing one a ALWAYS under a ACTIVE
m_suppressSemi = false;
m_sensesp = domainp;
}
+7 -1
View File
@@ -96,6 +96,10 @@ public:
UNPACKED, // Unsupported unpacked
UNSIGNED, // Comparison is constant due to unsigned arithmetic
UNUSED, // No receivers
USERERROR, // Elaboration time $error
USERFATAL, // Elaboration time $fatal
USERINFO, // Elaboration time $info
USERWARN, // Elaboration time $warning
VARHIDDEN, // Hiding variable
WIDTH, // Width mismatch
WIDTHCONCAT, // Unsized numbers/parameters in concatenations
@@ -104,8 +108,9 @@ public:
};
enum en m_e;
inline V3ErrorCode () : m_e(EC_MIN) {}
// cppcheck-suppress noExplicitConstructor
inline V3ErrorCode (en _e) : m_e(_e) {}
V3ErrorCode (const char* msgp); // Matching code or ERROR
explicit V3ErrorCode (const char* msgp); // Matching code or ERROR
explicit inline V3ErrorCode (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
const char* ascii() const {
@@ -131,6 +136,7 @@ public:
"REALCVT", "REDEFMACRO",
"SELRANGE", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET",
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNPACKED", "UNSIGNED", "UNUSED",
"USERERROR", "USERFATAL", "USERINFO", "USERWARN",
"VARHIDDEN", "WIDTH", "WIDTHCONCAT",
" MAX"
};
+17 -17
View File
@@ -86,7 +86,7 @@ private:
void replaceWithDelete (AstNode* nodep, AstNode* newp) {
newp->user1(1); // Already processed, don't need to re-iterate
nodep->replaceWith(newp);
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
AstNode* newWordAssign (AstNodeAssign* placep, int word, AstNode* lhsp, AstNode* rhsp) {
AstAssign* newp = new AstAssign (placep->fileline(),
@@ -332,7 +332,7 @@ private:
lhsp->dtypeFrom(nodep); // Just mark it, else nop
}
}
replaceWithDelete(nodep,newp); nodep=NULL;
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
}
}
bool expandWide (AstNodeAssign* nodep, AstExtend* rhsp) {
@@ -438,7 +438,7 @@ private:
if (midp) newp = new AstOr (nodep->fileline(), midp, newp);
if (hip) newp = new AstOr (nodep->fileline(), hip, newp);
newp->dtypeFrom(nodep);
replaceWithDelete(nodep,newp); nodep=NULL;
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
}
else { // Long/Quad from Long/Quad
UINFO(8," SEL->SHIFT "<<nodep<<endl);
@@ -454,7 +454,7 @@ private:
newp = new AstCCast (newp->fileline(), newp, nodep);
}
newp->dtypeFrom(nodep);
replaceWithDelete(nodep,newp); nodep=NULL;
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
}
}
@@ -541,8 +541,8 @@ private:
rhsp, lsb)));
}
}
rhsp->deleteTree(); rhsp=NULL;
destp->deleteTree(); destp=NULL;
rhsp->deleteTree(); VL_DANGLING(rhsp);
destp->deleteTree(); VL_DANGLING(destp);
} else {
UINFO(8," ASSIGNSEL(const,narrow) "<<nodep<<endl);
if (destp->isQuad() && !rhsp->isQuad()) rhsp = new AstCCast(nodep->fileline(), rhsp, nodep);
@@ -667,7 +667,7 @@ private:
nodep->width()),
rhsp);
newp->dtypeFrom(nodep); // Unsigned
replaceWithDelete(nodep,newp); nodep=NULL;
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
}
}
bool expandWide (AstNodeAssign* nodep, AstConcat* rhsp) {
@@ -720,7 +720,7 @@ private:
lhsp->deleteTree(); // Never used
}
newp->dtypeFrom(nodep); // Unsigned
replaceWithDelete(nodep,newp); nodep=NULL;
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
}
}
bool expandWide (AstNodeAssign* nodep, AstReplicate* rhsp) {
@@ -761,7 +761,7 @@ private:
newAstWordSelClone (nodep->rhsp(), w));
newp = (newp==NULL) ? eqp : (new AstOr (nodep->fileline(), newp, eqp));
}
replaceWithDelete(nodep,newp); nodep=NULL;
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
}
void visitEqNeq(AstNodeBiop* nodep) {
@@ -784,7 +784,7 @@ private:
newp = new AstEq (nodep->fileline(),
new AstConst (nodep->fileline(), 0), newp);
}
replaceWithDelete(nodep,newp); nodep=NULL;
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
}
}
virtual void visit(AstEq* nodep, AstNUser*) { visitEqNeq (nodep); }
@@ -803,7 +803,7 @@ private:
}
newp = new AstNeq (nodep->fileline(),
new AstConst (nodep->fileline(), 0), newp);
replaceWithDelete(nodep,newp); nodep=NULL;
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
} else {
UINFO(8," REDOR->EQ "<<nodep<<endl);
AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
@@ -811,7 +811,7 @@ private:
AstNode* newp = new AstNeq (nodep->fileline(),
new AstConst (nodep->fileline(), zero),
lhsp);
replaceWithDelete(nodep,newp); nodep=NULL;
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
}
}
virtual void visit(AstRedAnd* nodep, AstNUser*) {
@@ -833,14 +833,14 @@ private:
}
newp = new AstEq (nodep->fileline(),
new AstConst (nodep->fileline(), ~0), newp);
replaceWithDelete(nodep, newp); nodep=NULL;
replaceWithDelete(nodep, newp); VL_DANGLING(nodep);
} else {
UINFO(8," REDAND->EQ "<<nodep<<endl);
AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
AstNode* newp = new AstEq (nodep->fileline(),
new AstConst (nodep->fileline(), wordMask(lhsp)),
lhsp);
replaceWithDelete(nodep,newp); nodep=NULL;
replaceWithDelete(nodep,newp); VL_DANGLING(nodep);
}
}
virtual void visit(AstRedXor* nodep, AstNUser*) {
@@ -856,7 +856,7 @@ private:
}
newp = new AstRedXor (nodep->fileline(), newp);
UINFO(8," Wordize REDXORnew "<<newp<<endl);
replaceWithDelete(nodep, newp); nodep=NULL;
replaceWithDelete(nodep, newp); VL_DANGLING(nodep);
}
// We don't reduce non-wide XORs, as its more efficient to use a temp register,
// which the inlined function does nicely.
@@ -907,7 +907,7 @@ private:
}
// Cleanup common code
if (did) {
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
m_stmtp = NULL;
}
@@ -921,7 +921,7 @@ private:
public:
// CONSTUCTORS
ExpandVisitor(AstNetlist* nodep) {
explicit ExpandVisitor(AstNetlist* nodep) {
m_stmtp=NULL;
nodep->accept(*this);
}
+9 -7
View File
@@ -185,7 +185,7 @@ inline void V3FileDependImp::writeTimes(const string& filename, const string& cm
}
inline bool V3FileDependImp::checkTimes(const string& filename, const string& cmdlineIn) {
const auto_ptr<ifstream> ifp (V3File::new_ifstream_nodepend(filename));
const VL_UNIQUE_PTR<ifstream> ifp (V3File::new_ifstream_nodepend(filename));
if (ifp->fail()) {
UINFO(2," --check-times failed: no input "<<filename<<endl);
return false;
@@ -363,6 +363,7 @@ private:
}
return out;
}
// cppcheck-suppress unusedFunction unusedPrivateFunction
string readFilterLine() {
// Slow, but we don't need it much
UINFO(9,"readFilterLine\n");
@@ -380,6 +381,7 @@ private:
UINFO(6,"filter-line-in: "<<line);
return line;
}
// cppcheck-suppress unusedFunction unusedPrivateFunction
void writeFilter(const string& out) {
if (debug()>=6) { UINFO(6,"filter-out: "<<out); if (out[out.length()-1]!='\n') cout<<endl; }
if (!m_pid) { v3error("--pipe-filter: write to closed file\n"); m_readEof = true; stop(); }
@@ -521,7 +523,7 @@ protected:
return out;
}
// CONSTRUCTORS
V3InFilterImp(const string& command) {
explicit V3InFilterImp(const string& command) {
m_readEof = false;
m_pid = 0;
m_pidExited = false;
@@ -549,7 +551,7 @@ bool V3InFilter::readWholefile(const string& filename, V3InFilter::StrList& outl
// V3OutFormatter: A class for printing to a file, with automatic indentation of C++ code.
V3OutFormatter::V3OutFormatter(const string& filename, V3OutFormatter::Language lang)
: m_filename(filename), m_lang(lang)
: m_filename(filename), m_lang(lang), m_blockIndent(4)
, m_lineno(1), m_column(0)
, m_nobreak(false), m_prependIndent(true), m_indentLevel(0)
, m_declSAlign(0), m_declNSAlign(0), m_declPadNum(0) {
@@ -617,7 +619,7 @@ int V3OutFormatter::endLevels (const char *strg) {
// label/public/private: Deindent by 2 spaces
const char* mp=cp;
for (; isalnum(*mp); mp++) ;
if (mp[0]==':' && mp[1]!=':') return (levels-INDBLK/2);
if (mp[0]==':' && mp[1]!=':') return (levels-m_blockIndent/2);
}
// We want "} else {" to be one level to the left of normal
@@ -625,16 +627,16 @@ int V3OutFormatter::endLevels (const char *strg) {
switch (*cp) {
case '}':
case ')':
levels-=INDBLK;
levels-=m_blockIndent;
break;
case '<':
if (m_lang==LA_XML) {
if (cp[1] == '/') levels-=INDBLK;
if (cp[1] == '/') levels-=m_blockIndent;
}
break;
case 'e':
if (m_lang==LA_VERILOG && tokenEnd(cp)) {
levels-=INDBLK;
levels-=m_blockIndent;
}
break;
case '\t':
+17 -12
View File
@@ -77,6 +77,7 @@ class V3InFilterImp;
class V3InFilter {
V3InFilterImp* m_impp;
V3InFilter(const V3InFilter&); ///< N/A, no copy constructor
public:
// TYPES
typedef list<string> StrList;
@@ -86,7 +87,7 @@ public:
bool readWholefile(const string& filename, StrList& outl);
// CONSTRUCTORS
V3InFilter(const string& command);
explicit V3InFilter(const string& command);
~V3InFilter();
};
@@ -96,7 +97,6 @@ public:
class V3OutFormatter {
// TYPES
enum MiscConsts {
INDBLK = 4, // Indentation per block level
WIDTH = 50, // Width after which to break at ,'s
MAXSPACE = 80}; // After this indent, stop indenting more
public:
@@ -114,6 +114,7 @@ private:
// MEMBERS
string m_filename;
Language m_lang; // Indenting Verilog code
int m_blockIndent; // Characters per block indent
int m_lineno;
int m_column;
int m_nobreak; // Basic operator or begin paren, don't break next
@@ -132,7 +133,9 @@ public:
V3OutFormatter(const string& filename, Language lang);
virtual ~V3OutFormatter() {}
// ACCESSORS
int column() const { return m_column; }
int column() const { return m_column; }
int blockIndent() const { return m_blockIndent; }
void blockIndent(int flag) { m_blockIndent=flag; }
// METHODS
void printf(const char* fmt...) VL_ATTR_PRINTF(2);
void puts(const char* strg);
@@ -149,12 +152,12 @@ public:
bool exceededWidth() const { return m_column > WIDTH; }
bool tokenStart(const char* cp, const char* cmp);
bool tokenEnd(const char* cp);
void indentInc() { m_indentLevel += INDBLK; }
void indentInc() { m_indentLevel += m_blockIndent; }
void indentDec() {
m_indentLevel -= INDBLK;
m_indentLevel -= m_blockIndent;
UASSERT(m_indentLevel>=0, ": "<<m_filename<<": Underflow of indentation\n");
}
void blockInc() { m_parenVec.push(m_indentLevel + INDBLK); }
void blockInc() { m_parenVec.push(m_indentLevel + m_blockIndent); }
void blockDec() { if (!m_parenVec.empty()) m_parenVec.pop(); }
// STATIC METHODS
static const string indentSpaces(int levels);
@@ -183,7 +186,7 @@ private:
class V3OutCFile : public V3OutFile {
int m_private;
public:
V3OutCFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_C) {
explicit V3OutCFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_C) {
resetPrivate();
}
virtual ~V3OutCFile() {}
@@ -208,7 +211,7 @@ public:
class V3OutScFile : public V3OutCFile {
public:
V3OutScFile(const string& filename) : V3OutCFile(filename) {}
explicit V3OutScFile(const string& filename) : V3OutCFile(filename) {}
virtual ~V3OutScFile() {}
virtual void putsHeader() { puts("// Verilated -*- SystemC -*-\n"); }
virtual void putsIntTopInclude() {
@@ -219,7 +222,7 @@ public:
class V3OutSpFile : public V3OutCFile {
public:
V3OutSpFile(const string& filename) : V3OutCFile(filename) {}
explicit V3OutSpFile(const string& filename) : V3OutCFile(filename) {}
virtual ~V3OutSpFile() {}
virtual void putsHeader() { puts("// Verilated -*- SystemC -*-\n"); }
virtual void putsIntTopInclude() {
@@ -230,21 +233,23 @@ public:
class V3OutVFile : public V3OutFile {
public:
V3OutVFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_VERILOG) {}
explicit V3OutVFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_VERILOG) {}
virtual ~V3OutVFile() {}
virtual void putsHeader() { puts("// Verilated -*- Verilog -*-\n"); }
};
class V3OutXmlFile : public V3OutFile {
public:
V3OutXmlFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_XML) {}
explicit V3OutXmlFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_XML) {
blockIndent(2);
}
virtual ~V3OutXmlFile() {}
virtual void putsHeader() { puts("<?xml version=\"1.0\" ?>\n"); }
};
class V3OutMkFile : public V3OutFile {
public:
V3OutMkFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_MK) {}
explicit V3OutMkFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_MK) {}
virtual ~V3OutMkFile() {}
virtual void putsHeader() { puts("# Verilated -*- Makefile -*-\n"); }
// No automatic indentation yet.
+2 -2
View File
@@ -102,9 +102,9 @@ public:
FileLine (const string& filename, int lineno) {
m_lineno=lineno; m_filenameno = singleton().nameToNumber(filename);
m_warnOn=defaultFileLine().m_warnOn; }
FileLine (FileLine* fromp) {
explicit FileLine (FileLine* fromp) {
m_lineno=fromp->m_lineno; m_filenameno = fromp->m_filenameno; m_warnOn=fromp->m_warnOn; }
FileLine (EmptySecret);
explicit FileLine (EmptySecret);
~FileLine() { }
FileLine* create(const string& filename, int lineno) { return new FileLine(filename,lineno); }
FileLine* create(int lineno) { return create(filename(), lineno); }
+18 -18
View File
@@ -496,7 +496,7 @@ private:
public:
// CONSTUCTORS
GateVisitor(AstNode* nodep) {
explicit GateVisitor(AstNode* nodep) {
AstNode::user1ClearTree();
m_logicVertexp = NULL;
m_scopep = NULL;
@@ -617,7 +617,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
varvertexp->propagateAttrClocksFrom(vvertexp);
}
// Remove the edge
edgep->unlinkDelete(); edgep=NULL;
edgep->unlinkDelete(); VL_DANGLING(edgep);
++m_statRefs;
edgep = vvertexp->outBeginp();
}
@@ -625,7 +625,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
if (removedAllUsages) {
// Remove input links
while (V3GraphEdge* edgep = vvertexp->inBeginp()) {
edgep->unlinkDelete(); edgep=NULL;
edgep->unlinkDelete(); VL_DANGLING(edgep);
}
// Clone tree so we remember it for tracing, and keep the pointer
// to the "ALWAYS" part of the tree as part of this statement
@@ -678,25 +678,25 @@ void GateVisitor::replaceAssigns() {
if (vscp->valuep() && !vscp->valuep()->castNodeMath()) {
//if (debug()>9) vscp->dumpTree(cout, "-vscPre: ");
while (AstNode* delp=vscp->valuep()->castComment()) {
delp->unlinkFrBack()->deleteTree(); delp=NULL;
delp->unlinkFrBack()->deleteTree(); VL_DANGLING(delp);
}
if (AstInitial* delp=vscp->valuep()->castInitial()) {
AstNode* bodyp=delp->bodysp();
bodyp->unlinkFrBackWithNext();
delp->replaceWith(bodyp);
delp->deleteTree(); delp=NULL;
delp->deleteTree(); VL_DANGLING(delp);
}
if (AstAlways* delp=vscp->valuep()->castAlways()) {
AstNode* bodyp=delp->bodysp();
bodyp->unlinkFrBackWithNext();
delp->replaceWith(bodyp);
delp->deleteTree(); delp=NULL;
delp->deleteTree(); VL_DANGLING(delp);
}
if (AstNodeAssign* delp=vscp->valuep()->castNodeAssign()) {
AstNode* rhsp=delp->rhsp();
rhsp->unlinkFrBack();
delp->replaceWith(rhsp);
delp->deleteTree(); delp=NULL;
delp->deleteTree(); VL_DANGLING(delp);
}
//if (debug()>9) {vscp->dumpTree(cout, "-vscDone: "); cout<<endl;}
if (!vscp->valuep()->castNodeMath()
@@ -749,7 +749,7 @@ void GateVisitor::consumedMove() {
// Eventually: Move the statement to a new active block with "tracing-on" sensitivity
UINFO(8," Remove unconsumed "<<nodep<<endl);
nodep->unlinkFrBack();
pushDeletep(nodep); nodep=NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
}
}
}
@@ -817,7 +817,7 @@ private:
// Make the substp an rvalue like nodep. This facilitate the hashing in dedupe.
if (AstNodeVarRef* varrefp = substp->castNodeVarRef()) varrefp->lvalue(false);
nodep->replaceWith(substp);
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
}
virtual void visit(AstNode* nodep, AstNUser*) {
@@ -1039,7 +1039,7 @@ private:
// Remove inputs links
while (V3GraphEdge* inedgep = vvertexp->inBeginp()) {
inedgep->unlinkDelete(); inedgep=NULL;
inedgep->unlinkDelete(); VL_DANGLING(inedgep);
}
// replaceAssigns() does the deleteTree on lvertexNodep in a later step
AstNode* lvertexNodep = lvertexp->nodep();
@@ -1161,14 +1161,14 @@ private:
if (AstSel* newselp = merge(preselp, curselp)) {
UINFO(5, "assemble to new sel: "<<newselp<<endl);
// replace preSel with newSel
preselp->replaceWith(newselp); preselp->deleteTree(); preselp = NULL;
preselp->replaceWith(newselp); preselp->deleteTree(); VL_DANGLING(preselp);
// create new rhs for pre assignment
AstNode* newrhsp = new AstConcat(m_assignp->rhsp()->fileline(), m_assignp->rhsp()->cloneTree(false), assignp->rhsp()->cloneTree(false));
AstNode* oldrhsp = m_assignp->rhsp();
oldrhsp->replaceWith(newrhsp); oldrhsp->deleteTree(); oldrhsp = NULL;
oldrhsp->replaceWith(newrhsp); oldrhsp->deleteTree(); VL_DANGLING(oldrhsp);
m_assignp->dtypeChgWidthSigned(m_assignp->width()+assignp->width(), m_assignp->width()+assignp->width(), AstNumeric::fromBool(true));
// don't need to delete, will be handled
//assignp->unlinkFrBack(); assignp->deleteTree(); assignp = NULL;
//assignp->unlinkFrBack(); assignp->deleteTree(); VL_DANGLING(assignp);
// update the graph
{
@@ -1179,11 +1179,11 @@ private:
ledgep = ledgep->inNextp();
GateEitherVertex* fromvp = dynamic_cast<GateEitherVertex*>(oedgep->fromp());
new V3GraphEdge(m_graphp, fromvp, m_logicvp, 1);
oedgep->unlinkDelete(); oedgep = NULL;
oedgep->unlinkDelete(); VL_DANGLING(oedgep);
}
}
// delete all outedges to lvertexp, only one
oldedgep->unlinkDelete(); oldedgep = NULL;
oldedgep->unlinkDelete(); VL_DANGLING(oldedgep);
}
++m_numMergedAssigns;
} else {
@@ -1202,7 +1202,7 @@ private:
}
public:
GateMergeAssignsGraphVisitor(V3Graph* graphp) {
explicit GateMergeAssignsGraphVisitor(V3Graph* graphp) {
m_assignp = NULL;
m_activep = NULL;
m_logicvp = NULL;
@@ -1241,7 +1241,7 @@ private:
AstNode* valuep = assp->rhsp();
valuep->unlinkFrBack();
assp->replaceWith(valuep);
assp->deleteTree(); assp=NULL;
assp->deleteTree(); VL_DANGLING(assp);
}
}
// Speedups
@@ -1253,7 +1253,7 @@ private:
public:
// CONSTUCTORS
GateDeassignVisitor(AstNode* nodep) {
explicit GateDeassignVisitor(AstNode* nodep) {
nodep->accept(*this);
}
virtual ~GateDeassignVisitor() {}
+2 -2
View File
@@ -109,7 +109,7 @@ private:
AstVarScope* newvscp = genInpClk(vscp);
AstVarRef* newrefp = new AstVarRef(nodep->fileline(), newvscp, nodep->lvalue());
nodep->replaceWith(newrefp);
pushDeletep(nodep); nodep=NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
}
}
}
@@ -213,7 +213,7 @@ private:
}
public:
// CONSTRUCTORS
GenClkReadVisitor(AstNetlist* nodep) {
explicit GenClkReadVisitor(AstNetlist* nodep) {
m_activep = NULL;
m_assignp = NULL;
m_topModp = NULL;
+1 -1
View File
@@ -46,6 +46,7 @@ public:
};
enum en m_e;
inline VWidthMinUsage () : m_e(LINT_WIDTH) {}
// cppcheck-suppress noExplicitConstructor
inline VWidthMinUsage (en _e) : m_e(_e) {}
explicit inline VWidthMinUsage (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -63,7 +64,6 @@ class V3Global {
VWidthMinUsage m_widthMinUsage; // What AstNode::widthMin() is used for
int m_debugFileNumber; // Number to append to debug files created
int m_assertWidthsMatch; // Tree should have width()==widthMin()
bool m_assertDTypesResolved; // Tree should have dtypep()'s
bool m_constRemoveXs; // Const needs to strip any Xs
bool m_needHInlines; // Need __Inlines file
+1 -1
View File
@@ -288,7 +288,7 @@ void V3Graph::dumpDotFilePrefixedAlways(const string& nameComment, bool colorAsS
void V3Graph::dumpDotFile(const string& filename, bool colorAsSubgraph) {
// This generates a file used by graphviz, http://www.graphviz.org
// "hardcoded" parameters:
const auto_ptr<ofstream> logp (V3File::new_ofstream(filename));
const VL_UNIQUE_PTR<ofstream> logp (V3File::new_ofstream(filename));
if (logp->fail()) v3fatalSrc("Can't write "<<filename);
// Header
+1 -1
View File
@@ -167,7 +167,7 @@ protected:
// CONSTRUCTORS
V3GraphVertex(V3Graph* graphp, const V3GraphVertex& old);
public:
V3GraphVertex(V3Graph* graphp);
explicit V3GraphVertex(V3Graph* graphp);
//! Clone copy constructor. Doesn't copy edges or user/userp.
virtual V3GraphVertex* clone(V3Graph* graphp) const {
return new V3GraphVertex(graphp, *this); }
+15 -13
View File
@@ -269,7 +269,7 @@ void GraphAcyc::deleteMarked () {
nextp = vertexp->verticesNextp();
GraphAcycVertex* avertexp = (GraphAcycVertex*)vertexp;
if (avertexp->isDelete()) {
avertexp->unlinkDelete(&m_breakGraph); avertexp=NULL;
avertexp->unlinkDelete(&m_breakGraph); VL_DANGLING(avertexp);
}
}
}
@@ -285,13 +285,13 @@ void GraphAcyc::simplifyNone (GraphAcycVertex* avertexp) {
while (V3GraphEdge* edgep = avertexp->outBeginp()) {
V3GraphVertex* otherVertexp = edgep->top();
//UINFO(9," out "<<otherVertexp<<endl);
edgep->unlinkDelete(); edgep = NULL;
edgep->unlinkDelete(); VL_DANGLING(edgep);
workPush(otherVertexp);
}
while (V3GraphEdge* edgep = avertexp->inBeginp()) {
V3GraphVertex* otherVertexp = edgep->fromp();
//UINFO(9," in "<<otherVertexp<<endl);
edgep->unlinkDelete(); edgep = NULL;
edgep->unlinkDelete(); VL_DANGLING(edgep);
workPush(otherVertexp);
}
}
@@ -319,10 +319,11 @@ void GraphAcyc::simplifyOne (GraphAcycVertex* avertexp) {
&& (!outEdgep->cutable()
|| inEdgep->weight()<outEdgep->weight() ))
? inEdgep : outEdgep);
// cppcheck-suppress leakReturnValNotUsed
edgeFromEdge(templateEdgep, inVertexp, outVertexp);
// Remove old edge
inEdgep->unlinkDelete(); inEdgep = NULL;
outEdgep->unlinkDelete(); outEdgep = NULL; templateEdgep=NULL;
inEdgep->unlinkDelete(); VL_DANGLING(inEdgep);
outEdgep->unlinkDelete(); VL_DANGLING(outEdgep); VL_DANGLING(templateEdgep);
workPush(inVertexp);
workPush(outVertexp);
}
@@ -353,12 +354,13 @@ void GraphAcyc::simplifyOut (GraphAcycVertex* avertexp) {
return;
}
// Make a new edge connecting the two vertices directly
// cppcheck-suppress leakReturnValNotUsed
edgeFromEdge(inEdgep, inVertexp, outVertexp);
// Remove old edge
inEdgep->unlinkDelete(); inEdgep = NULL;
inEdgep->unlinkDelete(); VL_DANGLING(inEdgep);
workPush(inVertexp);
}
outEdgep->unlinkDelete(); outEdgep = NULL;
outEdgep->unlinkDelete(); VL_DANGLING(outEdgep);
workPush(outVertexp);
}
}
@@ -381,18 +383,18 @@ void GraphAcyc::simplifyDup (GraphAcycVertex* avertexp) {
// !cutable duplicates prev !cutable: we can ignore it, redundant
// cutable duplicates prev !cutable: know it's not a relevant loop, ignore it
UINFO(8," DelDupEdge "<<avertexp<<" -> "<<edgep->top()<<endl);
edgep->unlinkDelete(); edgep = NULL;
edgep->unlinkDelete(); VL_DANGLING(edgep);
} else if (!edgep->cutable()) {
// !cutable duplicates prev cutable: delete the earlier cutable
UINFO(8," DelDupPrev "<<avertexp<<" -> "<<prevEdgep->top()<<endl);
prevEdgep->unlinkDelete(); prevEdgep = NULL;
prevEdgep->unlinkDelete(); VL_DANGLING(prevEdgep);
outVertexp->userp(edgep);
} else {
// cutable duplicates prev cutable: combine weights
UINFO(8," DelDupComb "<<avertexp<<" -> "<<edgep->top()<<endl);
prevEdgep->weight (prevEdgep->weight() + edgep->weight());
addOrigEdgep (prevEdgep, edgep);
edgep->unlinkDelete(); edgep = NULL;
edgep->unlinkDelete(); VL_DANGLING(edgep);
}
workPush(outVertexp);
workPush(avertexp);
@@ -410,7 +412,7 @@ void GraphAcyc::cutBasic (GraphAcycVertex* avertexp) {
nextp = edgep->outNextp();
if (edgep->cutable() && edgep->top()==avertexp) {
cutOrigEdge (edgep, " Cut Basic");
edgep->unlinkDelete(); edgep = NULL;
edgep->unlinkDelete(); VL_DANGLING(edgep);
workPush(avertexp);
}
}
@@ -431,7 +433,7 @@ void GraphAcyc::cutBackward (GraphAcycVertex* avertexp) {
nextp = edgep->outNextp();
if (edgep->cutable() && edgep->top()->user()) {
cutOrigEdge (edgep, " Cut A->B->A");
edgep->unlinkDelete(); edgep = NULL;
edgep->unlinkDelete(); VL_DANGLING(edgep);
workPush(avertexp);
}
}
@@ -495,7 +497,7 @@ void GraphAcyc::placeTryEdge(V3GraphEdge* edgep) {
// Adding this edge would cause a loop, kill it
edgep->cutable(true); // So graph still looks pretty
cutOrigEdge (edgep, " Cut loop");
edgep->unlinkDelete(); edgep = NULL;
edgep->unlinkDelete(); VL_DANGLING(edgep);
// Backout the ranks we calculated
while (GraphAcycVertex* vertexp = workBeginp()) {
workPop();
+2 -2
View File
@@ -109,10 +109,10 @@ private:
}
if (saveOld) {
if (m_sumWeights) prevEdgep->weight(prevEdgep->weight() + edgep->weight());
edgep->unlinkDelete(); edgep = NULL;
edgep->unlinkDelete(); VL_DANGLING(edgep);
} else {
if (m_sumWeights) edgep->weight(prevEdgep->weight() + edgep->weight());
prevEdgep->unlinkDelete(); prevEdgep = NULL;
prevEdgep->unlinkDelete(); VL_DANGLING(prevEdgep);
outVertexp->userp(edgep);
}
}
+5 -5
View File
@@ -331,7 +331,7 @@ private:
for (V3GraphVertex* nextp,*vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=nextp) {
nextp = vertexp->verticesNextp();
if (nfaState(vertexp)) {
vertexp->unlinkDelete(m_graphp); vertexp=NULL;
vertexp->unlinkDelete(m_graphp); VL_DANGLING(vertexp);
}
}
@@ -381,7 +381,7 @@ private:
if (vvertexp->accepting()) {
for (V3GraphEdge* nextp,*edgep = vertexp->outBeginp(); edgep; edgep=nextp) {
nextp = edgep->outNextp();
edgep->unlinkDelete(); edgep=NULL;
edgep->unlinkDelete(); VL_DANGLING(edgep);
}
}
}
@@ -417,7 +417,7 @@ private:
for (V3GraphVertex* nextp,*vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=nextp) {
nextp = vertexp->verticesNextp();
if (!vertexp->user()) {
vertexp->unlinkDelete(m_graphp); vertexp=NULL;
vertexp->unlinkDelete(m_graphp); VL_DANGLING(vertexp);
}
}
}
@@ -458,7 +458,7 @@ private:
}
}
// Transitions to this state removed by the unlink function
vertexp->unlinkDelete(m_graphp); vertexp=NULL;
vertexp->unlinkDelete(m_graphp); VL_DANGLING(vertexp);
}
}
}
@@ -535,7 +535,7 @@ private:
DfaVertex* tovertexp = static_cast<DfaVertex*>(edgep->top());
if (tovertexp->accepting()) {
new DfaEdge(graphp(), vvertexp, m_tempNewerReject, vedgep);
edgep->unlinkDelete(); edgep=NULL;
edgep->unlinkDelete(); VL_DANGLING(edgep);
}
// NOT of all values goes to accept
+3 -2
View File
@@ -89,13 +89,14 @@ private:
//--------------------
// Default: Just iterate
virtual void visit(AstVar*, AstNUser*) {}
virtual void visit(AstTypedef*, AstNUser*) {}
virtual void visit(AstNode* nodep, AstNUser*) {
nodeHashIterate(nodep);
}
public:
// CONSTUCTORS
HashedVisitor(AstNode* nodep) {
explicit HashedVisitor(AstNode* nodep) {
nodeHashIterate(nodep);
//UINFO(9," stmthash "<<hex<<V3Hashed::nodeHash(nodep)<<" "<<nodep<<endl);
}
@@ -139,7 +140,7 @@ void V3Hashed::dumpFilePrefixed(const string& nameComment, bool tree) {
}
void V3Hashed::dumpFile(const string& filename, bool tree) {
const auto_ptr<ofstream> logp (V3File::new_ofstream(filename));
const VL_UNIQUE_PTR<ofstream> logp (V3File::new_ofstream(filename));
if (logp->fail()) v3fatalSrc("Can't write "<<filename);
map<int,int> dist;
+9 -9
View File
@@ -135,14 +135,14 @@ private:
} else {
m_modp->user1(1);
}
nodep->unlinkFrBack()->deleteTree(); nodep=NULL; // Remove so don't propagate to upper cell...
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); // Remove so don't propagate to upper cell...
} else if (nodep->pragType() == AstPragmaType::NO_INLINE_MODULE) {
if (!m_modp) {
nodep->v3error("Inline pragma not under a module");
} else {
cantInline("Pragma NO_INLINE_MODULE",false);
}
nodep->unlinkFrBack()->deleteTree(); nodep=NULL; // Remove so don't propagate to upper cell...
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep); // Remove so don't propagate to upper cell...
} else {
nodep->iterateChildren(*this);
}
@@ -185,7 +185,7 @@ private:
public:
// CONSTUCTORS
InlineMarkVisitor(AstNode* nodep) {
explicit InlineMarkVisitor(AstNode* nodep) {
m_modp = NULL;
m_stmtCnt = 0;
nodep->accept(*this);
@@ -227,7 +227,7 @@ private:
public:
// CONSTUCTORS
InlineCollectVisitor(AstNodeModule* nodep) { // passed OLD module, not new one
explicit InlineCollectVisitor(AstNodeModule* nodep) { // passed OLD module, not new one
nodep->accept(*this);
}
virtual ~InlineCollectVisitor() {}
@@ -347,7 +347,7 @@ private:
AstVarRef* exprvarrefp = nodep->varp()->user2p()->castNode()->castVarRef();
if (exprconstp) {
nodep->replaceWith(exprconstp->cloneTree(true));
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
return;
}
else if (exprvarrefp) {
@@ -521,9 +521,9 @@ private:
if (stmtsp) stmtsp->unlinkFrBackWithNext();
if (stmtsp) m_modp->addStmtp(stmtsp);
// Remove the cell
newmodp->deleteTree(); newmodp=NULL; // Clear any leftover ports, etc
newmodp->deleteTree(); VL_DANGLING(newmodp); // Clear any leftover ports, etc
nodep->unlinkFrBack();
pushDeletep(nodep); nodep = NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
if (debug()>=9) { m_modp->dumpTree(cout,"donemod:"); }
}
}
@@ -537,7 +537,7 @@ private:
public:
// CONSTUCTORS
InlineVisitor(AstNode* nodep) {
explicit InlineVisitor(AstNode* nodep) {
m_modp = NULL;
nodep->accept(*this);
}
@@ -560,7 +560,7 @@ void V3Inline::inlineAll(AstNetlist* nodep) {
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=nextmodp) {
nextmodp = modp->nextp()->castNodeModule();
if (modp->user1()) { // Was inlined
modp->unlinkFrBack()->deleteTree(); modp=NULL;
modp->unlinkFrBack()->deleteTree(); VL_DANGLING(modp);
}
}
V3Global::dumpCheckGlobalTree("inline.tree", 0, v3Global.opt.dumpTreeLevel(__FILE__) >= 3);
+62 -6
View File
@@ -109,8 +109,9 @@ private:
// Create an AstAssignVarScope for Vars to Cells so we can link with their scope later
AstNode* lhsp = new AstVarXRef (exprp->fileline(), nodep->modVarp(), m_cellp->name(), false);
AstVarRef* refp = exprp->castVarRef();
if (!refp) exprp->v3fatalSrc("Interfaces: Pin is not connected to a VarRef");
AstAssignVarScope* assp = new AstAssignVarScope(exprp->fileline(), lhsp, refp);
AstVarXRef* xrefp = exprp->castVarXRef();
if (!refp && !xrefp) exprp->v3fatalSrc("Interfaces: Pin is not connected to a VarRef or VarXRef");
AstAssignVarScope* assp = new AstAssignVarScope(exprp->fileline(), lhsp, exprp);
m_modp->addStmtp(assp);
} else {
nodep->v3error("Assigned pin is neither input nor output");
@@ -118,7 +119,7 @@ private:
}
// We're done with the pin
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
virtual void visit(AstUdpTable* nodep, AstNUser*) {
@@ -139,7 +140,7 @@ private:
}
public:
// CONSTUCTORS
InstVisitor(AstNode* nodep) {
explicit InstVisitor(AstNode* nodep) {
m_modp=NULL;
m_cellp=NULL;
//
@@ -169,6 +170,12 @@ private:
if (nodep->rangep()) {
m_cellRangep = nodep->rangep();
UINFO(4," CELL "<<nodep<<endl);
AstVar *ifaceVarp = nodep->nextp()->castVar();
bool isIface = ifaceVarp
&& ifaceVarp->dtypep()->castUnpackArrayDType()
&& 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++) {
@@ -181,6 +188,22 @@ private:
// 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__");
// If this AstCell is actually an interface instantiation, let's ensure we also clone
// the IfaceRef.
if (isIface) {
AstUnpackArrayDType *arrdtype = ifaceVarp->dtypep()->castUnpackArrayDType();
AstVar* varNewp = ifaceVarp->cloneTree(false);
AstIfaceRefDType *ifaceRefp = arrdtype->subDTypep()->castIfaceRefDType()->cloneTree(false);
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->dtypep(ifaceRefp);
newp->addNextHere(varNewp);
if (debug()==9) { varNewp->dumpTree(cout, "newintf: "); cout << endl; }
}
// Fixup pins
newp->pinsp()->iterateAndNext(*this);
if (debug()==9) { newp->dumpTree(cout,"newcell: "); cout<<endl; }
@@ -188,9 +211,14 @@ private:
// Done. Delete original
m_cellRangep=NULL;
nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
if (isIface) {
ifaceVarp->unlinkFrBack(); pushDeletep(ifaceVarp); VL_DANGLING(ifaceVarp);
}
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
}
nodep->iterateChildren(*this);
}
virtual void visit(AstPin* nodep, AstNUser*) {
// Any non-direct pins need reconnection with a part-select
if (!nodep->exprp()) return; // No-connect
@@ -217,6 +245,29 @@ private:
} else {
nodep->v3fatalSrc("Width mismatch; V3Width should have errored out.");
}
} else if(AstArraySel *arrselp = nodep->exprp()->castArraySel()) {
if (AstUnpackArrayDType *arrp = arrselp->lhsp()->dtypep()->castUnpackArrayDType()) {
if (!arrp->subDTypep()->castIfaceRefDType())
return;
AstConst *constp = arrselp->rhsp()->castConst();
if (!constp) {
nodep->v3error("Unsupported: Non-constant index when passing interface to module");
return;
}
string index = AstNode::encodeNumber(constp->toSInt());
AstVarRef *varrefp = arrselp->lhsp()->castVarRef();
AstVarXRef *newp = new AstVarXRef(nodep->fileline(),varrefp->name () + "__BRA__" + index + "__KET__", "", true);
AstVar *varp = varrefp->varp()->cloneTree(true);
varp->name(varp->name() + "__TMP__" + "__BRA__" + index + "__KET__");
varp->dtypep(arrp->subDTypep()->backp()->castIfaceRefDType());
newp->addNextHere(varp);
newp->varp(varp);
newp->dtypep(arrp->subDTypep()->castIfaceRefDType());
newp->packagep(varrefp->packagep());
arrselp->addNextHere(newp);
arrselp->unlinkFrBack()->deleteTree();
}
}
}
@@ -229,7 +280,7 @@ private:
}
public:
// CONSTUCTORS
InstDeVisitor(AstNode* nodep) {
explicit InstDeVisitor(AstNode* nodep) {
m_cellRangep=NULL;
m_instNum=0;
m_instLsb=0;
@@ -272,8 +323,10 @@ public:
// Else create a intermediate wire to perform the interconnect
// Return the new assignment, if one was made
// Note this module calles cloneTree() via new AstVar
AstVar* pinVarp = pinp->modVarp();
AstVarRef* connectRefp = pinp->exprp()->castVarRef();
AstVarXRef* connectXRefp = pinp->exprp()->castVarXRef();
AstBasicDType* pinBasicp = pinVarp->dtypep()->basicp(); // Maybe NULL
AstBasicDType* connBasicp = NULL;
AstAssignW* assignp = NULL;
@@ -288,6 +341,9 @@ public:
&& connectRefp
&& connectRefp->varp()->isIfaceRef()) {
// Done. Interface
} else if (!alwaysCvt
&& connectXRefp
&& connectXRefp->varp()->isIfaceRef()) {
} else if (!alwaysCvt
&& connBasicp
&& pinBasicp
+2 -1
View File
@@ -64,8 +64,9 @@ public:
//
enum en m_e;
inline V3LangCode () : m_e(L_ERROR) {}
// cppcheck-suppress noExplicitConstructor
inline V3LangCode (en _e) : m_e(_e) {}
V3LangCode (const char* textp);
explicit V3LangCode (const char* textp);
explicit inline V3LangCode (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
};
+9 -9
View File
@@ -93,10 +93,10 @@ public:
LifeVarEntry(SIMPLEASSIGN, AstNodeAssign* assp) {
init(true); simpleAssign(assp);
}
LifeVarEntry(COMPLEXASSIGN) {
explicit LifeVarEntry(COMPLEXASSIGN) {
init(false); complexAssign();
}
LifeVarEntry(CONSUMED) {
explicit LifeVarEntry(CONSUMED) {
init(false); consumed();
}
~LifeVarEntry() {}
@@ -162,7 +162,7 @@ public:
// above our current iteration point.
if (debug()>4) oldassp->dumpTree(cout, " REMOVE/SAMEBLK ");
entp->complexAssign();
m_statep->pushUnlinkDeletep(oldassp); oldassp=NULL;
m_statep->pushUnlinkDeletep(oldassp); VL_DANGLING(oldassp);
++m_statep->m_statAssnDel;
}
}
@@ -199,7 +199,7 @@ public:
// We'll later constant propagate
UINFO(4," replaceconst: "<<varrefp<<endl);
varrefp->replaceWith(constp->cloneTree(false));
varrefp->deleteTree(); varrefp=NULL;
varrefp->deleteTree(); VL_DANGLING(varrefp);
++m_statep->m_statAssnCon;
return; // **DONE, no longer a var reference**
}
@@ -313,7 +313,7 @@ private:
if (nodep->lvalue()) {
m_lifep->complexAssign(vscp);
} else {
m_lifep->varUsageReplace(vscp, nodep); nodep=NULL;
m_lifep->varUsageReplace(vscp, nodep); VL_DANGLING(nodep);
}
}
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
@@ -455,14 +455,14 @@ public:
m_sideEffect = false;
m_noopt = false;
{
// Cpp check bug, it is deleted
// cppcheck-suppress leak
m_lifep = new LifeBlock (NULL, m_statep);
nodep->accept(*this);
delete m_lifep; m_lifep=NULL;
if (m_lifep) { delete m_lifep; m_lifep=NULL; }
}
}
virtual ~LifeVisitor() {}
virtual ~LifeVisitor() {
if (m_lifep) { delete m_lifep; m_lifep=NULL; }
}
};
//######################################################################
+4 -4
View File
@@ -68,7 +68,7 @@ private:
UINFO(9, " Replace "<<nodep<<" to "<<newvscp<<endl);
AstVarRef* newrefp = new AstVarRef(nodep->fileline(), newvscp, nodep->lvalue());
nodep->replaceWith(newrefp);
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
}
virtual void visit(AstNodeModule* nodep, AstNUser*) {
@@ -86,7 +86,7 @@ private:
}
public:
// CONSTRUCTORS
LifePostElimVisitor(AstTopScope* nodep) {
explicit LifePostElimVisitor(AstTopScope* nodep) {
nodep->accept(*this);
}
virtual ~LifePostElimVisitor() {}
@@ -155,7 +155,7 @@ private:
UINFO(4," DELETE "<<nodep<<endl);
// Mark so LifePostElimVisitor will get it
rhsp->varScopep()->user4p(lhsp->varScopep());
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
++m_statAssnDel;
}
}
@@ -178,7 +178,7 @@ private:
}
public:
// CONSTRUCTORS
LifePostDlyVisitor(AstNetlist* nodep) {
explicit LifePostDlyVisitor(AstNetlist* nodep) {
nodep->accept(*this);
}
virtual ~LifePostDlyVisitor() {
+16 -7
View File
@@ -66,7 +66,7 @@ public:
class LibraryVertex : public V3GraphVertex {
public:
LibraryVertex(V3Graph* graphp)
explicit LibraryVertex(V3Graph* graphp)
: V3GraphVertex(graphp) {}
virtual ~LibraryVertex() {}
virtual string name() const { return "*LIBRARY*"; }
@@ -292,7 +292,7 @@ private:
if (pinStar) pinp->v3error("Duplicate .* in a cell");
pinStar = true;
// Done with this fake pin
pinp->unlinkFrBack()->deleteTree(); pinp=NULL;
pinp->unlinkFrBack()->deleteTree(); VL_DANGLING(pinp);
}
}
// Convert unnamed pins to pin number based assignments
@@ -348,11 +348,20 @@ private:
// This is quite similar to how classes work; when unpacked classes are better supported
// may remap interfaces to be more like a class.
if (!nodep->hasIfaceVar()) {
string varName = nodep->name()+"__Viftop"; // V3LinkDot looks for this naming
AstIfaceRefDType* idtypep = new AstIfaceRefDType(nodep->fileline(), nodep->name(), nodep->modp()->name());
idtypep->cellp(nodep); // Only set when real parent cell known
string varName = nodep->name() + "__Viftop"; // V3LinkDot looks for this naming
AstIfaceRefDType *idtypep = new AstIfaceRefDType(nodep->fileline(), nodep->name(),
nodep->modp()->name());
idtypep->ifacep(NULL); // cellp overrides
AstVar* varp = new AstVar(nodep->fileline(), AstVarType::IFACEREF, varName, VFlagChildDType(), idtypep);
AstVar *varp;
if (nodep->rangep()) {
AstNodeArrayDType *arrp = new AstUnpackArrayDType(nodep->fileline(),VFlagChildDType(), idtypep, nodep->rangep()->cloneTree(true));
varp = new AstVar(nodep->fileline(), AstVarType::IFACEREF, varName,
VFlagChildDType(), arrp);
} else {
idtypep->cellp(nodep); // Only set when real parent cell known
varp = new AstVar(nodep->fileline(), AstVarType::IFACEREF, varName,
VFlagChildDType(), idtypep);
}
varp->isIfaceParent(true);
nodep->addNextHere(varp);
nodep->hasIfaceVar(true);
@@ -384,7 +393,7 @@ private:
<<foundp->warnMore()<<"... Location of original declaration");
}
nodep->unlinkFrBack();
pushDeletep(nodep); nodep=NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
} else if (!foundp) {
m_mods.rootp()->insert(nodep->name(), new VSymEnt(&m_mods, nodep));
}
+80 -40
View File
@@ -372,7 +372,14 @@ public:
UINFO(9, " insAllIface se"<<(void*)varSymp<<" "<<varp<<endl);
AstIfaceRefDType* ifacerefp = varp->subDTypep()->castIfaceRefDType();
if (!ifacerefp) varp->v3fatalSrc("Non-ifacerefs on list!");
if (!ifacerefp->ifaceViaCellp()) ifacerefp->v3fatalSrc("Unlinked interface");
if (!ifacerefp->ifaceViaCellp()) {
if (!ifacerefp->cellp()) { // Probably a NotFoundModule, or a normal module if made mistake
ifacerefp->v3error("Cannot find file containing interface: "<<AstNode::prettyName(ifacerefp->ifaceName()));
continue;
} else {
ifacerefp->v3fatalSrc("Unlinked interface");
}
}
VSymEnt* ifaceSymp = getNodeSym(ifacerefp->ifaceViaCellp());
VSymEnt* ifOrPortSymp = ifaceSymp;
// Link Modport names to the Modport Node under the Interface
@@ -814,7 +821,7 @@ class LinkDotFindVisitor : public AstNVisitor {
newdtypep->unlinkFrBack();
findvarp->childDTypep(newdtypep);
}
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
} else {
nodep->v3error("Duplicate declaration of signal: "<<nodep->prettyName()<<endl
<<findvarp->warnMore()<<"... Location of original declaration");
@@ -1005,7 +1012,7 @@ private:
nodep->name(),
exprp);
cellp->addParamsp(pinp);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
}
virtual void visit(AstPort* nodep, AstNUser*) {
@@ -1025,7 +1032,7 @@ private:
symp->exported(false);
}
// Ports not needed any more
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
virtual void visit(AstAssignW* nodep, AstNUser*) {
// Deal with implicit definitions
@@ -1050,7 +1057,7 @@ private:
// Unsupported gates need implicit creation
pinImplicitExprRecurse(nodep);
// We're done with implicit gates
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
virtual void visit(AstNode* nodep, AstNUser*) {
// Default: Just iterate
@@ -1145,8 +1152,9 @@ class LinkDotScopeVisitor : public AstNVisitor {
VSymEnt* rhsSymp;
{
AstVarRef* refp = nodep->rhsp()->castVarRef();
if (!refp) nodep->v3fatalSrc("Unsupported: Non VarRef attached to interface pin");
string scopename = refp->name();
AstVarXRef* xrefp = nodep->rhsp()->castVarXRef();
if (!refp && !xrefp) nodep->v3fatalSrc("Unsupported: Non Var(X)Ref attached to interface pin");
string scopename = refp ? refp->name() : xrefp->name();
string baddot; VSymEnt* okSymp;
VSymEnt* symp = m_statep->findDotted(m_modSymp, scopename, baddot, okSymp);
if (!symp) nodep->v3fatalSrc("No symbol for interface alias rhs");
@@ -1168,7 +1176,7 @@ class LinkDotScopeVisitor : public AstNVisitor {
// or maybe an alias of an alias
m_statep->insertScopeAlias(LinkDotState::SAMN_IFTOP, lhsSymp, rhsSymp);
// We have stored the link, we don't need these any more
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
// For speed, don't recurse things that can't have scope
// Note we allow AstNodeStmt's as generates may be under them
@@ -1235,7 +1243,7 @@ class LinkDotIfaceVisitor : public AstNVisitor {
if (m_statep->forScopeCreation()) {
// Done with AstModportFTaskRef.
// Delete to prevent problems if we dead-delete pointed to ftask
nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
}
}
virtual void visit(AstModportVarRef* nodep, AstNUser*) {
@@ -1258,7 +1266,7 @@ class LinkDotIfaceVisitor : public AstNVisitor {
if (m_statep->forScopeCreation()) {
// Done with AstModportVarRef.
// Delete to prevent problems if we dead-delete pointed to variable
nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
}
}
virtual void visit(AstNode* nodep, AstNUser*) {
@@ -1322,12 +1330,15 @@ private:
DotPosition m_dotPos; // Scope part of dotted resolution
VSymEnt* m_dotSymp; // SymEnt for dotted AstParse lookup
AstDot* m_dotp; // Current dot
bool m_unresolved; // Unresolved, needs help from V3Param
AstNode* m_unlinkedScope;// Unresolved scope, needs corresponding VarXRef
bool m_dotErr; // Error found in dotted resolution, ignore upwards
string m_dotText; // String of dotted names found in below parseref
DotStates() { init(NULL); }
~DotStates() {}
void init(VSymEnt* curSymp) {
m_dotPos = DP_NONE; m_dotSymp = curSymp; m_dotp = NULL; m_dotErr = false; m_dotText = "";
m_unresolved = false; m_unlinkedScope = NULL;
}
string ascii() const {
static const char* names[] = { "NONE","PACKAGE","SCOPE","FINAL","MEMBER" };
@@ -1335,6 +1346,7 @@ private:
sstr<<"ds="<<names[m_dotPos];
sstr<<" dse"<<(void*)m_dotSymp;
sstr<<" txt="<<m_dotText;
sstr<<" unr="<<m_unresolved;
return sstr.str();
}
} m_ds; // State to preserve across recursions
@@ -1416,7 +1428,7 @@ private:
virtual void visit(AstCellInline* nodep, AstNUser*) {
checkNoDot(nodep);
if (m_statep->forScopeCreation()) {
nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
}
}
virtual void visit(AstCell* nodep, AstNUser*) {
@@ -1460,7 +1472,7 @@ private:
if (!refp) {
if (nodep->name() == "__paramNumber1" && m_cellp->modp()->castPrimitive()) {
// Primitive parameter is really a delay we can just ignore
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
return;
}
nodep->v3error(ucfirst(whatp)<<" not found: "<<nodep->prettyName());
@@ -1487,7 +1499,7 @@ private:
if (nodep->user3SetOnce()) return;
UINFO(8," "<<nodep<<endl);
DotStates lastStates = m_ds;
bool start = !m_ds.m_dotp; // Save, as m_dotp will be changed
bool start = (m_ds.m_dotPos == DP_NONE); // Save, as m_dotp will be changed
{
if (start) { // Starting dot sequence
if (debug()>=9) nodep->dumpTree("-dot-in: ");
@@ -1498,13 +1510,16 @@ private:
// m_ds.m_dotText communicates the cell prefix between stages
if (nodep->lhsp()->castPackageRef()) {
if (!start) { nodep->lhsp()->v3error("Package reference may not be embedded in dotted reference"); m_ds.m_dotErr=true; }
//if (!start) { nodep->lhsp()->v3error("Package reference may not be embedded in dotted reference"); m_ds.m_dotErr=true; }
m_ds.m_dotPos = DP_PACKAGE;
} else {
m_ds.m_dotPos = DP_SCOPE;
nodep->lhsp()->iterateAndNext(*this);
//if (debug()>=9) nodep->dumpTree("-dot-lho: ");
}
if (m_ds.m_unresolved && (nodep->lhsp()->castCellRef() || nodep->lhsp()->castCellArrayRef())) {
m_ds.m_unlinkedScope = nodep->lhsp();
}
if (!m_ds.m_dotErr) { // Once something wrong, give up
if (start && m_ds.m_dotPos==DP_SCOPE) m_ds.m_dotPos = DP_FINAL; // Top 'final' dot RHS is final RHS, else it's a DOT(DOT(x,*here*),real-rhs) which we consider a RHS
nodep->rhsp()->iterateAndNext(*this);
@@ -1520,11 +1535,15 @@ private:
}
if (debug()>=9) newp->dumpTree("-dot-out: ");
nodep->replaceWith(newp);
pushDeletep(nodep); nodep=NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
} else { // Dot midpoint
AstNode* newp = nodep->rhsp()->unlinkFrBack();
if (m_ds.m_unresolved) {
AstCellRef* crp = new AstCellRef(nodep->fileline(), nodep->name(), nodep->lhsp()->unlinkFrBack(), newp);
newp = crp;
}
nodep->replaceWith(newp);
pushDeletep(nodep); nodep=NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
}
}
if (start) {
@@ -1541,7 +1560,7 @@ private:
if (!m_ds.m_dotSymp) nodep->v3fatalSrc("NULL lookup symbol table");
if (!m_statep->forPrimary()) nodep->v3fatalSrc("ParseRefs should no longer exist");
DotStates lastStates = m_ds;
bool start = !m_ds.m_dotp;
bool start = (m_ds.m_dotPos == DP_NONE); // Save, as m_dotp will be changed
if (start) {
m_ds.init(m_curSymp);
// Note m_ds.m_dot remains NULL; this is a reference not under a dot
@@ -1551,7 +1570,7 @@ private:
AstNode* varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack();
AstNode* newp = new AstMemberSel(nodep->fileline(), varEtcp, VFlagChildDType(), nodep->name());
nodep->replaceWith(newp);
pushDeletep(nodep); nodep=NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
}
else {
//
@@ -1624,7 +1643,7 @@ private:
m_ds.m_dotPos = DP_SCOPE;
UINFO(9," cell -> iface varref "<<foundp->nodep()<<endl);
AstNode* newp = new AstVarRef(ifaceRefVarp->fileline(), ifaceRefVarp, false);
nodep->replaceWith(newp); pushDeletep(nodep); nodep = NULL;
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
}
}
else if (AstVar* varp = foundp->nodep()->castVar()) {
@@ -1638,21 +1657,28 @@ private:
m_ds.m_dotPos = DP_SCOPE;
ok = true;
AstNode* newp = new AstVarRef(nodep->fileline(), varp, false);
nodep->replaceWith(newp); pushDeletep(nodep); nodep = NULL;
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
}
else if (allowVar) {
AstNodeVarRef* newp;
AstNode* newp;
if (m_ds.m_dotText != "") {
newp = new AstVarXRef(nodep->fileline(), nodep->name(), m_ds.m_dotText, false); // lvalue'ness computed later
newp->varp(varp);
AstVarXRef* refp = new AstVarXRef(nodep->fileline(), nodep->name(), m_ds.m_dotText, false); // lvalue'ness computed later
refp->varp(varp);
m_ds.m_dotText = "";
if (m_ds.m_unresolved && m_ds.m_unlinkedScope) {
newp = new AstUnlinkedVarXRef(nodep->fileline(), refp->castVarXRef(), refp->name(), m_ds.m_unlinkedScope->unlinkFrBack());
m_ds.m_unlinkedScope = NULL;
m_ds.m_unresolved = false;
} else {
newp = refp;
}
} else {
newp = new AstVarRef(nodep->fileline(), nodep->name(), false); // lvalue'ness computed later
newp->varp(varp);
newp->packagep(foundp->packagep());
UINFO(9," new "<<newp<<endl);
AstVarRef* refp = new AstVarRef(nodep->fileline(), varp, false); // lvalue'ness computed later
refp->packagep(foundp->packagep());
newp = refp;
}
nodep->replaceWith(newp); pushDeletep(nodep); nodep = NULL;
UINFO(9," new "<<newp<<endl);
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
m_ds.m_dotPos = DP_MEMBER;
ok = true;
}
@@ -1682,13 +1708,13 @@ private:
ok = true;
AstVar* varp = makeIfaceModportVar(nodep->fileline(), cellp, ifacep, modportp);
AstVarRef* refp = new AstVarRef(varp->fileline(), varp, false);
nodep->replaceWith(refp); pushDeletep(nodep); nodep = NULL;
nodep->replaceWith(refp); pushDeletep(nodep); VL_DANGLING(nodep);
}
}
else if (AstEnumItem* valuep = foundp->nodep()->castEnumItem()) {
if (allowVar) {
AstNode* newp = new AstEnumItemRef(nodep->fileline(), valuep, foundp->packagep());
nodep->replaceWith(newp); pushDeletep(nodep); nodep = NULL;
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
ok = true;
m_ds.m_dotText = "";
}
@@ -1717,7 +1743,7 @@ private:
// Create if implicit, and also if error (so only complain once)
AstVarRef* newp = new AstVarRef(nodep->fileline(), nodep->name(), false);
nodep->replaceWith(newp);
pushDeletep(nodep); nodep = NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
createImplicitVar (m_curSymp, newp, m_modp, m_modSymp, err);
}
}
@@ -1795,7 +1821,7 @@ private:
UINFO(7," Resolved "<<nodep<<endl); // Also prints taskp
AstVarRef* newvscp = new AstVarRef(nodep->fileline(), vscp, nodep->lvalue());
nodep->replaceWith(newvscp);
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
UINFO(9," new "<<newvscp<<endl); // Also prints taskp
}
}
@@ -1838,7 +1864,7 @@ private:
AstNode* argsp = NULL; if (nodep->pinsp()) argsp = nodep->pinsp()->unlinkFrBackWithNext();
AstNode* newp = new AstMethodSel(nodep->fileline(), varEtcp, VFlagChildDType(), nodep->name(), argsp);
nodep->replaceWith(newp);
pushDeletep(nodep); nodep=NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
return;
} else {
checkNoDot(nodep);
@@ -1906,12 +1932,9 @@ private:
if (nodep->user3SetOnce()) return;
nodep->lhsp()->iterateAndNext(*this);
if (m_ds.m_dotPos == DP_SCOPE) { // Already under dot, so this is {modulepart} DOT {modulepart}
if (AstConst* constp = nodep->rhsp()->castConst()) {
string index = AstNode::encodeNumber(constp->toSInt());
m_ds.m_dotText += "__BRA__"+index+"__KET__";
} else {
nodep->v3error("Unsupported: Non-constant inside []'s in the cell part of a dotted reference");
}
UINFO(9," deferring until after a V3Param pass: "<<nodep<<endl);
m_ds.m_dotText += "__BRA__??__KET__";
m_ds.m_unresolved = true;
// And pass up m_ds.m_dotText
}
// Pass dot state down to fromp()
@@ -1923,6 +1946,11 @@ private:
nodep->attrp()->iterateAndNext(*this);
}
m_ds = lastStates;
if (m_ds.m_unresolved && m_ds.m_dotPos == DP_SCOPE) {
AstNode* exprp = nodep->bitp()->unlinkFrBack();
AstCellArrayRef* newp = new AstCellArrayRef(nodep->fileline(), nodep->fromp()->name(), exprp);
nodep->replaceWith(newp); pushDeletep(nodep); VL_DANGLING(nodep);
}
}
virtual void visit(AstNodePreSel* nodep, AstNUser*) {
// Excludes simple AstSelBit, see above
@@ -2016,7 +2044,19 @@ private:
virtual void visit(AstPackageImport* nodep, AstNUser*) {
// No longer needed
checkNoDot(nodep);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
virtual void visit(AstCellRef* nodep, AstNUser*) {
UINFO(5," AstCellRef: "<<nodep<<" "<<m_ds.ascii()<<endl);
nodep->iterateChildren(*this);
}
virtual void visit(AstCellArrayRef* nodep, AstNUser*) {
UINFO(5," AstCellArrayRef: "<<nodep<<" "<<m_ds.ascii()<<endl);
// Expression already iterated
}
virtual void visit(AstUnlinkedVarXRef* nodep, AstNUser*) {
UINFO(5," AstCellArrayRef: "<<nodep<<" "<<m_ds.ascii()<<endl);
// No need to iterate, if we have a UnlinkedVarXRef, we're already done
}
virtual void visit(AstNode* nodep, AstNUser*) {
// Default: Just iterate
+6 -6
View File
@@ -159,7 +159,7 @@ private:
initsp = initsp->addNext(newp);
newp = initsp;
nodep->replaceWith(newp);
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
virtual void visit(AstWhile* nodep, AstNUser*) {
// Don't need to track AstRepeat/AstFor as they have already been converted
@@ -192,7 +192,7 @@ private:
AstJumpLabel* labelp = findAddLabel(m_ftaskp, false);
nodep->addPrev(new AstJumpGo(nodep->fileline(), labelp));
}
nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
}
virtual void visit(AstBreak* nodep, AstNUser*) {
nodep->iterateChildren(*this);
@@ -202,7 +202,7 @@ private:
AstJumpLabel* labelp = findAddLabel(m_loopp, false);
nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp));
}
nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
}
virtual void visit(AstContinue* nodep, AstNUser*) {
nodep->iterateChildren(*this);
@@ -213,7 +213,7 @@ private:
AstJumpLabel* labelp = findAddLabel(m_loopp, true);
nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp));
}
nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
}
virtual void visit(AstDisable* nodep, AstNUser*) {
UINFO(8," DISABLE "<<nodep<<endl);
@@ -233,7 +233,7 @@ private:
AstJumpLabel* labelp = findAddLabel(beginp, false);
nodep->addNextHere(new AstJumpGo(nodep->fileline(), labelp));
}
nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
//if (debug()>=9) { UINFO(0,"\n"); beginp->dumpTree(cout," labelo: "); }
}
virtual void visit(AstVarRef* nodep, AstNUser*) {
@@ -246,7 +246,7 @@ private:
}
public:
// CONSTUCTORS
LinkJumpVisitor(AstNetlist* nodep) {
explicit LinkJumpVisitor(AstNetlist* nodep) {
m_modp = NULL;
m_ftaskp = NULL;
m_loopp = NULL;
+8
View File
@@ -211,6 +211,14 @@ private:
}
m_setRefLvalue = last_setRefLvalue;
}
virtual void visit(AstCellArrayRef* nodep, AstNUser*) {
bool last_setRefLvalue = m_setRefLvalue;
{ // selp is not an lvalue
m_setRefLvalue = false;
nodep->selp()->iterateAndNext(*this);
}
m_setRefLvalue = last_setRefLvalue;
}
virtual void visit(AstNodePreSel* nodep, AstNUser*) {
bool last_setRefLvalue = m_setRefLvalue;
{ // Only set lvalues on the from
+15 -15
View File
@@ -190,62 +190,62 @@ private:
AstTypedef* typep = nodep->backp()->castTypedef();
if (!typep) nodep->v3fatalSrc("Attribute not attached to typedef");
typep->attrPublic(true);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_CLOCK) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
m_varp->attrScClocked(true);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_CLOCK_ENABLE) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
m_varp->attrClockEn(true);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_PUBLIC) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
m_varp->sigUserRWPublic(true); m_varp->sigModPublic(true);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_PUBLIC_FLAT) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
m_varp->sigUserRWPublic(true);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_PUBLIC_FLAT_RD) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
m_varp->sigUserRdPublic(true);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_PUBLIC_FLAT_RW) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
m_varp->sigUserRWPublic(true);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_ISOLATE_ASSIGNMENTS) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
m_varp->attrIsolateAssign(true);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_SFORMAT) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
m_varp->attrSFormat(true);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_SC_BV) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
m_varp->attrScBv(true);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_CLOCKER) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
m_varp->attrClocker(AstVarAttrClocker::CLOCKER_YES);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
else if (nodep->attrType() == AstAttrType::VAR_NO_CLOCKER) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
m_varp->attrClocker(AstVarAttrClocker::CLOCKER_NO);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
}
@@ -288,7 +288,7 @@ private:
if (backp->castTypedef()) { // A typedef doesn't need us to make yet another level of typedefing
// For typedefs just remove the AstRefDType level of abstraction
nodep->replaceWith(dtypep);
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
return;
} else {
defp = new AstTypedef(nodep->fileline(), nodep->name(), NULL, VFlagChildDType(), dtypep);
@@ -297,7 +297,7 @@ private:
}
}
nodep->replaceWith(new AstRefDType(nodep->fileline(), defp->name()));
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
virtual void visit(AstTypedefFwd* nodep, AstNUser*) {
@@ -349,7 +349,7 @@ private:
public:
// CONSTUCTORS
LinkParseVisitor(AstNetlist* rootp) {
explicit LinkParseVisitor(AstNetlist* rootp) {
m_varp = NULL;
m_modp = NULL;
m_ftaskp = NULL;
+75 -37
View File
@@ -82,7 +82,7 @@ private:
nodep->iterateChildren(*this);
// Initial assignments under function/tasks can just be simple assignments without the initial
if (m_ftaskp) {
nodep->replaceWith(nodep->bodysp()->unlinkFrBackWithNext()); nodep=NULL;
nodep->replaceWith(nodep->bodysp()->unlinkFrBackWithNext()); VL_DANGLING(nodep);
}
}
virtual void visit(AstVAssert* nodep, AstNUser*) {
@@ -167,18 +167,18 @@ private:
did=0;
if (AstNodeSel* selp = nodep->sensp()->castNodeSel()) {
AstNode* fromp = selp->fromp()->unlinkFrBack();
selp->replaceWith(fromp); selp->deleteTree(); selp=NULL;
selp->replaceWith(fromp); selp->deleteTree(); VL_DANGLING(selp);
did=1;
}
// NodeSel doesn't include AstSel....
if (AstSel* selp = nodep->sensp()->castSel()) {
AstNode* fromp = selp->fromp()->unlinkFrBack();
selp->replaceWith(fromp); selp->deleteTree(); selp=NULL;
selp->replaceWith(fromp); selp->deleteTree(); VL_DANGLING(selp);
did=1;
}
if (AstNodePreSel* selp = nodep->sensp()->castNodePreSel()) {
AstNode* fromp = selp->lhsp()->unlinkFrBack();
selp->replaceWith(fromp); selp->deleteTree(); selp=NULL;
selp->replaceWith(fromp); selp->deleteTree(); VL_DANGLING(selp);
did=1;
}
}
@@ -204,10 +204,17 @@ private:
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) { // Maybe varxref - so need to clone
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
varrefp->cloneTree(false)));
} else if (AstUnlinkedVarXRef* uvxrp = basefromp->castUnlinkedVarXRef()) { // Maybe varxref - so need to clone
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::VAR_BASE,
uvxrp->cloneTree(false)));
} else if (AstMemberSel* fromp = basefromp->castMemberSel()) {
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::MEMBER_BASE,
fromp->cloneTree(false)));
} else if (AstEnumItemRef* fromp = basefromp->castEnumItemRef()) {
nodep->attrp(new AstAttrOf(nodep->fileline(), AstAttrType::ENUM_BASE,
fromp->cloneTree(false)));
} else {
if (basefromp) { UINFO(1," Related node: "<<basefromp<<endl); }
nodep->v3fatalSrc("Illegal bit select; no signal/member being extracted from");
}
}
@@ -229,17 +236,17 @@ private:
if (nodep->pragType() == AstPragmaType::PUBLIC_MODULE) {
if (!m_modp) nodep->v3fatalSrc("PUBLIC_MODULE not under a module\n");
m_modp->modPublic(true);
nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
}
else if (nodep->pragType() == AstPragmaType::PUBLIC_TASK) {
if (!m_ftaskp) nodep->v3fatalSrc("PUBLIC_TASK not under a task\n");
m_ftaskp->taskPublic(true);
m_modp->modPublic(true); // Need to get to the task...
nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
}
else if (nodep->pragType() == AstPragmaType::COVERAGE_BLOCK_OFF) {
if (!v3Global.opt.coverageLine()) { // No need for block statements; may optimize better without
nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
}
}
else {
@@ -247,7 +254,7 @@ private:
}
}
void expectFormat(AstNode* nodep, const string& format, AstNode* argp, bool isScan) {
string expectFormat(AstNode* nodep, const string& format, AstNode* argp, bool isScan) {
// Check display arguments
bool inPct = false;
for (string::const_iterator it = format.begin(); it != format.end(); ++it) {
@@ -266,6 +273,9 @@ private:
case 'm': // %m - auto insert "name"
if (isScan) nodep->v3error("Unsupported: %m in $fscanf");
break;
case 'l': // %l - auto insert "library"
if (isScan) nodep->v3error("Unsupported: %l in $fscanf");
break;
default: // Most operators, just move to next argument
if (!V3Number::displayedFmtLegal(ch)) {
nodep->v3error("Unknown $display-like format code: %"<<ch);
@@ -280,8 +290,57 @@ private:
} // switch
}
}
if (argp) {
argp->v3error("Extra arguments for $display-like format");
if (argp && !isScan) {
int skipCount = 0; // number of args consume by any additional format strings
string newFormat(format);
while (argp) {
if (skipCount) {
argp = argp->nextp();
skipCount--;
continue;
}
AstConst *constp = argp->castConst();
bool isFromString = (constp) ? constp->num().isFromString() : false;
if (isFromString) {
int numchars = argp->dtypep()->width()/8;
string str(numchars, ' ');
// now scan for % operators
bool inpercent = false;
for (int i = 0; i < numchars; i++) {
int ii = numchars - i - 1;
char c = constp->num().dataByte(ii);
str[i] = c;
if (!inpercent && c == '%') {
inpercent = true;
} else if (inpercent) {
inpercent = 0;
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '.':
inpercent = true;
break;
case '%':
break;
default:
if (V3Number::displayedFmtLegal(c)) {
skipCount++;
}
}
}
}
newFormat.append(str);
AstNode *nextp = argp->nextp();
argp->unlinkFrBack(); pushDeletep(argp); VL_DANGLING(argp);
argp = nextp;
} else {
newFormat.append("%h");
argp = argp->nextp();
}
}
return newFormat;
} else {
return string();
}
}
@@ -302,23 +361,8 @@ private:
nodep->iterateChildren(*this);
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
}
virtual void visit(AstFFlush* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (nodep->filep()) {
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
}
}
virtual void visit(AstFGetC* nodep, AstNUser*) {
nodep->iterateChildren(*this);
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
}
virtual void visit(AstFGetS* nodep, AstNUser*) {
nodep->iterateChildren(*this);
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
}
virtual void visit(AstFScanF* nodep, AstNUser*) {
nodep->iterateChildren(*this);
expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
expectFormat(nodep, nodep->text(), nodep->exprsp(), true);
}
virtual void visit(AstSScanF* nodep, AstNUser*) {
@@ -327,7 +371,9 @@ private:
}
virtual void visit(AstSFormatF* nodep, AstNUser*) {
nodep->iterateChildren(*this);
expectFormat(nodep, nodep->text(), nodep->exprsp(), false);
string newFormat = expectFormat(nodep, nodep->text(), nodep->exprsp(), false);
if (newFormat.size())
nodep->text(newFormat);
if ((nodep->backp()->castDisplay() && nodep->backp()->castDisplay()->displayType().needScopeTracking())
|| nodep->formatScopeTracking()) {
nodep->scopeNamep(new AstScopeName(nodep->fileline()));
@@ -335,14 +381,6 @@ private:
}
virtual void visit(AstDisplay* nodep, AstNUser* vup) {
nodep->iterateChildren(*this);
if (nodep->filep()) expectDescriptor(nodep, nodep->filep()->castNodeVarRef());
if (!m_assertp
&& (nodep->displayType() == AstDisplayType::DT_INFO
|| nodep->displayType() == AstDisplayType::DT_WARNING
|| nodep->displayType() == AstDisplayType::DT_ERROR
|| nodep->displayType() == AstDisplayType::DT_FATAL)) {
nodep->v3error(nodep->verilogKwd()+" only allowed under an assertion.");
}
}
virtual void visit(AstUdpTable* nodep, AstNUser*) {
@@ -368,7 +406,7 @@ private:
}
}
}
nodep->unlinkFrBack(); pushDeletep(nodep); nodep=NULL;
nodep->unlinkFrBack(); pushDeletep(nodep); VL_DANGLING(nodep);
}
}
@@ -395,7 +433,7 @@ private:
public:
// CONSTUCTORS
LinkResolveVisitor(AstNetlist* rootp) {
explicit LinkResolveVisitor(AstNetlist* rootp) {
m_ftaskp = NULL;
m_modp = NULL;
m_assertp = NULL;
@@ -447,7 +485,7 @@ private:
}
public:
// CONSTUCTORS
LinkBotupVisitor(AstNetlist* rootp) {
explicit LinkBotupVisitor(AstNetlist* rootp) {
m_modp = NULL;
//
rootp->accept(*this);
+2 -2
View File
@@ -93,7 +93,7 @@ private:
}
public:
// CONSTRUCTORS
LocalizeDehierVisitor(AstNetlist* nodep) {
explicit LocalizeDehierVisitor(AstNetlist* nodep) {
nodep->accept(*this);
}
virtual ~LocalizeDehierVisitor() {}
@@ -233,7 +233,7 @@ private:
}
public:
// CONSTRUCTORS
LocalizeVisitor(AstNetlist* nodep) {
explicit LocalizeVisitor(AstNetlist* nodep) {
m_cfuncp = NULL;
nodep->accept(*this);
}
+1 -1
View File
@@ -137,7 +137,7 @@ private:
}
public:
// CONSTUCTORS
NameVisitor(AstNetlist* nodep) {
explicit NameVisitor(AstNetlist* nodep) {
nodep->accept(*this);
}
virtual ~NameVisitor() {}
+15 -5
View File
@@ -56,10 +56,19 @@ public:
V3Number& setDouble(double value);
void setBit (int bit, char value) { // Note must be pre-zeroed!
if (bit>=m_width) return;
if (value=='0'||value==0) m_value [bit/32] &= ~(1UL<<(bit&31));
else {
if (value=='1'||value=='x'||value==1||value==3) m_value [bit/32] |= (1UL<<(bit&31));
if (value=='z'||value=='x'||value==2||value==3) m_valueX[bit/32] |= (1UL<<(bit&31));
uint32_t mask = (1UL<<(bit&31));
if (value=='0' || value==0) {
m_value [bit/32] &= ~mask;
m_valueX[bit/32] &= ~mask;
} else if (value=='1'|| value==1) {
m_value [bit/32] |= mask;
m_valueX[bit/32] &= ~mask;
} else if (value=='z'|| value==2) {
m_value [bit/32] &= ~mask;
m_valueX[bit/32] |= mask;
} else { // X
m_value [bit/32] |= mask;
m_valueX[bit/32] |= mask;
}
}
private:
@@ -120,7 +129,7 @@ private:
public:
// CONSTRUCTORS
V3Number(FileLine* fileline) { init(fileline, 1); }
explicit V3Number(FileLine* fileline) { init(fileline, 1); }
V3Number(FileLine* fileline, int width) { init(fileline, width); } // 0=unsized
V3Number(FileLine* fileline, int width, uint32_t value) { init(fileline, width); m_value[0]=value; opCleanThis(); }
V3Number(FileLine* fileline, const char* source); // Create from a verilog 32'hxxxx number.
@@ -196,6 +205,7 @@ public:
double toDouble() const;
uint32_t toHash() const;
uint32_t dataWord(int word) const;
uint8_t dataByte(int byte) const { return (dataWord(byte/4) >> (8*(byte&3))) & 0xff; }
uint32_t countOnes() const;
uint32_t mostSetBitP1() const; // Highest bit set plus one, IE for 16 return 5, for 0 return 0.
+22 -12
View File
@@ -563,9 +563,9 @@ bool V3Options::onoff(const char* sw, const char* arg, bool& flag) {
return false;
}
bool V3Options::suffixed(const char* sw, const char* arg) {
if (strlen(arg) > strlen(sw)) return false;
return (0==strcmp(sw+strlen(sw)-strlen(arg), arg));
bool V3Options::suffixed(const string& sw, const char* arg) {
if (strlen(arg) > sw.length()) return false;
return (0==strcmp(sw.c_str()+sw.length()-strlen(arg), arg));
}
void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char** argv) {
@@ -672,6 +672,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
else if ( onoff (sw, "-trace-structs", flag/*ref*/) ) { m_traceStructs = flag; }
else if ( onoff (sw, "-trace-underscore", flag/*ref*/) ) { m_traceUnderscore = flag; }
else if ( onoff (sw, "-underline-zero", flag/*ref*/) ) { m_underlineZero = flag; } // Undocumented, old Verilator-2
else if ( onoff (sw, "-vpi", flag/*ref*/) ) { m_vpi = flag; }
else if ( onoff (sw, "-x-initial-edge", flag/*ref*/) ) { m_xInitialEdge = flag; }
else if ( onoff (sw, "-xml-only", flag/*ref*/) ) { m_xmlOnly = flag; } // Undocumented, still experimental
// Optimization
@@ -711,6 +712,10 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
shift;
addCFlags(argv[i]);
}
else if ( !strcmp (sw, "-comp-limits-syms") && (i+1)<argc ) { // Undocumented
shift;
VName::maxLength(atoi(argv[i]));
}
else if ( !strcmp (sw, "-converge-limit") && (i+1)<argc ) {
shift;
m_convergeLimit = atoi(argv[i]);
@@ -957,15 +962,16 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
else {
// Filename
string filename = parseFileArg(optdir,argv[i]);
if (suffixed(filename.c_str(), ".cpp")
|| suffixed(filename.c_str(), ".cxx")
|| suffixed(filename.c_str(), ".cc")
|| suffixed(filename.c_str(), ".sp")) {
if (suffixed(filename, ".cpp")
|| suffixed(filename, ".cxx")
|| suffixed(filename, ".cc")
|| suffixed(filename, ".c")
|| suffixed(filename, ".sp")) {
V3Options::addCppFile(filename);
}
else if (suffixed(filename.c_str(), ".a")
|| suffixed(filename.c_str(), ".o")
|| suffixed(filename.c_str(), ".so")) {
else if (suffixed(filename, ".a")
|| suffixed(filename, ".o")
|| suffixed(filename, ".so")) {
V3Options::addLdLibs(filename);
}
else {
@@ -983,7 +989,7 @@ void V3Options::parseOptsFile(FileLine* fl, const string& filename, bool rel) {
// Read the specified -f filename and process as arguments
UINFO(1,"Reading Options File "<<filename<<endl);
const auto_ptr<ifstream> ifp (V3File::new_ifstream(filename));
const VL_UNIQUE_PTR<ifstream> ifp (V3File::new_ifstream(filename));
if (ifp->fail()) {
fl->v3error("Cannot open -f command file: "+filename);
return;
@@ -996,6 +1002,7 @@ void V3Options::parseOptsFile(FileLine* fl, const string& filename, bool rel) {
getline(*ifp, line);
// Strip simple comments
string oline;
// cppcheck-suppress StlMissingComparison
for (string::const_iterator pos = line.begin(); pos != line.end(); ++pos) {
if (inCmt) {
if (*pos=='*' && *(pos+1)=='/') {
@@ -1149,6 +1156,7 @@ V3Options::V3Options() {
m_preprocOnly = false;
m_preprocNoLine = false;
m_public = false;
m_reportUnoptflat = false;
m_savable = false;
m_skipIdentical = true;
m_stats = false;
@@ -1161,7 +1169,7 @@ V3Options::V3Options() {
m_traceStructs = false;
m_traceUnderscore = false;
m_underlineZero = false;
m_reportUnoptflat = false;
m_vpi = false;
m_xInitialEdge = false;
m_xmlOnly = false;
@@ -1189,6 +1197,8 @@ V3Options::V3Options() {
m_defaultLanguage = V3LangCode::mostRecent();
VName::maxLength(128); // Linux filename limits 256; leave half for prefix
optimize(true);
// Default +libext+
addLibExtV(""); // So include "filename.v" will find the same file
+6 -2
View File
@@ -85,6 +85,7 @@ class V3Options {
bool m_pinsUint8; // main switch: --pins-uint8
bool m_profileCFuncs;// main switch: --profile-cfuncs
bool m_public; // main switch: --public
bool m_reportUnoptflat; // main switch: --report-unoptflat
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
@@ -97,7 +98,7 @@ class V3Options {
bool m_traceStructs; // main switch: --trace-structs
bool m_traceUnderscore;// main switch: --trace-underscore
bool m_underlineZero;// main switch: --underline-zero; undocumented old Verilator 2
bool m_reportUnoptflat; // main switch: --report-unoptflat
bool m_vpi; // main switch: --vpi
bool m_xInitialEdge; // main switch: --x-initial-edge
bool m_xmlOnly; // main switch: --xml-netlist
@@ -167,13 +168,15 @@ class V3Options {
void showVersion(bool verbose);
void coverage(bool flag) { m_coverageLine = m_coverageToggle = m_coverageUser = flag; }
bool onoff(const char* sw, const char* arg, bool& flag);
bool suffixed(const char* sw, const char* arg);
bool suffixed(const string& sw, const char* arg);
string parseFileArg(const string& optdir, const string& relfilename);
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:
// CREATORS
V3Options();
@@ -239,6 +242,7 @@ class V3Options {
bool ignc() const { return m_ignc; }
bool inhibitSim() const { return m_inhibitSim; }
bool reportUnoptflat() const { return m_reportUnoptflat; }
bool vpi() const { return m_vpi; }
bool xInitialEdge() const { return m_xInitialEdge; }
bool xmlOnly() const { return m_xmlOnly; }
+6 -6
View File
@@ -363,7 +363,7 @@ private:
public:
// CONSTUCTORS
OrderClkMarkVisitor(AstNode* nodep) {
explicit OrderClkMarkVisitor(AstNode* nodep) {
m_hasClk = false;
m_inClocked = false;
m_inAss = false;
@@ -410,7 +410,7 @@ private:
public:
// CONSTUCTORS
OrderClkAssVisitor(AstNode* nodep) {
explicit OrderClkAssVisitor(AstNode* nodep) {
m_clkAss = false;
nodep->accept(*this);
}
@@ -1265,7 +1265,7 @@ void OrderVisitor::processDomainsIterate(OrderEitherVertex* vertexp) {
domainp->dumpTree(cout);
cout<<endl;
}
newtreep->deleteTree(); newtreep=NULL;
newtreep->deleteTree(); VL_DANGLING(newtreep);
}
}
} // next input edgep
@@ -1476,7 +1476,7 @@ void OrderVisitor::processMoveDoneOne(OrderMoveVertex* vertexp) {
UINFO(9," Clear to "<<(toVertexp->inEmpty()?"[EMP] ":" ")
<<toVertexp<<endl);
// Delete this edge
edgep->unlinkDelete(); edgep=NULL;
edgep->unlinkDelete(); VL_DANGLING(edgep);
if (toVertexp->inEmpty()) {
// If destination node now has all inputs resolved; recurse to move that vertex
// This is thus depth first (before width) which keeps the resulting executable's d-cache happy.
@@ -1530,7 +1530,7 @@ void OrderVisitor::processMoveOne(OrderMoveVertex* vertexp, OrderMoveDomScope* d
nodep->unlinkFrBack();
if (domainp == m_deleteDomainp) {
UINFO(4," Ordering deleting pre-settled "<<nodep<<endl);
pushDeletep(nodep); nodep=NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
} else {
m_pomNewFuncp->addStmtsp(nodep);
if (v3Global.opt.outputSplitCFuncs()) {
@@ -1646,7 +1646,7 @@ void OrderVisitor::process() {
m_graph.dumpDotFilePrefixed("orderg_done");
if (0 && debug()) {
string dfilename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"_INT_order.tree";
const auto_ptr<ofstream> logp (V3File::new_ofstream(dfilename));
const VL_UNIQUE_PTR<ofstream> logp (V3File::new_ofstream(dfilename));
if (logp->fail()) v3fatalSrc("Can't write "<<dfilename);
m_graph.dump(*logp);
}
+1
View File
@@ -104,6 +104,7 @@ struct OrderVEdgeType {
}
enum en m_e;
inline OrderVEdgeType () : m_e(VERTEX_UNKNOWN) {}
// cppcheck-suppress noExplicitConstructor
inline OrderVEdgeType (en _e) : m_e(_e) {}
explicit inline OrderVEdgeType (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
+1 -1
View File
@@ -55,7 +55,7 @@ void V3Os::setenvStr(const string& envvar, const string& value, const string& wh
} else {
UINFO(1,"export "<<envvar<<"="<<value<<endl);
}
#if defined(_BSD_SOURCE) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L)
#if !defined(__MINGW32__) && (defined(_BSD_SOURCE) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L))
setenv(envvar.c_str(),value.c_str(),true);
#else
//setenv() replaced by putenv() in MinGW/Solaris environment. Prototype is different
+67 -14
View File
@@ -88,7 +88,7 @@ private:
struct ModInfo {
AstNodeModule* m_modp; // Module with specified name
VarCloneMap m_cloneMap; // Map of old-varp -> new cloned varp
ModInfo(AstNodeModule* modp) { m_modp=modp; }
explicit ModInfo(AstNodeModule* modp) { m_modp=modp; }
};
typedef map<string,ModInfo> ModNameMap;
ModNameMap m_modNameMap; // Hash of created module flavors by name
@@ -108,6 +108,8 @@ private:
typedef deque<AstCell*> CellList;
CellList m_cellps; // Cells left to process (in this module)
string m_unlinkedTxt; // Text for AstUnlinkedVarXRef
// METHODS
static int debug() {
static int level = -1;
@@ -248,6 +250,44 @@ private:
virtual void visit(AstVarRef* nodep, AstNUser*) {
if (nodep->varp()) nodep->varp()->iterate(*this);
}
virtual void visit(AstVarXRef* nodep, AstNUser*) {
nodep->varp(NULL); // Needs relink, as may remove pointed-to var
}
virtual void visit(AstUnlinkedVarXRef* nodep, AstNUser*) {
m_unlinkedTxt.clear();
nodep->cellrefp()->iterate(*this);
nodep->varxrefp()->dotted(m_unlinkedTxt);
nodep->replaceWith(nodep->varxrefp()->unlinkFrBack());
pushDeletep(nodep); VL_DANGLING(nodep);
}
virtual void visit(AstCellArrayRef* nodep, AstNUser*) {
V3Const::constifyParamsEdit(nodep->selp());
if (AstConst* constp = nodep->selp()->castConst()) {
string index = AstNode::encodeNumber(constp->toSInt());
m_unlinkedTxt += nodep->name() + "__BRA__"+index+"__KET__";
} else {
nodep->v3error("Could not expand constant selection inside dotted reference: "<<nodep->selp()->prettyName());
return;
}
}
virtual void visit(AstCellRef* nodep, AstNUser*) {
// Children must be CellArrayRef, CellRef or ParseRef
if (nodep->cellp()->castCellArrayRef() || nodep->cellp()->castCellRef()) {
nodep->cellp()->iterate(*this);
} else if (nodep->cellp()->castParseRef()) {
m_unlinkedTxt += nodep->cellp()->name();
} else {
nodep->v3error("Could not elaborate dotted reference (LHS): "<<nodep->cellp()->prettyName());
}
m_unlinkedTxt += ".";
if (nodep->exprp()->castCellArrayRef() || nodep->exprp()->castCellRef()) {
nodep->exprp()->iterate(*this);
} else if (nodep->exprp()->castParseRef()) {
m_unlinkedTxt += nodep->exprp()->name();
} else {
nodep->v3error("Could not elaborate dotted reference (RHS): "<<nodep->exprp()->prettyName());
}
}
// Generate Statements
virtual void visit(AstGenerate* nodep, AstNUser*) {
@@ -262,7 +302,7 @@ private:
} else {
nodep->unlinkFrBack();
}
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
virtual void visit(AstGenIf* nodep, AstNUser*) {
UINFO(9," GENIF "<<nodep<<endl);
@@ -283,7 +323,7 @@ private:
} else {
nodep->unlinkFrBack();
}
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
// Normal edit rules will now recurse the replacement
} else {
nodep->condp()->v3error("Generate If condition must evaluate to constant");
@@ -310,7 +350,7 @@ private:
string beginName = nodep->name();
// Leave the original Begin, as need a container for the (possible) GENVAR
// Note V3Unroll will replace some AstVarRef's to the loop variable with constants
V3Unroll::unrollGen(forp, beginName); forp=NULL;
V3Unroll::unrollGen(forp, beginName); VL_DANGLING(forp);
// Blocks were constructed under the special begin, move them up
// Note forp is null, so grab statements again
if (AstNode* stmtsp = nodep->genforp()) {
@@ -339,8 +379,7 @@ private:
for (AstNode* ep = itemp->condsp(); ep; ) {
AstNode* nextp = ep->nextp(); //May edit list
ep->iterateAndNext(*this);
V3Const::constifyParamsEdit(ep); ep=NULL; // ep may change
// cppcheck-suppress redundantAssignment
V3Const::constifyParamsEdit(ep); VL_DANGLING(ep); // ep may change
ep = nextp;
}
}
@@ -372,7 +411,7 @@ private:
nodep->replaceWith(keepp);
}
else nodep->unlinkFrBack();
nodep->deleteTree(); nodep=NULL;
nodep->deleteTree(); VL_DANGLING(nodep);
}
// Default: Just iterate
@@ -382,7 +421,7 @@ private:
public:
// CONSTUCTORS
ParamVisitor(AstNetlist* nodep) {
explicit ParamVisitor(AstNetlist* nodep) {
m_longId = 0;
//
nodep->accept(*this);
@@ -442,15 +481,28 @@ void ParamVisitor::visitCell(AstCell* nodep) {
AstVar* modvarp = pinp->modVarp();
if (modvarp->isIfaceRef()) {
AstIfaceRefDType* portIrefp = modvarp->subDTypep()->castIfaceRefDType();
AstIfaceRefDType* pinIrefp = NULL;
AstNode *exprp = pinp->exprp();
if (exprp
&& exprp->castVarRef()
&& exprp->castVarRef()->varp()
&& exprp->castVarRef()->varp()->subDTypep()
&& exprp->castVarRef()->varp()->subDTypep()->castIfaceRefDType())
pinIrefp = exprp->castVarRef()->varp()->subDTypep()->castIfaceRefDType();
else if (exprp
&& exprp->op1p()
&& exprp->op1p()->castVarRef()
&& exprp->op1p()->castVarRef()->varp()
&& exprp->op1p()->castVarRef()->varp()->subDTypep()
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()
&& exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType())
pinIrefp = exprp->op1p()->castVarRef()->varp()->subDTypep()->castUnpackArrayDType()->subDTypep()->castIfaceRefDType();
//UINFO(9," portIfaceRef "<<portIrefp<<endl);
if (!pinp->exprp()
|| !pinp->exprp()->castVarRef()
|| !pinp->exprp()->castVarRef()->varp()
|| !pinp->exprp()->castVarRef()->varp()->subDTypep()
|| !pinp->exprp()->castVarRef()->varp()->subDTypep()->castIfaceRefDType()) {
if (!pinIrefp) {
pinp->v3error("Interface port '"<<modvarp->prettyName()<<"' is not connected to interface/modport pin expression");
} else {
AstIfaceRefDType* pinIrefp = pinp->exprp()->castVarRef()->varp()->subDTypep()->castIfaceRefDType();
//UINFO(9," pinIfaceRef "<<pinIrefp<<endl);
if (portIrefp->ifaceViaCellp() != pinIrefp->ifaceViaCellp()) {
UINFO(9," IfaceRefDType needs reconnect "<<pinIrefp<<endl);
@@ -467,6 +519,7 @@ void ParamVisitor::visitCell(AstCell* nodep) {
} else {
// If the name is very long, we don't want to overwhelm the filename limit
// We don't do this always, as it aids debugability to have intuitive naming.
// TODO can use new V3Name hash replacement instead of this
string newname = longname;
if (longname.length()>30) {
LongMap::iterator iter = m_longMap.find(longname);
+1
View File
@@ -36,6 +36,7 @@ class V3Parse {
private:
V3ParseImp* m_impp;
V3Parse(const V3Parse&); ///< N/A, no copy constructor
public:
// CONSTRUCTORS
// We must allow reading multiple files into one parser
+1 -1
View File
@@ -146,7 +146,7 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
}
if (ofp) {
ofp->close();
delete ofp; ofp = NULL;
delete ofp; VL_DANGLING(ofp);
}
}
}
+1 -1
View File
@@ -133,7 +133,7 @@ public:
}
public:
// CREATORS
V3ParseSym(AstNetlist* rootp)
explicit V3ParseSym(AstNetlist* rootp)
: m_syms(rootp) {
s_anonNum = 0; // Number of next anonymous object
pushScope(findNewTable(rootp));
+1 -1
View File
@@ -1074,7 +1074,7 @@ int V3PreProcImp::getStateToken() {
out = defineSubst(refp);
//NOP: out = m_preprocp->defSubstitute(out);
}
m_defRefs.pop(); refp=NULL;
m_defRefs.pop(); VL_DANGLING(refp);
if (m_defRefs.empty()) {
statePop();
if (!m_off) unputDefrefString(out);
+2 -2
View File
@@ -85,7 +85,7 @@ private:
public:
// CONSTRUCTORS
PremitAssignVisitor(AstNodeAssign* nodep) {
explicit PremitAssignVisitor(AstNodeAssign* nodep) {
UINFO(4," PremitAssignVisitor on "<<nodep<<endl);
m_noopt = false;
nodep->accept(*this);
@@ -383,7 +383,7 @@ private:
public:
// CONSTUCTORS
PremitVisitor(AstNetlist* nodep) {
explicit PremitVisitor(AstNetlist* nodep) {
m_modp = NULL;
m_funcp = NULL;
m_stmtp = NULL;
+3 -3
View File
@@ -294,7 +294,7 @@ private:
}
public:
// CONSTUCTORS
ScopeVisitor(AstNetlist* nodep) {
explicit ScopeVisitor(AstNetlist* nodep) {
m_aboveCellp = NULL;
m_aboveScopep = NULL;
m_modp = NULL;
@@ -334,7 +334,7 @@ private:
nodep->iterateChildren(*this);
} else {
// A block that was just moved under a scope, Kill it.
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
}
@@ -402,7 +402,7 @@ private:
}
public:
// CONSTUCTORS
ScopeCleanupVisitor(AstNetlist* nodep) {
explicit ScopeCleanupVisitor(AstNetlist* nodep) {
m_scopep = NULL;
nodep->accept(*this);
}
+90 -5
View File
@@ -260,7 +260,10 @@ private:
// We can't have non-delayed assignments with same value on LHS and RHS
// as we don't figure out variable ordering.
// Delayed is OK though, as we'll decode the next state separately.
if (!nodep->varp()->dtypeSkipRefp()->castBasicDType()) clearOptimizable(nodep,"Array references/not basic");
if (!nodep->varp()->dtypeSkipRefp()->castBasicDType()
&& !nodep->varp()->dtypeSkipRefp()->castPackArrayDType()
&& !nodep->varp()->dtypeSkipRefp()->castStructDType())
clearOptimizable(nodep,"Array references/not basic");
if (nodep->lvalue()) {
if (m_inDlyAssign) {
if (!(vscp->user1() & VU_LVDLY)) {
@@ -342,6 +345,19 @@ private:
setNumber(nodep, &(nodep->num()));
}
}
virtual void visit(AstEnumItemRef* nodep, AstNUser*) {
checkNodeInfo(nodep);
if (!nodep->itemp()) nodep->v3fatalSrc("Not linked");
if (!m_checkOnly && optimizable()) {
AstNode* valuep = nodep->itemp()->valuep();
if (valuep) {
valuep->iterateAndNext(*this);
newNumber(nodep)->opAssign(*fetchNumber(valuep));
} else {
clearOptimizable(nodep, "No value found for enum item");
}
}
}
virtual void visit(AstNodeUniop* nodep, AstNUser*) {
if (!optimizable()) return; // Accelerate
checkNodeInfo(nodep);
@@ -450,7 +466,7 @@ private:
if (!m_params) { clearOptimizable(nodep, "LHS has select"); return; }
checkNodeInfo(selp);
AstVarRef* varrefp = selp->fromp()->castVarRef();
if (!varrefp) {
if (!varrefp) {
clearOptimizable(nodep, "Select LHS isn't simple variable");
return;
}
@@ -564,6 +580,7 @@ private:
}
}
virtual void visit(AstStop* nodep, AstNUser*) {
if (jumpingOver(nodep)) return;
if (m_params) { // This message seems better than an obscure $stop
// The spec says $stop is just ignored, it seems evil to ignore assertions
clearOptimizable(nodep,"$stop executed during function constification; maybe indicates assertion firing");
@@ -637,8 +654,7 @@ private:
UINFO(5," FUNCREF "<<nodep<<endl);
if (!m_params) { badNodeType(nodep); return; }
AstNodeFTask* funcp = nodep->taskp()->castNodeFTask(); if (!funcp) nodep->v3fatalSrc("Not linked");
// cppcheck-suppress redundantAssignment
if (m_params) { V3Width::widthParamsEdit(funcp); } funcp=NULL; // Make sure we've sized the function
if (m_params) { V3Width::widthParamsEdit(funcp); } VL_DANGLING(funcp); // Make sure we've sized the function
funcp = nodep->taskp()->castNodeFTask(); if (!funcp) nodep->v3fatalSrc("Not linked");
// Apply function call values to function
V3TaskConnects tconnects = V3Task::taskConnects(nodep, nodep->taskp()->stmtsp());
@@ -680,9 +696,78 @@ private:
if (!m_params) { badNodeType(nodep); return; }
}
virtual void visit(AstSFormatF *nodep, AstNUser *) {
if (jumpingOver(nodep)) return;
nodep->iterateChildren(*this);
if (m_params) {
AstNode* nextArgp = nodep->exprsp();
string result = "";
string format = nodep->text();
string::const_iterator pos = format.begin();
bool inPct = false;
for (; pos != format.end(); ++pos) {
if (!inPct && pos[0] == '%') {
inPct = true;
} else if (!inPct) { // Normal text
result += *pos;
} else { // Format character
AstNode* argp = nextArgp;
inPct = false;
nextArgp = nextArgp->nextp();
if (V3Number::displayedFmtLegal(tolower(pos[0]))) {
V3Number* nump = fetchNumberNull(argp);
if (!nump) {
clearOptimizable(nodep, "Argument for $display like statement is not constant");
break;
}
string format = string("%") + pos[0];
result += nump->displayed(format);
} else {
switch (tolower(pos[0])) {
case '%':
result += "%";
break;
default:
clearOptimizable(nodep, "Unknown $display-like format code.");
break;
}
}
}
}
nodep->text(result);
}
}
virtual void visit(AstDisplay *nodep, AstNUser *) {
if (jumpingOver(nodep)) return;
nodep->iterateChildren(*this);
if (m_params) {
switch (nodep->displayType()) {
case AstDisplayType::DT_DISPLAY: // FALLTHRU
case AstDisplayType::DT_INFO:
v3warn(USERINFO, nodep->fmtp()->text());
break;
case AstDisplayType::DT_ERROR:
v3warn(USERERROR, nodep->fmtp()->text());
break;
case AstDisplayType::DT_WARNING:
v3warn(USERWARN, nodep->fmtp()->text());
break;
case AstDisplayType::DT_FATAL:
v3warn(USERFATAL, nodep->fmtp()->text());
break;
case AstDisplayType::DT_WRITE: // FALLTHRU
default:
clearOptimizable(nodep, "Unexpected display type");
}
}
}
// default
// These types are definately not reducable
// AstCoverInc, AstDisplay, AstArraySel, AstStop, AstFinish,
// AstCoverInc, AstArraySel, AstFinish,
// AstRand, AstTime, AstUCFunc, AstCCall, AstCStmt, AstUCStmt
virtual void visit(AstNode* nodep, AstNUser*) {
if (jumpingOver(nodep)) return;
+18 -16
View File
@@ -124,7 +124,7 @@ class SliceCloneVisitor : public AstNVisitor {
clonep->iterateChildren(*this);
nodep->addNextHere(clonep);
}
nodep->unlinkFrBack()->deleteTree(); nodep = NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
// Not all Uniop nodes should be cloned down to a single bit
@@ -164,7 +164,7 @@ class SliceCloneVisitor : public AstNVisitor {
}
}
nodep->addNextHere(lhsp);
nodep->unlinkFrBack()->deleteTree(); nodep = NULL;
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
}
virtual void visit(AstRedOr* nodep, AstNUser*) {
cloneUniop(nodep);
@@ -185,7 +185,7 @@ class SliceCloneVisitor : public AstNVisitor {
}
public:
// CONSTUCTORS
SliceCloneVisitor(AstNode* nodep) {
explicit SliceCloneVisitor(AstNode* nodep) {
nodep->accept(*this);
}
virtual ~SliceCloneVisitor() {}
@@ -295,7 +295,7 @@ class SliceVisitor : public AstNVisitor {
AstVarRef* clonep = nodep->cloneTree(false);
clonep->user1p(nodep);
AstNode* newp = insertImplicit(clonep, 1, dimensions);
nodep->replaceWith(newp); nodep = NULL;
nodep->replaceWith(newp); VL_DANGLING(nodep);
newp->accept(*this);
}
}
@@ -422,7 +422,7 @@ class SliceVisitor : public AstNVisitor {
}
//if (debug()>=9) newp->dumpTreeAndNext(cout, "-InitArrayOut: ");
nodep->replaceWith(newp);
pushDeletep(nodep); nodep=NULL;
pushDeletep(nodep); VL_DANGLING(nodep);
return; // WIll iterate in a moment
}
// Hasn't been searched for implicit slices yet
@@ -446,17 +446,19 @@ class SliceVisitor : public AstNVisitor {
if ((int)(dim - varDim.second) < 0) {
// Unpacked dimensions are referenced first, make sure we have them all
nodep->v3error("Unary operator used across unpacked dimensions");
} else if ((int)(dim - (varDim.second)) < 0) {
// Implicit packed dimensions are allowed, make them explicit
uint32_t newDim = (varDim.second) - dim;
AstNode* clonep = nodep->lhsp()->cloneTree(false);
clonep->user1p(refp);
AstNode* newp = insertImplicit(clonep, dim+1, newDim);
nodep->lhsp()->replaceWith(newp); refp = NULL;
int clones = countClones(nodep->lhsp()->castArraySel());
nodep->user2(clones);
SliceCloneVisitor scv(nodep);
}
//Dead code
//else if ((int)(dim - (varDim.second)) < 0) {
// // Implicit packed dimensions are allowed, make them explicit
// uint32_t newDim = (varDim.second) - dim;
// AstNode* clonep = nodep->lhsp()->cloneTree(false);
// clonep->user1p(refp);
// AstNode* newp = insertImplicit(clonep, dim+1, newDim);
// nodep->lhsp()->replaceWith(newp); VL_DANGLING(refp);
// int clones = countClones(nodep->lhsp()->castArraySel());
// nodep->user2(clones);
// SliceCloneVisitor scv(nodep);
//}
}
}
virtual void visit(AstRedOr* nodep, AstNUser*) {
@@ -487,7 +489,7 @@ class SliceVisitor : public AstNVisitor {
public:
// CONSTUCTORS
SliceVisitor(AstNetlist* rootp) {
explicit SliceVisitor(AstNetlist* rootp) {
m_assignp = NULL;
m_lhsVarRefp = NULL;
rootp->accept(*this);
+1 -1
View File
@@ -69,7 +69,7 @@
class SplitPliVertex : public V3GraphVertex {
public:
SplitPliVertex(V3Graph* graphp)
explicit SplitPliVertex(V3Graph* graphp)
: V3GraphVertex(graphp) {}
virtual ~SplitPliVertex() {}
virtual string name() const { return "*PLI*"; }
+2 -2
View File
@@ -71,7 +71,7 @@ private:
}
public:
// CONSTUCTORS
SplitAsFindVisitor(AstAlways* nodep) {
explicit SplitAsFindVisitor(AstAlways* nodep) {
m_splitVscp = NULL;
nodep->accept(*this);
}
@@ -200,7 +200,7 @@ private:
public:
// CONSTUCTORS
SplitAsVisitor(AstNetlist* nodep) {
explicit SplitAsVisitor(AstNetlist* nodep) {
m_splitVscp = NULL;
AstNode::user1ClearTree(); // user1p() used on entire tree
nodep->accept(*this);
+1 -1
View File
@@ -37,7 +37,7 @@ public:
~V3Double0() {}
// Implicit conversion operators:
inline V3Double0 (const vluint64_t v) : m_d(v) { }
inline explicit V3Double0 (const vluint64_t v) : m_d(v) { }
inline operator double () const { return m_d; }
// Explicit operators:
+2 -2
View File
@@ -177,7 +177,7 @@ public:
}
// CONSTRUCTORS
StatsReport(ofstream* aofp)
explicit StatsReport(ofstream* aofp)
: os(*aofp) {
header();
sumit();
@@ -214,5 +214,5 @@ void V3Stats::statsReport() {
StatsReport reporter (ofp);
// Cleanup
ofp->close(); delete ofp; ofp = NULL;
ofp->close(); delete ofp; VL_DANGLING(ofp);
}
+238
View File
@@ -21,7 +21,13 @@
#include "config_build.h"
#include "verilatedos.h"
#include "V3Global.h"
#include "V3String.h"
#include "V3Error.h"
size_t VName::s_minLength = 32;
size_t VName::s_maxLength = 0; // Disabled
//######################################################################
// Wildcard
@@ -70,3 +76,235 @@ string VString::downcase(const string& str) {
}
return out;
}
//######################################################################
// VHashSha1
static inline uint32_t sha1Rotl32(uint32_t lhs, uint32_t rhs) VL_ATTR_ALWINLINE;
static inline uint32_t sha1Rotl32(uint32_t lhs, uint32_t rhs) {
return ((lhs << rhs) | (lhs >> (32 - rhs)));
}
static inline void sha1Block(uint32_t* h, uint32_t* w) VL_ATTR_ALWINLINE;
static inline void sha1Block(uint32_t* h, uint32_t* w) {
#define SHA1ITER(func, roundConst) do { \
uint32_t t = sha1Rotl32(a, 5) + (func) + e + (roundConst) + w[round]; \
e = d; d = c; c = sha1Rotl32(b, 30); b = a; a = t; \
} while (0)
uint32_t a = h[0];
uint32_t b = h[1];
uint32_t c = h[2];
uint32_t d = h[3];
uint32_t e = h[4];
int round = 0;
for (; round < 16; ++round) {
SHA1ITER((b & c) | (~b & d), 0x5a827999);
}
for (; round < 20; ++round) {
w[round] = sha1Rotl32((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
SHA1ITER((b & c) | (~b & d), 0x5a827999);
}
for (; round < 40; ++round) {
w[round] = sha1Rotl32((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
SHA1ITER(b ^ c ^ d, 0x6ed9eba1);
}
for (; round < 60; ++round) {
w[round] = sha1Rotl32((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
SHA1ITER((b & c) | (b & d) | (c & d), 0x8f1bbcdc);
}
for (; round < 80; ++round) {
w[round] = sha1Rotl32((w[round - 3] ^ w[round - 8] ^ w[round - 14] ^ w[round - 16]), 1);
SHA1ITER(b ^ c ^ d, 0xca62c1d6);
}
h[0] += a;
h[1] += b;
h[2] += c;
h[3] += d;
h[4] += e;
#undef SHA1ITER
}
void VHashSha1::insert(const void* datap, size_t length) {
UASSERT(!m_final, "Called VHashSha1::insert after finalized the hash value");
m_totLength += length;
string tempData;
int chunkLen;
const uint8_t* chunkp;
if (m_remainder=="") {
chunkLen = length;
chunkp = (const uint8_t*)datap;
} else {
// If there are large inserts it would be more efficient to avoid this copy
// by copying bytes in the loop below from either m_remainder or the data
// as appropriate.
tempData = m_remainder + string((const char*)datap,length);
chunkLen = tempData.length();
chunkp = (const uint8_t*)tempData.data();
}
// See wikipedia SHA-1 algorithm summary
uint32_t w[80]; // Round buffer, [0..15] are input data, rest used by rounds
int posBegin = 0; // Position in buffer for start of this block
int posEnd = 0; // Position in buffer for end of this block
// Process complete 64-byte blocks
while (posBegin <= chunkLen - 64) {
posEnd = posBegin + 64;
// 64 byte round input data, being careful to swap on big, keep on little
for (int roundByte = 0; posBegin < posEnd; posBegin += 4) {
w[roundByte++] = ((uint32_t) chunkp[posBegin + 3]
| (((uint32_t) chunkp[posBegin + 2]) << 8)
| (((uint32_t) chunkp[posBegin + 1]) << 16)
| (((uint32_t) chunkp[posBegin]) << 24));
}
sha1Block(m_inthash, w);
}
m_remainder = string((const char*)(chunkp+posBegin), chunkLen-posEnd);
}
void VHashSha1::finalize() {
if (!m_final) {
// Make sure no 64 byte blocks left
insert("");
m_final = true;
// Process final possibly non-complete 64-byte block
uint32_t w[80]; // Round buffer, [0..15] are input data, rest used by rounds
for (int i=0; i<16; ++i) w[i] = 0;
size_t blockPos = 0;
for (; blockPos < m_remainder.length(); ++blockPos) {
w[blockPos >> 2] |= ((uint32_t) m_remainder[blockPos]) << ((3 - (blockPos & 3)) << 3);
}
w[blockPos >> 2] |= 0x80 << ((3 - (blockPos & 3)) << 3);
if (m_remainder.length() >= 56) {
sha1Block(m_inthash, w);
for (int i=0; i<16; ++i) w[i] = 0;
}
w[15] = m_totLength << 3;
sha1Block(m_inthash, w);
m_remainder.clear();
}
}
string VHashSha1::digestBinary() {
finalize();
string out; out.reserve(20);
for (size_t i=0; i<20; ++i) {
out[i] = (m_inthash[i >> 2] >> (((3 - i) & 0x3) << 3)) & 0xff;
}
return out;
}
uint64_t VHashSha1::digestUInt64() {
const string& binhash = digestBinary();
uint64_t out = 0;
for (size_t byte=0; byte<sizeof(uint64_t); ++byte) {
out = (out<<8) | binhash[byte];
}
return out;
}
string VHashSha1::digestHex() {
static const char digits[16+1] = "0123456789abcdef";
const string& binhash = digestBinary();
string out; out.reserve(40);
for (size_t byte=0; byte<20; ++byte) {
out += digits[ (binhash[byte]>>4) & 0xf ];
out += digits[ (binhash[byte]>>0) & 0xf ];
}
return out;
}
string VHashSha1::digestSymbol() {
// Make a symbol name from hash. Similar to base64, however base 64
// has + and / for last two digits, but need C symbol, and we also
// avoid conflicts with use of _, so use "AB" at the end.
// Thus this function is non-reversable.
static const char digits[64+1] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789AB";
const string& binhash = digestBinary();
string out; out.reserve(28);
int pos = 0;
for (; pos < (160/8) - 2; pos += 3) {
out += digits[((binhash[pos] >> 2) & 0x3f)];
out += digits[((binhash[pos] & 0x3) << 4)
| ((int) (binhash[pos + 1] & 0xf0) >> 4)];
out += digits[((binhash[pos + 1] & 0xf) << 2)
| ((int) (binhash[pos + 2] & 0xc0) >> 6)];
out += digits[((binhash[pos + 2] & 0x3f))];
}
if (0) { // Not needed for 160 bit hash
out += digits[((binhash[pos] >> 2) & 0x3f)];
out += digits[((binhash[pos] & 0x3) << 4)];
}
else {
out += digits[((binhash[pos] >> 2) & 0x3f)];
out += digits[((binhash[pos] & 0x3) << 4)
| ((int) (binhash[pos + 1] & 0xf0) >> 4)];
out += digits[((binhash[pos + 1] & 0xf) << 2)];
}
return out;
}
void VHashSha1::selfTestOne(const string& data, const string& data2,
const string& exp, const string& exp64) {
VHashSha1 digest (data);
if (data2!="") digest.insert(data2);
if (digest.digestHex() != exp) {
cerr << "%Error: When hashing '"<<data+data2<<"'"<<endl;
cerr << "%Error: got="<<digest.digestHex()<<endl;
cerr << "%Error: exp="<<exp<<endl;
}
if (digest.digestSymbol() != exp64) {
cerr << "%Error: When hashing '"<<data+data2<<"'"<<endl;
cerr << "%Error: got="<<digest.digestSymbol()<<endl;
cerr << "%Error: exp="<<exp64<<endl;
}
}
void VHashSha1::selfTest() {
selfTestOne("", "",
"da39a3ee5e6b4b0d3255bfef95601890afd80709",
"2jmj7l5rSw0yVbBvlWAYkKBYBwk");
selfTestOne("a", "",
"86f7e437faa5a7fce15d1ddcb9eaeaea377667b8",
"hvfkNBqlpBzhXR3cuerq6jd2Z7g");
selfTestOne("The quick brown fox jumps over the lazy dog", "",
"2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",
"L9ThxnotKPzthJ7hu3bnORuT6xI");
selfTestOne("The quick brown fox jumps over the lazy"," dog",
"2fd4e1c67a2d28fced849ee1bb76e7391b93eb12",
"L9ThxnotKPzthJ7hu3bnORuT6xI");
selfTestOne("Test using larger than block-size key and larger than one block-size data", "",
"9026e8faed6ef4ec5ae3ff049020d7f0af7abbbf",
"kCboAu1u9Oxa4B8EkCDX8K96u78");
selfTestOne("Test using", " larger than block-size key and larger than one block-size data",
"9026e8faed6ef4ec5ae3ff049020d7f0af7abbbf",
"kCboAu1u9Oxa4B8EkCDX8K96u78");
}
//######################################################################
// VName
string VName::hashedName() {
if (m_name=="") return "";
if (m_hashed!="") return m_hashed; // Memoized
if (s_maxLength==0 || m_name.length() < s_maxLength) {
m_hashed = m_name;
return m_hashed;
} else {
VHashSha1 hash(m_name);
string suffix = "__Vhsh"+hash.digestSymbol();
if (s_minLength < s_maxLength) {
m_hashed = m_name.substr(0,s_minLength) + suffix;
} else {
m_hashed = suffix;
}
return m_hashed;
}
}

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