mirror of
https://github.com/verilator/verilator.git
synced 2026-10-02 16:13:34 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02530172e7 | ||
|
|
447d803800 | ||
|
|
6b04901c4d | ||
|
|
7fb29621c3 | ||
|
|
b032fce962 | ||
|
|
ce879122bb | ||
|
|
2fa16708b7 | ||
|
|
54bc8608e3 | ||
|
|
706a7802cc | ||
|
|
9dc01cf540 | ||
|
|
8943ad5966 | ||
|
|
deb7a1c9c0 | ||
|
|
96a5445d44 | ||
|
|
d693065afb | ||
|
|
bdeee35669 | ||
|
|
62b3deb90d | ||
|
|
9df9ff59e0 | ||
|
|
23a3271c06 | ||
|
|
f4a5aa2e94 | ||
|
|
bdd54eed1c | ||
|
|
c6a20a72f2 | ||
|
|
d7a54b3632 | ||
|
|
be6a3d0f10 | ||
|
|
e9125a3a22 | ||
|
|
c27a60658f | ||
|
|
8f2bc6e028 | ||
|
|
a6b78cbbee | ||
|
|
182a7076fd | ||
|
|
17a9b22dce | ||
|
|
f190d12802 | ||
|
|
b12dd526f9 | ||
|
|
473d555dc1 | ||
|
|
fa9208ccdd | ||
|
|
4aa088eb2f | ||
|
|
8f8147d646 | ||
|
|
e637dd2390 | ||
|
|
c90960fc88 | ||
|
|
da86a1c9f2 | ||
|
|
0adb789238 | ||
|
|
15082a178b | ||
|
|
4a0db26c36 | ||
|
|
ad3ea636d5 | ||
|
|
6a238b0514 | ||
|
|
e6d7e7e329 | ||
|
|
f942aba855 | ||
|
|
2f34132275 | ||
|
|
663b2be065 | ||
|
|
a1e4d676c3 | ||
|
|
6f28d21207 | ||
|
|
9f115e056e | ||
|
|
8352ba4af4 | ||
|
|
9b06310cbe | ||
|
|
77fe33e57f | ||
|
|
df58eb9bc7 | ||
|
|
2d0084308d | ||
|
|
7efa40966a | ||
|
|
6d644dc764 | ||
|
|
b0de0b1176 | ||
|
|
c72d473e96 | ||
|
|
c8a91bd46f | ||
|
|
498f19a6a1 | ||
|
|
c7a2138ece | ||
|
|
4078902543 | ||
|
|
9e38ed9a39 | ||
|
|
183cabc77d | ||
|
|
b582e481c6 | ||
|
|
ad39931e87 | ||
|
|
1ae22e1365 | ||
|
|
b748ddfe06 | ||
|
|
e52f5f1b63 | ||
|
|
bda4b326ab | ||
|
|
70ddf32719 | ||
|
|
3edba7b662 | ||
|
|
f74ef650ac | ||
|
|
f093c3d78b | ||
|
|
d933f33bdb | ||
|
|
813d62005d | ||
|
|
411de9bddf | ||
|
|
bd28945374 | ||
|
|
1e4c3751e1 | ||
|
|
5b6f47cd0f | ||
|
|
bec8c5bf4c | ||
|
|
15495bb200 | ||
|
|
999f278971 | ||
|
|
7ca1d35a4e | ||
|
|
2117fe414e | ||
|
|
7d8c51181d | ||
|
|
c30211cb27 | ||
|
|
901da118e5 | ||
|
|
f11757e43a | ||
|
|
3f143317a6 | ||
|
|
45d7312dfc | ||
|
|
26774eb045 | ||
|
|
6789d247e2 | ||
|
|
462bc3d707 | ||
|
|
e1755ea6a8 |
@@ -1,7 +1,114 @@
|
||||
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!
|
||||
The contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
|
||||
* Verilator 3.904 2017-05-30
|
||||
|
||||
*** Fix non-cutable ordering loops on clock arrays, bug1009. [Todd Strader]
|
||||
|
||||
*** Support ports of array of reals, bug1154. [J Briquet]
|
||||
|
||||
*** Support arrayed parameter overrides, bug1153. [John Stevenson]
|
||||
|
||||
*** Support $value$plusargs with variables, bug1165. [Wesley Terpstra]
|
||||
|
||||
**** Support modport access to un-modport objects, bug1161. [Todd Strader]
|
||||
|
||||
**** Add stack trace when can't optimize function, bug1158. [Todd Strader]
|
||||
|
||||
**** Add warning on mis-sized literal, bug1156. [Todd Strader]
|
||||
|
||||
**** Fix interface functions returning wrong parameters, bug996. [Todd Strader]
|
||||
|
||||
**** Fix non-arrayed cells with interface arrays, bug1153. [John Stevenson]
|
||||
|
||||
**** Fix --assert with complex case statements, bug1164. [Enzo Chi]
|
||||
|
||||
|
||||
* Verilator 3.902 2017-04-02
|
||||
|
||||
** Add -FI option to force includes,msg2146. [Amir Gonnen]
|
||||
|
||||
** Add --relative-includes. [Rob Stoddard]
|
||||
|
||||
*** Add error on duplicate pattern assignments, bug1145. [Johan Bjork]
|
||||
|
||||
**** Fix error on improperly widthed default function, bug984. [Todd Strader]
|
||||
|
||||
**** Fix 2009 localparam syntax, msg2139. [Galen Seitz]
|
||||
|
||||
**** Fix ugly interface-to-non-interface errors, bug1112. [Johan Bjork]
|
||||
|
||||
**** Fix LDFLAGS and CFLAGS not preserving order, bug1130. [Olof Kindgren]
|
||||
|
||||
**** Fix internal error on initializing parameter array, bug1131. [Jie Xu]
|
||||
|
||||
**** Fix internal error on interface arrays, bug1135. [John Stevenson]
|
||||
|
||||
**** Fix calling sformatf to display, and elab $displays, bug1139. [Johan Bjork]
|
||||
|
||||
**** Fix realpath compile issue on MSVC++, bug1141. [Miodrag Milanovic]
|
||||
|
||||
**** Fix missing error on interface size mismatch, bug1143. [Johan Bjork]
|
||||
|
||||
**** Fix error on parameters with dotted references, bug1146. [Johan Bjork]
|
||||
|
||||
**** Fix wreal not handling continuous assign, bug1150. [J Briquet]
|
||||
|
||||
**** Fix nested structure parameter selects, bug1150. [J Briquet]
|
||||
|
||||
|
||||
* Verilator 3.900 2017-01-15
|
||||
|
||||
** Internal code changes for improved compatibility and performance.
|
||||
|
||||
*** Support old-style $display($time), bug467. [John Demme]
|
||||
|
||||
**** With --bbox-unsup, suppress desassign and mixed edges, bug1120. [Galen Seitz]
|
||||
|
||||
**** Fix parsing sensitivity with &&, bug934. [Luke Yang]
|
||||
|
||||
**** Fix internal error on double-for loop unrolling, bug1044. [Jan Egil Ruud]
|
||||
|
||||
**** Fix internal error on unique casez with --assert, bug1117. [Enzo Chi]
|
||||
|
||||
**** Fix bad code when tracing array of structs, bug1122. [Andrew Bardsley]
|
||||
|
||||
|
||||
* Verilator 3.890 2016-11-25
|
||||
|
||||
*** Honor --output-split on coverage constructors, bug1098. [Johan Bjork]
|
||||
|
||||
**** Fix various issues when making outside of the kit.
|
||||
|
||||
**** Fix flex 2.6.2 bug, bug1103. [Sergey Kvachonok]
|
||||
|
||||
**** Fix error on bad interface name, bug1097. [Todd Strader]
|
||||
|
||||
**** Fix error on referencing variable in parent, bug1099. [Ian Thompson]
|
||||
|
||||
**** Fix type parameters with low optimization, bug1101. [Stefan Wallentowitz]
|
||||
|
||||
|
||||
* Verilator 3.888 2016-10-14
|
||||
|
||||
** Support foreach, bug1078. [Xuan Guo]
|
||||
|
||||
*** Add --no-decoration to remove output comments, msg2015. [Frederic Requin]
|
||||
|
||||
*** If VM_PARALLEL_BUILDS=1, use OPT_FAST and OPT_SLOW. [Frederic Requin]
|
||||
Set VM_DEFAULT_RULES=0 for old behavior.
|
||||
|
||||
**** Add error on DPI functions > 32 bits, msg1995. [Elliot Mednick]
|
||||
|
||||
**** Fix SystemC compiles with VPI, bug1081. [Arthur Kahlich]
|
||||
|
||||
**** Fix error on wide numbers that represent shifts, msg1991, bug1088. [Mandy Xu]
|
||||
|
||||
**** Improve Verilation performance on internal strings, msg1975. [Johan Bjork]
|
||||
|
||||
**** Improve Verilation performance on trace duplicates, bug1090. [Johan Bjork]
|
||||
|
||||
|
||||
* Verilator 3.886 2016-07-30
|
||||
@@ -2736,7 +2843,7 @@ of input ports exists for tracing.
|
||||
|
||||
This uses outline mode in Emacs. See C-h m [M-x describe-mode].
|
||||
|
||||
Copyright 2001-2016 by Wilson Snyder. This program is free software; you
|
||||
Copyright 2001-2017 by Wilson Snyder. This program is free software; you
|
||||
can redistribute it and/or modify it under the terms of either the GNU
|
||||
Lesser General Public License Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
+7
-6
@@ -7,7 +7,7 @@
|
||||
#
|
||||
#*****************************************************************************
|
||||
#
|
||||
# Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
# Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
@@ -42,9 +42,6 @@
|
||||
# reconstructed with this Makefile. This typically includes
|
||||
# everything deleted by distclean, plus more: C source files
|
||||
# produced by Bison, tags tables, info files, and so on.
|
||||
#
|
||||
# make extraclean
|
||||
# Still more severe - delete backup and autosave files, too.
|
||||
|
||||
#### Start of system configuration section. ####
|
||||
|
||||
@@ -71,7 +68,7 @@ exec_prefix = @exec_prefix@
|
||||
# Directory in which to install scripts.
|
||||
bindir = @bindir@
|
||||
|
||||
# Directory in which to install scripts.
|
||||
# Directory in which to install manpages.
|
||||
mandir = @mandir@
|
||||
|
||||
# Directory in which to install library files.
|
||||
@@ -135,6 +132,8 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
|
||||
test_verilated/vgen*.pl \
|
||||
test_regress/t/t*/*.sv* \
|
||||
test_regress/t/t*/*.v* \
|
||||
test_regress/t/t*/*/*.sv* \
|
||||
test_regress/t/t*/*/*.v* \
|
||||
test_regress/t/*.cpp \
|
||||
test_regress/t/*.h \
|
||||
test_regress/t/*.dat \
|
||||
@@ -273,6 +272,7 @@ VL_INST_BIN_FILES = verilator verilator_bin verilator_bin_dbg verilator_coverage
|
||||
VL_INST_MAN_FILES = verilator.1 verilator_coverage.1 verilator_profcfunc.1
|
||||
|
||||
VL_INST_INC_BLDDIR_FILES = \
|
||||
include/verilated_config.h \
|
||||
include/verilated.mk \
|
||||
|
||||
# Files under srcdir, instead of build time
|
||||
@@ -300,7 +300,8 @@ installbin:
|
||||
# So important we use $< so VPATH is searched
|
||||
installman: $(VL_INST_MAN_FILES)
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(mandir)/man1
|
||||
for p in $^ ; do \
|
||||
cd $(srcdir) \
|
||||
; for p in $(VL_INST_MAN_FILES) ; do \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(mandir)/man1/$$p; \
|
||||
done
|
||||
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ This is the Verilator package README file.
|
||||
|
||||
http://www.veripool.org/verilator
|
||||
|
||||
This package is Copyright 2003-2016 by Wilson Snyder. (Report bugs to
|
||||
This package is Copyright 2003-2017 by Wilson Snyder. (Report bugs to
|
||||
L<http://www.veripool.org/>.)
|
||||
|
||||
Verilator is free software; you can redistribute it and/or modify it under
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// DESCRIPTION: Verilator: List of To Do issues.
|
||||
//
|
||||
// Copyright 2004-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2004-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+258
-183
@@ -3,7 +3,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
|
||||
if 0;
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2003-2016 by Wilson Snyder. This program is free software; you
|
||||
# Copyright 2003-2017 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
@@ -19,8 +19,8 @@ require 5.006_001;
|
||||
use warnings;
|
||||
BEGIN {
|
||||
if ($ENV{DIRPROJECT} && $ENV{DIRPROJECT_PERL_BOOT}) {
|
||||
# Magic to allow author testing of perl packages in local directory
|
||||
require $ENV{DIRPROJECT}."/".$ENV{DIRPROJECT_PERL_BOOT};
|
||||
# Magic to allow author testing of perl packages in local directory
|
||||
require $ENV{DIRPROJECT}."/".$ENV{DIRPROJECT_PERL_BOOT};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,16 +71,16 @@ foreach my $sw (@ARGV) {
|
||||
|
||||
Getopt::Long::config ("no_auto_abbrev","pass_through");
|
||||
if (! GetOptions (
|
||||
# Major operating modes
|
||||
"help" => \&usage,
|
||||
"debug:s" => \&debug,
|
||||
# "version!" => \&version, # Also passthru'ed
|
||||
# Switches
|
||||
"gdb!" => \$opt_gdb,
|
||||
"gdbbt!" => \$opt_gdbbt,
|
||||
# Additional parameters
|
||||
"<>" => sub {}, # Ignored
|
||||
)) {
|
||||
# Major operating modes
|
||||
"help" => \&usage,
|
||||
"debug:s" => \&debug,
|
||||
# "version!" => \&version, # Also passthru'ed
|
||||
# Switches
|
||||
"gdb!" => \$opt_gdb,
|
||||
"gdbbt!" => \$opt_gdbbt,
|
||||
# Additional parameters
|
||||
"<>" => sub {}, # Ignored
|
||||
)) {
|
||||
pod2usage(-exitstatus=>2, -verbose=>0);
|
||||
}
|
||||
|
||||
@@ -92,22 +92,22 @@ if ($opt_gdbbt && !gdb_works()) {
|
||||
if ($opt_gdb) {
|
||||
# Generic GDB interactive
|
||||
run (("gdb"||$ENV{VERILATOR_GDB})
|
||||
." ".verilator_bin()
|
||||
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
|
||||
." -ex 'set width 0'"
|
||||
." -ex 'bt'");
|
||||
." ".verilator_bin()
|
||||
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
|
||||
." -ex 'set width 0'"
|
||||
." -ex 'bt'");
|
||||
} elsif ($opt_gdbbt && $Debug) {
|
||||
# Run under GDB to get gdbbt
|
||||
run ("gdb"
|
||||
." ".verilator_bin()
|
||||
." --batch --quiet --return-child-result"
|
||||
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
|
||||
." -ex 'set width 0'"
|
||||
." -ex 'bt'");
|
||||
." ".verilator_bin()
|
||||
." --batch --quiet --return-child-result"
|
||||
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
|
||||
." -ex 'set width 0'"
|
||||
." -ex 'bt'");
|
||||
} else {
|
||||
# Normal, non gdb
|
||||
run (verilator_bin()
|
||||
." ".join(' ',@Opt_Verilator_Sw));
|
||||
." ".join(' ',@Opt_Verilator_Sw));
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@@ -130,23 +130,23 @@ sub verilator_bin {
|
||||
my $bin = "";
|
||||
# Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path
|
||||
my $basename = ($ENV{VERILATOR_BIN}
|
||||
|| ($Debug ? "verilator_bin_dbg" : "verilator_bin"));
|
||||
|| ($Debug ? "verilator_bin_dbg" : "verilator_bin"));
|
||||
if (defined($ENV{VERILATOR_ROOT})) {
|
||||
my $dir = $ENV{VERILATOR_ROOT};
|
||||
if (-x "$dir/bin/$basename") { # From a "make install" into VERILATOR_ROOT
|
||||
$bin = "$dir/bin/$basename";
|
||||
} else {
|
||||
$bin = "$dir/$basename"; # From pointing to kit directory
|
||||
}
|
||||
my $dir = $ENV{VERILATOR_ROOT};
|
||||
if (-x "$dir/bin/$basename") { # From a "make install" into VERILATOR_ROOT
|
||||
$bin = "$dir/bin/$basename";
|
||||
} else {
|
||||
$bin = "$dir/$basename"; # From pointing to kit directory
|
||||
}
|
||||
} else {
|
||||
if (-x "$RealBin/$basename") {
|
||||
$bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed
|
||||
} else {
|
||||
$bin = $basename; # Find in PATH
|
||||
}
|
||||
# Note we don't look under bin/$basename which would be right if running
|
||||
# in the kit dir. Running that would likely break, since
|
||||
# VERILATOR_ROOT wouldn't be set and Verilator won't find internal files.
|
||||
if (-x "$RealBin/$basename") {
|
||||
$bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed
|
||||
} else {
|
||||
$bin = $basename; # Find in PATH
|
||||
}
|
||||
# Note we don't look under bin/$basename which would be right if running
|
||||
# in the kit dir. Running that would likely break, since
|
||||
# VERILATOR_ROOT wouldn't be set and Verilator won't find internal files.
|
||||
}
|
||||
return $bin;
|
||||
}
|
||||
@@ -158,10 +158,10 @@ sub verilator_bin {
|
||||
sub gdb_works {
|
||||
$! = undef; # Cleanup -x
|
||||
system("gdb /bin/echo"
|
||||
." --batch-silent --quiet --return-child-result"
|
||||
." -ex 'run -n'" # `echo -n`
|
||||
." -ex 'set width 0'"
|
||||
." -ex 'bt'");
|
||||
." --batch-silent --quiet --return-child-result"
|
||||
." -ex 'run -n'" # `echo -n`
|
||||
." -ex 'set width 0'"
|
||||
." -ex 'bt'");
|
||||
my $status = $?;
|
||||
return $status==0;
|
||||
}
|
||||
@@ -174,23 +174,23 @@ sub run {
|
||||
system($command);
|
||||
my $status = $?;
|
||||
if ($status) {
|
||||
if ($! =~ /no such file or directory/i) {
|
||||
warn "%Error: verilator: Misinstalled, or VERILATOR_ROOT might need to be in environment\n";
|
||||
}
|
||||
if ($Debug) { # For easy rerunning
|
||||
warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n";
|
||||
warn "%Error: $command\n";
|
||||
}
|
||||
if ($status & 127) {
|
||||
if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV
|
||||
warn "%Error: Verilator internal fault, sorry. Consider trying --debug --gdbbt\n" if !$Debug;
|
||||
} elsif (($status & 127) == 6) { # SIGABRT
|
||||
warn "%Error: Verilator aborted. Consider trying --debug --gdbbt\n" if !$Debug;
|
||||
} else {
|
||||
warn "%Error: Verilator threw signal $status. Consider trying --debug --gdbbt\n" if !$Debug;
|
||||
}
|
||||
}
|
||||
die "%Error: Command Failed $command\n";
|
||||
if ($! =~ /no such file or directory/i) {
|
||||
warn "%Error: verilator: Misinstalled, or VERILATOR_ROOT might need to be in environment\n";
|
||||
}
|
||||
if ($Debug) { # For easy rerunning
|
||||
warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n";
|
||||
warn "%Error: $command\n";
|
||||
}
|
||||
if ($status & 127) {
|
||||
if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV
|
||||
warn "%Error: Verilator internal fault, sorry. Consider trying --debug --gdbbt\n" if !$Debug;
|
||||
} elsif (($status & 127) == 6) { # SIGABRT
|
||||
warn "%Error: Verilator aborted. Consider trying --debug --gdbbt\n" if !$Debug;
|
||||
} else {
|
||||
warn "%Error: Verilator threw signal $status. Consider trying --debug --gdbbt\n" if !$Debug;
|
||||
}
|
||||
}
|
||||
die "%Error: Command Failed $command\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,9 +209,9 @@ Verilator - Convert Verilog code to C++/SystemC
|
||||
|
||||
verilator --help
|
||||
verilator --version
|
||||
verilator --cc [options] [top_level.v]... [opt_c_files.cpp/c/cc/a/o/so]
|
||||
verilator --sc [options] [top_level.v]... [opt_c_files.cpp/c/cc/a/o/so]
|
||||
verilator --lint-only [top_level.v]...
|
||||
verilator --cc [options] [source_files.v]... [opt_c_files.cpp/c/cc/a/o/so]
|
||||
verilator --sc [options] [source_files.v]... [opt_c_files.cpp/c/cc/a/o/so]
|
||||
verilator --lint-only [source_files.v]...
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
@@ -239,7 +239,7 @@ To get started, jump down to "EXAMPLE C++ EXECUTION".
|
||||
This is a short summary of the arguments to Verilator. See the detailed
|
||||
descriptions in the next sections for more information.
|
||||
|
||||
{file.v} Verilog top level filenames
|
||||
{file.v} Verilog package, module and top module filenames
|
||||
{file.c/cc/cpp} Optional C++ files to compile in
|
||||
{file.a/o/so} Optional C++ files to link in
|
||||
|
||||
@@ -280,6 +280,7 @@ descriptions in the next sections for more information.
|
||||
--exe Link to create executable
|
||||
-F <file> Parse options from a file, relatively
|
||||
-f <file> Parse options from a file
|
||||
-FI <file> Force include of a file
|
||||
-G<name>=<value> Overwrite toplevel parameter
|
||||
--gdb Run Verilator under GDB interactively
|
||||
--gdbbt Run Verilator under GDB for backtrace
|
||||
@@ -300,6 +301,7 @@ descriptions in the next sections for more information.
|
||||
--Mdir <directory> Name of output object directory
|
||||
--mod-prefix <topname> Name to prepend to lower classes
|
||||
--no-clk <signal-name> Prevent marking specified signal as clock
|
||||
--no-decoration Disable comments and symbol decorations
|
||||
--no-pins64 Don't use vluint64_t's for 33-64 bit sigs
|
||||
--no-skip-identical Disable skipping identical output
|
||||
+notimingchecks Ignored
|
||||
@@ -322,8 +324,9 @@ descriptions in the next sections for more information.
|
||||
--private Debugging; see docs
|
||||
--public Debugging; see docs
|
||||
-pvalue+<name>=<value> Overwrite toplevel parameter
|
||||
--relative-includes Resolve includes relative to current file
|
||||
--report-unoptflat Extra diagnostics for UNOPTFLAT
|
||||
--savable Enable model save-restore
|
||||
--savable Enable model save-restore
|
||||
--sc Create SystemC output
|
||||
--stats Create statistics file
|
||||
--stats-vars Provide statistics on variables
|
||||
@@ -443,9 +446,10 @@ calls.
|
||||
|
||||
=item --bbox-unsup
|
||||
|
||||
Black box some unsupported language features, currently UDP tables and the
|
||||
cmos and tran gate primitives. This may enable linting the rest of the
|
||||
design even when unsupported constructs are present.
|
||||
Black box some unsupported language features, currently UDP tables, the
|
||||
cmos and tran gate primitives, deassign statements, and mixed edge errors.
|
||||
This may enable linting the rest of the design even when unsupported
|
||||
constructs are present.
|
||||
|
||||
=item --bin I<filename>
|
||||
|
||||
@@ -491,6 +495,10 @@ 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.
|
||||
|
||||
If clock signals are assigned to vectors and then later used individually,
|
||||
Verilator will attempt to decompose the vector and connect the single-bit
|
||||
clock signals directly. This should be transparent to the user.
|
||||
|
||||
=item --compiler I<compiler-name>
|
||||
|
||||
Enables tunings and workarounds for the specified C++ compiler.
|
||||
@@ -702,6 +710,14 @@ The file may contain // comments which are ignored to the end of the line.
|
||||
Any $VAR, $(VAR), or ${VAR} will be replaced with the specified environment
|
||||
variable.
|
||||
|
||||
=item -FI <file>
|
||||
|
||||
Force include of the specified C++ header file. All generated C++ files
|
||||
will insert a #include of the specified file before any other includes. The
|
||||
specified file might be used to contain define prototypes of custom
|
||||
VL_VPRINTF functions, and may need to include verilatedos.h as this file is
|
||||
included before any other standard includes.
|
||||
|
||||
=item -GI<name>=I<value>
|
||||
|
||||
Overwrites the given parameter of the toplevel module. The value is limited
|
||||
@@ -843,6 +859,13 @@ the same as --prefix.
|
||||
|
||||
Prevent the specified signal from being marked as clock. See C<--clk>.
|
||||
|
||||
=item --no-decoration
|
||||
|
||||
When creating output Verilated code, minimize comments, whitespace, symbol
|
||||
names and other decorative items, at the cost of greatly reduced
|
||||
readability. This may assist C++ compile times. This will not typically
|
||||
change the ultimate model's performance, but may in some cases.
|
||||
|
||||
=item --no-pins64
|
||||
|
||||
Backward compatible alias for "--pins-bv 33".
|
||||
@@ -1005,6 +1028,12 @@ inlining. This will also turn off inlining as if all modules had a
|
||||
Overwrites the given parameter(s) of the toplevel module. See -G for a
|
||||
detailed description.
|
||||
|
||||
=item --relative-includes
|
||||
|
||||
When a file references an include file, resolve the filename relative to
|
||||
the path of the referencing file, instead of relative to the current
|
||||
directory.
|
||||
|
||||
=item --report-unoptflat
|
||||
|
||||
Extra diagnostics for UNOPTFLAT warnings. This includes for each loop, the
|
||||
@@ -1328,7 +1357,7 @@ We'll compile this example into C++.
|
||||
#include "Vour.h"
|
||||
#include "verilated.h"
|
||||
int main(int argc, char **argv, char **env) {
|
||||
Verilated::commandArgs(argc, argv);
|
||||
Verilated::commandArgs(argc, argv);
|
||||
Vour* top = new Vour;
|
||||
while (!Verilated::gotFinish()) { top->eval(); }
|
||||
delete top;
|
||||
@@ -1336,9 +1365,15 @@ We'll compile this example into C++.
|
||||
}
|
||||
EOF
|
||||
|
||||
If you installed Verilator from sources, or a tarball, but not as part of
|
||||
your operating system (as an RPM), first you need to point to the kit:
|
||||
See the README in the source kit for various ways to install or point to
|
||||
Verilator binaries. In brief, if you are running Verilator that came from
|
||||
your operating system (as an RPM), or did a "make install" to place
|
||||
Verilator into your default path, you do not need anything special in your
|
||||
environment, and should not have VERILATOR_ROOT set. However, if you
|
||||
installed Verilator from sources and want to run Verilator out of where you
|
||||
compiled Verilator, you need to point to the kit:
|
||||
|
||||
# See above; don't do this if using an OS-distributed Verilator
|
||||
export VERILATOR_ROOT=/path/to/where/verilator/was/installed
|
||||
export PATH=$VERILATOR_ROOT/bin:$PATH
|
||||
|
||||
@@ -1353,8 +1388,7 @@ section below for descriptions of some of the files that were created.
|
||||
|
||||
We then can compile it
|
||||
|
||||
cd obj_dir
|
||||
make -j -f Vour.mk Vour
|
||||
make -j -C obj_dir -f Vour.mk Vour
|
||||
|
||||
(Verilator included a default compile rule and link rule, since we used
|
||||
--exe and passed a .cpp file on the Verilator command line. You can also
|
||||
@@ -1362,7 +1396,6 @@ write your own compile rules, as we'll show in the SYSTEMC section.)
|
||||
|
||||
And now we run it
|
||||
|
||||
cd ..
|
||||
obj_dir/Vour
|
||||
|
||||
And we get as output
|
||||
@@ -1371,8 +1404,9 @@ And we get as output
|
||||
- our.v:2: Verilog $finish
|
||||
|
||||
Really, you're better off writing a Makefile to do all this for you. Then,
|
||||
when your source changes it will automatically run all of these steps. See
|
||||
the test_c directory in the distribution for an example.
|
||||
when your source changes it will automatically run all of these steps; to
|
||||
aid this Verilator can create a makefile dependency file. See the test_c
|
||||
directory in the distribution for an example.
|
||||
|
||||
|
||||
=head1 EXAMPLE SYSTEMC EXECUTION
|
||||
@@ -1393,7 +1427,7 @@ This is an example similar to the above, but using SystemC.
|
||||
cat <<EOF >sc_main.cpp
|
||||
#include "Vour.h"
|
||||
int sc_main(int argc, char **argv) {
|
||||
Verilated::commandArgs(argc, argv);
|
||||
Verilated::commandArgs(argc, argv);
|
||||
sc_clock clk ("clk",10, 0.5, 3, true);
|
||||
Vour* top;
|
||||
top = new Vour("top"); // SP_CELL (top, Vour);
|
||||
@@ -1404,9 +1438,15 @@ This is an example similar to the above, but using SystemC.
|
||||
}
|
||||
EOF
|
||||
|
||||
If you installed Verilator from sources, or a tarball, but not as part of
|
||||
your operating system (as an RPM), first you need to point to the kit:
|
||||
See the README in the source kit for various ways to install or point to
|
||||
Verilator binaries. In brief, if you are running Verilator that came from
|
||||
your operating system (as an RPM), or did a "make install" to place
|
||||
Verilator into your default path, you do not need anything special in your
|
||||
environment, and should not have VERILATOR_ROOT set. However, if you
|
||||
installed Verilator from sources and want to run Verilator out of where you
|
||||
compiled Verilator, you need to point to the kit:
|
||||
|
||||
# See above; don't do this if using an OS-distributed Verilator
|
||||
export VERILATOR_ROOT=/path/to/where/verilator/was/installed
|
||||
export PATH=$VERILATOR_ROOT/bin:$PATH
|
||||
|
||||
@@ -1416,6 +1456,7 @@ Now we run Verilator on our little example.
|
||||
|
||||
We then can compile it
|
||||
|
||||
cd obj_dir
|
||||
make -j -f Vour.mk Vour__ALL.a
|
||||
make -j -f Vour.mk ../sc_main.o verilated.o
|
||||
|
||||
@@ -1521,42 +1562,42 @@ All output files are placed in the output directory name specified with the
|
||||
|
||||
Verilator creates the following files in the output directory:
|
||||
|
||||
{prefix}.mk // Make include file for compiling
|
||||
{prefix}_classes.mk // Make include file with class names
|
||||
{prefix}.mk // Make include file for compiling
|
||||
{prefix}_classes.mk // Make include file with class names
|
||||
|
||||
For -cc and -sc mode, it also creates:
|
||||
|
||||
{prefix}.cpp // Top level C++ file
|
||||
{prefix}.h // Top level header
|
||||
{prefix}{each_verilog_module}.cpp // Lower level internal C++ files
|
||||
{prefix}{each_verilog_module}.h // Lower level internal header files
|
||||
{prefix}.cpp // Top level C++ file
|
||||
{prefix}.h // Top level header
|
||||
{prefix}{each_verilog_module}.cpp // Lower level internal C++ files
|
||||
{prefix}{each_verilog_module}.h // Lower level internal header files
|
||||
|
||||
In certain optimization modes, it also creates:
|
||||
|
||||
{prefix}__Dpi.h // DPI import and export declarations
|
||||
{prefix}__Inlines.h // Inline support functions
|
||||
{prefix}__Slow.cpp // Constructors and infrequent routines
|
||||
{prefix}__Syms.cpp // Global symbol table C++
|
||||
{prefix}__Syms.h // Global symbol table header
|
||||
{prefix}__Trace.cpp // Wave file generation code (--trace)
|
||||
{prefix}__cdc.txt // Clock Domain Crossing checks (--cdc)
|
||||
{prefix}__stats.txt // Statistics (--stats)
|
||||
{prefix}__Dpi.h // DPI import and export declarations
|
||||
{prefix}__Inlines.h // Inline support functions
|
||||
{prefix}__Slow.cpp // Constructors and infrequent routines
|
||||
{prefix}__Syms.cpp // Global symbol table C++
|
||||
{prefix}__Syms.h // Global symbol table header
|
||||
{prefix}__Trace.cpp // Wave file generation code (--trace)
|
||||
{prefix}__cdc.txt // Clock Domain Crossing checks (--cdc)
|
||||
{prefix}__stats.txt // Statistics (--stats)
|
||||
|
||||
It also creates internal files that can be mostly ignored:
|
||||
|
||||
{each_verilog_module}.vpp // Post-processed verilog (--debug)
|
||||
{prefix}.flags_vbin // Verilator dependencies
|
||||
{prefix}.flags_vpp // Pre-processor dependencies
|
||||
{prefix}__verFiles.dat // Timestamps for skip-identical
|
||||
{prefix}{misc}.d // Make dependencies (-MMD)
|
||||
{prefix}{misc}.dot // Debugging graph files (--debug)
|
||||
{prefix}{misc}.tree // Debugging files (--debug)
|
||||
{each_verilog_module}.vpp // Post-processed verilog (--debug)
|
||||
{prefix}.flags_vbin // Verilator dependencies
|
||||
{prefix}.flags_vpp // Pre-processor dependencies
|
||||
{prefix}__verFiles.dat // Timestamps for skip-identical
|
||||
{prefix}{misc}.d // Make dependencies (-MMD)
|
||||
{prefix}{misc}.dot // Debugging graph files (--debug)
|
||||
{prefix}{misc}.tree // Debugging files (--debug)
|
||||
|
||||
After running Make, the C++ compiler should produce the following:
|
||||
|
||||
{prefix} // Final executable (w/--exe argument)
|
||||
{prefix}__ALL.a // Library of all Verilated objects
|
||||
{prefix}{misc}.o // Intermediate objects
|
||||
{prefix} // Final executable (w/--exe argument)
|
||||
{prefix}__ALL.a // Library of all Verilated objects
|
||||
{prefix}{misc}.o // Intermediate objects
|
||||
|
||||
|
||||
=head1 ENVIRONMENT
|
||||
@@ -1651,46 +1692,47 @@ simulation executable.
|
||||
The user must write the top level of the simulation. Here's a simple
|
||||
example:
|
||||
|
||||
#include <verilated.h> // Defines common routines
|
||||
#include "Vtop.h" // From Verilating "top.v"
|
||||
#include <verilated.h> // Defines common routines
|
||||
#include <iostream> // Need std::cout
|
||||
#include "Vtop.h" // From Verilating "top.v"
|
||||
|
||||
Vtop *top; // Instantiation of module
|
||||
Vtop *top; // Instantiation of module
|
||||
|
||||
vluint64_t main_time = 0; // Current simulation time
|
||||
// This is a 64-bit integer to reduce wrap over issues and
|
||||
// allow modulus. You can also use a double, if you wish.
|
||||
vluint64_t main_time = 0; // Current simulation time
|
||||
// This is a 64-bit integer to reduce wrap over issues and
|
||||
// allow modulus. You can also use a double, if you wish.
|
||||
|
||||
double sc_time_stamp () { // Called by $time in Verilog
|
||||
return main_time; // converts to double, to match
|
||||
// what SystemC does
|
||||
}
|
||||
double sc_time_stamp () { // Called by $time in Verilog
|
||||
return main_time; // converts to double, to match
|
||||
// what SystemC does
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
Verilated::commandArgs(argc, argv); // Remember args
|
||||
int main(int argc, char** argv) {
|
||||
Verilated::commandArgs(argc, argv); // Remember args
|
||||
|
||||
top = new Vtop; // Create instance
|
||||
top = new Vtop; // Create instance
|
||||
|
||||
top->reset_l = 0; // Set some inputs
|
||||
top->reset_l = 0; // Set some inputs
|
||||
|
||||
while (!Verilated::gotFinish()) {
|
||||
if (main_time > 10) {
|
||||
top->reset_l = 1; // Deassert reset
|
||||
}
|
||||
if ((main_time % 10) == 1) {
|
||||
top->clk = 1; // Toggle clock
|
||||
}
|
||||
if ((main_time % 10) == 6) {
|
||||
top->clk = 0;
|
||||
}
|
||||
top->eval(); // Evaluate model
|
||||
cout << top->out << endl; // Read a output
|
||||
main_time++; // Time passes...
|
||||
}
|
||||
while (!Verilated::gotFinish()) {
|
||||
if (main_time > 10) {
|
||||
top->reset_l = 1; // Deassert reset
|
||||
}
|
||||
if ((main_time % 10) == 1) {
|
||||
top->clk = 1; // Toggle clock
|
||||
}
|
||||
if ((main_time % 10) == 6) {
|
||||
top->clk = 0;
|
||||
}
|
||||
top->eval(); // Evaluate model
|
||||
cout << top->out << endl; // Read a output
|
||||
main_time++; // Time passes...
|
||||
}
|
||||
|
||||
top->final(); // Done simulating
|
||||
// // (Though this example doesn't get here)
|
||||
delete top;
|
||||
}
|
||||
top->final(); // Done simulating
|
||||
// // (Though this example doesn't get here)
|
||||
delete top;
|
||||
}
|
||||
|
||||
Note signals are read and written as member variables of the lower module.
|
||||
You call the eval() method to evaluate the model. When the simulation is
|
||||
@@ -1875,54 +1917,71 @@ documented below.
|
||||
Verilator has an important difference from an event based simulator; signal
|
||||
values that are changed by the VPI will not immediately propagate their
|
||||
values, instead the top level header file's eval() method must be called.
|
||||
Normally this would be part of the normal evaluation (IE the next clock
|
||||
Normally this would be part of the normal evaluation (i.e. the next clock
|
||||
edge), not as part of the value change. This makes the performance of VPI
|
||||
routines extremely fast compared to event based simulators, but can confuse
|
||||
some test-benches that expect immediate propagation.
|
||||
|
||||
Note the VPI by it's specified implementation will always be much slower
|
||||
Note the VPI by its specified implementation will always be much slower
|
||||
than accessing the Verilator values by direct reference
|
||||
(structure->module->signame), as the VPI accessors perform lookup in
|
||||
functions at runtime requiring at best hundreds of instructions, while the
|
||||
direct references are evaluated by the compiler and result in only a couple
|
||||
of instructions.
|
||||
|
||||
For signal callbacks to work the main loop of the program must call
|
||||
VerilatedVpi::callValueCbs().
|
||||
|
||||
=head2 VPI Example
|
||||
|
||||
In the below example, we have readme marked read-only, and writeme which if
|
||||
written from outside the model will have the same semantics as if it
|
||||
changed on the specified clock edge.
|
||||
|
||||
module t;
|
||||
reg readme /*verilator public_flat_rd*/;
|
||||
reg writeme /*verilator public_flat_rw @(posedge clk) */;
|
||||
endmodule
|
||||
cat <<EOF >our.v
|
||||
module our (input clk);
|
||||
reg readme /*verilator public_flat_rd*/;
|
||||
reg writeme /*verilator public_flat_rw @(posedge clk) */;
|
||||
initial $finish;
|
||||
endmodule
|
||||
EOF
|
||||
|
||||
There are many online tutorials and books on the VPI, but an example that
|
||||
accesses the above would be:
|
||||
accesses the above signal "readme" 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"
|
||||
cat <<EOF >sim_main.cpp
|
||||
#include "Vour.h"
|
||||
#include "verilated.h"
|
||||
#include "verilated_vpi.h" // Required to get definitions
|
||||
|
||||
s_vpi_value v;
|
||||
v.format = vpiIntVal;
|
||||
vpi_get_value(vh1, &v);
|
||||
printf("Value of v: %d\n", v.value.integer); // Prints "readme"
|
||||
}
|
||||
vluint64_t main_time = 0; // See comments in first example
|
||||
double sc_time_stamp () { return main_time; }
|
||||
|
||||
For signal callbacks to work the main loop of the program must call
|
||||
VerilatedVpi::callValueCbs().
|
||||
void read_and_check() {
|
||||
vpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)"TOP.our.readme", NULL);
|
||||
if (!vh1) { vl_fatal(__FILE__, __LINE__, "sim_main", "No handle found"); }
|
||||
const char* name = vpi_get_str(vpiName, vh1);
|
||||
printf("Module name: %s\n", name); // Prints "readme"
|
||||
|
||||
#include "verilated_vpi.h" // Required to get definitions
|
||||
...
|
||||
while (time passes) {
|
||||
...
|
||||
topp->eval();
|
||||
VerilatedVpi::callValueCbs();
|
||||
}
|
||||
s_vpi_value v;
|
||||
v.format = vpiIntVal;
|
||||
vpi_get_value(vh1, &v);
|
||||
printf("Value of v: %d\n", v.value.integer); // Prints "readme"
|
||||
}
|
||||
|
||||
int main(int argc, char **argv, char **env) {
|
||||
Verilated::commandArgs(argc, argv);
|
||||
Vour* top = new Vour;
|
||||
Verilated::internalsDump(); // See scopes to help debug
|
||||
while (!Verilated::gotFinish()) {
|
||||
top->eval();
|
||||
VerilatedVpi::callValueCbs(); // For signal callbacks
|
||||
read_and_check();
|
||||
}
|
||||
delete top;
|
||||
exit(0);
|
||||
}
|
||||
EOF
|
||||
|
||||
|
||||
=head1 CROSS COMPILATION
|
||||
@@ -1965,10 +2024,10 @@ underneath NC:
|
||||
|
||||
cd obj_dir
|
||||
ncsc_run \
|
||||
sc_main.cpp \
|
||||
Vour__ALLcls.cpp \
|
||||
Vour__ALLsup.cpp \
|
||||
verilated.cpp
|
||||
sc_main.cpp \
|
||||
Vour__ALLcls.cpp \
|
||||
Vour__ALLsup.cpp \
|
||||
verilated.cpp
|
||||
|
||||
For larger designs you'll want to automate this using makefiles, which pull
|
||||
the names of the .cpp files to compile in from the make variables generated
|
||||
@@ -2020,8 +2079,9 @@ numbers (or all lines if omitted).
|
||||
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 enabled/disabled. This will
|
||||
override all later lint warning enables for the specified region.
|
||||
If the -msg is omitted, all lint warnings (see list in -Wno-lint) are
|
||||
enabled/disabled. This will override all later lint warning enables for
|
||||
the specified region.
|
||||
|
||||
=item tracing_on [-file "<filename>" [-lines <line> [ - <line> ]]]
|
||||
|
||||
@@ -2362,6 +2422,14 @@ reduce the size of the final executable when a task is used a very large
|
||||
number of times. For this flag to work, the task and tasks below it must
|
||||
be pure; they cannot reference any variables outside the task itself.
|
||||
|
||||
=item /*verilator public*/ (parameter)
|
||||
|
||||
Used after a parameter declaration to indicate the emitted C code should
|
||||
have the parameter values visible. Due to C++ language restrictions, this
|
||||
may only be used on 64-bit or narrower integral enumerations.
|
||||
|
||||
parameter [2:0] PARAM /*verilator public*/ = 2'b0;
|
||||
|
||||
=item /*verilator public*/ (typedef enum)
|
||||
|
||||
Used after an enum typedef declaration to indicate the emitted C code
|
||||
@@ -2485,7 +2553,7 @@ such as $stop, $finish and $display. That is, you cannot use hierarchical
|
||||
references, events or similar features of the Verilog language. It also
|
||||
simulates as Synopsys's Design Compiler would; namely a block of the form:
|
||||
|
||||
always @ (x) y = x & z;
|
||||
always @ (x) y = x & z;
|
||||
|
||||
This will recompute y when there is even a potential for change in x or a
|
||||
change in z, that is when the flops computing x or z evaluate (which is
|
||||
@@ -2495,6 +2563,14 @@ always @* to reduce missing activity items. Avoid putting $displays in
|
||||
combo blocks, as they may print multiple times when not desired, even on
|
||||
compliant simulators as event ordering is not specified.
|
||||
|
||||
=head2 Signal Naming
|
||||
|
||||
To avoid conflicts with C symbol naming, any character in a signal name
|
||||
that is not alphanumeric nor a single underscore will be replaced by __0hh
|
||||
where hh is the hex code of the character. To avoid conflicts with
|
||||
Verilator's internal symbols, any double underscore are replaced with
|
||||
___05F (5F is the hex code of an underscore.)
|
||||
|
||||
=head2 Bind
|
||||
|
||||
Verilator only supports "bind" to a target module name, not an instance
|
||||
@@ -2829,9 +2905,9 @@ Warnings may be disabled in three ways. First, when the warning is
|
||||
printed it will include a warning code. Simply surround the offending
|
||||
line with a warn_off/warn_on pair:
|
||||
|
||||
// verilator lint_off UNSIGNED
|
||||
if (`DEF_THAT_IS_EQ_ZERO <= 3) $stop;
|
||||
// verilator lint_on UNSIGNED
|
||||
// verilator lint_off UNSIGNED
|
||||
if (`DEF_THAT_IS_EQ_ZERO <= 3) $stop;
|
||||
// verilator lint_on UNSIGNED
|
||||
|
||||
Second, warnings may be disabled using a configuration file with a lint_off
|
||||
command. This is useful when a script is suppressing warnings and the
|
||||
@@ -2899,13 +2975,12 @@ Simply use a different register for the flop:
|
||||
always @* foo[0] = foo_flopped[0];
|
||||
always @* foo[1] = ...
|
||||
|
||||
This is good coding practice anyways.
|
||||
|
||||
It is also possible to disable this error when one of the assignments is
|
||||
inside a public task.
|
||||
|
||||
Ignoring this warning may make Verilator simulations differ from other
|
||||
simulators.
|
||||
This is not illegal in SystemVerilog, but a violation of good coding
|
||||
practice. Verilator reports this as an error, because ignoring this warning
|
||||
may make Verilator simulations differ from other simulators.
|
||||
|
||||
=item BLKSEQ
|
||||
|
||||
@@ -2929,10 +3004,10 @@ were used, the simulator would have to copy large arrays every cycle. (In
|
||||
smaller loops, loop unrolling allows the delayed assignment to work, though
|
||||
it's a bit slower than a non-delayed assignment.) Here's an example
|
||||
|
||||
always @ (posedge clk)
|
||||
always @ (posedge clk)
|
||||
if (~reset_l) begin
|
||||
for (i=0; i<`ARRAY_SIZE; i++) begin
|
||||
array[i] = 0; // Non-delayed for verilator
|
||||
array[i] = 0; // Non-delayed for verilator
|
||||
end
|
||||
|
||||
This message is only seen on large or complicated loops because Verilator
|
||||
@@ -3390,9 +3465,9 @@ A recommended style for unused nets is to put at the bottom of a file code
|
||||
similar to the following:
|
||||
|
||||
wire _unused_ok = &{1'b0,
|
||||
sig_not_used_a,
|
||||
sig_not_used_yet_b, // To be fixed
|
||||
1'b0};
|
||||
sig_not_used_a,
|
||||
sig_not_used_yet_b, // To be fixed
|
||||
1'b0};
|
||||
|
||||
The reduction AND and constant zeros mean the net will always be zero, so
|
||||
won't use simulation time. The redundant leading and trailing zeros avoid
|
||||
@@ -3429,11 +3504,11 @@ unwidthed. Verilator considers zero to be any width needed.
|
||||
|
||||
Concatenate leading zeros when doing arithmetic. In the statement
|
||||
|
||||
wire [5:0] plus_one = from[5:0] + 6'd1 + carry[0];
|
||||
wire [5:0] plus_one = from[5:0] + 6'd1 + carry[0];
|
||||
|
||||
The best fix, which clarifies intent and will also make all tools happy is:
|
||||
|
||||
wire [5:0] plus_one = from[5:0] + 6'd1 + {5'd0,carry[0]};
|
||||
wire [5:0] plus_one = from[5:0] + 6'd1 + {5'd0,carry[0]};
|
||||
|
||||
Ignoring this warning will only suppress the lint check, it will simulate
|
||||
correctly.
|
||||
@@ -3631,7 +3706,7 @@ trace file if you want all data to land in the same output file.
|
||||
tfp->open ("obj_dir/t_trace_ena_cc/simx.vcd");
|
||||
...
|
||||
sc_start(1);
|
||||
...
|
||||
...
|
||||
tfp->close();
|
||||
}
|
||||
|
||||
@@ -3978,7 +4053,7 @@ Thanks to them, and all those we've missed including above.
|
||||
|
||||
The latest version is available from L<http://www.veripool.org/>.
|
||||
|
||||
Copyright 2003-2016 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2003-2017 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify the Verilator internals under the terms of
|
||||
either the GNU Lesser General Public License Version 3 or the Perl Artistic
|
||||
License Version 2.0.
|
||||
|
||||
@@ -3,7 +3,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
|
||||
if 0;
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2003-2016 by Wilson Snyder. This program is free software; you
|
||||
# Copyright 2003-2017 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
@@ -271,7 +271,7 @@ Specifies a module search directory.
|
||||
|
||||
The latest version is available from L<http://www.veripool.org/>.
|
||||
|
||||
Copyright 2003-2016 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2003-2017 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify the Verilator internals under the terms of
|
||||
either the GNU Lesser General Public License Version 3 or the Perl Artistic
|
||||
License Version 2.0.
|
||||
|
||||
@@ -235,7 +235,7 @@ Do not show differences in line numbering.
|
||||
|
||||
The latest version is available from L<http://www.veripool.org/verilator>.
|
||||
|
||||
Copyright 2005-2016 by Wilson Snyder. This package is free software; you can
|
||||
Copyright 2005-2017 by Wilson Snyder. This package is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ eval 'exec perl -wS $0 ${1+"$@"}'
|
||||
if 0;
|
||||
# DESCRIPTION: Print include statements for each ARGV
|
||||
#
|
||||
# Copyright 2003-2016 by Wilson Snyder. This package is free software; you can
|
||||
# Copyright 2003-2017 by Wilson Snyder. This package is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
# General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
######################################################################
|
||||
|
||||
@@ -222,7 +222,7 @@ Displays this message and program version and exits.
|
||||
|
||||
The latest version is available from L<http://www.veripool.org/>.
|
||||
|
||||
Copyright 2007-2016 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2007-2017 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
|
||||
+15
-3
@@ -1,12 +1,12 @@
|
||||
# DESCRIPTION: Process this file with autoconf to produce a configure script.
|
||||
#
|
||||
# Copyright 2003-2016 by Wilson Snyder. Verilator is free software; you can
|
||||
# Copyright 2003-2017 by Wilson Snyder. Verilator is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
# General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
|
||||
#AC_INIT([Verilator],[#.### devel])
|
||||
AC_INIT([Verilator],[3.886 2016-07-30])
|
||||
AC_INIT([Verilator],[3.904 2017-05-30])
|
||||
# When releasing, also update header of Changes file
|
||||
|
||||
AC_CONFIG_HEADER(src/config_build.h)
|
||||
@@ -15,7 +15,7 @@ AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk incl
|
||||
AC_MSG_RESULT([configuring for $PACKAGE_STRING])
|
||||
|
||||
# Special Substitutions - CFG_WITH_DEFENV
|
||||
AC_MSG_CHECKING(whether to disable hardcoded paths)
|
||||
AC_MSG_CHECKING(whether to use hardcoded paths)
|
||||
AC_ARG_ENABLE([defenv],
|
||||
[AS_HELP_STRING([--disable-defenv],
|
||||
[disable using some hardcoded data paths extracted from some default environment variables (the default is to use hardcoded paths)])],
|
||||
@@ -120,6 +120,18 @@ AC_DEFUN([_MY_CXX_CHECK_OPT],
|
||||
fi
|
||||
fi],
|
||||
[_my_result=no])
|
||||
# GCC is annoying, trying to be helpful, it postpones unknown -Wno-
|
||||
# options if there's no error We want to see them regardless, so try
|
||||
# forcing an error and see if we get a gcc warning
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([[an_error "intentional-error-for-test.h"
|
||||
]],[])],
|
||||
[], # Ignore ok exit
|
||||
[if test -s conftest.err; then
|
||||
if grep -e "$2" conftest.err >/dev/null; then
|
||||
_my_result=no
|
||||
fi
|
||||
fi])
|
||||
AC_MSG_RESULT($_my_result)
|
||||
if test "$_my_result" = "yes" ; then
|
||||
$1="$$1 $2"
|
||||
|
||||
+63
-21
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
@@ -302,8 +302,7 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
|
||||
bool inPct = false;
|
||||
bool widthSet = false;
|
||||
int width = 0;
|
||||
const char* pos = formatp;
|
||||
for (; *pos; ++pos) {
|
||||
for (const char* pos = formatp; *pos; ++pos) {
|
||||
if (!inPct && pos[0]=='%') {
|
||||
pctp = pos;
|
||||
inPct = true;
|
||||
@@ -1077,22 +1076,36 @@ IData VL_TESTPLUSARGS_I(const char* formatp) {
|
||||
else return 1;
|
||||
}
|
||||
|
||||
IData VL_VALUEPLUSARGS_IN(int, const char* prefixp, char, string& ldr) {
|
||||
const string& match = VerilatedImp::argPlusMatch(prefixp);
|
||||
const char* dp = match.c_str() + 1 /*leading + */ + strlen(prefixp);
|
||||
if (match == "") return 0;
|
||||
ldr = string(dp);
|
||||
return 1;
|
||||
}
|
||||
IData VL_VALUEPLUSARGS_INW(int rbits, const string& ld, WDataOutP rwp) {
|
||||
string prefix;
|
||||
bool inPct = false;
|
||||
bool done = false;
|
||||
char fmt = ' ';
|
||||
for (const char* posp = ld.c_str(); !done && *posp; ++posp) {
|
||||
if (!inPct && posp[0]=='%') {
|
||||
inPct = true;
|
||||
} else if (!inPct) { // Normal text
|
||||
prefix += *posp;
|
||||
} else { // Format character
|
||||
switch (tolower(*posp)) {
|
||||
case '%':
|
||||
prefix += *posp;
|
||||
inPct = false;
|
||||
break;
|
||||
default:
|
||||
fmt = *posp;
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rwp) {
|
||||
const string& match = VerilatedImp::argPlusMatch(prefixp);
|
||||
const char* dp = match.c_str() + 1 /*leading + */ + strlen(prefixp);
|
||||
const string& match = VerilatedImp::argPlusMatch(prefix.c_str());
|
||||
const char* dp = match.c_str() + 1 /*leading + */ + prefix.length();
|
||||
if (match == "") return 0;
|
||||
|
||||
VL_ZERO_RESET_W(rbits, rwp);
|
||||
switch (tolower(fmt)) {
|
||||
case '%':
|
||||
break;
|
||||
case 'd':
|
||||
vlsint64_t ld;
|
||||
sscanf(dp,"%30" VL_PRI64 "d",&ld);
|
||||
@@ -1108,18 +1121,47 @@ IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rw
|
||||
case 'x':
|
||||
_vl_vsss_based(rwp,rbits, 4, dp, 0, (int)strlen(dp));
|
||||
break;
|
||||
case 's':
|
||||
for (int i=0, lsb=0, pos=((int)strlen(dp))-1; i<rbits && pos>=0; pos--) {
|
||||
_vl_vsss_setbit(rwp,rbits,lsb, 8, dp[pos]); lsb+=8;
|
||||
case 's': // string/no conversion
|
||||
for (int i=0, lsb=0, posp=((int)strlen(dp))-1; i<rbits && posp>=0; posp--) {
|
||||
_vl_vsss_setbit(rwp,rbits,lsb, 8, dp[posp]); lsb+=8;
|
||||
}
|
||||
break;
|
||||
default: // Compile time should have found all errors before this
|
||||
vl_fatal (__FILE__, __LINE__, "", "$value$plusargs format error");
|
||||
break;
|
||||
case 'e': //FALLTHRU - Unsupported
|
||||
case 'f': //FALLTHRU - Unsupported
|
||||
case 'g': //FALLTHRU - Unsupported
|
||||
default: // Other simulators simply return 0 in these cases and don't error out
|
||||
return 0;
|
||||
}
|
||||
_VL_CLEAN_INPLACE_W(rbits,rwp);
|
||||
return 1;
|
||||
}
|
||||
IData VL_VALUEPLUSARGS_INN(int, const string& ld, string& rdr) {
|
||||
string prefix;
|
||||
bool inPct = false;
|
||||
bool done = false;
|
||||
for (const char* posp = ld.c_str(); !done && *posp; ++posp) {
|
||||
if (!inPct && posp[0]=='%') {
|
||||
inPct = true;
|
||||
} else if (!inPct) { // Normal text
|
||||
prefix += *posp;
|
||||
} else { // Format character
|
||||
switch (tolower(*posp)) {
|
||||
case '%':
|
||||
prefix += *posp;
|
||||
inPct = false;
|
||||
break;
|
||||
default:
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
const string& match = VerilatedImp::argPlusMatch(prefix.c_str());
|
||||
const char* dp = match.c_str() + 1 /*leading + */ + prefix.length();
|
||||
if (match == "") return 0;
|
||||
rdr = string(dp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char* vl_mc_scan_plusargs(const char* prefixp) {
|
||||
const string& match = VerilatedImp::argPlusMatch(prefixp);
|
||||
|
||||
+3
-1
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
@@ -1077,7 +1077,9 @@ static inline QData VL_MULS_QQQ(int,int lbits,int, QData lhs,QData rhs) {
|
||||
|
||||
static inline WDataOutP VL_MULS_WWW(int,int lbits,int, WDataOutP owp,WDataInP lwp,WDataInP rwp){
|
||||
int words = VL_WORDS_I(lbits);
|
||||
// cppcheck-suppress variableScope
|
||||
IData lwstore[VL_MULS_MAX_WORDS]; // Fixed size, as MSVC++ doesn't allow [words] here
|
||||
// cppcheck-suppress variableScope
|
||||
IData rwstore[VL_MULS_MAX_WORDS];
|
||||
WDataInP lwusp = lwp;
|
||||
WDataInP rwusp = rwp;
|
||||
|
||||
+16
-16
@@ -2,7 +2,7 @@
|
||||
######################################################################
|
||||
# DESCRIPTION: Makefile commands for all verilated target files
|
||||
#
|
||||
# Copyright 2003-2016 by Wilson Snyder. Verilator is free software; you can
|
||||
# Copyright 2003-2017 by Wilson Snyder. Verilator is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
# General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
######################################################################
|
||||
@@ -43,8 +43,9 @@ VK_CPPFLAGS_ALWAYS += \
|
||||
-I$(VERILATOR_ROOT)/include \
|
||||
-I$(VERILATOR_ROOT)/include/vltstd \
|
||||
-DVL_PRINTF=printf \
|
||||
-DVM_TRACE=$(VM_TRACE) \
|
||||
-DVM_COVERAGE=$(VM_COVERAGE) \
|
||||
-DVM_SC=$(VM_SC) \
|
||||
-DVM_TRACE=$(VM_TRACE) \
|
||||
$(CFG_CXXFLAGS_NO_UNUSED) \
|
||||
|
||||
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
|
||||
@@ -123,19 +124,10 @@ else
|
||||
preproc:
|
||||
endif
|
||||
|
||||
#######################################################################
|
||||
##### SystemC w/o SystemPerl builds
|
||||
|
||||
ifeq ($(VM_SC),1)
|
||||
LIBS += -lm -lstdc++
|
||||
endif
|
||||
|
||||
#######################################################################
|
||||
##### C/H builds
|
||||
|
||||
ifeq ($(VM_PCLI),1)
|
||||
LIBS += -lm -lstdc++
|
||||
endif
|
||||
LIBS += -lm -lstdc++
|
||||
|
||||
#######################################################################
|
||||
# Overall Objects Linking
|
||||
@@ -171,16 +163,24 @@ $(VM_PREFIX)__ALL.a: $(VK_OBJS)
|
||||
######################################################################
|
||||
### Compile rules
|
||||
|
||||
#Default rule embedded in make: (Not defined so user makefiles can override it)
|
||||
#.cpp.o:
|
||||
# $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
|
||||
ifneq ($(VM_DEFAULT_RULES),0)
|
||||
$(VM_PREFIX)__ALLsup.o: $(VM_PREFIX)__ALLsup.cpp
|
||||
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_SLOW) -c -o $@ $<
|
||||
|
||||
$(VM_PREFIX)__ALLcls.o: $(VM_PREFIX)__ALLcls.cpp
|
||||
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<
|
||||
|
||||
$(VM_PREFIX)%__Slow.o: $(VM_PREFIX)%__Slow.cpp
|
||||
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_SLOW) -c -o $@ $<
|
||||
|
||||
$(VM_PREFIX)%.o: $(VM_PREFIX)%.cpp
|
||||
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<
|
||||
endif
|
||||
|
||||
#Default rule embedded in make:
|
||||
#.cpp.o:
|
||||
# $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
|
||||
######################################################################
|
||||
### Debugging
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2016 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2017 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2016 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2017 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2016 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2017 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2009-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2010-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2010-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
@@ -66,6 +66,19 @@ extern void VL_READMEM_N(bool hex, int width, int depth, int array_lsb, int fnwo
|
||||
extern IData VL_SSCANF_INX(int lbits, const string& ld, const char* formatp, ...);
|
||||
extern void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...);
|
||||
extern string VL_SFORMATF_NX(const char* formatp, ...);
|
||||
extern IData VL_VALUEPLUSARGS_IN(int rbits, const char* prefixp, char fmt, string& ldr);
|
||||
extern IData VL_VALUEPLUSARGS_INW(int rbits, const string& ld, WDataOutP rdp);
|
||||
inline IData VL_VALUEPLUSARGS_INI(int rbits, const string& ld, IData& rdr) {
|
||||
IData rwp[1];
|
||||
IData got = VL_VALUEPLUSARGS_INW(rbits,ld,rwp);
|
||||
if (got) rdr = rwp[0];
|
||||
return got;
|
||||
}
|
||||
inline IData VL_VALUEPLUSARGS_INQ(int rbits, const string& ld, QData& rdr) {
|
||||
IData rwp[2];
|
||||
IData got = VL_VALUEPLUSARGS_INW(rbits,ld,rwp);
|
||||
if (got) rdr = VL_SET_QW(rwp);
|
||||
return got;
|
||||
}
|
||||
extern IData VL_VALUEPLUSARGS_INN(int, const string& ld, string& rdr);
|
||||
|
||||
#endif // Guard
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2009-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2016 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2017 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2012-2016 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2012-2017 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2009-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2016 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2017 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2016 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2017 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2016 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2017 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2016 by Wilson Snyder. This program is free software;
|
||||
// Copyright 2001-2017 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2009-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
@@ -26,6 +26,9 @@
|
||||
//=========================================================================
|
||||
|
||||
|
||||
#if VM_SC
|
||||
# include "verilated_sc.h"
|
||||
#endif
|
||||
#include "verilated.h"
|
||||
#include "verilated_vpi.h"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2009-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
|
||||
+1
-1
@@ -785,7 +785,7 @@ in C<src/Makefile_obj.in> and reconfigure.
|
||||
|
||||
The latest version is available from L<http://www.veripool.org/>.
|
||||
|
||||
Copyright 2008-2016 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2008-2017 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/perl -w
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2007-2016 by Wilson Snyder. This package is free software; you
|
||||
# Copyright 2007-2017 by Wilson Snyder. This package is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/perl -w
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2007-2016 by Wilson Snyder. This package is free software; you
|
||||
# Copyright 2007-2017 by Wilson Snyder. This package is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
+1
-1
@@ -143,7 +143,7 @@ Displays this message and program version and exits.
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2016 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2005-2017 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
|
||||
+1
-1
@@ -184,7 +184,7 @@ Displays this message and program version and exits.
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2016 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2005-2017 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/perl -w
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2007-2016 by Wilson Snyder. This package is free software; you
|
||||
# Copyright 2007-2017 by Wilson Snyder. This package is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
+3
-2
@@ -115,7 +115,8 @@ sub write_verilog {
|
||||
|
||||
sub cleanenv {
|
||||
foreach my $var (keys %ENV) {
|
||||
if ($var eq "VERILATOR_ROOT") {
|
||||
if ($var eq "VERILATOR_ROOT"
|
||||
|| $var eq "VERILATOR_INCLUDE") {
|
||||
print "unset $var # Was '$ENV{$var}'\n";
|
||||
delete $ENV{$var}
|
||||
}
|
||||
@@ -183,7 +184,7 @@ Runs a specific test stage (see the script).
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2009-2016 by Wilson Snyder. This package is free software; you
|
||||
Copyright 2009-2017 by Wilson Snyder. This package is free software; you
|
||||
can redistribute it and/or modify it under the terms of either the GNU
|
||||
Lesser General Public License Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ invoke_atsim - Invoke tool under "modules" command
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2016 by Wilson Snyder. This package is free software; you
|
||||
Copyright 2005-2017 by Wilson Snyder. This package is free software; you
|
||||
can redistribute it and/or modify it under the terms of either the GNU
|
||||
Lesser General Public License Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ invoke_iccr - Invoke tool under "modules" command
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2007-2016 by Wilson Snyder. This package is free software; you
|
||||
Copyright 2007-2017 by Wilson Snyder. This package is free software; you
|
||||
can redistribute it and/or modify it under the terms of either the GNU
|
||||
Lesser General Public License Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
@@ -28,7 +28,7 @@ invoke_ncverilog - Invoke tool under "modules" command
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2016 by Wilson Snyder. This package is free software; you
|
||||
Copyright 2005-2017 by Wilson Snyder. This package is free software; you
|
||||
can redistribute it and/or modify it under the terms of either the GNU
|
||||
Lesser General Public License Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ invoke_vcs - Invoke tool under "modules" command
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2016 by Wilson Snyder. This package is free software; you
|
||||
Copyright 2005-2017 by Wilson Snyder. This package is free software; you
|
||||
can redistribute it and/or modify it under the terms of either the GNU
|
||||
Lesser General Public License Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
@@ -331,7 +331,7 @@ Displays this message and program version and exits.
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2016 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2005-2017 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# DESCRIPTION: Verilator: GDB startup file with useful defines
|
||||
#
|
||||
# Copyright 2012-2016 by Wilson Snyder. This program is free software; you can
|
||||
# Copyright 2012-2017 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
#
|
||||
#*****************************************************************************
|
||||
#
|
||||
# Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
# Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
+3
-3
@@ -7,7 +7,7 @@
|
||||
#
|
||||
#*****************************************************************************
|
||||
#
|
||||
# Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
# Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
@@ -166,6 +166,7 @@ RAW_OBJS = \
|
||||
V3Begin.o \
|
||||
V3Branch.o \
|
||||
V3Broken.o \
|
||||
V3CCtors.o \
|
||||
V3Case.o \
|
||||
V3Cast.o \
|
||||
V3Cdc.o \
|
||||
@@ -237,7 +238,6 @@ RAW_OBJS = \
|
||||
V3Undriven.o \
|
||||
V3Unknown.o \
|
||||
V3Unroll.o \
|
||||
V3VarResets.o \
|
||||
V3Width.o \
|
||||
V3WidthSel.o \
|
||||
|
||||
@@ -302,7 +302,7 @@ serial:: V3Ast__gen_classes.h V3ParseBison.c
|
||||
|
||||
serial_vlcov:: vlcovgen.d
|
||||
|
||||
vlcovgen.d: $(VLCOVGEN) $(srcdir)/include/verilated_cov_key.h
|
||||
vlcovgen.d: $(VLCOVGEN) $(srcdir)/../include/verilated_cov_key.h
|
||||
$(PERL) $(VLCOVGEN) --srcdir $(srcdir)
|
||||
touch $@
|
||||
|
||||
|
||||
+26
-24
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -73,7 +73,7 @@ private:
|
||||
m_scopep->addActivep(nodep);
|
||||
}
|
||||
// VISITORS
|
||||
virtual void visit(AstScope* nodep, AstNUser*) {
|
||||
virtual void visit(AstScope* nodep) {
|
||||
m_scopep = nodep;
|
||||
m_iActivep = NULL;
|
||||
m_cActivep = NULL;
|
||||
@@ -81,15 +81,15 @@ private:
|
||||
nodep->iterateChildren(*this);
|
||||
// Don't clear scopep, the namer persists beyond this visit
|
||||
}
|
||||
virtual void visit(AstSenTree* nodep, AstNUser*) {
|
||||
virtual void visit(AstSenTree* nodep) {
|
||||
// Simplify sensitivity list
|
||||
V3Const::constifyExpensiveEdit(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
// Empty visitors, speed things up
|
||||
virtual void visit(AstNodeStmt* nodep, AstNUser*) { }
|
||||
virtual void visit(AstNodeStmt* nodep) { }
|
||||
//--------------------
|
||||
// Default
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
// Default: Just iterate
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
@@ -169,7 +169,7 @@ private:
|
||||
AstNode* m_alwaysp; // Always we're under
|
||||
AstNode* m_assignp; // In assign
|
||||
// VISITORS
|
||||
virtual void visit(AstAssignDly* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssignDly* nodep) {
|
||||
if (m_check != CT_SEQ) {
|
||||
// Convert to a non-delayed assignment
|
||||
UINFO(5," ASSIGNDLY "<<nodep<<endl);
|
||||
@@ -187,7 +187,7 @@ private:
|
||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstAssign* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssign* nodep) {
|
||||
if (m_check == CT_SEQ) {
|
||||
AstNode* las = m_assignp;
|
||||
m_assignp = nodep;
|
||||
@@ -195,7 +195,7 @@ private:
|
||||
m_assignp = las;
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstVarRef* nodep) {
|
||||
AstVar* varp=nodep->varp();
|
||||
if (m_check == CT_SEQ
|
||||
&& m_assignp
|
||||
@@ -214,7 +214,7 @@ private:
|
||||
}
|
||||
}
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
@@ -244,7 +244,7 @@ private:
|
||||
bool m_itemSequent; // Found a SenItem sequential
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstScope* nodep, AstNUser*) {
|
||||
virtual void visit(AstScope* nodep) {
|
||||
// Create required actives and add to scope
|
||||
UINFO(4," SCOPE "<<nodep<<endl);
|
||||
// Clear last scope's names, and collect this scope's existing names
|
||||
@@ -252,10 +252,10 @@ private:
|
||||
m_scopeFinalp = NULL;
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstActive* nodep, AstNUser*) {
|
||||
virtual void visit(AstActive* nodep) {
|
||||
// Actives are being formed, so we can ignore any already made
|
||||
}
|
||||
virtual void visit(AstInitial* nodep, AstNUser*) {
|
||||
virtual void visit(AstInitial* nodep) {
|
||||
// Relink to IACTIVE, unless already under it
|
||||
UINFO(4," INITIAL "<<nodep<<endl);
|
||||
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_INITIAL);
|
||||
@@ -263,28 +263,28 @@ private:
|
||||
nodep->unlinkFrBack();
|
||||
wantactivep->addStmtsp(nodep);
|
||||
}
|
||||
virtual void visit(AstAssignAlias* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssignAlias* nodep) {
|
||||
// Relink to CACTIVE, unless already under it
|
||||
UINFO(4," ASSIGNW "<<nodep<<endl);
|
||||
AstActive* wantactivep = m_namer.getCActive(nodep->fileline());
|
||||
nodep->unlinkFrBack();
|
||||
wantactivep->addStmtsp(nodep);
|
||||
}
|
||||
virtual void visit(AstAssignW* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssignW* nodep) {
|
||||
// Relink to CACTIVE, unless already under it
|
||||
UINFO(4," ASSIGNW "<<nodep<<endl);
|
||||
AstActive* wantactivep = m_namer.getCActive(nodep->fileline());
|
||||
nodep->unlinkFrBack();
|
||||
wantactivep->addStmtsp(nodep);
|
||||
}
|
||||
virtual void visit(AstCoverToggle* nodep, AstNUser*) {
|
||||
virtual void visit(AstCoverToggle* nodep) {
|
||||
// Relink to CACTIVE, unless already under it
|
||||
UINFO(4," COVERTOGGLE "<<nodep<<endl);
|
||||
AstActive* wantactivep = m_namer.getCActive(nodep->fileline());
|
||||
nodep->unlinkFrBack();
|
||||
wantactivep->addStmtsp(nodep);
|
||||
}
|
||||
virtual void visit(AstFinal* nodep, AstNUser*) {
|
||||
virtual void visit(AstFinal* nodep) {
|
||||
// Relink to CFUNC for the final
|
||||
UINFO(4," FINAL "<<nodep<<endl);
|
||||
if (!nodep->bodysp()) { // Empty, Kill it.
|
||||
@@ -329,7 +329,9 @@ private:
|
||||
|
||||
if (!combo && !sequent) combo=true; // If no list, Verilog 2000: always @ (*)
|
||||
if (combo && sequent) {
|
||||
nodep->v3error("Unsupported: Mixed edge (pos/negedge) and activity (no edge) sensitive activity list");
|
||||
if (!v3Global.opt.bboxUnsup()) {
|
||||
nodep->v3error("Unsupported: Mixed edge (pos/negedge) and activity (no edge) sensitive activity list");
|
||||
}
|
||||
sequent = false;
|
||||
}
|
||||
|
||||
@@ -370,7 +372,7 @@ private:
|
||||
ActiveDlyVisitor dlyvisitor (nodep, ActiveDlyVisitor::CT_SEQ);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstAlways* nodep, AstNUser*) {
|
||||
virtual void visit(AstAlways* nodep) {
|
||||
// Move always to appropriate ACTIVE based on its sense list
|
||||
UINFO(4," ALW "<<nodep<<endl);
|
||||
//if (debug()>=9) nodep->dumpTree(cout," Alw: ");
|
||||
@@ -382,13 +384,13 @@ private:
|
||||
}
|
||||
visitAlways(nodep, nodep->sensesp(), nodep->keyword());
|
||||
}
|
||||
virtual void visit(AstAlwaysPublic* nodep, AstNUser*) {
|
||||
virtual void visit(AstAlwaysPublic* nodep) {
|
||||
// Move always to appropriate ACTIVE based on its sense list
|
||||
UINFO(4," ALWPub "<<nodep<<endl);
|
||||
//if (debug()>=9) nodep->dumpTree(cout," Alw: ");
|
||||
visitAlways(nodep, nodep->sensesp(), VAlwaysKwd::ALWAYS);
|
||||
}
|
||||
virtual void visit(AstSenGate* nodep, AstNUser*) {
|
||||
virtual void visit(AstSenGate* nodep) {
|
||||
AstSenItem* subitemp = nodep->sensesp();
|
||||
if (subitemp->edgeType() != AstEdgeType::ET_ANYEDGE
|
||||
&& subitemp->edgeType() != AstEdgeType::ET_POSEDGE
|
||||
@@ -397,7 +399,7 @@ private:
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstSenItem* nodep, AstNUser*) {
|
||||
virtual void visit(AstSenItem* nodep) {
|
||||
if (nodep->edgeType() == AstEdgeType::ET_ANYEDGE) {
|
||||
m_itemCombo = true;
|
||||
// Delete the sensitivity
|
||||
@@ -413,10 +415,10 @@ private:
|
||||
}
|
||||
|
||||
// Empty visitors, speed things up
|
||||
virtual void visit(AstNodeMath* nodep, AstNUser*) {}
|
||||
virtual void visit(AstVarScope* nodep, AstNUser*) {}
|
||||
virtual void visit(AstNodeMath* nodep) {}
|
||||
virtual void visit(AstVarScope* nodep) {}
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+14
-14
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -65,19 +65,19 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstTopScope* nodep, AstNUser*) {
|
||||
virtual void visit(AstTopScope* nodep) {
|
||||
m_topscopep = nodep;
|
||||
m_finder.main(m_topscopep);
|
||||
nodep->iterateChildren(*this);
|
||||
m_topscopep = NULL;
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
// Create required actives and add to module
|
||||
// We can start ordering at a module, or a scope
|
||||
UINFO(4," MOD "<<nodep<<endl);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstActive* nodep, AstNUser*) {
|
||||
virtual void visit(AstActive* nodep) {
|
||||
UINFO(4," ACTIVE "<<nodep<<endl);
|
||||
V3Const::constifyExpensiveEdit(nodep); // Remove duplicate clocks and such; sensesp() may change!
|
||||
AstSenTree* sensesp = nodep->sensesp();
|
||||
@@ -108,7 +108,7 @@ private:
|
||||
// Move the active's contents to the other active
|
||||
UINFO(4," merge active "<<sensesp<<" into "<<wantp<<endl);
|
||||
if (nodep->sensesStorep()) {
|
||||
if (sensesp != nodep->sensesStorep()) nodep->v3fatalSrc("sensesStore should have been deleted earlier if different\n");
|
||||
if (sensesp != nodep->sensesStorep()) nodep->v3fatalSrc("sensesStore should have been deleted earlier if different");
|
||||
sensesp->unlinkFrBack();
|
||||
// There may be other references to same sense tree,
|
||||
// we'll be removing all references when we get to them,
|
||||
@@ -120,29 +120,29 @@ private:
|
||||
// No need to do statements under it, they're already moved.
|
||||
//nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstInitial* nodep, AstNUser*) {
|
||||
virtual void visit(AstInitial* nodep) {
|
||||
nodep->v3fatalSrc("Node should have been under ACTIVE");
|
||||
}
|
||||
virtual void visit(AstAssignAlias* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssignAlias* nodep) {
|
||||
nodep->v3fatalSrc("Node should have been under ACTIVE");
|
||||
}
|
||||
virtual void visit(AstAssignW* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssignW* nodep) {
|
||||
nodep->v3fatalSrc("Node should have been under ACTIVE");
|
||||
}
|
||||
virtual void visit(AstAlways* nodep, AstNUser*) {
|
||||
virtual void visit(AstAlways* nodep) {
|
||||
nodep->v3fatalSrc("Node should have been under ACTIVE");
|
||||
}
|
||||
virtual void visit(AstAlwaysPublic* nodep, AstNUser*) {
|
||||
virtual void visit(AstAlwaysPublic* nodep) {
|
||||
nodep->v3fatalSrc("Node should have been under ACTIVE");
|
||||
}
|
||||
virtual void visit(AstFinal* nodep, AstNUser*) {
|
||||
virtual void visit(AstFinal* nodep) {
|
||||
nodep->v3fatalSrc("Node should have been deleted");
|
||||
}
|
||||
// Empty visitors, speed things up
|
||||
virtual void visit(AstNodeMath* nodep, AstNUser*) {}
|
||||
virtual void visit(AstVarScope* nodep, AstNUser*) {}
|
||||
virtual void visit(AstNodeMath* nodep) {}
|
||||
virtual void visit(AstVarScope* nodep) {}
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+23
-16
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2005-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2005-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -163,7 +163,7 @@ private:
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstIf* nodep, AstNUser*) {
|
||||
virtual void visit(AstIf* nodep) {
|
||||
if (nodep->user1SetOnce()) return;
|
||||
if (nodep->uniquePragma() || nodep->unique0Pragma()) {
|
||||
AstNodeIf* ifp = nodep;
|
||||
@@ -205,8 +205,8 @@ private:
|
||||
// Note: if this ends with an 'else', then we don't need to validate that one of the
|
||||
// predicates evaluates to true.
|
||||
AstNode* ohot = ((allow_none || hasDefaultElse)
|
||||
? (new AstOneHot0(nodep->fileline(), propp))->castNode()
|
||||
: (new AstOneHot (nodep->fileline(), propp))->castNode());
|
||||
? static_cast<AstNode*>(new AstOneHot0(nodep->fileline(), propp))
|
||||
: static_cast<AstNode*>(new AstOneHot (nodep->fileline(), propp)));
|
||||
AstIf* checkifp = new AstIf (nodep->fileline(),
|
||||
new AstLogNot (nodep->fileline(), ohot),
|
||||
newFireAssert(nodep, "'unique if' statement violated"),
|
||||
@@ -220,7 +220,7 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS //========== Case assertions
|
||||
virtual void visit(AstCase* nodep, AstNUser*) {
|
||||
virtual void visit(AstCase* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (!nodep->user1SetOnce()) {
|
||||
bool has_default=false;
|
||||
@@ -245,17 +245,24 @@ private:
|
||||
AstNode* propp = NULL;
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) {
|
||||
AstNode* onep = new AstEq(icondp->fileline(),
|
||||
nodep->exprp()->cloneTree(false),
|
||||
icondp->cloneTree(false));
|
||||
AstNode* onep;
|
||||
if (nodep->casex() || nodep->casez() || nodep->caseInside()) {
|
||||
onep = AstEqWild::newTyped(itemp->fileline(),
|
||||
nodep->exprp()->cloneTree(false),
|
||||
icondp->cloneTree(false));
|
||||
} else {
|
||||
onep = AstEq::newTyped(icondp->fileline(),
|
||||
nodep->exprp()->cloneTree(false),
|
||||
icondp->cloneTree(false));
|
||||
}
|
||||
if (propp) propp = new AstConcat(icondp->fileline(), onep, propp);
|
||||
else propp = onep;
|
||||
}
|
||||
}
|
||||
bool allow_none = has_default || nodep->unique0Pragma();
|
||||
AstNode* ohot = (allow_none
|
||||
? (new AstOneHot0(nodep->fileline(), propp))->castNode()
|
||||
: (new AstOneHot (nodep->fileline(), propp))->castNode());
|
||||
? static_cast<AstNode*>(new AstOneHot0(nodep->fileline(), propp))
|
||||
: static_cast<AstNode*>(new AstOneHot (nodep->fileline(), propp)));
|
||||
AstIf* ifp = new AstIf (nodep->fileline(),
|
||||
new AstLogNot (nodep->fileline(), ohot),
|
||||
newFireAssert(nodep, "synthesis parallel_case, but multiple matches found"),
|
||||
@@ -268,7 +275,7 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS //========== Statements
|
||||
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
||||
virtual void visit(AstDisplay* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
// Replace the special types with standard text
|
||||
if (nodep->displayType()==AstDisplayType::DT_INFO) {
|
||||
@@ -281,27 +288,27 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstPslCover* nodep, AstNUser*) {
|
||||
virtual void visit(AstPslCover* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_beginp && nodep->name() == "") nodep->name(m_beginp->name());
|
||||
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(),
|
||||
nodep->stmtsp(), nodep->name()); VL_DANGLING(nodep);
|
||||
++m_statAsCover;
|
||||
}
|
||||
virtual void visit(AstVAssert* nodep, AstNUser*) {
|
||||
virtual void visit(AstVAssert* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
newVAssertion(nodep, nodep->propp()); VL_DANGLING(nodep);
|
||||
++m_statAsSV;
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
m_modp = nodep;
|
||||
//
|
||||
nodep->iterateChildren(*this);
|
||||
// Reset defaults
|
||||
m_modp = NULL;
|
||||
}
|
||||
virtual void visit(AstBegin* nodep, AstNUser*) {
|
||||
virtual void visit(AstBegin* nodep) {
|
||||
// This code is needed rather than a visitor in V3Begin,
|
||||
// because V3Assert is called before V3Begin
|
||||
AstBegin* lastp = m_beginp;
|
||||
@@ -312,7 +319,7 @@ private:
|
||||
m_beginp = lastp;
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2005-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2005-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+6
-6
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2005-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2005-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -73,7 +73,7 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS //========== Statements
|
||||
virtual void visit(AstClocking* nodep, AstNUser*) {
|
||||
virtual void visit(AstClocking* nodep) {
|
||||
UINFO(8," CLOCKING"<<nodep<<endl);
|
||||
// Store the new default clock, reset on new module
|
||||
m_seniDefaultp = nodep->sensesp();
|
||||
@@ -86,14 +86,14 @@ private:
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstPslCover* nodep, AstNUser*) {
|
||||
virtual void visit(AstPslCover* nodep) {
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
clearAssertInfo();
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->sentreep(newSenTree(nodep));
|
||||
clearAssertInfo();
|
||||
}
|
||||
virtual void visit(AstPslClocked* nodep, AstNUser*) {
|
||||
virtual void visit(AstPslClocked* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_senip) {
|
||||
nodep->v3error("Unsupported: Only one PSL clock allowed per assertion");
|
||||
@@ -111,12 +111,12 @@ private:
|
||||
nodep->replaceWith(blockp);
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
// Reset defaults
|
||||
m_seniDefaultp = NULL;
|
||||
}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2005-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2005-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+71
-62
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -80,15 +80,15 @@ void AstNode::init() {
|
||||
// Attributes
|
||||
m_didWidth = false;
|
||||
m_doingWidth = false;
|
||||
m_user1p = NULL;
|
||||
m_user1u = VNUser(0);
|
||||
m_user1Cnt = 0;
|
||||
m_user2p = NULL;
|
||||
m_user2u = VNUser(0);
|
||||
m_user2Cnt = 0;
|
||||
m_user3p = NULL;
|
||||
m_user3u = VNUser(0);
|
||||
m_user3Cnt = 0;
|
||||
m_user4p = NULL;
|
||||
m_user4u = VNUser(0);
|
||||
m_user4Cnt = 0;
|
||||
m_user5p = NULL;
|
||||
m_user5u = VNUser(0);
|
||||
m_user5Cnt = 0;
|
||||
}
|
||||
|
||||
@@ -166,44 +166,53 @@ string AstNode::vcdName(const string& namein) {
|
||||
}
|
||||
|
||||
string AstNode::prettyName(const string& namein) {
|
||||
// This function is somewhat hot, so we short-circuit some compares
|
||||
string pretty;
|
||||
pretty = "";
|
||||
pretty.reserve(namein.length());
|
||||
for (const char* pos = namein.c_str(); *pos; ) {
|
||||
if (0==strncmp(pos,"__BRA__",7)) {
|
||||
pretty += "[";
|
||||
pos += 7;
|
||||
}
|
||||
else if (0==strncmp(pos,"__KET__",7)) {
|
||||
pretty += "]";
|
||||
pos += 7;
|
||||
}
|
||||
else if (0==strncmp(pos,"__DOT__",7)) {
|
||||
pretty += ".";
|
||||
pos += 7;
|
||||
}
|
||||
else if (0==strncmp(pos,"->",2)) {
|
||||
if (pos[0]=='-' && pos[1]=='>') { // ->
|
||||
pretty += ".";
|
||||
pos += 2;
|
||||
continue;
|
||||
}
|
||||
else if (0==strncmp(pos,"__PVT__",7)) {
|
||||
pretty += "";
|
||||
pos += 7;
|
||||
}
|
||||
else if (pos[0]=='_' && pos[1]=='_' && pos[2]=='0'
|
||||
&& isxdigit(pos[3]) && isxdigit(pos[4])) {
|
||||
char value = 0;
|
||||
value += 16*(isdigit(pos[3]) ? (pos[3]-'0') : (tolower(pos[3])-'a'+10));
|
||||
value += (isdigit(pos[4]) ? (pos[4]-'0') : (tolower(pos[4])-'a'+10));
|
||||
pretty += value;
|
||||
pos += 5;
|
||||
}
|
||||
else {
|
||||
pretty += pos[0];
|
||||
++pos;
|
||||
if (pos[0]=='_' && pos[1]=='_') { // Short-circuit
|
||||
if (0==strncmp(pos,"__BRA__",7)) {
|
||||
pretty += "[";
|
||||
pos += 7;
|
||||
continue;
|
||||
}
|
||||
if (0==strncmp(pos,"__KET__",7)) {
|
||||
pretty += "]";
|
||||
pos += 7;
|
||||
continue;
|
||||
}
|
||||
if (0==strncmp(pos,"__DOT__",7)) {
|
||||
pretty += ".";
|
||||
pos += 7;
|
||||
continue;
|
||||
}
|
||||
if (0==strncmp(pos,"__PVT__",7)) {
|
||||
pretty += "";
|
||||
pos += 7;
|
||||
continue;
|
||||
}
|
||||
if (pos[0]=='_' && pos[1]=='_' && pos[2]=='0'
|
||||
&& isxdigit(pos[3]) && isxdigit(pos[4])) {
|
||||
char value = 0;
|
||||
value += 16*(isdigit(pos[3]) ? (pos[3]-'0') : (tolower(pos[3])-'a'+10));
|
||||
value += (isdigit(pos[4]) ? (pos[4]-'0') : (tolower(pos[4])-'a'+10));
|
||||
pretty += value;
|
||||
pos += 5;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Default
|
||||
pretty += pos[0];
|
||||
++pos;
|
||||
}
|
||||
if (pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
|
||||
if (pretty.substr(0,5) == "TOP->") pretty.replace(0,5,"");
|
||||
if (pretty[0]=='T' && pretty.substr(0,4) == "TOP.") pretty.replace(0,4,"");
|
||||
if (pretty[0]=='T' && pretty.substr(0,5) == "TOP->") pretty.replace(0,5,"");
|
||||
return pretty;
|
||||
}
|
||||
|
||||
@@ -723,31 +732,31 @@ void AstNode::operator delete(void* objp, size_t size) {
|
||||
//======================================================================
|
||||
// Iterators
|
||||
|
||||
void AstNode::iterateChildren(AstNVisitor& v, AstNUser* vup) {
|
||||
void AstNode::iterateChildren(AstNVisitor& v) {
|
||||
// This is a very hot function
|
||||
ASTNODE_PREFETCH(m_op1p);
|
||||
ASTNODE_PREFETCH(m_op2p);
|
||||
ASTNODE_PREFETCH(m_op3p);
|
||||
ASTNODE_PREFETCH(m_op4p);
|
||||
if (m_op1p) m_op1p->iterateAndNext(v, vup);
|
||||
if (m_op2p) m_op2p->iterateAndNext(v, vup);
|
||||
if (m_op3p) m_op3p->iterateAndNext(v, vup);
|
||||
if (m_op4p) m_op4p->iterateAndNext(v, vup);
|
||||
if (m_op1p) m_op1p->iterateAndNext(v);
|
||||
if (m_op2p) m_op2p->iterateAndNext(v);
|
||||
if (m_op3p) m_op3p->iterateAndNext(v);
|
||||
if (m_op4p) m_op4p->iterateAndNext(v);
|
||||
}
|
||||
|
||||
void AstNode::iterateChildrenConst(AstNVisitor& v, AstNUser* vup) {
|
||||
void AstNode::iterateChildrenConst(AstNVisitor& v) {
|
||||
// This is a very hot function
|
||||
ASTNODE_PREFETCH(m_op1p);
|
||||
ASTNODE_PREFETCH(m_op2p);
|
||||
ASTNODE_PREFETCH(m_op3p);
|
||||
ASTNODE_PREFETCH(m_op4p);
|
||||
if (m_op1p) m_op1p->iterateAndNextConst(v, vup);
|
||||
if (m_op2p) m_op2p->iterateAndNextConst(v, vup);
|
||||
if (m_op3p) m_op3p->iterateAndNextConst(v, vup);
|
||||
if (m_op4p) m_op4p->iterateAndNextConst(v, vup);
|
||||
if (m_op1p) m_op1p->iterateAndNextConst(v);
|
||||
if (m_op2p) m_op2p->iterateAndNextConst(v);
|
||||
if (m_op3p) m_op3p->iterateAndNextConst(v);
|
||||
if (m_op4p) m_op4p->iterateAndNextConst(v);
|
||||
}
|
||||
|
||||
void AstNode::iterateAndNext(AstNVisitor& v, AstNUser* vup) {
|
||||
void AstNode::iterateAndNext(AstNVisitor& v) {
|
||||
// This is a very hot function
|
||||
// IMPORTANT: If you replace a node that's the target of this iterator,
|
||||
// then the NEW node will be iterated on next, it isn't skipped!
|
||||
@@ -764,7 +773,7 @@ void AstNode::iterateAndNext(AstNVisitor& v, AstNUser* vup) {
|
||||
//if (VL_UNLIKELY(niterp->m_iterpp)) niterp->v3fatalSrc("IterateAndNext under iterateAndNext may miss edits");
|
||||
// cppcheck-suppress nullPointer
|
||||
niterp->m_iterpp = &niterp;
|
||||
niterp->accept(v, vup);
|
||||
niterp->accept(v);
|
||||
// accept may do a replaceNode and change niterp on us...
|
||||
//if (niterp != nodep) UINFO(1,"iterateAndNext edited "<<(void*)nodep<<" now into "<<(void*)niterp<<endl); // niterp maybe NULL, so need cast
|
||||
if (!niterp) return; // Perhaps node deleted inside accept
|
||||
@@ -777,37 +786,37 @@ void AstNode::iterateAndNext(AstNVisitor& v, AstNUser* vup) {
|
||||
}
|
||||
}
|
||||
|
||||
void AstNode::iterateListBackwards(AstNVisitor& v, AstNUser* vup) {
|
||||
void AstNode::iterateListBackwards(AstNVisitor& v) {
|
||||
UDEBUGONLY(UASSERT(dynamic_cast<AstNode*>(this),"this should not be NULL"););
|
||||
AstNode* nodep=this;
|
||||
while (nodep->m_nextp) nodep=nodep->m_nextp;
|
||||
while (nodep) {
|
||||
// Edits not supported: nodep->m_iterpp = &nodep;
|
||||
nodep->accept(v, vup);
|
||||
nodep->accept(v);
|
||||
if (nodep->backp()->m_nextp == nodep) nodep=nodep->backp();
|
||||
else nodep = NULL; // else: backp points up the tree.
|
||||
}
|
||||
}
|
||||
|
||||
void AstNode::iterateChildrenBackwards(AstNVisitor& v, AstNUser* vup) {
|
||||
if (m_op1p) m_op1p->iterateListBackwards(v,vup);
|
||||
if (m_op2p) m_op2p->iterateListBackwards(v,vup);
|
||||
if (m_op3p) m_op3p->iterateListBackwards(v,vup);
|
||||
if (m_op4p) m_op4p->iterateListBackwards(v,vup);
|
||||
void AstNode::iterateChildrenBackwards(AstNVisitor& v) {
|
||||
if (m_op1p) m_op1p->iterateListBackwards(v);
|
||||
if (m_op2p) m_op2p->iterateListBackwards(v);
|
||||
if (m_op3p) m_op3p->iterateListBackwards(v);
|
||||
if (m_op4p) m_op4p->iterateListBackwards(v);
|
||||
}
|
||||
|
||||
void AstNode::iterateAndNextConst(AstNVisitor& v, AstNUser* vup) {
|
||||
void AstNode::iterateAndNextConst(AstNVisitor& v) {
|
||||
// Keep following the current list even if edits change it
|
||||
if (!this) return; // A few cases could be cleaned up, but want symmetry with iterateAndNext
|
||||
for (AstNode* nodep=this; nodep; ) { // effectively: if (!this) return; // Callers rely on this
|
||||
AstNode* nnextp = nodep->m_nextp;
|
||||
ASTNODE_PREFETCH(nnextp);
|
||||
nodep->accept(v, vup);
|
||||
nodep->accept(v);
|
||||
nodep = nnextp;
|
||||
}
|
||||
}
|
||||
|
||||
AstNode* AstNode::acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup) {
|
||||
AstNode* AstNode::iterateSubtreeReturnEdits(AstNVisitor& v) {
|
||||
// Some visitors perform tree edits (such as V3Const), and may even
|
||||
// replace/delete the exact nodep that the visitor is called with. If
|
||||
// this happens, the parent will lose the handle to the node that was
|
||||
@@ -817,12 +826,12 @@ AstNode* AstNode::acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup) {
|
||||
AstNode* nodep = this; // Note "this" may point to bogus point later in this function
|
||||
if (nodep->castNetlist()) {
|
||||
// Calling on top level; we know the netlist won't get replaced
|
||||
nodep->accept(v, vup);
|
||||
nodep->accept(v);
|
||||
} else if (!nodep->backp()) {
|
||||
// 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); VL_DANGLING(nodep); // nodep to null as may be replaced
|
||||
tempp->stmtsp()->accept(v); VL_DANGLING(nodep); // nodep to null as may be replaced
|
||||
}
|
||||
nodep = tempp->stmtsp()->unlinkFrBackWithNext();
|
||||
tempp->deleteTree(); VL_DANGLING(tempp);
|
||||
@@ -836,7 +845,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); VL_DANGLING(nodep); // nodep to null as may be replaced
|
||||
nodep->accept(v); VL_DANGLING(nodep); // nodep to null as may be replaced
|
||||
}
|
||||
nodep = *nextnodepp; // Grab new node from point where old was connected
|
||||
}
|
||||
@@ -849,7 +858,7 @@ void AstNode::cloneRelinkTree() {
|
||||
// private: Cleanup clone() operation on whole tree. Publicly call cloneTree() instead.
|
||||
for (AstNode* nodep=this; nodep; nodep=nodep->m_nextp) {
|
||||
if (m_dtypep && m_dtypep->clonep()) {
|
||||
m_dtypep = m_dtypep->clonep()->castNodeDType();
|
||||
m_dtypep = m_dtypep->clonep();
|
||||
}
|
||||
nodep->cloneRelink();
|
||||
if (nodep->m_op1p) nodep->m_op1p->cloneRelinkTree();
|
||||
|
||||
+147
-112
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -427,6 +427,7 @@ public:
|
||||
SUPPLY0,
|
||||
SUPPLY1,
|
||||
WIRE,
|
||||
WREAL,
|
||||
IMPLICITWIRE,
|
||||
TRIWIRE,
|
||||
TRI0,
|
||||
@@ -448,13 +449,13 @@ public:
|
||||
static const char* names[] = {
|
||||
"?","GPARAM","LPARAM","GENVAR",
|
||||
"VAR","INPUT","OUTPUT","INOUT",
|
||||
"SUPPLY0","SUPPLY1","WIRE","IMPLICITWIRE",
|
||||
"SUPPLY0","SUPPLY1","WIRE","WREAL","IMPLICITWIRE",
|
||||
"TRIWIRE","TRI0","TRI1",
|
||||
"PORT",
|
||||
"BLOCKTEMP","MODULETEMP","STMTTEMP","XTEMP",
|
||||
"IFACEREF"};
|
||||
return names[m_e]; }
|
||||
bool isSignal() const { return (m_e==WIRE || m_e==IMPLICITWIRE
|
||||
bool isSignal() const { return (m_e==WIRE || m_e==WREAL || m_e==IMPLICITWIRE
|
||||
|| m_e==TRIWIRE
|
||||
|| m_e==TRI0 || m_e==TRI1
|
||||
|| m_e==SUPPLY0 || m_e==SUPPLY1
|
||||
@@ -715,7 +716,7 @@ struct VBasicTypeKey {
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// AstNUser - Generic pointer base class for AST User nodes.
|
||||
// AstNUser - Generic base class for AST User nodes.
|
||||
// - Also used to allow parameter passing up/down iterate calls
|
||||
|
||||
class WidthVP;
|
||||
@@ -724,26 +725,30 @@ class OrderBlockNU;
|
||||
class OrderVarNU;
|
||||
class V3GraphVertex;
|
||||
class VSymEnt;
|
||||
struct AstNUser {
|
||||
AstNUser* p() { return this; } // So can take address of temporary: iterate(...,AstNUser(args).p())
|
||||
|
||||
class VNUser {
|
||||
union {
|
||||
void* up;
|
||||
int ui;
|
||||
} m_u;
|
||||
public:
|
||||
VNUser() {}
|
||||
VNUser(int i) { m_u.up = 0; m_u.ui = i; }
|
||||
VNUser(void* p) { m_u.up = p; }
|
||||
~VNUser() {}
|
||||
// Casters
|
||||
WidthVP* c() { return ((WidthVP*)this); }
|
||||
LinkVP* castLinkVP() { return ((LinkVP*)this); }
|
||||
VSymEnt* castSymEnt() { return ((VSymEnt*)this); }
|
||||
AstNode* castNode() { return ((AstNode*)this); }
|
||||
OrderBlockNU* castOrderBlock() { return ((OrderBlockNU*)this); }
|
||||
OrderVarNU* castOrderVar() { return ((OrderVarNU*)this); }
|
||||
V3GraphVertex* castGraphVertex() { return ((V3GraphVertex*)this); }
|
||||
inline int castInt() {
|
||||
union { AstNUser* up; int ui; } u;
|
||||
u.up = this;
|
||||
return u.ui;
|
||||
}
|
||||
static inline AstNUser* fromInt (int i) {
|
||||
union { AstNUser* up; int ui; } u;
|
||||
u.up=0; u.ui=i;
|
||||
return u.up;
|
||||
WidthVP* c() { return ((WidthVP*)m_u.up); }
|
||||
LinkVP* toLinkVP() { return ((LinkVP*)m_u.up); }
|
||||
VSymEnt* toSymEnt() { return ((VSymEnt*)m_u.up); }
|
||||
AstNode* toNodep() { return ((AstNode*)m_u.up); }
|
||||
OrderBlockNU* toOrderBlock() { return ((OrderBlockNU*)m_u.up); }
|
||||
OrderVarNU* toOrderVar() { return ((OrderVarNU*)m_u.up); }
|
||||
V3GraphVertex* toGraphVertex() { return ((V3GraphVertex*)m_u.up); }
|
||||
inline int toInt() {
|
||||
return m_u.ui;
|
||||
}
|
||||
static inline VNUser fromZero () { return VNUser(0); }
|
||||
static inline VNUser fromInt (int i) { return VNUser(i); }
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
@@ -862,8 +867,8 @@ public:
|
||||
}
|
||||
#include "V3Ast__gen_visitor.h" // From ./astgen
|
||||
// Things like:
|
||||
// virtual void visit(AstBreak* nodep, AstNUser* vup) { visit((AstNodeStmt*)(nodep),vup); }
|
||||
// virtual void visit(AstNodeStmt* nodep, AstNUser* vup) { visit((AstNode*)(nodep),vup); }
|
||||
// virtual void visit(AstBreak* nodep) { visit((AstNodeStmt*)(nodep)); }
|
||||
// virtual void visit(AstNodeStmt* nodep) { visit((AstNode*)(nodep)); }
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
@@ -916,7 +921,7 @@ public:
|
||||
class FullValue {}; // for creator type-overload selection
|
||||
explicit V3Hash(Illegal) { m_both=0; }
|
||||
// Saving and restoring inside a userp
|
||||
explicit V3Hash(AstNUser* up) { m_both=up->castInt(); }
|
||||
explicit V3Hash(VNUser u) { m_both=u.toInt(); }
|
||||
V3Hash operator+= (const V3Hash& rh) {
|
||||
setBoth(depth()+rh.depth(), (hshval()*31+rh.hshval()));
|
||||
return *this; };
|
||||
@@ -975,15 +980,15 @@ class AstNode {
|
||||
// // Space for more bools here
|
||||
|
||||
// This member ordering both allows 64 bit alignment and puts associated data together
|
||||
AstNUser* m_user1p; // Pointer to any information the user iteration routine wants
|
||||
VNUser m_user1u; // Contains any information the user iteration routine wants
|
||||
uint32_t m_user1Cnt; // Mark of when userp was set
|
||||
uint32_t m_user2Cnt; // Mark of when userp was set
|
||||
AstNUser* m_user2p; // Pointer to any information the user iteration routine wants
|
||||
AstNUser* m_user3p; // Pointer to any information the user iteration routine wants
|
||||
VNUser m_user2u; // Contains any information the user iteration routine wants
|
||||
VNUser m_user3u; // Contains any information the user iteration routine wants
|
||||
uint32_t m_user3Cnt; // Mark of when userp was set
|
||||
uint32_t m_user4Cnt; // Mark of when userp was set
|
||||
AstNUser* m_user4p; // Pointer to any information the user iteration routine wants
|
||||
AstNUser* m_user5p; // Pointer to any information the user iteration routine wants
|
||||
VNUser m_user4u; // Contains any information the user iteration routine wants
|
||||
VNUser m_user5u; // Contains any information the user iteration routine wants
|
||||
uint32_t m_user5Cnt; // Mark of when userp was set
|
||||
|
||||
// METHODS
|
||||
@@ -993,7 +998,7 @@ class AstNode {
|
||||
void op4p(AstNode* nodep) { m_op4p = nodep; if (nodep) nodep->m_backp = this; }
|
||||
|
||||
void init(); // initialize value of AstNode
|
||||
void iterateListBackwards(AstNVisitor& v, AstNUser* vup=NULL);
|
||||
void iterateListBackwards(AstNVisitor& v);
|
||||
private:
|
||||
AstNode* cloneTreeIter();
|
||||
AstNode* cloneTreeIterList();
|
||||
@@ -1111,57 +1116,75 @@ public:
|
||||
bool isSigned() const;
|
||||
bool isString() const;
|
||||
|
||||
AstNUser* user1p() const {
|
||||
VNUser user1u() const {
|
||||
// Slows things down measurably, so disabled by default
|
||||
//UASSERT_STATIC(AstUser1InUse::s_userBusy, "userp set w/o busy");
|
||||
return ((m_user1Cnt==AstUser1InUse::s_userCntGbl)?m_user1p:NULL);
|
||||
return ((m_user1Cnt==AstUser1InUse::s_userCntGbl) ? m_user1u : VNUser(0));
|
||||
}
|
||||
void user1p(void* userp) { m_user1p=(AstNUser*)(userp); m_user1Cnt=AstUser1InUse::s_userCntGbl; }
|
||||
int user1() const { return user1p()->castInt(); }
|
||||
void user1(int val) { user1p(AstNUser::fromInt(val)); }
|
||||
AstNode* user1p() const { return user1u().toNodep(); }
|
||||
void user1u(const VNUser& user) { m_user1u=user; m_user1Cnt=AstUser1InUse::s_userCntGbl; }
|
||||
void user1p(void* userp) { user1u(VNUser(userp)); }
|
||||
int user1() const { return user1u().toInt(); }
|
||||
void user1(int val) { user1u(VNUser(val)); }
|
||||
int user1Inc(int val=1) { int v=user1(); user1(v+val); return v; }
|
||||
int user1SetOnce() { int v=user1(); if (!v) user1(1); return v; } // Better for cache than user1Inc()
|
||||
static void user1ClearTree() { AstUser1InUse::clear(); } // Clear userp()'s across the entire tree
|
||||
|
||||
AstNUser* user2p() const {
|
||||
//UASSERT_STATIC(AstUser2InUse::s_userBusy, "user2p set w/o busy");
|
||||
return ((m_user2Cnt==AstUser2InUse::s_userCntGbl)?m_user2p:NULL); }
|
||||
void user2p(void* userp) { m_user2p=(AstNUser*)(userp); m_user2Cnt=AstUser2InUse::s_userCntGbl; }
|
||||
int user2() const { return user2p()->castInt(); }
|
||||
void user2(int val) { user2p(AstNUser::fromInt(val)); }
|
||||
VNUser user2u() const {
|
||||
// Slows things down measurably, so disabled by default
|
||||
//UASSERT_STATIC(AstUser2InUse::s_userBusy, "userp set w/o busy");
|
||||
return ((m_user2Cnt==AstUser2InUse::s_userCntGbl) ? m_user2u : VNUser(0));
|
||||
}
|
||||
AstNode* user2p() const { return user2u().toNodep(); }
|
||||
void user2u(const VNUser& user) { m_user2u=user; m_user2Cnt=AstUser2InUse::s_userCntGbl; }
|
||||
void user2p(void* userp) { user2u(VNUser(userp)); }
|
||||
int user2() const { return user2u().toInt(); }
|
||||
void user2(int val) { user2u(VNUser(val)); }
|
||||
int user2Inc(int val=1) { int v=user2(); user2(v+val); return v; }
|
||||
int user2SetOnce() { int v=user2(); if (!v) user2(1); return v; }
|
||||
static void user2ClearTree() { AstUser2InUse::clear(); }
|
||||
int user2SetOnce() { int v=user2(); if (!v) user2(1); return v; } // Better for cache than user2Inc()
|
||||
static void user2ClearTree() { AstUser2InUse::clear(); } // Clear userp()'s across the entire tree
|
||||
|
||||
AstNUser* user3p() const {
|
||||
//UASSERT_STATIC(AstUser3InUse::s_userBusy, "user3p set w/o busy");
|
||||
return ((m_user3Cnt==AstUser3InUse::s_userCntGbl)?m_user3p:NULL); }
|
||||
void user3p(void* userp) { m_user3p=(AstNUser*)(userp); m_user3Cnt=AstUser3InUse::s_userCntGbl; }
|
||||
int user3() const { return user3p()->castInt(); }
|
||||
void user3(int val) { user3p(AstNUser::fromInt(val)); }
|
||||
VNUser user3u() const {
|
||||
// Slows things down measurably, so disabled by default
|
||||
//UASSERT_STATIC(AstUser3InUse::s_userBusy, "userp set w/o busy");
|
||||
return ((m_user3Cnt==AstUser3InUse::s_userCntGbl) ? m_user3u : VNUser(0));
|
||||
}
|
||||
AstNode* user3p() const { return user3u().toNodep(); }
|
||||
void user3u(const VNUser& user) { m_user3u=user; m_user3Cnt=AstUser3InUse::s_userCntGbl; }
|
||||
void user3p(void* userp) { user3u(VNUser(userp)); }
|
||||
int user3() const { return user3u().toInt(); }
|
||||
void user3(int val) { user3u(VNUser(val)); }
|
||||
int user3Inc(int val=1) { int v=user3(); user3(v+val); return v; }
|
||||
int user3SetOnce() { int v=user3(); if (!v) user3(1); return v; }
|
||||
static void user3ClearTree() { AstUser3InUse::clear(); }
|
||||
int user3SetOnce() { int v=user3(); if (!v) user3(1); return v; } // Better for cache than user3Inc()
|
||||
static void user3ClearTree() { AstUser3InUse::clear(); } // Clear userp()'s across the entire tree
|
||||
|
||||
AstNUser* user4p() const {
|
||||
//UASSERT_STATIC(AstUser4InUse::s_userBusy, "user4p set w/o busy");
|
||||
return ((m_user4Cnt==AstUser4InUse::s_userCntGbl)?m_user4p:NULL); }
|
||||
void user4p(void* userp) { m_user4p=(AstNUser*)(userp); m_user4Cnt=AstUser4InUse::s_userCntGbl; }
|
||||
int user4() const { return user4p()->castInt(); }
|
||||
void user4(int val) { user4p(AstNUser::fromInt(val)); }
|
||||
VNUser user4u() const {
|
||||
// Slows things down measurably, so disabled by default
|
||||
//UASSERT_STATIC(AstUser4InUse::s_userBusy, "userp set w/o busy");
|
||||
return ((m_user4Cnt==AstUser4InUse::s_userCntGbl) ? m_user4u : VNUser(0));
|
||||
}
|
||||
AstNode* user4p() const { return user4u().toNodep(); }
|
||||
void user4u(const VNUser& user) { m_user4u=user; m_user4Cnt=AstUser4InUse::s_userCntGbl; }
|
||||
void user4p(void* userp) { user4u(VNUser(userp)); }
|
||||
int user4() const { return user4u().toInt(); }
|
||||
void user4(int val) { user4u(VNUser(val)); }
|
||||
int user4Inc(int val=1) { int v=user4(); user4(v+val); return v; }
|
||||
int user4SetOnce() { int v=user4(); if (!v) user4(1); return v; }
|
||||
static void user4ClearTree() { AstUser4InUse::clear(); }
|
||||
int user4SetOnce() { int v=user4(); if (!v) user4(1); return v; } // Better for cache than user4Inc()
|
||||
static void user4ClearTree() { AstUser4InUse::clear(); } // Clear userp()'s across the entire tree
|
||||
|
||||
AstNUser* user5p() const {
|
||||
//UASSERT_STATIC(AstUser5InUse::s_userBusy, "user5p set w/o busy");
|
||||
return ((m_user5Cnt==AstUser5InUse::s_userCntGbl)?m_user5p:NULL); }
|
||||
void user5p(void* userp) { m_user5p=(AstNUser*)(userp); m_user5Cnt=AstUser5InUse::s_userCntGbl; }
|
||||
int user5() const { return user5p()->castInt(); }
|
||||
void user5(int val) { user5p(AstNUser::fromInt(val)); }
|
||||
VNUser user5u() const {
|
||||
// Slows things down measurably, so disabled by default
|
||||
//UASSERT_STATIC(AstUser5InUse::s_userBusy, "userp set w/o busy");
|
||||
return ((m_user5Cnt==AstUser5InUse::s_userCntGbl) ? m_user5u : VNUser(0));
|
||||
}
|
||||
AstNode* user5p() const { return user5u().toNodep(); }
|
||||
void user5u(const VNUser& user) { m_user5u=user; m_user5Cnt=AstUser5InUse::s_userCntGbl; }
|
||||
void user5p(void* userp) { user5u(VNUser(userp)); }
|
||||
int user5() const { return user5u().toInt(); }
|
||||
void user5(int val) { user5u(VNUser(val)); }
|
||||
int user5Inc(int val=1) { int v=user5(); user5(v+val); return v; }
|
||||
int user5SetOnce() { int v=user5(); if (!v) user5(1); return v; }
|
||||
static void user5ClearTree() { AstUser5InUse::clear(); }
|
||||
int user5SetOnce() { int v=user5(); if (!v) user5(1); return v; } // Better for cache than user5Inc()
|
||||
static void user5ClearTree() { AstUser5InUse::clear(); } // Clear userp()'s across the entire tree
|
||||
|
||||
vluint64_t editCount() const { return m_editCount; }
|
||||
void editCountInc() { m_editCount = ++s_editCntGbl; } // Preincrement, so can "watch AstNode::s_editCntGbl=##"
|
||||
@@ -1265,17 +1288,16 @@ public:
|
||||
virtual const char* broken() const { return NULL; }
|
||||
|
||||
// INVOKERS
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) = 0;
|
||||
void iterate(AstNVisitor& v, AstNUser* vup=NULL) { this->accept(v,vup); } // Does this; excludes following this->next
|
||||
void iterateAndNext(AstNVisitor& v, AstNUser* vup=NULL);
|
||||
void iterateAndNextConst(AstNVisitor& v, AstNUser* vup=NULL);
|
||||
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL); // Excludes following this->next
|
||||
void iterateChildrenBackwards(AstNVisitor& v, AstNUser* vup=NULL); // Excludes following this->next
|
||||
void iterateChildrenConst(AstNVisitor& v, AstNUser* vup=NULL); // Excludes following this->next
|
||||
AstNode* acceptSubtreeReturnEdits(AstNVisitor& v, AstNUser* vup=NULL); // Return edited nodep; see comments in V3Ast.cpp
|
||||
virtual void accept(AstNVisitor& v) = 0;
|
||||
void iterate(AstNVisitor& v) { this->accept(v); } // Does this; excludes following this->next
|
||||
void iterateAndNext(AstNVisitor& v);
|
||||
void iterateAndNextConst(AstNVisitor& v);
|
||||
void iterateChildren(AstNVisitor& v); // Excludes following this->next
|
||||
void iterateChildrenBackwards(AstNVisitor& v); // Excludes following this->next
|
||||
void iterateChildrenConst(AstNVisitor& v); // Excludes following this->next
|
||||
AstNode* iterateSubtreeReturnEdits(AstNVisitor& v); // Return edited nodep; see comments in V3Ast.cpp
|
||||
|
||||
// CONVERSION
|
||||
AstNode* castNode() { return this; }
|
||||
#include "V3Ast__gen_interface.h" // From ./astgen
|
||||
// Things like:
|
||||
// AstAlways* castAlways();
|
||||
@@ -1290,7 +1312,8 @@ inline void AstNRelinker::relink(AstNode* newp) { newp->AstNode::relink(this); }
|
||||
|
||||
#define ASTNODE_BASE_FUNCS(name) \
|
||||
virtual ~Ast ##name() {} \
|
||||
Ast ##name * cloneTree(bool cloneNext) { return AstNode::cloneTree(cloneNext)->cast ##name(); }
|
||||
Ast ##name * cloneTree(bool cloneNext) { return static_cast<Ast ##name *>(AstNode::cloneTree(cloneNext)); } \
|
||||
Ast ##name * clonep() const { return static_cast<Ast ##name *>(AstNode::clonep()); }
|
||||
|
||||
class AstNodeMath : public AstNode {
|
||||
// Math -- anything that's part of an expression tree
|
||||
@@ -1318,7 +1341,7 @@ public:
|
||||
// Know no children, and hot function, so skip iterator for speed
|
||||
// See checkTreeIter also that asserts no children
|
||||
// cppcheck-suppress functionConst
|
||||
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { }
|
||||
void iterateChildren(AstNVisitor& v) { }
|
||||
};
|
||||
|
||||
class AstNodeUniop : public AstNodeMath {
|
||||
@@ -1329,7 +1352,7 @@ public:
|
||||
dtypeFrom(lhsp);
|
||||
setOp1p(lhsp); }
|
||||
ASTNODE_BASE_FUNCS(NodeUniop)
|
||||
AstNode* lhsp() const { return op1p()->castNode(); }
|
||||
AstNode* lhsp() const { return op1p(); }
|
||||
void lhsp(AstNode* nodep) { return setOp1p(nodep); }
|
||||
// METHODS
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) = 0; // Set out to evaluation of a AstConst'ed lhs
|
||||
@@ -1352,8 +1375,8 @@ public:
|
||||
ASTNODE_BASE_FUNCS(NodeBiop)
|
||||
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp)=0; // Clone single node, just get same type back.
|
||||
// ACCESSORS
|
||||
AstNode* lhsp() const { return op1p()->castNode(); }
|
||||
AstNode* rhsp() const { return op2p()->castNode(); }
|
||||
AstNode* lhsp() const { return op1p(); }
|
||||
AstNode* rhsp() const { return op2p(); }
|
||||
void lhsp(AstNode* nodep) { return setOp1p(nodep); }
|
||||
void rhsp(AstNode* nodep) { return setOp2p(nodep); }
|
||||
// METHODS
|
||||
@@ -1377,9 +1400,9 @@ public:
|
||||
: AstNodeMath(fl) {
|
||||
setOp1p(lhs); setOp2p(rhs); setOp3p(ths); }
|
||||
ASTNODE_BASE_FUNCS(NodeTriop)
|
||||
AstNode* lhsp() const { return op1p()->castNode(); }
|
||||
AstNode* rhsp() const { return op2p()->castNode(); }
|
||||
AstNode* thsp() const { return op3p()->castNode(); }
|
||||
AstNode* lhsp() const { return op1p(); }
|
||||
AstNode* rhsp() const { return op2p(); }
|
||||
AstNode* thsp() const { return op3p(); }
|
||||
void lhsp(AstNode* nodep) { return setOp1p(nodep); }
|
||||
void rhsp(AstNode* nodep) { return setOp2p(nodep); }
|
||||
void thsp(AstNode* nodep) { return setOp3p(nodep); }
|
||||
@@ -1421,9 +1444,9 @@ public:
|
||||
ASTNODE_BASE_FUNCS(NodeCond)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs, const V3Number& ths) {
|
||||
if (lhs.isNeqZero()) out.opAssign(rhs); else out.opAssign(ths); }
|
||||
AstNode* condp() const { return op1p()->castNode(); } // op1 = Condition
|
||||
AstNode* expr1p() const { return op2p()->castNode(); } // op2 = If true...
|
||||
AstNode* expr2p() const { return op3p()->castNode(); } // op3 = If false...
|
||||
AstNode* condp() const { return op1p(); } // op1 = Condition
|
||||
AstNode* expr1p() const { return op2p(); } // op2 = If true...
|
||||
AstNode* expr2p() const { return op3p(); } // op3 = If false...
|
||||
virtual string emitVerilog() { return "%k(%l %f? %r %k: %t)"; }
|
||||
virtual string emitC() { return "VL_COND_%nq%lq%rq%tq(%nw,%lw,%rw,%tw, %P, %li, %ri, %ti)"; }
|
||||
virtual bool cleanOut() { return false; } // clean if e1 & e2 clean
|
||||
@@ -1441,10 +1464,10 @@ public:
|
||||
: AstNode(fl) {
|
||||
setOp1p(lhs); setOp2p(rhs); setNOp3p(ths); }
|
||||
ASTNODE_BASE_FUNCS(NodePreSel)
|
||||
AstNode* lhsp() const { return op1p()->castNode(); }
|
||||
AstNode* lhsp() const { return op1p(); }
|
||||
AstNode* fromp() const { return lhsp(); }
|
||||
AstNode* rhsp() const { return op2p()->castNode(); }
|
||||
AstNode* thsp() const { return op3p()->castNode(); }
|
||||
AstNode* rhsp() const { return op2p(); }
|
||||
AstNode* thsp() const { return op3p(); }
|
||||
AstAttrOf* attrp() const { return op4p()->castAttrOf(); }
|
||||
void lhsp(AstNode* nodep) { return setOp1p(nodep); }
|
||||
void rhsp(AstNode* nodep) { return setOp2p(nodep); }
|
||||
@@ -1476,8 +1499,8 @@ public:
|
||||
ASTNODE_BASE_FUNCS(NodeAssign)
|
||||
virtual AstNode* cloneType(AstNode* lhsp, AstNode* rhsp)=0; // Clone single node, just get same type back.
|
||||
// So iteration hits the RHS which is "earlier" in execution order, it's op1, not op2
|
||||
AstNode* rhsp() const { return op1p()->castNode(); } // op1 = Assign from
|
||||
AstNode* lhsp() const { return op2p()->castNode(); } // op2 = Assign to
|
||||
AstNode* rhsp() const { return op1p(); } // op1 = Assign from
|
||||
AstNode* lhsp() const { return op2p(); } // op2 = Assign to
|
||||
void rhsp(AstNode* np) { setOp1p(np); }
|
||||
void lhsp(AstNode* np) { setOp2p(np); }
|
||||
virtual bool hasDType() const { return true; }
|
||||
@@ -1496,10 +1519,10 @@ public:
|
||||
addNOp1p(initsp); setOp2p(condp); addNOp3p(incsp); addNOp4p(bodysp);
|
||||
}
|
||||
ASTNODE_BASE_FUNCS(NodeFor)
|
||||
AstNode* initsp() const { return op1p()->castNode(); } // op1= initial statements
|
||||
AstNode* condp() const { return op2p()->castNode(); } // op2= condition to continue
|
||||
AstNode* incsp() const { return op3p()->castNode(); } // op3= increment statements
|
||||
AstNode* bodysp() const { return op4p()->castNode(); } // op4= body of loop
|
||||
AstNode* initsp() const { return op1p(); } // op1= initial statements
|
||||
AstNode* condp() const { return op2p(); } // op2= condition to continue
|
||||
AstNode* incsp() const { return op3p(); } // op3= increment statements
|
||||
AstNode* bodysp() const { return op4p(); } // op4= body of loop
|
||||
virtual bool isGateOptimizable() const { return false; }
|
||||
virtual int instrCount() const { return instrCountBranch(); }
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
@@ -1538,9 +1561,9 @@ public:
|
||||
}
|
||||
ASTNODE_BASE_FUNCS(NodeCase)
|
||||
virtual int instrCount() const { return instrCountBranch(); }
|
||||
AstNode* exprp() const { return op1p()->castNode(); } // op1 = case condition <expression>
|
||||
AstNode* exprp() const { return op1p(); } // op1 = case condition <expression>
|
||||
AstCaseItem* itemsp() const { return op2p()->castCaseItem(); } // op2 = list of case expressions
|
||||
AstNode* notParallelp() const { return op3p()->castNode(); } // op3 = assertion code for non-full case's
|
||||
AstNode* notParallelp() const { return op3p(); } // op3 = assertion code for non-full case's
|
||||
void addItemsp(AstNode* nodep) { addOp2p(nodep); }
|
||||
void addNotParallelp(AstNode* nodep) { setOp3p(nodep); }
|
||||
};
|
||||
@@ -1602,7 +1625,7 @@ public:
|
||||
// Know no children, and hot function, so skip iterator for speed
|
||||
// See checkTreeIter also that asserts no children
|
||||
// cppcheck-suppress functionConst
|
||||
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { }
|
||||
void iterateChildren(AstNVisitor& v) { }
|
||||
};
|
||||
|
||||
class AstNodeText : public AstNode {
|
||||
@@ -1652,6 +1675,7 @@ public:
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
virtual AstNodeDType* virtRefDTypep() const { return NULL; } // Iff has a non-null refDTypep(), as generic node function
|
||||
virtual void virtRefDTypep(AstNodeDType* nodep) { } // Iff has refDTypep(), set as generic node function
|
||||
virtual bool similarDType(AstNodeDType* samep) const = 0; // Assignable equivalence. Call skipRefp() on this and samep before calling
|
||||
//
|
||||
// Changing the width may confuse the data type resolution, so must clear TypeTable cache after use.
|
||||
void widthForce(int width, int sized) { m_width=width; m_widthMin=sized; }
|
||||
@@ -1701,6 +1725,9 @@ public:
|
||||
virtual int widthAlignBytes() const; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
||||
virtual int widthTotalBytes() const; // (Slow) recurses - Width in bytes rounding up 1,2,4,8,12,...
|
||||
// op1 = members
|
||||
virtual bool similarDType(AstNodeDType* samep) const {
|
||||
return this==samep; // We don't compare members, require exact equivalence
|
||||
}
|
||||
AstMemberDType* membersp() const { return op1p()->castMemberDType(); } // op1 = AstMember list
|
||||
void addMembersp(AstNode* nodep) { addNOp1p(nodep); }
|
||||
bool packed() const { return m_packed; }
|
||||
@@ -1731,15 +1758,23 @@ public:
|
||||
virtual void dump(ostream& str);
|
||||
virtual void dumpSmall(ostream& str);
|
||||
virtual const char* broken() const { BROKEN_RTN(!((m_refDTypep && !childDTypep() && m_refDTypep->brokeExists())
|
||||
|| (!m_refDTypep && childDTypep()))); return NULL; }
|
||||
|| (!m_refDTypep && childDTypep()))); return NULL; }
|
||||
virtual void cloneRelink() { if (m_refDTypep && m_refDTypep->clonep()) {
|
||||
m_refDTypep = m_refDTypep->clonep()->castNodeDType();
|
||||
m_refDTypep = m_refDTypep->clonep();
|
||||
}}
|
||||
virtual bool same(AstNode* samep) const {
|
||||
AstNodeArrayDType* sp = samep->castNodeArrayDType();
|
||||
return (msb()==sp->msb()
|
||||
&& subDTypep()==sp->subDTypep()
|
||||
&& rangenp()->sameTree(sp->rangenp())); } // HashedDT doesn't recurse, so need to check children
|
||||
virtual bool similarDType(AstNodeDType* samep) const {
|
||||
AstNodeArrayDType* sp = samep->castNodeArrayDType();
|
||||
return (sp
|
||||
&& type() == samep->type()
|
||||
&& msb() == sp->msb()
|
||||
&& rangenp()->sameTree(sp->rangenp())
|
||||
&& subDTypep()->skipRefp()->similarDType(sp->subDTypep()->skipRefp()));
|
||||
}
|
||||
virtual V3Hash sameHash() const { return V3Hash(V3Hash(m_refDTypep),V3Hash(msb()),V3Hash(lsb())); }
|
||||
AstNodeDType* getChildDTypep() const { return childDTypep(); }
|
||||
AstNodeDType* childDTypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
|
||||
@@ -1769,9 +1804,9 @@ public:
|
||||
AstNodeSel(FileLine* fl, AstNode* fromp, AstNode* bitp)
|
||||
:AstNodeBiop(fl, fromp, bitp) {}
|
||||
ASTNODE_BASE_FUNCS(NodeSel)
|
||||
AstNode* fromp() const { return op1p()->castNode(); } // op1 = Extracting what (NULL=TBD during parsing)
|
||||
AstNode* fromp() const { return op1p(); } // op1 = Extracting what (NULL=TBD during parsing)
|
||||
void fromp(AstNode* nodep) { setOp1p(nodep); }
|
||||
AstNode* bitp() const { return op2p()->castNode(); } // op2 = Msb selection expression
|
||||
AstNode* bitp() const { return op2p(); } // op2 = Msb selection expression
|
||||
void bitp(AstNode* nodep) { setOp2p(nodep); }
|
||||
int bitConst() const;
|
||||
virtual bool hasDType() const { return true; }
|
||||
@@ -1823,11 +1858,11 @@ public:
|
||||
string cname() const { return m_cname; }
|
||||
void cname(const string& cname) { m_cname = cname; }
|
||||
// op1 = Output variable (functions only, NULL for tasks)
|
||||
AstNode* fvarp() const { return op1p()->castNode(); }
|
||||
AstNode* fvarp() const { return op1p(); }
|
||||
void addFvarp(AstNode* nodep) { addNOp1p(nodep); }
|
||||
bool isFunction() const { return fvarp()!=NULL; }
|
||||
// op3 = Statements/Ports/Vars
|
||||
AstNode* stmtsp() const { return op3p()->castNode(); } // op3 = List of statements
|
||||
AstNode* stmtsp() const { return op3p(); } // op3 = List of statements
|
||||
void addStmtsp(AstNode* nodep) { addNOp3p(nodep); }
|
||||
// op4 = scope name
|
||||
AstScopeName* scopeNamep() const { return op4p()->castScopeName(); }
|
||||
@@ -1872,7 +1907,7 @@ public:
|
||||
ASTNODE_BASE_FUNCS(NodeFTaskRef)
|
||||
virtual const char* broken() const { BROKEN_RTN(m_taskp && !m_taskp->brokeExists()); return NULL; }
|
||||
virtual void cloneRelink() { if (m_taskp && m_taskp->clonep()) {
|
||||
m_taskp = m_taskp->clonep()->castNodeFTask();
|
||||
m_taskp = m_taskp->clonep();
|
||||
}}
|
||||
virtual void dump(ostream& str=cout);
|
||||
virtual string name() const { return m_name; } // * = Var name
|
||||
@@ -1890,7 +1925,7 @@ public:
|
||||
// op1 = namep
|
||||
AstNode* namep() const { return op1p(); }
|
||||
// op2 = Pin interconnection list
|
||||
AstNode* pinsp() const { return op2p()->castNode(); }
|
||||
AstNode* pinsp() const { return op2p(); }
|
||||
void addPinsp(AstNode* nodep) { addOp2p(nodep); }
|
||||
// op3 = scope tracking
|
||||
AstScopeName* scopeNamep() const { return op3p()->castScopeName(); }
|
||||
@@ -1922,7 +1957,7 @@ public:
|
||||
virtual void dump(ostream& str);
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
virtual string name() const { return m_name; }
|
||||
AstNode* stmtsp() const { return op2p()->castNode(); } // op2 = List of statements
|
||||
AstNode* stmtsp() const { return op2p(); } // op2 = List of statements
|
||||
AstActive* activesp() const { return op3p()->castActive(); } // op3 = List of i/sblocks
|
||||
// METHODS
|
||||
void addInlinesp(AstNode* nodep) { addOp1p(nodep); }
|
||||
@@ -1984,8 +2019,8 @@ inline int AstNodeArrayDType::elementsConst() const { return rangep()->elementsC
|
||||
inline VNumRange AstNodeArrayDType::declRange() const { return VNumRange(msb(), lsb(), rangep()->littleEndian()); }
|
||||
|
||||
inline void AstIfaceRefDType::cloneRelink() {
|
||||
if (m_cellp && m_cellp->clonep()) m_cellp = m_cellp->clonep()->castCell();
|
||||
if (m_ifacep && m_ifacep->clonep()) m_ifacep = m_ifacep->clonep()->castIface();
|
||||
if (m_modportp && m_modportp->clonep()) m_modportp = m_modportp->clonep()->castModport(); }
|
||||
if (m_cellp && m_cellp->clonep()) m_cellp = m_cellp->clonep();
|
||||
if (m_ifacep && m_ifacep->clonep()) m_ifacep = m_ifacep->clonep();
|
||||
if (m_modportp && m_modportp->clonep()) m_modportp = m_modportp->clonep(); }
|
||||
|
||||
#endif // Guard
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+14
-5
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -53,7 +53,7 @@ const char* AstNodeVarRef::broken() const {
|
||||
}
|
||||
|
||||
void AstNodeVarRef::cloneRelink() {
|
||||
if (m_varp && m_varp->clonep()) { m_varp = m_varp->clonep()->castVar(); }
|
||||
if (m_varp && m_varp->clonep()) { m_varp = m_varp->clonep(); }
|
||||
}
|
||||
|
||||
int AstNodeSel::bitConst() const {
|
||||
@@ -140,6 +140,13 @@ AstNodeBiop* AstLte::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
|
||||
}
|
||||
}
|
||||
|
||||
AstNodeBiop* AstEqWild::newTyped(FileLine* fl, AstNode* lhsp, AstNode* rhsp) {
|
||||
if (lhsp->isDouble() && rhsp->isDouble()) {
|
||||
return new AstEqD(fl, lhsp, rhsp);
|
||||
} else {
|
||||
return new AstEqWild(fl, lhsp, rhsp);
|
||||
}
|
||||
}
|
||||
|
||||
bool AstVar::isSigPublic() const {
|
||||
return (m_sigPublic || (v3Global.opt.allPublic() && !isTemp() && !isGenVar()));
|
||||
@@ -195,6 +202,8 @@ string AstVar::verilogKwd() const {
|
||||
return "tri";
|
||||
} else if (varType()==AstVarType::WIRE) {
|
||||
return "wire";
|
||||
} else if (varType()==AstVarType::WREAL) {
|
||||
return "wreal";
|
||||
} else {
|
||||
return dtypep()->name();
|
||||
}
|
||||
@@ -495,9 +504,9 @@ const char* AstScope::broken() const {
|
||||
}
|
||||
|
||||
void AstScope::cloneRelink() {
|
||||
if (m_aboveScopep && m_aboveScopep->clonep()) m_aboveScopep->clonep()->castScope();
|
||||
if (m_aboveCellp && m_aboveCellp->clonep()) m_aboveCellp->clonep()->castCell();
|
||||
if (m_modp && ((AstNode*)m_modp)->clonep()) ((AstNode*)m_modp)->clonep()->castNodeModule();
|
||||
if (m_aboveScopep && m_aboveScopep->clonep()) m_aboveScopep->clonep();
|
||||
if (m_aboveCellp && m_aboveCellp->clonep()) m_aboveCellp->clonep();
|
||||
if (m_modp && ((AstNode*)m_modp)->clonep()) ((AstNode*)m_modp)->clonep();
|
||||
}
|
||||
|
||||
string AstScope::nameDotless() const {
|
||||
|
||||
+409
-358
File diff suppressed because it is too large
Load Diff
+15
-15
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -84,13 +84,13 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
m_modp = nodep;
|
||||
m_repeatNum = 0;
|
||||
nodep->iterateChildren(*this);
|
||||
m_modp = NULL;
|
||||
}
|
||||
virtual void visit(AstNodeFTask* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeFTask* nodep) {
|
||||
UINFO(8," "<<nodep<<endl);
|
||||
// Rename it
|
||||
if (m_unnamedScope != "") {
|
||||
@@ -113,7 +113,7 @@ private:
|
||||
m_namedScope = oldScope;
|
||||
m_unnamedScope = oldUnnamed;
|
||||
}
|
||||
virtual void visit(AstBegin* nodep, AstNUser*) {
|
||||
virtual void visit(AstBegin* nodep) {
|
||||
// Begin blocks were only useful in variable creation, change names and delete
|
||||
UINFO(8," "<<nodep<<endl);
|
||||
string oldScope = m_namedScope;
|
||||
@@ -162,7 +162,7 @@ private:
|
||||
}
|
||||
pushDeletep(nodep); VL_DANGLING(nodep);
|
||||
}
|
||||
virtual void visit(AstVar* nodep, AstNUser*) {
|
||||
virtual void visit(AstVar* nodep) {
|
||||
if (m_unnamedScope != "") {
|
||||
// Rename it
|
||||
nodep->name(m_unnamedScope+"__DOT__"+nodep->name());
|
||||
@@ -173,7 +173,7 @@ private:
|
||||
else m_modp->addStmtp(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCell* nodep, AstNUser*) {
|
||||
virtual void visit(AstCell* nodep) {
|
||||
UINFO(8," CELL "<<nodep<<endl);
|
||||
if (m_namedScope != "") {
|
||||
m_statep->userMarkChanged(nodep);
|
||||
@@ -186,14 +186,14 @@ private:
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstVarXRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstVarXRef* nodep) {
|
||||
UINFO(9, " VARXREF "<<nodep<<endl);
|
||||
if (m_namedScope != "" && nodep->inlinedDots() == "") {
|
||||
nodep->inlinedDots(m_namedScope);
|
||||
UINFO(9, " rescope to "<<nodep<<endl);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
||||
virtual void visit(AstScopeName* nodep) {
|
||||
// If there's a %m in the display text, we add a special node that will contain the name()
|
||||
// Similar code in V3Inline
|
||||
if (nodep->user1SetOnce()) return; // Don't double-add text's
|
||||
@@ -206,13 +206,13 @@ private:
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstCoverDecl* nodep, AstNUser*) {
|
||||
virtual void visit(AstCoverDecl* nodep) {
|
||||
// Don't need to fix path in coverage statements, they're not under
|
||||
// any BEGINs, but V3Coverage adds them all under the module itself.
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
// VISITORS - LINT CHECK
|
||||
virtual void visit(AstIf* nodep, AstNUser*) { // Note not AstNodeIf; other types don't get covered
|
||||
virtual void visit(AstIf* nodep) { // Note not AstNodeIf; other types don't get covered
|
||||
// Check IFDEPTH warning - could be in other transform files if desire
|
||||
int prevIfDepth = m_ifDepth;
|
||||
if (m_ifDepth == -1 || v3Global.opt.ifDepth()<1) { // Turned off
|
||||
@@ -226,7 +226,7 @@ private:
|
||||
nodep->iterateChildren(*this);
|
||||
m_ifDepth = prevIfDepth;
|
||||
}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
@@ -252,21 +252,21 @@ private:
|
||||
// AstNodeFTask::user1p // Node replaced, rename it
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeFTaskRef* nodep) {
|
||||
if (nodep->taskp()->user1()) { // It was converted
|
||||
UINFO(9, " relinkFTask "<<nodep<<endl);
|
||||
nodep->name(nodep->taskp()->name());
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstVarRef* nodep) {
|
||||
if (nodep->varp()->user1()) { // It was converted
|
||||
UINFO(9, " relinVarRef "<<nodep<<endl);
|
||||
nodep->name(nodep->varp()->name());
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstIfaceRefDType* nodep, AstNUser*) {
|
||||
virtual void visit(AstIfaceRefDType* nodep) {
|
||||
// May have changed cell names
|
||||
// TypeTable is always after all modules, so names are stable
|
||||
UINFO(8," IFACEREFDTYPE "<<nodep<<endl);
|
||||
@@ -275,7 +275,7 @@ private:
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+5
-5
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -75,7 +75,7 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeIf* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeIf* nodep) {
|
||||
UINFO(4," IF: "<<nodep<<endl);
|
||||
int lastLikely = m_likely;
|
||||
int lastUnlikely = m_unlikely;
|
||||
@@ -101,17 +101,17 @@ private:
|
||||
m_likely = lastLikely;
|
||||
m_unlikely = lastUnlikely;
|
||||
}
|
||||
virtual void visit(AstCCall* nodep, AstNUser*) {
|
||||
virtual void visit(AstCCall* nodep) {
|
||||
checkUnlikely(nodep);
|
||||
nodep->funcp()->user1Inc();
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep, AstNUser*) {
|
||||
virtual void visit(AstCFunc* nodep) {
|
||||
checkUnlikely(nodep);
|
||||
m_cfuncsp.push_back(nodep);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
checkUnlikely(nodep);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+8
-8
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
if (debug()>=9) cout<<"-nodeDel: "<<(void*)(nodep)<<endl;
|
||||
NodeMap::iterator iter = s_nodes.find(nodep);
|
||||
if (iter==s_nodes.end() || !(iter->second & FLAG_ALLOCATED)) {
|
||||
((AstNode*)(nodep))->v3fatalSrc("Deleting AstNode object that was never tracked or already deleted\n");
|
||||
((AstNode*)(nodep))->v3fatalSrc("Deleting AstNode object that was never tracked or already deleted");
|
||||
}
|
||||
if (iter!=s_nodes.end()) s_nodes.erase(iter);
|
||||
}
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
if (debug()>=9) cout<<"-nodeNew: "<<(void*)(nodep)<<endl;
|
||||
NodeMap::iterator iter = s_nodes.find(nodep);
|
||||
if (iter!=s_nodes.end() || (iter->second & FLAG_ALLOCATED)) {
|
||||
((AstNode*)(nodep))->v3fatalSrc("Newing AstNode object that is already allocated\n");
|
||||
((AstNode*)(nodep))->v3fatalSrc("Newing AstNode object that is already allocated");
|
||||
}
|
||||
if (iter == s_nodes.end()) {
|
||||
int flags = FLAG_ALLOCATED; // This int needed to appease GCC 4.1.2
|
||||
@@ -94,16 +94,16 @@ public:
|
||||
NodeMap::iterator iter = s_nodes.find(nodep);
|
||||
if (iter == s_nodes.end()) {
|
||||
#ifdef VL_LEAK_CHECKS
|
||||
nodep->v3fatalSrc("AstNode is in tree, but not allocated\n");
|
||||
nodep->v3fatalSrc("AstNode is in tree, but not allocated");
|
||||
#endif
|
||||
} else {
|
||||
if (!(iter->second & FLAG_ALLOCATED)) {
|
||||
#ifdef VL_LEAK_CHECKS
|
||||
nodep->v3fatalSrc("AstNode is in tree, but not allocated\n");
|
||||
nodep->v3fatalSrc("AstNode is in tree, but not allocated");
|
||||
#endif
|
||||
}
|
||||
if (iter->second & FLAG_IN_TREE) {
|
||||
nodep->v3fatalSrc("AstNode is already in tree at another location\n");
|
||||
nodep->v3fatalSrc("AstNode is already in tree at another location");
|
||||
}
|
||||
}
|
||||
int or_flags = FLAG_IN_TREE | (linkable?FLAG_LINKABLE:0);
|
||||
@@ -192,7 +192,7 @@ private:
|
||||
nodep->iterateChildrenConst(*this);
|
||||
}
|
||||
// VISITORS
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
processAndIterate(nodep);
|
||||
}
|
||||
public:
|
||||
@@ -236,7 +236,7 @@ private:
|
||||
nodep->iterateChildrenConst(*this);
|
||||
BrokenTable::setUnder(nodep,false);
|
||||
}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
processAndIterate(nodep);
|
||||
}
|
||||
public:
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Generate AstCReset nodes.
|
||||
// DESCRIPTION: Verilator: Generate C language constructors and AstCReset nodes.
|
||||
//
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -17,9 +17,12 @@
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//*************************************************************************
|
||||
// V3VarReset's Transformations:
|
||||
// Iterates over all modules and creates a _ctor_var_reset AstCFunc
|
||||
// V3CCtors's Transformations:
|
||||
// Iterates over all modules and
|
||||
// for all AstVar, create a creates a AstCReset node in an _ctor_var_reset AstCFunc.
|
||||
// for all AstCoverDecl, move the declaration into a _configure_coverage AstCFunc.
|
||||
// For each variable that needs reset, add a AstCReset node.
|
||||
//
|
||||
// This transformation honors outputSplitCFuncs.
|
||||
//*************************************************************************
|
||||
#include "config_build.h"
|
||||
@@ -33,62 +36,87 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "V3Global.h"
|
||||
#include "V3VarResets.h"
|
||||
#include "V3EmitCBase.h"
|
||||
#include "V3CCtors.h"
|
||||
|
||||
class V3VarReset {
|
||||
class V3CCtorsVisitor {
|
||||
private:
|
||||
string m_basename;
|
||||
string m_argsp;
|
||||
string m_callargsp;
|
||||
AstNodeModule* m_modp; // Current module
|
||||
AstCFunc* m_tlFuncp; // Top level function being built
|
||||
AstCFunc* m_funcp; // Current function
|
||||
int m_numStmts; // Number of statements output
|
||||
int m_funcNum; // Function number being built
|
||||
|
||||
void initializeVar(AstVar* nodep) {
|
||||
public:
|
||||
void add(AstNode* nodep) {
|
||||
if (v3Global.opt.outputSplitCFuncs()
|
||||
&& v3Global.opt.outputSplitCFuncs() < m_numStmts) {
|
||||
m_funcp = NULL;
|
||||
}
|
||||
if (!m_funcp) {
|
||||
m_funcp = new AstCFunc(m_modp->fileline(), "_ctor_var_reset_" + cvtToStr(++m_funcNum), NULL, "void");
|
||||
m_funcp = new AstCFunc(m_modp->fileline(), m_basename + "_" + cvtToStr(++m_funcNum), NULL, "void");
|
||||
m_funcp->isStatic(false);
|
||||
m_funcp->declPrivate(true);
|
||||
m_funcp->slow(true);
|
||||
m_funcp->argTypes(m_argsp);
|
||||
m_modp->addStmtp(m_funcp);
|
||||
|
||||
// Add a top call to it
|
||||
AstCCall* callp = new AstCCall(m_modp->fileline(), m_funcp);
|
||||
callp->argTypes(m_callargsp);
|
||||
|
||||
m_tlFuncp->addStmtsp(callp);
|
||||
m_numStmts = 0;
|
||||
}
|
||||
m_funcp->addStmtsp(new AstCReset(nodep->fileline(), new AstVarRef(nodep->fileline(), nodep, true)));
|
||||
m_funcp->addStmtsp(nodep);
|
||||
m_numStmts += 1;
|
||||
}
|
||||
|
||||
public:
|
||||
V3VarReset(AstNodeModule* nodep) {
|
||||
V3CCtorsVisitor(AstNodeModule* nodep, string basename, string argsp="", string callargsp="",
|
||||
const string& stmt="") {
|
||||
m_basename = basename;
|
||||
m_argsp = argsp;
|
||||
m_callargsp = callargsp;
|
||||
m_modp = nodep;
|
||||
m_numStmts = 0;
|
||||
m_funcNum = 0;
|
||||
m_tlFuncp = new AstCFunc(nodep->fileline(), "_ctor_var_reset", NULL, "void");
|
||||
m_tlFuncp = new AstCFunc(nodep->fileline(), basename, NULL, "void");
|
||||
m_tlFuncp->declPrivate(true);
|
||||
m_tlFuncp->isStatic(false);
|
||||
m_tlFuncp->slow(true);
|
||||
m_tlFuncp->argTypes(m_argsp);
|
||||
if (stmt != "") {
|
||||
m_tlFuncp->addStmtsp(new AstCStmt(nodep->fileline(), stmt));
|
||||
}
|
||||
m_funcp = m_tlFuncp;
|
||||
m_modp->addStmtp(m_tlFuncp);
|
||||
for (AstNode* np = m_modp->stmtsp(); np; np = np->nextp()) {
|
||||
AstVar* varp = np->castVar();
|
||||
if (varp) initializeVar(varp);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
||||
void V3VarResets::emitResets() {
|
||||
void V3CCtors::cctorsAll() {
|
||||
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||
for (AstNodeModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castNodeModule()) {
|
||||
// Process each module in turn
|
||||
V3VarReset v(nodep);
|
||||
for (AstNodeModule* modp = v3Global.rootp()->modulesp(); modp; modp=modp->nextp()->castNodeModule()) {
|
||||
// Process each module in turn
|
||||
V3CCtorsVisitor var_reset (modp, "_ctor_var_reset");
|
||||
V3CCtorsVisitor configure_coverage (modp, "_configure_coverage",
|
||||
EmitCBaseVisitor::symClassVar()+ ", bool first", "vlSymsp, first",
|
||||
"if (0 && vlSymsp && first) {} // Prevent unused\n");
|
||||
|
||||
for (AstNode* np = modp->stmtsp(); np; np = np->nextp()) {
|
||||
AstVar* varp = np->castVar();
|
||||
if (varp) var_reset.add(new AstCReset(varp->fileline(), new AstVarRef(varp->fileline(), varp, true)));
|
||||
AstCoverDecl* coverp = np->castCoverDecl();
|
||||
if (coverp) {
|
||||
AstNode* backp = coverp->backp();
|
||||
coverp->unlinkFrBack();
|
||||
configure_coverage.add(coverp);
|
||||
np = backp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +1,12 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit C++ code for module tree
|
||||
// DESCRIPTION: Verilator: Emit CFunc's for class construction and configuration
|
||||
//
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -18,8 +18,8 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#ifndef _V3VARRESETS_H_
|
||||
#define _V3VARRESETS_H_ 1
|
||||
#ifndef _V3CCTORS_H_
|
||||
#define _V3CCTORS_H_ 1
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include "V3Error.h"
|
||||
@@ -27,9 +27,9 @@
|
||||
|
||||
//============================================================================
|
||||
|
||||
class V3VarResets {
|
||||
class V3CCtors {
|
||||
public:
|
||||
static void emitResets();
|
||||
static void cctorsAll();
|
||||
};
|
||||
|
||||
|
||||
+7
-7
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -65,7 +65,7 @@ private:
|
||||
return level;
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeCase* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeCase* nodep) {
|
||||
if (nodep->castCase() && nodep->castCase()->casex()) {
|
||||
nodep->v3warn(CASEX,"Suggest casez (with ?'s) in place of casex (with X's)");
|
||||
}
|
||||
@@ -90,7 +90,7 @@ private:
|
||||
m_caseExprp = NULL;
|
||||
}
|
||||
}
|
||||
virtual void visit(AstConst* nodep, AstNUser*) {
|
||||
virtual void visit(AstConst* nodep) {
|
||||
// See also neverItem
|
||||
if (m_caseExprp && nodep->num().isFourState()) {
|
||||
if (m_caseExprp->castGenCase()) {
|
||||
@@ -107,7 +107,7 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
@@ -174,7 +174,7 @@ private:
|
||||
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondp->nextp()) {
|
||||
//if (debug()>=9) icondp->dumpTree(cout," caseitem: ");
|
||||
AstConst* iconstp = icondp->castConst();
|
||||
if (!iconstp) nodep->v3fatalSrc("above 'can't parse' should have caught this\n");
|
||||
if (!iconstp) nodep->v3fatalSrc("above 'can't parse' should have caught this");
|
||||
if (neverItem(nodep, iconstp)) {
|
||||
// X in casez can't ever be executed
|
||||
} else {
|
||||
@@ -451,7 +451,7 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstCase* nodep, AstNUser*) {
|
||||
virtual void visit(AstCase* nodep) {
|
||||
V3Case::caseLint(nodep);
|
||||
nodep->iterateChildren(*this);
|
||||
if (debug()>=9) nodep->dumpTree(cout," case_old: ");
|
||||
@@ -467,7 +467,7 @@ private:
|
||||
}
|
||||
//--------------------
|
||||
// Default: Just iterate
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+10
-10
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2004-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2004-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -107,19 +107,19 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeUniop* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeUniop* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->user1(nodep->lhsp()->user1());
|
||||
if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp());
|
||||
}
|
||||
virtual void visit(AstNodeBiop* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeBiop* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->user1(nodep->lhsp()->user1()
|
||||
| nodep->rhsp()->user1());
|
||||
if (nodep->sizeMattersLhs()) insureCast(nodep->lhsp());
|
||||
if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp());
|
||||
}
|
||||
virtual void visit(AstNodeTriop* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeTriop* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->user1(nodep->lhsp()->user1()
|
||||
| nodep->rhsp()->user1()
|
||||
@@ -128,12 +128,12 @@ private:
|
||||
if (nodep->sizeMattersRhs()) insureCast(nodep->rhsp());
|
||||
if (nodep->sizeMattersThs()) insureCast(nodep->thsp());
|
||||
}
|
||||
virtual void visit(AstCCast* nodep, AstNUser*) {
|
||||
virtual void visit(AstCCast* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
insureLower32Cast(nodep);
|
||||
nodep->user1(1);
|
||||
}
|
||||
virtual void visit(AstNegate* nodep, AstNUser*) {
|
||||
virtual void visit(AstNegate* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->user1(nodep->lhsp()->user1());
|
||||
if (nodep->lhsp()->widthMin()==1) {
|
||||
@@ -145,7 +145,7 @@ private:
|
||||
insureCast(nodep->lhsp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstVarRef* nodep) {
|
||||
if (!nodep->lvalue()
|
||||
&& !nodep->backp()->castCCast()
|
||||
&& nodep->backp()->castNodeMath()
|
||||
@@ -158,7 +158,7 @@ private:
|
||||
}
|
||||
nodep->user1(1);
|
||||
}
|
||||
virtual void visit(AstConst* nodep, AstNUser*) {
|
||||
virtual void visit(AstConst* nodep) {
|
||||
// Constants are of unknown size if smaller than 33 bits, becase
|
||||
// we're too lazy to wrap every constant in the universe in
|
||||
// ((IData)#).
|
||||
@@ -166,11 +166,11 @@ private:
|
||||
}
|
||||
|
||||
// NOPs
|
||||
virtual void visit(AstVar* nodep, AstNUser*) {}
|
||||
virtual void visit(AstVar* nodep) {}
|
||||
|
||||
//--------------------
|
||||
// Default: Just iterate
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2004-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2004-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+29
-29
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -138,7 +138,7 @@ private:
|
||||
ofstream* m_ofp; // Output file
|
||||
string m_prefix;
|
||||
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
*m_ofp<<m_prefix;
|
||||
if (nodep->user3()) *m_ofp<<" %%";
|
||||
else *m_ofp<<" ";
|
||||
@@ -172,7 +172,7 @@ private:
|
||||
int m_maxLineno;
|
||||
size_t m_maxFilenameLen;
|
||||
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
// Keeping line+filename lengths separate is much faster than calling ascii().length()
|
||||
if (nodep->fileline()->lineno() >= m_maxLineno) {
|
||||
@@ -604,19 +604,19 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
m_modp = nodep;
|
||||
nodep->iterateChildren(*this);
|
||||
m_modp = NULL;
|
||||
}
|
||||
virtual void visit(AstScope* nodep, AstNUser*) {
|
||||
virtual void visit(AstScope* nodep) {
|
||||
UINFO(4," SCOPE "<<nodep<<endl);
|
||||
m_scopep = nodep;
|
||||
m_logicVertexp = NULL;
|
||||
nodep->iterateChildren(*this);
|
||||
m_scopep = NULL;
|
||||
}
|
||||
virtual void visit(AstActive* nodep, AstNUser*) {
|
||||
virtual void visit(AstActive* nodep) {
|
||||
// Create required blocks and add to module
|
||||
UINFO(4," BLOCK "<<nodep<<endl);
|
||||
AstNode::user2ClearTree();
|
||||
@@ -627,11 +627,11 @@ private:
|
||||
m_domainp = NULL;
|
||||
AstNode::user2ClearTree();
|
||||
}
|
||||
virtual void visit(AstNodeVarRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeVarRef* nodep) {
|
||||
if (m_scopep) {
|
||||
if (!m_logicVertexp) nodep->v3fatalSrc("Var ref not under a logic block\n");
|
||||
if (!m_logicVertexp) nodep->v3fatalSrc("Var ref not under a logic block");
|
||||
AstVarScope* varscp = nodep->varScopep();
|
||||
if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp\n");
|
||||
if (!varscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp");
|
||||
CdcVarVertex* varvertexp = makeVarVertex(varscp);
|
||||
UINFO(5," VARREF to "<<varscp<<endl);
|
||||
// We use weight of one for normal edges,
|
||||
@@ -655,72 +655,72 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstAssignDly* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssignDly* nodep) {
|
||||
m_inDly = true;
|
||||
nodep->iterateChildren(*this);
|
||||
m_inDly = false;
|
||||
}
|
||||
virtual void visit(AstSenItem* nodep, AstNUser*) {
|
||||
virtual void visit(AstSenItem* nodep) {
|
||||
// Note we look at only AstSenItems, not AstSenGate's
|
||||
// The gating term of a AstSenGate is normal logic
|
||||
m_inSenItem = true;
|
||||
nodep->iterateChildren(*this);
|
||||
m_inSenItem = false;
|
||||
}
|
||||
virtual void visit(AstAlways* nodep, AstNUser*) {
|
||||
virtual void visit(AstAlways* nodep) {
|
||||
iterateNewStmt(nodep);
|
||||
}
|
||||
virtual void visit(AstAlwaysPublic* nodep, AstNUser*) {
|
||||
virtual void visit(AstAlwaysPublic* nodep) {
|
||||
// CDC doesn't care about public variables
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep, AstNUser*) {
|
||||
virtual void visit(AstCFunc* nodep) {
|
||||
iterateNewStmt(nodep);
|
||||
}
|
||||
virtual void visit(AstSenGate* nodep, AstNUser*) {
|
||||
virtual void visit(AstSenGate* nodep) {
|
||||
// First handle the clock part will be handled in a minute by visit AstSenItem
|
||||
// The logic gating term is delt with as logic
|
||||
iterateNewStmt(nodep);
|
||||
}
|
||||
virtual void visit(AstAssignAlias* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssignAlias* nodep) {
|
||||
iterateNewStmt(nodep);
|
||||
}
|
||||
virtual void visit(AstAssignW* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssignW* nodep) {
|
||||
iterateNewStmt(nodep);
|
||||
}
|
||||
|
||||
// Math that shouldn't cause us to clear hazard
|
||||
virtual void visit(AstConst* nodep, AstNUser*) { }
|
||||
virtual void visit(AstReplicate* nodep, AstNUser*) {
|
||||
virtual void visit(AstConst* nodep) { }
|
||||
virtual void visit(AstReplicate* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstConcat* nodep, AstNUser*) {
|
||||
virtual void visit(AstConcat* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstNot* nodep, AstNUser*) {
|
||||
virtual void visit(AstNot* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstSel* nodep, AstNUser*) {
|
||||
virtual void visit(AstSel* nodep) {
|
||||
if (!nodep->lsbp()->castConst()) setNodeHazard(nodep);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstNodeSel* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeSel* nodep) {
|
||||
if (!nodep->bitp()->castConst()) setNodeHazard(nodep);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
// Ignores
|
||||
virtual void visit(AstInitial* nodep, AstNUser*) { }
|
||||
virtual void visit(AstTraceInc* nodep, AstNUser*) { }
|
||||
virtual void visit(AstCoverToggle* nodep, AstNUser*) { }
|
||||
virtual void visit(AstNodeDType* nodep, AstNUser*) { }
|
||||
virtual void visit(AstInitial* nodep) { }
|
||||
virtual void visit(AstTraceInc* nodep) { }
|
||||
virtual void visit(AstCoverToggle* nodep) { }
|
||||
virtual void visit(AstNodeDType* nodep) { }
|
||||
|
||||
//--------------------
|
||||
// Default
|
||||
virtual void visit(AstNodeMath* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeMath* nodep) {
|
||||
setNodeHazard(nodep);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+12
-12
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -143,13 +143,13 @@ private:
|
||||
m_statep->m_numStmts += visitor.count();
|
||||
}
|
||||
|
||||
virtual void visit(AstBasicDType* nodep, AstNUser*) {
|
||||
virtual void visit(AstBasicDType* nodep) {
|
||||
newChangeDet();
|
||||
}
|
||||
virtual void visit(AstPackArrayDType* nodep, AstNUser*) {
|
||||
virtual void visit(AstPackArrayDType* nodep) {
|
||||
newChangeDet();
|
||||
}
|
||||
virtual void visit(AstUnpackArrayDType* nodep, AstNUser*) {
|
||||
virtual void visit(AstUnpackArrayDType* nodep) {
|
||||
for (int index=0; index < nodep->elementsConst(); ++index) {
|
||||
AstNode* origVEp = m_varEqnp;
|
||||
AstNode* origNLEp = m_newLvEqnp;
|
||||
@@ -170,7 +170,7 @@ private:
|
||||
m_newRvEqnp = origNREp;
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeClassDType* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeClassDType* nodep) {
|
||||
if (nodep->packedUnsup()) {
|
||||
newChangeDet();
|
||||
} else {
|
||||
@@ -178,7 +178,7 @@ private:
|
||||
m_vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable (probably with UNOPTFLAT warning suppressed): "<<m_vscp->varp()->prettyName());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (debug()) nodep->dumpTree(cout,"-DETECTARRAY-general-");
|
||||
m_vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable (probably with UNOPTFLAT warning suppressed): "<<m_vscp->varp()->prettyName());
|
||||
@@ -239,7 +239,7 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
UINFO(4," MOD "<<nodep<<endl);
|
||||
if (nodep->isTop()) {
|
||||
m_statep->m_topModp = nodep;
|
||||
@@ -247,13 +247,13 @@ private:
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
virtual void visit(AstTopScope* nodep, AstNUser*) {
|
||||
virtual void visit(AstTopScope* nodep) {
|
||||
UINFO(4," TS "<<nodep<<endl);
|
||||
// Clearing
|
||||
AstNode::user1ClearTree();
|
||||
// Create the change detection function
|
||||
AstScope* scopep = nodep->scopep();
|
||||
if (!scopep) nodep->v3fatalSrc("No scope found on top level, perhaps you have no statements?\n");
|
||||
if (!scopep) nodep->v3fatalSrc("No scope found on top level, perhaps you have no statements?");
|
||||
m_statep->m_scopetopp = scopep;
|
||||
|
||||
// Create a wrapper change detection function that calls each change detection function
|
||||
@@ -269,7 +269,7 @@ private:
|
||||
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstVarScope* nodep, AstNUser*) {
|
||||
virtual void visit(AstVarScope* nodep) {
|
||||
if (nodep->isCircular()) {
|
||||
UINFO(8," CIRC "<<nodep<<endl);
|
||||
if (!nodep->user1SetOnce()) {
|
||||
@@ -277,12 +277,12 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeMath* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeMath* nodep) {
|
||||
// Short-circuit
|
||||
}
|
||||
//--------------------
|
||||
// Default: Just iterate
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+24
-24
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -78,7 +78,7 @@ private:
|
||||
if (old_dtypep->width() != width) {
|
||||
// Since any given dtype's cppWidth() is the same, we can just
|
||||
// remember one convertion for each, and reuse it
|
||||
if (AstNodeDType* new_dtypep = old_dtypep->user3p()->castNode()->castNodeDType()) {
|
||||
if (AstNodeDType* new_dtypep = old_dtypep->user3p()->castNodeDType()) {
|
||||
nodep->dtypep(new_dtypep);
|
||||
} else {
|
||||
nodep->dtypeChgWidth(width, nodep->widthMin());
|
||||
@@ -173,12 +173,12 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
m_modp = nodep;
|
||||
nodep->iterateChildren(*this);
|
||||
m_modp = NULL;
|
||||
}
|
||||
virtual void visit(AstNodeUniop* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeUniop* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
computeCppWidth(nodep);
|
||||
if (nodep->cleanLhs()) {
|
||||
@@ -186,45 +186,45 @@ private:
|
||||
}
|
||||
setClean (nodep, nodep->cleanOut());
|
||||
}
|
||||
virtual void visit(AstNodeBiop* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeBiop* nodep) {
|
||||
operandBiop(nodep);
|
||||
setClean (nodep, nodep->cleanOut());
|
||||
}
|
||||
virtual void visit(AstAnd* nodep, AstNUser*) {
|
||||
virtual void visit(AstAnd* nodep) {
|
||||
operandBiop(nodep);
|
||||
setClean (nodep, isClean(nodep->lhsp()) || isClean(nodep->rhsp()));
|
||||
}
|
||||
virtual void visit(AstXor* nodep, AstNUser*) {
|
||||
virtual void visit(AstXor* nodep) {
|
||||
operandBiop(nodep);
|
||||
setClean (nodep, isClean(nodep->lhsp()) && isClean(nodep->rhsp()));
|
||||
}
|
||||
virtual void visit(AstOr* nodep, AstNUser*) {
|
||||
virtual void visit(AstOr* nodep) {
|
||||
operandBiop(nodep);
|
||||
setClean (nodep, isClean(nodep->lhsp()) && isClean(nodep->rhsp()));
|
||||
}
|
||||
virtual void visit(AstNodeMath* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeMath* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
computeCppWidth(nodep);
|
||||
setClean (nodep, nodep->cleanOut());
|
||||
}
|
||||
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeAssign* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
computeCppWidth(nodep);
|
||||
if (nodep->cleanRhs()) {
|
||||
insureClean(nodep->rhsp());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstText* nodep, AstNUser*) {
|
||||
virtual void visit(AstText* nodep) {
|
||||
setClean (nodep, true);
|
||||
}
|
||||
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
||||
virtual void visit(AstScopeName* nodep) {
|
||||
setClean (nodep, true);
|
||||
}
|
||||
virtual void visit(AstSel* nodep, AstNUser*) {
|
||||
virtual void visit(AstSel* nodep) {
|
||||
operandTriop(nodep);
|
||||
setClean (nodep, nodep->cleanOut());
|
||||
}
|
||||
virtual void visit(AstUCFunc* nodep, AstNUser*) {
|
||||
virtual void visit(AstUCFunc* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
computeCppWidth(nodep);
|
||||
setClean (nodep, false);
|
||||
@@ -234,43 +234,43 @@ private:
|
||||
}
|
||||
insureCleanAndNext (nodep->bodysp());
|
||||
}
|
||||
virtual void visit(AstTraceInc* nodep, AstNUser*) {
|
||||
virtual void visit(AstTraceInc* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
insureCleanAndNext (nodep->valuep());
|
||||
}
|
||||
virtual void visit(AstTypedef* nodep, AstNUser*) {
|
||||
virtual void visit(AstTypedef* nodep) {
|
||||
// No cleaning, or would loose pointer to enum
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstParamTypeDType* nodep, AstNUser*) {
|
||||
virtual void visit(AstParamTypeDType* nodep) {
|
||||
// No cleaning, or would loose pointer to enum
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
// Control flow operators
|
||||
virtual void visit(AstNodeCond* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeCond* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
insureClean(nodep->condp());
|
||||
setClean(nodep, isClean(nodep->expr1p()) && isClean(nodep->expr2p()));
|
||||
}
|
||||
virtual void visit(AstWhile* nodep, AstNUser*) {
|
||||
virtual void visit(AstWhile* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
insureClean(nodep->condp());
|
||||
}
|
||||
virtual void visit(AstNodeIf* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeIf* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
insureClean(nodep->condp());
|
||||
}
|
||||
virtual void visit(AstSFormatF* nodep, AstNUser*) {
|
||||
virtual void visit(AstSFormatF* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
insureCleanAndNext (nodep->exprsp());
|
||||
setClean(nodep, true); // generates a string, so not relevant
|
||||
}
|
||||
virtual void visit(AstUCStmt* nodep, AstNUser*) {
|
||||
virtual void visit(AstUCStmt* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
insureCleanAndNext (nodep->bodysp());
|
||||
}
|
||||
virtual void visit(AstCCall* nodep, AstNUser*) {
|
||||
virtual void visit(AstCCall* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
insureCleanAndNext (nodep->argsp());
|
||||
setClean (nodep, true);
|
||||
@@ -278,7 +278,7 @@ private:
|
||||
|
||||
//--------------------
|
||||
// Default: Just iterate
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
computeCppWidth(nodep);
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+22
-22
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2008-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2008-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -199,19 +199,19 @@ private:
|
||||
if (m_isSimple) nodep->iterateChildren(*this);
|
||||
}
|
||||
// VISITORS
|
||||
virtual void visit(AstOr* nodep, AstNUser*) { okIterate(nodep); }
|
||||
virtual void visit(AstAnd* nodep, AstNUser*) { okIterate(nodep); }
|
||||
virtual void visit(AstNot* nodep, AstNUser*) { okIterate(nodep); }
|
||||
virtual void visit(AstLogOr* nodep, AstNUser*) { okIterate(nodep); }
|
||||
virtual void visit(AstLogAnd* nodep, AstNUser*) { okIterate(nodep); }
|
||||
virtual void visit(AstLogNot* nodep, AstNUser*) { okIterate(nodep); }
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) { okIterate(nodep); }
|
||||
virtual void visit(AstOr* nodep) { okIterate(nodep); }
|
||||
virtual void visit(AstAnd* nodep) { okIterate(nodep); }
|
||||
virtual void visit(AstNot* nodep) { okIterate(nodep); }
|
||||
virtual void visit(AstLogOr* nodep) { okIterate(nodep); }
|
||||
virtual void visit(AstLogAnd* nodep) { okIterate(nodep); }
|
||||
virtual void visit(AstLogNot* nodep) { okIterate(nodep); }
|
||||
virtual void visit(AstVarRef* nodep) { okIterate(nodep); }
|
||||
|
||||
// Other possibilities are equals, etc
|
||||
// But, we don't want to get too complicated or it will take too much
|
||||
// effort to calculate the gater
|
||||
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
m_isSimple = false;
|
||||
//nodep->iterateChildren(*this);
|
||||
}
|
||||
@@ -248,10 +248,10 @@ class GaterBodyVisitor : public GaterBaseVisitor {
|
||||
uint32_t m_state; // Parsing state
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstVarRef* nodep) {
|
||||
if (nodep->lvalue()) {
|
||||
AstVarScope* vscp = nodep->varScopep();
|
||||
if (vscp->user2p()->castNode() == m_exprp) {
|
||||
if (vscp->user2p() == m_exprp) {
|
||||
// This variable's block needs to move to the new always
|
||||
if (m_original) {
|
||||
UINFO(9," VARREF delete in old: "<<nodep<<endl);
|
||||
@@ -272,11 +272,11 @@ class GaterBodyVisitor : public GaterBaseVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
//virtual void visit(AstNodeIf* nodep, AstNUser*) { ... }
|
||||
//virtual void visit(AstNodeIf* nodep) { ... }
|
||||
// Not needed, it's the same handling as any other statement. Cool, huh?
|
||||
// (We may get empty IFs but the constant propagater will rip them up for us)
|
||||
|
||||
virtual void visit(AstNodeStmt* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeStmt* nodep) {
|
||||
uint32_t oldstate = m_state;
|
||||
// Find if children want to delete this or not.
|
||||
// Note children may bicker, and want to both keep and delete (branches on a if)
|
||||
@@ -304,7 +304,7 @@ class GaterBodyVisitor : public GaterBaseVisitor {
|
||||
m_state |= STATE_KEEP;
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
@@ -559,7 +559,7 @@ class GaterVisitor : public GaterBaseVisitor {
|
||||
if (!vVxp->inBeginp()) {
|
||||
// At this point, any variable not linked is an error
|
||||
// (It should have at least landed under the Head node)
|
||||
vVxp->nodep()->v3fatalSrc("Variable became stranded in clk gate detection\n");
|
||||
vVxp->nodep()->v3fatalSrc("Variable became stranded in clk gate detection");
|
||||
}
|
||||
if (!lastVxp || vVxp->sortCmp(lastVxp)) {
|
||||
// Different sources for this new node
|
||||
@@ -701,7 +701,7 @@ class GaterVisitor : public GaterBaseVisitor {
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstAlways* nodep, AstNUser*) {
|
||||
virtual void visit(AstAlways* nodep) {
|
||||
if (debug()>=9) cout<<endl<<endl<<endl;
|
||||
UINFO(5, "Gater: ALWAYS: "<<nodep<<endl);
|
||||
if (nodep->user4SetOnce()) return;
|
||||
@@ -751,7 +751,7 @@ class GaterVisitor : public GaterBaseVisitor {
|
||||
}
|
||||
UINFO(5, " Gater done"<<endl);
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstVarRef* nodep) {
|
||||
if (nodep->lvalue()) {
|
||||
AstVarScope* vscp = nodep->varScopep();
|
||||
if (nodep->varp()->isSigPublic()) {
|
||||
@@ -778,7 +778,7 @@ class GaterVisitor : public GaterBaseVisitor {
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeIf* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeIf* nodep) {
|
||||
m_ifDepth++;
|
||||
bool allowGater = m_directlyUnderAlw && m_ifDepth <= IF_DEPTH_MAX;
|
||||
if (allowGater) {
|
||||
@@ -819,12 +819,12 @@ class GaterVisitor : public GaterBaseVisitor {
|
||||
m_ifDepth--;
|
||||
}
|
||||
|
||||
virtual void visit(AstAssignDly* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssignDly* nodep) {
|
||||
// iterateChildrenAlw will detect this is a statement for us
|
||||
iterateChildrenAlw(nodep, false);
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeAssign* nodep) {
|
||||
// Note NOT AssignDly; handled above, We'll just mark this block as
|
||||
// not optimizable.
|
||||
//
|
||||
@@ -836,7 +836,7 @@ class GaterVisitor : public GaterBaseVisitor {
|
||||
// No reason to iterate.
|
||||
}
|
||||
|
||||
virtual void visit(AstSenItem* nodep, AstNUser*) {
|
||||
virtual void visit(AstSenItem* nodep) {
|
||||
if (!nodep->isClocked()) {
|
||||
nonOptimizable(nodep, "Non-clocked sensitivity");
|
||||
}
|
||||
@@ -844,7 +844,7 @@ class GaterVisitor : public GaterBaseVisitor {
|
||||
}
|
||||
|
||||
//--------------------
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
if (m_nonopt=="") { // Else accelerate
|
||||
iterateChildrenAlw(nodep, false);
|
||||
}
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+19
-13
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -108,6 +108,12 @@ private:
|
||||
// HIGHEDGE: var
|
||||
// LOWEDGE: ~var
|
||||
AstNode* newp = NULL;
|
||||
if (nodep->edgeType()==AstEdgeType::ET_ILLEGAL) {
|
||||
if (!v3Global.opt.bboxUnsup()) {
|
||||
nodep->v3error("Unsupported: Complicated event expression in sensitive activity list");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
AstVarScope* clkvscp = nodep->varrefp()->varScopep();
|
||||
if (nodep->edgeType()==AstEdgeType::ET_POSEDGE) {
|
||||
AstVarScope* lastVscp = getCreateLastClk(clkvscp);
|
||||
@@ -182,11 +188,11 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstTopScope* nodep, AstNUser*) {
|
||||
virtual void visit(AstTopScope* nodep) {
|
||||
UINFO(4," TOPSCOPE "<<nodep<<endl);
|
||||
m_topScopep=nodep;
|
||||
m_scopep = nodep->scopep();
|
||||
if (!m_scopep) nodep->v3fatalSrc("No scope found on top level, perhaps you have no statements?\n");
|
||||
if (!m_scopep) nodep->v3fatalSrc("No scope found on top level, perhaps you have no statements?");
|
||||
//VV***** We reset all user1p()
|
||||
AstNode::user1ClearTree();
|
||||
// Make top functions
|
||||
@@ -243,14 +249,14 @@ private:
|
||||
m_topScopep=NULL;
|
||||
m_scopep = NULL;
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
//UINFO(4," MOD "<<nodep<<endl);
|
||||
m_modp = nodep;
|
||||
m_stableNum = 0;
|
||||
nodep->iterateChildren(*this);
|
||||
m_modp= NULL;
|
||||
}
|
||||
virtual void visit(AstScope* nodep, AstNUser*) {
|
||||
virtual void visit(AstScope* nodep) {
|
||||
//UINFO(4," SCOPE "<<nodep<<endl);
|
||||
m_scopep = nodep;
|
||||
nodep->iterateChildren(*this);
|
||||
@@ -261,7 +267,7 @@ private:
|
||||
}
|
||||
m_scopep = NULL;
|
||||
}
|
||||
virtual void visit(AstAlways* nodep, AstNUser*) {
|
||||
virtual void visit(AstAlways* nodep) {
|
||||
AstNode* cmtp = new AstComment(nodep->fileline(), nodep->typeName());
|
||||
nodep->replaceWith(cmtp);
|
||||
if (AstNode* stmtsp = nodep->bodysp()) {
|
||||
@@ -270,7 +276,7 @@ private:
|
||||
}
|
||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
virtual void visit(AstAlwaysPost* nodep, AstNUser*) {
|
||||
virtual void visit(AstAlwaysPost* nodep) {
|
||||
AstNode* cmtp = new AstComment(nodep->fileline(), nodep->typeName());
|
||||
nodep->replaceWith(cmtp);
|
||||
if (AstNode* stmtsp = nodep->bodysp()) {
|
||||
@@ -279,7 +285,7 @@ private:
|
||||
}
|
||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
virtual void visit(AstCoverToggle* nodep, AstNUser*) {
|
||||
virtual void visit(AstCoverToggle* nodep) {
|
||||
//nodep->dumpTree(cout,"ct:");
|
||||
//COVERTOGGLE(INC, ORIG, CHANGE) ->
|
||||
// IF(ORIG ^ CHANGE) { INC; CHANGE = ORIG; }
|
||||
@@ -299,7 +305,7 @@ private:
|
||||
origp->cloneTree(false)));
|
||||
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
virtual void visit(AstInitial* nodep, AstNUser*) {
|
||||
virtual void visit(AstInitial* nodep) {
|
||||
AstNode* cmtp = new AstComment(nodep->fileline(), nodep->typeName());
|
||||
nodep->replaceWith(cmtp);
|
||||
if (AstNode* stmtsp = nodep->bodysp()) {
|
||||
@@ -308,7 +314,7 @@ private:
|
||||
}
|
||||
nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep, AstNUser*) {
|
||||
virtual void visit(AstCFunc* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
// Link to global function
|
||||
if (nodep->formCallTree()) {
|
||||
@@ -318,7 +324,7 @@ private:
|
||||
m_finalFuncp->addStmtsp(callp);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSenTree* nodep, AstNUser*) {
|
||||
virtual void visit(AstSenTree* nodep) {
|
||||
// Delete it later; Actives still pointing to it
|
||||
nodep->unlinkFrBack();
|
||||
pushDeletep(nodep);
|
||||
@@ -335,7 +341,7 @@ private:
|
||||
if (m_untilp) m_untilp->addBodysp(stmtsp); // In a until loop, add to body
|
||||
else m_initFuncp->addStmtsp(stmtsp); // else add to top level function
|
||||
}
|
||||
virtual void visit(AstActive* nodep, AstNUser*) {
|
||||
virtual void visit(AstActive* nodep) {
|
||||
// Careful if adding variables here, ACTIVES can be under other ACTIVES
|
||||
// Need to save and restore any member state in AstUntilStable block
|
||||
if (!m_topScopep || !nodep->stmtsp()) {
|
||||
@@ -380,7 +386,7 @@ private:
|
||||
|
||||
//--------------------
|
||||
// Default: Just iterate
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+15
-15
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -134,13 +134,13 @@ public:
|
||||
}
|
||||
private:
|
||||
// VISITORS
|
||||
virtual void visit(AstCCall* nodep, AstNUser*) {
|
||||
virtual void visit(AstCCall* nodep) {
|
||||
addCall(nodep);
|
||||
}
|
||||
// Speed things up
|
||||
virtual void visit(AstNodeAssign* nodep, AstNUser*) {}
|
||||
virtual void visit(AstNodeMath* nodep, AstNUser*) {}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeAssign* nodep) {}
|
||||
virtual void visit(AstNodeMath* nodep) {}
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
@@ -163,7 +163,7 @@ private:
|
||||
// OUTPUT:
|
||||
// AstNode::user3() -> bool. True to indicate duplicated
|
||||
// VISITORS
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->user3(true);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
@@ -239,7 +239,7 @@ private:
|
||||
V3Hash hashval = it->first;
|
||||
AstNode* node1p = it->second;
|
||||
if (!node1p->castCFunc()) continue;
|
||||
if (hashval.isIllegal()) node1p->v3fatalSrc("Illegal (unhashed) nodes\n");
|
||||
if (hashval.isIllegal()) node1p->v3fatalSrc("Illegal (unhashed) nodes");
|
||||
for (V3Hashed::iterator eqit = it; eqit != m_hashed.end(); ++eqit) {
|
||||
AstNode* node2p = eqit->second;
|
||||
if (!(eqit->first == hashval)) break;
|
||||
@@ -389,7 +389,7 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
virtual void visit(AstNetlist* nodep) {
|
||||
// Track all callers of each function
|
||||
m_call.main(nodep);
|
||||
//
|
||||
@@ -398,7 +398,7 @@ private:
|
||||
// Required so that a module instantiating another can benefit from collapsing.
|
||||
nodep->iterateChildrenBackwards(*this);
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
UINFO(4," MOD "<<nodep<<endl);
|
||||
m_modp = nodep;
|
||||
m_modNFuncs = 0;
|
||||
@@ -426,7 +426,7 @@ private:
|
||||
}
|
||||
m_modp = NULL;
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep, AstNUser*) {
|
||||
virtual void visit(AstCFunc* nodep) {
|
||||
m_funcp = nodep;
|
||||
if (!nodep->dontCombine()) {
|
||||
if (m_state == STATE_HASH) {
|
||||
@@ -437,7 +437,7 @@ private:
|
||||
}
|
||||
m_funcp = NULL;
|
||||
}
|
||||
virtual void visit(AstNodeStmt* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeStmt* nodep) {
|
||||
if (m_state == STATE_HASH && m_funcp) {
|
||||
hashStatement(nodep);
|
||||
}
|
||||
@@ -448,10 +448,10 @@ private:
|
||||
|
||||
//--------------------
|
||||
// Default: Just iterate
|
||||
virtual void visit(AstVar*, AstNUser*) {}
|
||||
virtual void visit(AstTraceDecl*, AstNUser*) {}
|
||||
virtual void visit(AstTraceInc*, AstNUser*) {}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstVar*) {}
|
||||
virtual void visit(AstTraceDecl*) {}
|
||||
virtual void visit(AstTraceInc*) {}
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2010-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2010-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2010-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2010-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+56
-42
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -47,10 +47,10 @@ class ConstVarMarkVisitor : public AstNVisitor {
|
||||
// AstVar::user4p -> bool, Var marked, 0=not set yet
|
||||
private:
|
||||
// VISITORS
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstVarRef* nodep) {
|
||||
if (nodep->varp()) nodep->varp()->user4(1);
|
||||
}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
@@ -69,17 +69,17 @@ class ConstVarFindVisitor : public AstNVisitor {
|
||||
bool m_found;
|
||||
private:
|
||||
// VISITORS
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstVarRef* nodep) {
|
||||
if (nodep->varp() && nodep->varp()->user4()) m_found = true;
|
||||
}
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
// CONSTUCTORS
|
||||
explicit ConstVarFindVisitor(AstNode* nodep) {
|
||||
m_found = false;
|
||||
nodep->iterateAndNext(*this, NULL);
|
||||
nodep->iterateAndNext(*this);
|
||||
}
|
||||
virtual ~ConstVarFindVisitor() {}
|
||||
// METHODS
|
||||
@@ -555,7 +555,7 @@ private:
|
||||
// Replace oldp node with a constant set to specified value
|
||||
UASSERT (oldp, "Null old\n");
|
||||
if (oldp->castConst() && !oldp->castConst()->num().isFourState()) {
|
||||
oldp->v3fatalSrc("Already constant??\n");
|
||||
oldp->v3fatalSrc("Already constant??");
|
||||
}
|
||||
AstNode* newp = new AstConst(oldp->fileline(), num);
|
||||
newp->dtypeFrom(oldp);
|
||||
@@ -808,8 +808,8 @@ private:
|
||||
// like a AstExtend{$rhsp}, but we need to set the width correctly from base node
|
||||
arg0p->unlinkFrBack();
|
||||
AstNode* newp = (nodep->castExtendS()
|
||||
? (new AstExtendS(nodep->fileline(), arg0p))->castNode()
|
||||
: (new AstExtend (nodep->fileline(), arg0p))->castNode());
|
||||
? static_cast<AstNode*>(new AstExtendS(nodep->fileline(), arg0p))
|
||||
: static_cast<AstNode*>(new AstExtend (nodep->fileline(), arg0p)));
|
||||
newp->dtypeFrom(nodep);
|
||||
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
@@ -1195,23 +1195,23 @@ private:
|
||||
//----------------------------------------
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
virtual void visit(AstNetlist* nodep) {
|
||||
// Iterate modules backwards, in bottom-up order. That's faster
|
||||
nodep->iterateChildrenBackwards(*this);
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
m_modp = nodep;
|
||||
nodep->iterateChildren(*this);
|
||||
m_modp = NULL;
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep, AstNUser*) {
|
||||
virtual void visit(AstCFunc* nodep) {
|
||||
// No ASSIGNW removals under funcs, we've long eliminated INITIALs
|
||||
// (We should perhaps rename the assignw's to just assigns)
|
||||
m_wremove = false;
|
||||
nodep->iterateChildren(*this);
|
||||
m_wremove = true;
|
||||
}
|
||||
virtual void visit(AstScope* nodep, AstNUser*) {
|
||||
virtual void visit(AstScope* nodep) {
|
||||
// No ASSIGNW removals under scope, we've long eliminated INITIALs
|
||||
m_scopep = nodep;
|
||||
m_wremove = false;
|
||||
@@ -1284,16 +1284,16 @@ private:
|
||||
}
|
||||
|
||||
// Special cases
|
||||
virtual void visit(AstConst* nodep, AstNUser*) {} // Already constant
|
||||
virtual void visit(AstConst* nodep) {} // Already constant
|
||||
|
||||
virtual void visit(AstCell* nodep, AstNUser*) {
|
||||
virtual void visit(AstCell* nodep) {
|
||||
if (m_params) {
|
||||
nodep->paramsp()->iterateAndNext(*this);
|
||||
} else {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstPin* nodep, AstNUser*) {
|
||||
virtual void visit(AstPin* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
@@ -1414,14 +1414,14 @@ private:
|
||||
nodep->replaceWith(fromp); nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstAttrOf* nodep, AstNUser*) {
|
||||
virtual void visit(AstAttrOf* nodep) {
|
||||
AstAttrOf* oldAttr = m_attrp;
|
||||
m_attrp = nodep;
|
||||
nodep->iterateChildren(*this);
|
||||
m_attrp = oldAttr;
|
||||
}
|
||||
|
||||
virtual void visit(AstArraySel* nodep, AstNUser*) {
|
||||
virtual void visit(AstArraySel* nodep) {
|
||||
nodep->bitp()->iterateAndNext(*this);
|
||||
if (nodep->bitp()->castConst()
|
||||
&& nodep->fromp()->castVarRef()
|
||||
@@ -1435,12 +1435,17 @@ private:
|
||||
if (!m_selp) {
|
||||
nodep->v3error("Illegal assignment of constant to unpacked array");
|
||||
} else {
|
||||
nodep->replaceWith(nodep->fromp()->unlinkFrBack());
|
||||
AstNode* fromp = nodep->fromp()->unlinkFrBack();
|
||||
nodep->replaceWith(fromp);
|
||||
if (fromp->dtypep()->skipRefp()->castNodeArrayDType()) {
|
||||
// Strip off array to find what array references
|
||||
fromp->dtypeFrom(fromp->dtypep()->skipRefp()->castNodeArrayDType()->subDTypep());
|
||||
}
|
||||
}
|
||||
}
|
||||
m_selp = NULL;
|
||||
}
|
||||
virtual void visit(AstNodeVarRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeVarRef* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (!nodep->varp()) nodep->v3fatalSrc("Not linked");
|
||||
bool did=false;
|
||||
@@ -1486,13 +1491,21 @@ private:
|
||||
did=true;
|
||||
}
|
||||
}
|
||||
else if (m_params && valuep->castInitArray() && nodep->backp()->castPin()) {
|
||||
// Allow parameters to pass arrays
|
||||
// Earlier recursion of InitArray made sure each array value is constant
|
||||
// This exception is fairly fragile, i.e. doesn't support arrays of arrays or other stuff
|
||||
AstNode* newp = valuep->cloneTree(false);
|
||||
nodep->replaceWith(newp); nodep->deleteTree(); VL_DANGLING(nodep);
|
||||
did = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!did && m_required) {
|
||||
nodep->v3error("Expecting expression to be constant, but variable isn't const: "<<nodep->varp()->prettyName());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstEnumItemRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstEnumItemRef* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (!nodep->itemp()) nodep->v3fatalSrc("Not linked");
|
||||
bool did=false;
|
||||
@@ -1510,7 +1523,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
// virtual void visit(AstCvtPackString* nodep, AstNUser*) {
|
||||
// virtual void visit(AstCvtPackString* nodep) {
|
||||
// Not constant propagated (for today) because AstMath::isOpaque is set
|
||||
// Someday if lower is constant, convert to quoted "string".
|
||||
|
||||
@@ -1518,7 +1531,7 @@ private:
|
||||
// Only one if it's not in a list
|
||||
return (!nodep->nextp() && nodep->backp()->nextp() != nodep);
|
||||
}
|
||||
virtual void visit(AstSenItem* nodep, AstNUser*) {
|
||||
virtual void visit(AstSenItem* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_doNConst
|
||||
&& (nodep->sensp()->castConst()
|
||||
@@ -1554,11 +1567,12 @@ private:
|
||||
} else if (!m_doNConst // Deal with later when doNConst missing
|
||||
&& (nodep->sensp()->castEnumItemRef()
|
||||
|| nodep->sensp()->castConst())) {
|
||||
} else if (nodep->isIllegal()) { // Deal with later
|
||||
} else {
|
||||
if (nodep->hasVar() && !nodep->varrefp()) nodep->v3fatalSrc("Null sensitivity variable");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSenGate* nodep, AstNUser*) {
|
||||
virtual void visit(AstSenGate* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (AstConst* constp = nodep->rhsp()->castConst()) {
|
||||
if (constp->isZero()) {
|
||||
@@ -1604,7 +1618,7 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
virtual void visit(AstSenTree* nodep, AstNUser*) {
|
||||
virtual void visit(AstSenTree* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_doExpensive) {
|
||||
//cout<<endl; nodep->dumpTree(cout,"ssin: ");
|
||||
@@ -1708,17 +1722,17 @@ private:
|
||||
|
||||
//-----
|
||||
// Zero elimination
|
||||
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeAssign* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_doNConst && replaceNodeAssign(nodep)) return;
|
||||
}
|
||||
virtual void visit(AstAssignAlias* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssignAlias* nodep) {
|
||||
// Don't perform any optimizations, keep the alias around
|
||||
}
|
||||
virtual void visit(AstAssignVarScope* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssignVarScope* nodep) {
|
||||
// Don't perform any optimizations, the node won't be linked yet
|
||||
}
|
||||
virtual void visit(AstAssignW* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssignW* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_doNConst && replaceNodeAssign(nodep)) return;
|
||||
AstNodeVarRef* varrefp = nodep->lhsp()->castVarRef(); // Not VarXRef, as different refs may set different values to each hierarchy
|
||||
@@ -1745,7 +1759,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeIf* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeIf* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_doNConst) {
|
||||
if (AstConst* constp = nodep->condp()->castConst()) {
|
||||
@@ -1823,7 +1837,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstSFormatF* nodep, AstNUser*) {
|
||||
virtual void visit(AstSFormatF* nodep) {
|
||||
// Substitute constants into displays. The main point of this is to
|
||||
// simplify assertion methodologies which call functions with display's.
|
||||
// This eliminates a pile of wide temps, and makes the C a whole lot more readable.
|
||||
@@ -1885,17 +1899,17 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstFuncRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstFuncRef* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_params) { // Only parameters force us to do constant function call propagation
|
||||
replaceWithSimulation(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstArg* nodep, AstNUser*) {
|
||||
virtual void visit(AstArg* nodep) {
|
||||
// replaceWithSimulation on the Arg's parent FuncRef replaces these
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstWhile* nodep, AstNUser*) {
|
||||
virtual void visit(AstWhile* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_doNConst) {
|
||||
if (nodep->condp()->isZero()) {
|
||||
@@ -1909,17 +1923,17 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstInitArray* nodep, AstNUser*) {
|
||||
virtual void visit(AstInitArray* nodep) {
|
||||
// Constant if all children are constant
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
// These are converted by V3Param. Don't constify as we don't want the from() VARREF to disappear, if any
|
||||
// If output of a presel didn't get consted, chances are V3Param didn't visit properly
|
||||
virtual void visit(AstNodePreSel* nodep, AstNUser*) {}
|
||||
virtual void visit(AstNodePreSel* nodep) {}
|
||||
|
||||
// Ignored, can eliminate early
|
||||
virtual void visit(AstSysIgnore* nodep, AstNUser*) {
|
||||
virtual void visit(AstSysIgnore* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_doNConst) {
|
||||
nodep->unlinkFrBack()->deleteTree(); VL_DANGLING(nodep);
|
||||
@@ -1927,7 +1941,7 @@ private:
|
||||
}
|
||||
|
||||
// Simplify
|
||||
virtual void visit(AstBasicDType* nodep, AstNUser*) {
|
||||
virtual void visit(AstBasicDType* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->cvtRangeConst();
|
||||
}
|
||||
@@ -1935,12 +1949,12 @@ private:
|
||||
//-----
|
||||
// Jump elimination
|
||||
|
||||
virtual void visit(AstJumpGo* nodep, AstNUser*) {
|
||||
virtual void visit(AstJumpGo* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_doExpensive) { nodep->labelp()->user4(true); }
|
||||
}
|
||||
|
||||
virtual void visit(AstJumpLabel* nodep, AstNUser*) {
|
||||
virtual void visit(AstJumpLabel* nodep) {
|
||||
// Because JumpLabels disable many optimizations,
|
||||
// remove JumpLabels that are not pointed to by any AstJumpGos
|
||||
// Note this assumes all AstJumpGos are underneath the given label; V3Broken asserts this
|
||||
@@ -2269,7 +2283,7 @@ private:
|
||||
// Note we can't convert EqCase/NeqCase to Eq/Neq here because that would break 3'b1x1==3'b101
|
||||
|
||||
//-----
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
// Default: Just iterate
|
||||
if (m_required) {
|
||||
if (nodep->castNodeDType() || nodep->castRange()) {
|
||||
@@ -2329,7 +2343,7 @@ public:
|
||||
virtual ~ConstVisitor() {}
|
||||
AstNode* mainAcceptEdit(AstNode* nodep) {
|
||||
// Operate starting at a random place
|
||||
return nodep->acceptSubtreeReturnEdits(*this);
|
||||
return nodep->iterateSubtreeReturnEdits(*this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+12
-12
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -83,10 +83,10 @@ private:
|
||||
const char* varIgnoreToggle(AstVar* nodep) {
|
||||
// Return true if this shouldn't be traced
|
||||
// See also similar rule in V3TraceDecl::varIgnoreTrace
|
||||
string prettyName = nodep->prettyName();
|
||||
if (!nodep->isToggleCoverable())
|
||||
return "Not relevant signal type";
|
||||
if (!v3Global.opt.coverageUnderscore()) {
|
||||
string prettyName = nodep->prettyName();
|
||||
if (prettyName[0] == '_')
|
||||
return "Leading underscore";
|
||||
if (prettyName.find("._") != string::npos)
|
||||
@@ -128,7 +128,7 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS - BOTH
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
m_modp = nodep;
|
||||
m_inModOff = nodep->isTop(); // Ignore coverage on top module; it's a shell we created
|
||||
m_fileps.clear();
|
||||
@@ -138,7 +138,7 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS - TOGGLE COVERAGE
|
||||
virtual void visit(AstNodeFTask* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeFTask* nodep) {
|
||||
bool oldtog = m_inToggleOff;
|
||||
{
|
||||
m_inToggleOff = true;
|
||||
@@ -146,7 +146,7 @@ private:
|
||||
}
|
||||
m_inToggleOff = oldtog;
|
||||
}
|
||||
virtual void visit(AstVar* nodep, AstNUser*) {
|
||||
virtual void visit(AstVar* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_modp && !m_inModOff && !m_inToggleOff
|
||||
&& nodep->fileline()->coverageOn() && v3Global.opt.coverageToggle()) {
|
||||
@@ -279,7 +279,7 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS - LINE COVERAGE
|
||||
virtual void visit(AstIf* nodep, AstNUser*) { // Note not AstNodeIf; other types don't get covered
|
||||
virtual void visit(AstIf* nodep) { // Note not AstNodeIf; other types don't get covered
|
||||
UINFO(4," IF: "<<nodep<<endl);
|
||||
if (m_checkBlock) {
|
||||
// An else-if. When we iterate the if, use "elsif" marking
|
||||
@@ -312,7 +312,7 @@ private:
|
||||
m_checkBlock = true; // Reset as a child may have cleared it
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCaseItem* nodep, AstNUser*) {
|
||||
virtual void visit(AstCaseItem* nodep) {
|
||||
UINFO(4," CASEI: "<<nodep<<endl);
|
||||
if (m_checkBlock && !m_inModOff
|
||||
&& nodep->fileline()->coverageOn() && v3Global.opt.coverageLine()) {
|
||||
@@ -324,7 +324,7 @@ private:
|
||||
m_checkBlock = true; // Reset as a child may have cleared it
|
||||
}
|
||||
}
|
||||
virtual void visit(AstPslCover* nodep, AstNUser*) {
|
||||
virtual void visit(AstPslCover* nodep) {
|
||||
UINFO(4," PSLCOVER: "<<nodep<<endl);
|
||||
m_checkBlock = true; // Always do cover blocks, even if there's a $stop
|
||||
nodep->iterateChildren(*this);
|
||||
@@ -334,11 +334,11 @@ private:
|
||||
}
|
||||
m_checkBlock = true; // Reset as a child may have cleared it
|
||||
}
|
||||
virtual void visit(AstStop* nodep, AstNUser*) {
|
||||
virtual void visit(AstStop* nodep) {
|
||||
UINFO(4," STOP: "<<nodep<<endl);
|
||||
m_checkBlock = false;
|
||||
}
|
||||
virtual void visit(AstPragma* nodep, AstNUser*) {
|
||||
virtual void visit(AstPragma* nodep) {
|
||||
if (nodep->pragType() == AstPragmaType::COVERAGE_BLOCK_OFF) {
|
||||
// Skip all NEXT nodes under this block, and skip this if/case branch
|
||||
UINFO(4," OFF: "<<nodep<<endl);
|
||||
@@ -348,7 +348,7 @@ private:
|
||||
if (m_checkBlock) nodep->iterateChildren(*this);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstBegin* nodep, AstNUser*) {
|
||||
virtual void visit(AstBegin* nodep) {
|
||||
// Record the hierarchy of any named begins, so we can apply to user
|
||||
// coverage points. This is because there may be cov points inside
|
||||
// generate blocks; each point should get separate consideration.
|
||||
@@ -368,7 +368,7 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS - BOTH
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
// Default: Just iterate
|
||||
if (m_checkBlock) {
|
||||
nodep->iterateChildren(*this);
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -103,19 +103,19 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
virtual void visit(AstNetlist* nodep) {
|
||||
// Find all Coverage's
|
||||
nodep->iterateChildren(*this);
|
||||
// Simplify
|
||||
detectDuplicates();
|
||||
}
|
||||
virtual void visit(AstCoverToggle* nodep, AstNUser*) {
|
||||
virtual void visit(AstCoverToggle* nodep) {
|
||||
m_toggleps.push_back(nodep);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
//--------------------
|
||||
virtual void visit(AstNodeMath* nodep, AstNUser*) {} // Accelerate
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeMath* nodep) {} // Accelerate
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+19
-19
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -58,13 +58,13 @@ private:
|
||||
// NODE STATE
|
||||
// ** Shared with DeadVisitor **
|
||||
// VISITORS
|
||||
virtual void visit(AstCell* nodep, AstNUser*) {
|
||||
virtual void visit(AstCell* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->modp()->user1Inc(-1);
|
||||
}
|
||||
//-----
|
||||
virtual void visit(AstNodeMath* nodep, AstNUser*) {} // Accelerate
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeMath* nodep) {} // Accelerate
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
public:
|
||||
@@ -135,18 +135,18 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
m_modp = nodep;
|
||||
nodep->iterateChildren(*this);
|
||||
checkAll(nodep);
|
||||
m_modp = NULL;
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep, AstNUser*) {
|
||||
virtual void visit(AstCFunc* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
checkAll(nodep);
|
||||
if (nodep->scopep()) nodep->scopep()->user1Inc();
|
||||
}
|
||||
virtual void visit(AstScope* nodep, AstNUser*) {
|
||||
virtual void visit(AstScope* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
checkAll(nodep);
|
||||
if (nodep->aboveScopep()) nodep->aboveScopep()->user1Inc();
|
||||
@@ -155,14 +155,14 @@ private:
|
||||
m_scopesp.push_back(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstCell* nodep, AstNUser*) {
|
||||
virtual void visit(AstCell* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
checkAll(nodep);
|
||||
m_cellsp.push_back(nodep);
|
||||
nodep->modp()->user1Inc();
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeVarRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeVarRef* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
checkAll(nodep);
|
||||
if (nodep->varScopep()) {
|
||||
@@ -177,7 +177,7 @@ private:
|
||||
else nodep->packagep()->user1Inc();
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeFTaskRef* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
checkAll(nodep);
|
||||
if (nodep->packagep()) {
|
||||
@@ -185,7 +185,7 @@ private:
|
||||
else nodep->packagep()->user1Inc();
|
||||
}
|
||||
}
|
||||
virtual void visit(AstRefDType* nodep, AstNUser*) {
|
||||
virtual void visit(AstRefDType* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
checkDType(nodep);
|
||||
checkAll(nodep);
|
||||
@@ -194,12 +194,12 @@ private:
|
||||
else nodep->packagep()->user1Inc();
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeDType* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeDType* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
checkDType(nodep);
|
||||
checkAll(nodep);
|
||||
}
|
||||
virtual void visit(AstEnumItemRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstEnumItemRef* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
checkAll(nodep);
|
||||
if (nodep->packagep()) {
|
||||
@@ -208,7 +208,7 @@ private:
|
||||
}
|
||||
checkAll(nodep);
|
||||
}
|
||||
virtual void visit(AstModport* nodep, AstNUser*) {
|
||||
virtual void visit(AstModport* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_elimCells) {
|
||||
if (!nodep->varsp()) {
|
||||
@@ -218,7 +218,7 @@ private:
|
||||
}
|
||||
checkAll(nodep);
|
||||
}
|
||||
virtual void visit(AstTypedef* nodep, AstNUser*) {
|
||||
virtual void visit(AstTypedef* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_elimCells && !nodep->attrPublic()) {
|
||||
pushDeletep(nodep->unlinkFrBack()); VL_DANGLING(nodep);
|
||||
@@ -229,7 +229,7 @@ private:
|
||||
// Normal modules may disappear, e.g. if they are parameterized then removed
|
||||
if (nodep->attrPublic() && m_modp && m_modp->castPackage()) m_modp->user1Inc();
|
||||
}
|
||||
virtual void visit(AstVarScope* nodep, AstNUser*) {
|
||||
virtual void visit(AstVarScope* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
checkAll(nodep);
|
||||
if (nodep->scopep()) nodep->scopep()->user1Inc();
|
||||
@@ -237,7 +237,7 @@ private:
|
||||
m_vscsp.push_back(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVar* nodep, AstNUser*) {
|
||||
virtual void visit(AstVar* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
checkAll(nodep);
|
||||
if (nodep->isSigPublic() && m_modp && m_modp->castPackage()) m_modp->user1Inc();
|
||||
@@ -245,7 +245,7 @@ private:
|
||||
m_varsp.push_back(nodep);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeAssign* nodep) {
|
||||
// See if simple assignments to variables may be eliminated because that variable is never used.
|
||||
// Similar code in V3Life
|
||||
m_sideEffect = false;
|
||||
@@ -264,7 +264,7 @@ private:
|
||||
}
|
||||
|
||||
//-----
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
if (nodep->isOutputter()) m_sideEffect=true;
|
||||
nodep->iterateChildren(*this);
|
||||
checkAll(nodep);
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+21
-21
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -207,8 +207,8 @@ private:
|
||||
dimvalp.push_front(valp);
|
||||
}
|
||||
AstVarRef* varrefp = dimselp->castVarRef();
|
||||
if (!varrefp) nodep->v3fatalSrc("No var underneath arraysels\n");
|
||||
if (!varrefp->varScopep()) varrefp->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp\n");
|
||||
if (!varrefp) nodep->v3fatalSrc("No var underneath arraysels");
|
||||
if (!varrefp->varScopep()) varrefp->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp");
|
||||
varrefp->unlinkFrBack();
|
||||
AstVar* oldvarp = varrefp->varp();
|
||||
int modVecNum = oldvarp->user4(); oldvarp->user4(modVecNum+1);
|
||||
@@ -268,7 +268,7 @@ private:
|
||||
// then we told this nodep->user3 we can use its Vdlyvset rather than making a new one.
|
||||
// This is good for code like:
|
||||
// for (i=0; i<5; i++) vector[i] <= something;
|
||||
setvscp = nodep->user3p()->castNode()->castVarScope();
|
||||
setvscp = nodep->user3p()->castVarScope();
|
||||
++m_statSharedSet;
|
||||
} else { // Create new one
|
||||
string setvarname = (string("__Vdlyvset__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
|
||||
@@ -303,9 +303,9 @@ private:
|
||||
// Build "IF (changeit) ...
|
||||
UINFO(9," For "<<setvscp<<endl);
|
||||
UINFO(9," & "<<varrefp<<endl);
|
||||
AstAlwaysPost* finalp = varrefp->varScopep()->user4p()->castNode()->castAlwaysPost();
|
||||
AstAlwaysPost* finalp = varrefp->varScopep()->user4p()->castAlwaysPost();
|
||||
if (finalp) {
|
||||
AstActive* oldactivep = finalp->user2p()->castNode()->castActive();
|
||||
AstActive* oldactivep = finalp->user2p()->castActive();
|
||||
checkActivePost(varrefp, oldactivep);
|
||||
if (setinitp) oldactivep->addStmtsp(setinitp);
|
||||
} else { // first time we've dealt with this memory
|
||||
@@ -318,10 +318,10 @@ private:
|
||||
if (setinitp) newactp->addStmtsp(setinitp);
|
||||
}
|
||||
AstIf* postLogicp;
|
||||
if (finalp->user3p()->castNode() == setvscp) {
|
||||
if (finalp->user3p() == setvscp) {
|
||||
// Optimize as above; if sharing Vdlyvset *ON SAME VARIABLE*,
|
||||
// we can share the IF statement too
|
||||
postLogicp = finalp->user4p()->castNode()->castIf();
|
||||
postLogicp = finalp->user4p()->castIf();
|
||||
if (!postLogicp) nodep->v3fatalSrc("Delayed assignment misoptimized; prev var found w/o associated IF");
|
||||
} else {
|
||||
postLogicp = new AstIf (nodep->fileline(),
|
||||
@@ -338,22 +338,22 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
virtual void visit(AstNetlist* nodep) {
|
||||
//VV***** We reset all userp() on the netlist
|
||||
m_modVarMap.clear();
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstScope* nodep, AstNUser*) {
|
||||
virtual void visit(AstScope* nodep) {
|
||||
UINFO(4," MOD "<<nodep<<endl);
|
||||
AstNode::user3ClearTree();
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep, AstNUser*) {
|
||||
virtual void visit(AstCFunc* nodep) {
|
||||
m_cfuncp = nodep;
|
||||
nodep->iterateChildren(*this);
|
||||
m_cfuncp = NULL;
|
||||
}
|
||||
virtual void visit(AstActive* nodep, AstNUser*) {
|
||||
virtual void visit(AstActive* nodep) {
|
||||
m_activep = nodep;
|
||||
bool oldinit = m_inInitial;
|
||||
m_inInitial = nodep->hasInitial();
|
||||
@@ -361,7 +361,7 @@ private:
|
||||
nodep->iterateChildren(*this);
|
||||
m_inInitial = oldinit;
|
||||
}
|
||||
virtual void visit(AstAssignDly* nodep, AstNUser*) {
|
||||
virtual void visit(AstAssignDly* nodep) {
|
||||
m_inDly = true;
|
||||
m_nextDlyp = nodep->nextp()->castAssignDly(); // Next assignment in same block, maybe NULL.
|
||||
if (m_cfuncp) nodep->v3error("Unsupported: Delayed assignment inside public function/task");
|
||||
@@ -385,7 +385,7 @@ private:
|
||||
m_nextDlyp = NULL;
|
||||
}
|
||||
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
virtual void visit(AstVarRef* nodep) {
|
||||
if (!nodep->user2Inc()) { // Not done yet
|
||||
if (m_inDly && nodep->lvalue()) {
|
||||
UINFO(4,"AssignDlyVar: "<<nodep<<endl);
|
||||
@@ -393,10 +393,10 @@ private:
|
||||
if (!m_activep) nodep->v3fatalSrc("<= not under sensitivity block");
|
||||
if (!m_activep->hasClocked()) nodep->v3error("Internal: Blocking <= assignment in non-clocked block, should have converted in V3Active");
|
||||
AstVarScope* oldvscp = nodep->varScopep();
|
||||
if (!oldvscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp\n");
|
||||
AstVarScope* dlyvscp = oldvscp->user1p()->castNode()->castVarScope();
|
||||
if (!oldvscp) nodep->v3fatalSrc("Var didn't get varscoped in V3Scope.cpp");
|
||||
AstVarScope* dlyvscp = oldvscp->user1p()->castVarScope();
|
||||
if (dlyvscp) { // Multiple use of delayed variable
|
||||
AstActive* oldactivep = dlyvscp->user2p()->castNode()->castActive();
|
||||
AstActive* oldactivep = dlyvscp->user2p()->castActive();
|
||||
checkActivePost(nodep, oldactivep);
|
||||
}
|
||||
if (!dlyvscp) { // First use of this delayed variable
|
||||
@@ -432,10 +432,10 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeFor* nodep, AstNUser*) {
|
||||
nodep->v3fatalSrc("For statements should have been converted to while statements in V3Begin\n");
|
||||
virtual void visit(AstNodeFor* nodep) {
|
||||
nodep->v3fatalSrc("For statements should have been converted to while statements in V3Begin");
|
||||
}
|
||||
virtual void visit(AstWhile* nodep, AstNUser*) {
|
||||
virtual void visit(AstWhile* nodep) {
|
||||
bool oldloop = m_inLoop;
|
||||
m_inLoop = true;
|
||||
nodep->iterateChildren(*this);
|
||||
@@ -444,7 +444,7 @@ private:
|
||||
|
||||
//--------------------
|
||||
// Default: Just iterate
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+10
-10
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -85,14 +85,14 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
UINFO(4," MOD "<<nodep<<endl);
|
||||
m_modp = nodep;
|
||||
m_funcp = NULL;
|
||||
nodep->iterateChildren(*this);
|
||||
m_modp = NULL;
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep, AstNUser*) {
|
||||
virtual void visit(AstCFunc* nodep) {
|
||||
m_funcp = nodep;
|
||||
m_depth = 0;
|
||||
m_maxdepth = 0;
|
||||
@@ -106,13 +106,13 @@ private:
|
||||
nodep->iterateChildren(*this);
|
||||
m_stmtp = NULL;
|
||||
}
|
||||
virtual void visit(AstNodeStmt* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeStmt* nodep) {
|
||||
visitStmt(nodep);
|
||||
}
|
||||
// Operators
|
||||
virtual void visit(AstNodeTermop* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeTermop* nodep) {
|
||||
}
|
||||
virtual void visit(AstNodeMath* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeMath* nodep) {
|
||||
// We have some operator defines that use 2 parens, so += 2.
|
||||
m_depth += 2;
|
||||
if (m_depth>m_maxdepth) m_maxdepth=m_depth;
|
||||
@@ -139,19 +139,19 @@ private:
|
||||
m_funcp->isStatic(false);
|
||||
}
|
||||
}
|
||||
virtual void visit(AstUCFunc* nodep, AstNUser*) {
|
||||
virtual void visit(AstUCFunc* nodep) {
|
||||
needNonStaticFunc(nodep);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstUCStmt* nodep, AstNUser*) {
|
||||
virtual void visit(AstUCStmt* nodep) {
|
||||
needNonStaticFunc(nodep);
|
||||
visitStmt(nodep);
|
||||
}
|
||||
|
||||
//--------------------
|
||||
// Default: Just iterate
|
||||
virtual void visit(AstVar* nodep, AstNUser*) {} // Don't hit varrefs under vars
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstVar* nodep) {} // Don't hit varrefs under vars
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2016 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2017 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -76,14 +76,14 @@ private:
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeModule* nodep) {
|
||||
UINFO(4," MOD "<<nodep<<endl);
|
||||
m_modp = nodep;
|
||||
m_deepNum = 0;
|
||||
nodep->iterateChildren(*this);
|
||||
m_modp = NULL;
|
||||
}
|
||||
virtual void visit(AstCFunc* nodep, AstNUser*) {
|
||||
virtual void visit(AstCFunc* nodep) {
|
||||
// We recurse into this.
|
||||
int lastDepth = m_depth;
|
||||
AstCFunc* lastFuncp = m_funcp;
|
||||
@@ -111,15 +111,15 @@ private:
|
||||
}
|
||||
m_depth--;
|
||||
}
|
||||
virtual void visit(AstNodeStmt* nodep, AstNUser*) {
|
||||
virtual void visit(AstNodeStmt* nodep) {
|
||||
visitStmt(nodep);
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeMath* nodep, AstNUser*) {} // Accelerate
|
||||
virtual void visit(AstNodeMath* nodep) {} // Accelerate
|
||||
//--------------------
|
||||
// Default: Just iterate
|
||||
virtual void visit(AstVar* nodep, AstNUser*) {} // Don't hit varrefs under vars
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
virtual void visit(AstVar* nodep) {} // Don't hit varrefs under vars
|
||||
virtual void visit(AstNode* nodep) {
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user