mirror of
https://github.com/verilator/verilator.git
synced 2026-10-04 09:03:31 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0029d068c7 | ||
|
|
de388b3dc8 | ||
|
|
fb904d53cd | ||
|
|
600cc02de3 | ||
|
|
946d0cd219 | ||
|
|
4d0b964e36 | ||
|
|
2b12ab4d5a | ||
|
|
8114957e6d | ||
|
|
50edef4ab2 | ||
|
|
e5a991988f | ||
|
|
e85eb6d0f4 | ||
|
|
6949f35f22 | ||
|
|
e0391b93c4 | ||
|
|
4a5e775a2b | ||
|
|
323f019350 | ||
|
|
98053c2d4c | ||
|
|
aab338760c | ||
|
|
ab9a2b1728 | ||
|
|
6a38d3bcf3 | ||
|
|
76f3cbdf4c | ||
|
|
d45d58b6bf | ||
|
|
f32a422330 | ||
|
|
74d4be28dd | ||
|
|
b4a31bd292 | ||
|
|
cc1adf9b38 | ||
|
|
1601b3b6b0 | ||
|
|
61cbdd1a19 | ||
|
|
a3ee6131a3 | ||
|
|
6dfddaa453 | ||
|
|
de696b7092 | ||
|
|
9165233657 | ||
|
|
aa3a417e97 | ||
|
|
996f48fcf0 | ||
|
|
81d83f629f | ||
|
|
5e3b0bf348 | ||
|
|
4a31463299 | ||
|
|
8a5471e175 | ||
|
|
605fd9f8e1 | ||
|
|
2bda43875d | ||
|
|
11edc9e7a7 | ||
|
|
3b9b823511 | ||
|
|
da0ecf59c6 | ||
|
|
e5b1fdf668 | ||
|
|
204fb82975 | ||
|
|
37839e2709 | ||
|
|
dbaedb5995 | ||
|
|
0a832e90bd | ||
|
|
b4e908d04d | ||
|
|
4619d29b78 | ||
|
|
c63b697636 | ||
|
|
06d29d6fda | ||
|
|
c0f7bc4b5e | ||
|
|
7139c9ae59 | ||
|
|
0ae00fc921 | ||
|
|
fe456cb83d |
+2
-1
@@ -9,6 +9,7 @@
|
||||
.*.swp
|
||||
*.tmp
|
||||
*.tex
|
||||
*.pdf
|
||||
/Makefile
|
||||
README
|
||||
autom4te.cache
|
||||
@@ -16,8 +17,8 @@ config.cache
|
||||
config.status
|
||||
configure
|
||||
dddrun*
|
||||
doxygen-doc
|
||||
gdbrun*
|
||||
internals.txt
|
||||
verilator.pdf
|
||||
verilator.txt
|
||||
verilator_bin*
|
||||
|
||||
@@ -4,6 +4,29 @@ The contributors that suggested a given feature are shown in []. [by ...]
|
||||
indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
|
||||
* Verilator 3.833 2012/04/15
|
||||
|
||||
*** Support += and -= in standard for loops, bug463. [Alex Solomatnikov]
|
||||
|
||||
*** Fix processing unused parametrized modules, bug469, bug470. [Alex Solomatnikov]
|
||||
|
||||
**** Add SELRANGE as warning instead of error, bug477. [Alex Solomatnikov]
|
||||
|
||||
**** Add readme.pdf and internal.pdf and doxygen, bug483. [by Jeremy Bennett]
|
||||
|
||||
**** Fix change detections on arrays, bug364. [John Stevenson, Alex Solomatnikov]
|
||||
|
||||
**** Fix signed array warning, bug456. [Alex Solomatnikov]
|
||||
|
||||
**** Fix genvar and begin under generate, bug461. [Alex Solomatnikov]
|
||||
|
||||
**** Fix real constant parameter functions, bug475. [Alex Solomatnikov]
|
||||
|
||||
**** Fix and document --gdb option, bug454. [Jeremy Bennett]
|
||||
|
||||
**** Fix OpenSolaris compile error. [Sanjay Singh]
|
||||
|
||||
|
||||
* Verilator 3.832 2012/03/07
|
||||
|
||||
*** Fix memory delayed assignments from multiple clock domains. [Andrew Ling]
|
||||
@@ -56,7 +79,7 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
**** Support $system. [Ruben Diez]
|
||||
|
||||
**** Support $sscanf with %g. [Holger Wächtler]
|
||||
**** Support $sscanf with %g. [Holger Waechtler]
|
||||
|
||||
**** Indicate 'exiting due to errors' if errors, not warnings. [Ruben Diez]
|
||||
|
||||
@@ -64,7 +87,7 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
**** Fix reporting not found modules if generate-off, bug403. [Jeremy Bennett]
|
||||
|
||||
**** Fix $display with %d following %g. [Holger Wächtler]
|
||||
**** Fix $display with %d following %g. [Holger Waechtler]
|
||||
|
||||
|
||||
* Verilator 3.824 2011/10/25
|
||||
|
||||
@@ -35,3 +35,4 @@ nodist/
|
||||
/simv.daidir/
|
||||
/vc_hdrs.h$
|
||||
/csrc/
|
||||
doxygen-doc/.*
|
||||
|
||||
+37
-11
@@ -54,11 +54,13 @@ srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
HOST = @HOST@
|
||||
|
||||
DOXYGEN = doxygen
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
MAKEINFO = makeinfo
|
||||
POD2TEXT = pod2text
|
||||
POD2LATEXFIX = $(srcdir)/src/pod2latexfix
|
||||
PERL = @PERL@
|
||||
|
||||
# Destination prefix for RPMs
|
||||
@@ -100,7 +102,8 @@ SHELL = /bin/sh
|
||||
|
||||
SUBDIRS = src test_verilated test_c test_sc test_sp test_regress test_vcs
|
||||
|
||||
INFOS = README internals.txt verilator.txt verilator.html verilator.1 verilator.pdf
|
||||
INFOS = README README.html README.pdf internals.txt internals.html \
|
||||
internals.pdf verilator.txt verilator.html verilator.1 verilator.pdf
|
||||
|
||||
# Files that can be generated, but should be up to date for a distribution.
|
||||
DISTDEP = info Makefile
|
||||
@@ -110,6 +113,7 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
|
||||
Changes TODO \
|
||||
MANIFEST.SKIP \
|
||||
bin/* \
|
||||
doxygen-mainpage doxygen.config veripool-logo.png \
|
||||
install-sh configure mkinstalldirs *.pod \
|
||||
include/*.[chv]* \
|
||||
include/*.in \
|
||||
@@ -121,7 +125,8 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
|
||||
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
|
||||
test_*/*.pl test_*/*.v test_*/*.vc test_*/*.vh \
|
||||
test_verilated/vgen*.pl \
|
||||
test_regress/t/tsub/*.v* \
|
||||
test_regress/t/t*/*.sv* \
|
||||
test_regress/t/t*/*.v* \
|
||||
test_regress/t/*.cpp \
|
||||
test_regress/t/*.h \
|
||||
test_regress/t/*.dat \
|
||||
@@ -215,15 +220,7 @@ verilator.html: ${srcdir}/bin/verilator
|
||||
# PDF needs DIST variables; but having configure.ac as dependency isn't detected
|
||||
verilator.pdf: ${srcdir}/bin/verilator Makefile
|
||||
pod2latex --full --out verilator.tex ${srcdir}/bin/verilator
|
||||
cat < verilator.tex \
|
||||
| sed 's/\\begin{document}/\\usepackage[left=1.7in,right=1.7in,top=1.3in,bottom=1.3in]{geometry}\n\\begin{document}/' \
|
||||
| sed 's/\\begin{document}/\\usepackage[pdftex,bookmarks=true,bookmarksnumbered=true,hypertexnames=false,breaklinks=true,linkbordercolor={0 0 1}]{hyperref}\n\\begin{document}/' \
|
||||
| sed 's/\\begin{document}/\\usepackage{fancyhdr} \\pagestyle{fancy}\n\\begin{document}/' \
|
||||
| sed 's/\\begin{document}/\\setlength{\\parindent}{0pt} \\setlength{\\parskip}{\\baselineskip}\n\\begin{document}/' \
|
||||
| sed 's/\\begin{document}/\\title{$(DISTTITLE)} \\date{${DISTDATE}} \\author{Wilson Snyder\\\\ http:\/\/www.veripool.org}\n\\begin{document}/' \
|
||||
| sed 's/\\begin{document}/\\lhead[$(DISTTITLE)]{$(DISTTITLE)}\n\\begin{document}/' \
|
||||
| sed 's/\\tableofcontents/\\begin{titlepage} \\maketitle \\end{titlepage}\n\\tableofcontents/' \
|
||||
> verilator2.tex
|
||||
$(PERL) $(POD2LATEXFIX) "$(DISTTITLE)" "${DISTDATE}" < verilator.tex > verilator2.tex
|
||||
mv verilator2.tex verilator.tex
|
||||
pdflatex verilator.tex
|
||||
pdflatex verilator.tex
|
||||
@@ -233,10 +230,34 @@ README: readme.pod
|
||||
-rm -f $@
|
||||
$(POD2TEXT) --loose $< > $@
|
||||
|
||||
README.html: readme.pod
|
||||
pod2html $< >$@
|
||||
|
||||
# PDF needs DIST variables; but having configure.ac as dependency isn't detected
|
||||
README.pdf: readme.pod Makefile
|
||||
pod2latex --full --out README.tex readme.pod
|
||||
$(PERL) $(POD2LATEXFIX) "$(DISTTITLE) README File" "${DISTDATE}" < README.tex > README2.tex
|
||||
mv README2.tex README.tex
|
||||
pdflatex README.tex
|
||||
pdflatex README.tex
|
||||
-rm -f README.toc README.aux README.idx README.out
|
||||
|
||||
internals.txt: internals.pod
|
||||
-rm -f $@
|
||||
$(POD2TEXT) --loose $< > $@
|
||||
|
||||
internals.html: internals.pod
|
||||
pod2html $< >$@
|
||||
|
||||
# PDF needs DIST variables; but having configure.ac as dependency isn't detected
|
||||
internals.pdf: internals.pod Makefile
|
||||
pod2latex --full --out internals.tex internals.pod
|
||||
$(PERL) $(POD2LATEXFIX) "$(DISTTITLE) Internals Manual" "${DISTDATE}" < internals.tex > internals2.tex
|
||||
mv internals2.tex internals.tex
|
||||
pdflatex internals.tex
|
||||
pdflatex internals.tex
|
||||
-rm -f internals.toc internals.aux internals.idx internals.out
|
||||
|
||||
# See uninstall also - don't put wildcards in this variable, it might uninstall other stuff
|
||||
VL_INST_BIN_FILES = verilator verilator_bin verilator_bin_dbg \
|
||||
verilator_includer verilator_profcfunc
|
||||
@@ -442,6 +463,11 @@ TAGFILES=${srcdir}/*/*.cpp ${srcdir}/*/*.h ${srcdir}/*/[a-z]*.in \
|
||||
TAGS: $(TAGFILES)
|
||||
etags $(TAGFILES)
|
||||
|
||||
.PHONY: doxygen
|
||||
|
||||
doxygen:
|
||||
$(DOXYGEN) doxygen.config
|
||||
|
||||
######################################################################
|
||||
# Test targets
|
||||
|
||||
|
||||
+125
-50
@@ -69,7 +69,7 @@ if (! GetOptions (
|
||||
"debug:s" => \&debug,
|
||||
# "version!" => \&version, # Also passthru'ed
|
||||
# Switches
|
||||
"gdb=s" => \$opt_gdb, # Undocumented debugging
|
||||
"gdb!" => \$opt_gdb,
|
||||
"gdbbt!" => \$opt_gdbbt,
|
||||
# Additional parameters
|
||||
"<>" => sub {}, # Ignored
|
||||
@@ -82,17 +82,24 @@ if ($opt_gdbbt && !gdb_works()) {
|
||||
warn "-Info: --gdbbt ignored: gdb doesn't seem to be working\n" if $Debug;
|
||||
$opt_gdbbt = 0;
|
||||
}
|
||||
if ($opt_gdbbt && !$opt_gdb && $Debug) {
|
||||
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'");
|
||||
} elsif ($opt_gdbbt && $Debug) {
|
||||
# Run under GDB to get gdbbt
|
||||
run ("gdb ".verilator_bin()
|
||||
run ("gdb"
|
||||
." ".verilator_bin()
|
||||
." --batch --quiet --return-child-result"
|
||||
." -ex 'run ".join(' ',@Opt_Verilator_Sw)."'"
|
||||
." -ex 'set width 0'"
|
||||
." -ex 'bt'");
|
||||
} else {
|
||||
# Normal, non gdb
|
||||
run (($opt_gdb?"$opt_gdb ":"")
|
||||
.verilator_bin()
|
||||
run (verilator_bin()
|
||||
." ".join(' ',@Opt_Verilator_Sw));
|
||||
}
|
||||
|
||||
@@ -247,7 +254,7 @@ descriptions in the next sections for more information.
|
||||
--coverage-line Enable line coverage
|
||||
--coverage-toggle Enable toggle coverage
|
||||
--coverage-user Enable PSL/SVL user coverage
|
||||
--coverage-underscore Enable covarge of _signals
|
||||
--coverage-underscore Enable coverage of _signals
|
||||
-D<var>[=<value>] Set preprocessor define
|
||||
--debug Enable debugging
|
||||
--debug-check Enable debugging assertions
|
||||
@@ -255,11 +262,13 @@ descriptions in the next sections for more information.
|
||||
--debugi-<srcfile> <level> Enable debugging a source file at a level
|
||||
+define+<var>+<value> Set preprocessor define
|
||||
--dump-tree Enable dumping .tree files
|
||||
--dump-treei <level> Enable dumping .tree files at a level
|
||||
-E Preprocess, but do not compile
|
||||
--error-limit <value> Abort after this number of errors
|
||||
--exe Link to create executable
|
||||
-F <file> Parse options from a file, relatively
|
||||
-f <file> Parse options from a file
|
||||
--gdb Run Verilator under GDB interactively
|
||||
--gdbbt Run Verilator under GDB for backtrace
|
||||
--help Display this help
|
||||
-I<dir> Directory to search for includes
|
||||
@@ -521,9 +530,16 @@ standard across Verilog tools while -D is an alias for GCC compatibility.
|
||||
|
||||
=item --dump-tree
|
||||
|
||||
Rarely needed. Enable writing .tree debug files. This is enabled with
|
||||
--debug, so "--debug --no-dump-tree" may be useful if the dump files are
|
||||
large and not desired.
|
||||
Rarely needed. Enable writing .tree debug files with dumping level 3,
|
||||
which dumps the standard critical stages. --dump-tree is enabled
|
||||
automatically with --debug, so "--debug --no-dump-tree" may be useful if
|
||||
the dump files are large and not desired.
|
||||
|
||||
=item --dump-treei
|
||||
|
||||
Rarely needed. Enable writing .tree debug files with a specific dumping
|
||||
level, 0 disbles dumps and is equivelent to "--no-dump-tree". Level 9
|
||||
enables dumping of every stage.
|
||||
|
||||
=item -E
|
||||
|
||||
@@ -558,11 +574,17 @@ 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 --gdb
|
||||
|
||||
Run Verilator underneath an interactive GDB (or VERILATOR_GDB environment
|
||||
variable value) session. See also --gdbbt.
|
||||
|
||||
=item --gdbbt
|
||||
|
||||
If --debug is specified, run Verilator underneath a GDB process and print
|
||||
a backtrace on exit. Without --debug or if GDB doesn't seem to work, this
|
||||
flag is ignored.
|
||||
If --debug is specified, run Verilator underneath a GDB process and print a
|
||||
backtrace on exit, then exit GDB immediately. Without --debug or if GDB
|
||||
doesn't seem to work, this flag is ignored. Intended for easy creation of
|
||||
backtraces by users; otherwise see the --gdb flag.
|
||||
|
||||
=item --help
|
||||
|
||||
@@ -1270,7 +1292,7 @@ SYSTEMC/include.
|
||||
|
||||
If set, specifies the directory containing the libsystemc.a library. If not
|
||||
specified, it will come from a default optionally specified at configure
|
||||
time (before Verilator was compiled), or compted from
|
||||
time (before Verilator was compiled), or computed from
|
||||
SYSTEMC/lib-SYSTEMC_ARCH.
|
||||
|
||||
=item SYSTEMPERL
|
||||
@@ -1299,6 +1321,11 @@ baseline regression tests.
|
||||
If set, specifies an alternative name of the Verilator binary. May be used
|
||||
for debugging and selecting between multiple operating system builds.
|
||||
|
||||
=item VERILATOR_GDB
|
||||
|
||||
If set, the command to run when using the --gdb option, such as "ddd". If
|
||||
not specified, it will use "gdb".
|
||||
|
||||
=item VERILATOR_ROOT
|
||||
|
||||
Specifies the directory containing the distribution kit. This is used to
|
||||
@@ -1451,6 +1478,26 @@ DPI compatible but is easier to read and better supports multiple designs.
|
||||
Vour::publicSetBool(value);
|
||||
// or top->publicSetBool(value);
|
||||
|
||||
Note that if the DPI task or function accesses any register or net within the
|
||||
RTL, it will require a scope to be set. This can be done using the standard
|
||||
functions within svdpi.h, after the module is instantiated, but before the
|
||||
task(s) and/or function(s) are called.
|
||||
|
||||
For example, if the top level module is instantiated with the name "dut" and
|
||||
the name references within tasks are all hierarchical (dotted) names with
|
||||
respect to that top level module, then the scope could be set with
|
||||
|
||||
#include "svdpi.h"
|
||||
...
|
||||
svSetScope (svGetScopeFromName ("dut"));
|
||||
|
||||
(Remember that Verilator adds a "V" to the top of the module hierarchy.)
|
||||
|
||||
Scope can also be set from within a DPI imported C function that has been
|
||||
called from Verilog by querying the scope of that function. See the
|
||||
sections on DPI Context Functions and DPI Header Isolation below and the
|
||||
comments within the svdpi.h header for more information.
|
||||
|
||||
=head2 DPI Display Functions
|
||||
|
||||
Verilator allows writing $display like functions using this syntax:
|
||||
@@ -1895,9 +1942,17 @@ The Verilog code returns to the last language mode specified with
|
||||
|
||||
Used after a signal declaration to indicate the signal is used to gate a
|
||||
clock, and the user takes responsibility for insuring there are no races
|
||||
related to it. (Typically by adding a latch, and running static timing
|
||||
analysis.) This will cause the clock gate to be ignored in the scheduling
|
||||
algorithm, improving performance. It's also a good idea to enable the
|
||||
related to it. (Typically by adding a latch, and running static timing
|
||||
analysis.) For example:
|
||||
|
||||
reg enable_r /*verilator clock_enable*/;
|
||||
wire gated_clk = clk & enable_r;
|
||||
always_ff @ (posedge clk)
|
||||
enable_r <= enable_early;
|
||||
|
||||
The clock_enable attribute will cause the clock gate to be ignored in the
|
||||
scheduling algorithm, sometimes required for correct clock behavior, and
|
||||
always improving performance. It's also a good idea to enable the
|
||||
IMPERFECTSCH warning, to insure all clock enables are properly recognized.
|
||||
|
||||
=item /*verilator coverage_block_off*/
|
||||
@@ -2214,10 +2269,12 @@ different.)
|
||||
|
||||
=head2 Generated Clocks
|
||||
|
||||
Verilator attempts to deal with generated clocks correctly, however new
|
||||
cases may turn up bugs in the scheduling algorithm. The safest option is
|
||||
to have all clocks as primary inputs to the model, or wires directly
|
||||
attached to primary inputs.
|
||||
Verilator attempts to deal with generated and enabled clocks correctly,
|
||||
however some cases cause problems in the scheduling algorithm which is
|
||||
optimized for performance. The safest option is to have all clocks as
|
||||
primary inputs to the model, or wires directly attached to primary inputs.
|
||||
For proper behavior clock enables may also need the /*verilator
|
||||
clock_enable*/ attribute.
|
||||
|
||||
=head2 Ranges must be big-bit-endian
|
||||
|
||||
@@ -2714,6 +2771,23 @@ is not possible, add a undef to indicate the code is overriding the value:
|
||||
`undef MACRO
|
||||
`define MACRO otherdef
|
||||
|
||||
=item SELRANGE
|
||||
|
||||
Warns that a selection index will go out of bounds:
|
||||
|
||||
wire vec[6:0];
|
||||
initial out = vec[7]; // There is no 7
|
||||
|
||||
Verilator will assume zero for this value, instead of X. Note that in some
|
||||
cases this warning may be false, when a condition upstream or downstream of
|
||||
the access means the access out of bounds will never execute or be used.
|
||||
|
||||
wire vec[6:0];
|
||||
initial begin
|
||||
seven = 7;
|
||||
...
|
||||
if (seven != 7) out = vec[seven]; // Never will use vec[7]
|
||||
|
||||
=item STMTDLY
|
||||
|
||||
Warns that you have a statement with a delayed time in front of it, for
|
||||
@@ -3370,43 +3444,44 @@ faster than many popular commercial simulators.
|
||||
Many people have provided ideas and other assistance with Verilator.
|
||||
|
||||
The major corporate sponsors of Verilator, by providing significant
|
||||
contributions of time or funds include include Compaq Corporation, Digital
|
||||
Equipment Corporation, Intel Corporation, Mindspeed Technologies Inc.,
|
||||
MicroTune Inc., picoChip Designs Ltd., Sun Microsystems, Nauticus Networks,
|
||||
and SiCortex Inc.
|
||||
contributions of time or funds include include Cavium Networks, Compaq
|
||||
Corporation, Digital Equipment Corporation, Embecosm Ltd., Intel
|
||||
Corporation, Mindspeed Technologies Inc., MicroTune Inc., picoChip Designs
|
||||
Ltd., Sun Microsystems, Nauticus Networks, and SiCortex Inc.
|
||||
|
||||
The people who have contributed major functionality are Byron Bradley, Lane
|
||||
Brooks, Duane Galbi, Paul Wasson, and Wilson Snyder. Major testers include
|
||||
Jeff Dutton, Ralf Karge, David Hewson, Wim Michiels, and Gene Weber.
|
||||
The people who have contributed major functionality are Byron Bradley,
|
||||
Jeremy Bennett, Lane Brooks, Duane Galbi, Paul Wasson, and Wilson Snyder.
|
||||
Major testers include Jeff Dutton, Ralf Karge, David Hewson, Wim Michiels,
|
||||
Alex Solomatnikov, Sebastien Van Cauwenberghe and Gene Weber.
|
||||
|
||||
Some of the people who have provided ideas and feedback for Verilator
|
||||
include: David Addison, Hans Van Antwerpen, Vasu Arasanipalai, Jens Arm, J
|
||||
Baxter, Jeremy Bennett, David Black, Gregg Bouchard, Christopher Boumenot,
|
||||
Nick Bowler, Byron Bradley, Bryan Brady, Lane Brooks, John Brownlee,
|
||||
Lawrence Butcher, Chris Candler, Lauren Carlson, Donal Casey, Terry Chen,
|
||||
Robert A. Clark, Allan Cochrane, Gunter Dannoritzer, Ashutosh Das, Bernard
|
||||
Deadman, John Deroo, John Dickol, Danny Ding, Ivan Djordjevic, Alex Duller,
|
||||
Jeff Dutton, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy, Robert Farrell,
|
||||
Eugen Fekete, Andrea Foletto, Bob Fredieu, Shankar Giri, Sam Gladstone,
|
||||
Amir Gonnen, Chitlesh Goorah, Neil Hamilton, Thomas Hawkins, David Hewson,
|
||||
Jae Hossell, Ben Jackson, Iztok Jeras, Mike Kagen, Guy-Armand Kamendje,
|
||||
Vasu Kandadi, Patricio Kaplan, Ralf Karge, Dan Katz, Sol Katzman, Jonathan
|
||||
Kimmitt, Gernot Koch, Soon Koh, Steve Kolecki, Steve Lang, Stephane
|
||||
Laurent, Christian Leber, Charlie Lind, Paul Liu, Dan Lussier, Fred Ma,
|
||||
include: David Addison, Vasu Arasanipalai, Jens Arm, J Baxter, Jeremy
|
||||
Bennett, David Black, Gregg Bouchard, Christopher Boumenot, Nick Bowler,
|
||||
Byron Bradley, Bryan Brady, Lane Brooks, John Brownlee, Lawrence Butcher,
|
||||
Chris Candler, Lauren Carlson, Donal Casey, Terry Chen, Robert A. Clark,
|
||||
Allan Cochrane, Gunter Dannoritzer, Ashutosh Das, Bernard Deadman, Mike
|
||||
Denio, John Deroo, John Dickol, Ruben Diez, Danny Ding, Ivan Djordjevic,
|
||||
Alex Duller, Jeff Dutton, Chandan Egbert, Joe Eiler, Ahmed El-Mahmoudy,
|
||||
Robert Farrell, Eugen Fekete, Andrea Foletto, Bob Fredieu, Shankar Giri,
|
||||
Sam Gladstone, Amir Gonnen, Chitlesh Goorah, Neil Hamilton, Thomas Hawkins,
|
||||
David Hewson, Jae Hossell, Ben Jackson, Iztok Jeras, Christophe Joly, Mike
|
||||
Kagen, Guy-Armand Kamendje, Vasu Kandadi, Patricio Kaplan, Ralf Karge, Dan
|
||||
Katz, Sol Katzman, Jonathan Kimmitt, Gernot Koch, Soon Koh, Steve Kolecki,
|
||||
David Kravitz, Steve Lang, Stephane Laurent, Walter Lavino, Christian
|
||||
Leber, John Li, Charlie Lind, Andrew Ling, Paul Liu, Dan Lussier, Fred Ma,
|
||||
Duraid Madina, Mark Marshall, Jason McMullan, Wim Michiels, Dennis
|
||||
Muhlestein, John Murphy, Richard Myers, Dimitris Nalbantis, Paul Nitza,
|
||||
Pete Nixon, Lisa Noack, Mark Nodine, Andreas Olofsson, Brad Parker, Dominic
|
||||
Plunkett, Niranjan Prabhu, Usha Priyadharshini, Oleg Rodionov, John
|
||||
Sanguinetti, Salman Sheikh, Mike Shinkarovsky, Rafael Shirakawa, Jeffrey
|
||||
Short, Rodney Sinclair, Brian Small, Alex Solomatnikov, Art Stamness, John
|
||||
Stroebel, Emerson Suguimoto, Gene Sullivan, Renga Sundararajan, Stefan
|
||||
Thiede, Gary Thomas, Steve Tong, Holger Waechtler, Stefan Wallentowitz,
|
||||
Shawn Wang, Greg Waters, Eugene Weber, David Welch, Leon Wildman, Gerald
|
||||
Williams, Trevor Williams, Jeff Winston, Joshua Wise, Johan Wouters, and
|
||||
Ding Xiaoliang.
|
||||
|
||||
Thanks all.
|
||||
Plunkett, Niranjan Prabhu, Usha Priyadharshini, Alberto Del Rio, Oleg
|
||||
Rodionov, John Sanguinetti, Salman Sheikh, Mike Shinkarovsky, Rafael
|
||||
Shirakawa, Jeffrey Short, Rodney Sinclair, Brian Small, Alex Solomatnikov,
|
||||
Art Stamness, John Stroebel, Emerson Suguimoto, Gene Sullivan, Renga
|
||||
Sundararajan, Stefan Thiede, Gary Thomas, Steve Tong, Hans Van Antwerpen,
|
||||
Holger Waechtler, Stefan Wallentowitz, Shawn Wang, Greg Waters, Thomas
|
||||
Watts, Eugene Weber, David Welch, Leon Wildman, Gerald Williams, Trevor
|
||||
Williams, Jeff Winston, Joshua Wise, Johan Wouters, and Ding Xiaoliang.
|
||||
|
||||
Thanks to them, and all those we've missed including above.
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
# 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],[3.832 2012-03-07])
|
||||
AC_INIT([Verilator],[3.833 2012-04-15])
|
||||
AC_CONFIG_HEADER(src/config_build.h)
|
||||
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk)
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/*! \mainpage Verilator Doxygen Documentation
|
||||
*
|
||||
* \section intro_sec Introduction
|
||||
*
|
||||
* This is a full doxygen analysis of the Verilator source tree.
|
||||
*/
|
||||
+1772
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
@@ -27,7 +27,7 @@
|
||||
#include "verilated_imp.h"
|
||||
#include <cctype>
|
||||
|
||||
#define VL_VALUE_STRING_MAX_WIDTH 1024 ///< Max static char array for VL_VALUE_STRING
|
||||
#define VL_VALUE_STRING_MAX_WIDTH 8192 ///< Max static char array for VL_VALUE_STRING
|
||||
|
||||
//===========================================================================
|
||||
// Global variables
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2012 by Wilson Snyder. This program is free software; you can
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2010-2012 by Wilson Snyder. This program is free software; you can
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2012 by Wilson Snyder. This program is free software; you can
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2012 by Wilson Snyder. This program is free software; you can
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// -*- SystemC -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// -*- SystemC -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// -*- SystemC -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// -*- SystemC -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2012 by Wilson Snyder. This program is free software; you can
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2012 by Wilson Snyder. This program is free software; you can
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 by Wilson Snyder. This program is free software; you can
|
||||
|
||||
+239
-37
@@ -52,7 +52,11 @@ preprocessing, then lexical analysis with Flex and parsing with Bison.
|
||||
This produces an abstract syntax tree (AST) representation of the design,
|
||||
which is what is visible in the .tree files described below.
|
||||
|
||||
Cells are then linked, which will read and parse additional files as above.
|
||||
Verilator then makes a series of passes over the AST, progressively refining
|
||||
and optimizing it.
|
||||
|
||||
Cells in the AST first linked, which will read and parse additional files as
|
||||
above.
|
||||
|
||||
Functions, variable and other references are linked to their definitions.
|
||||
|
||||
@@ -87,6 +91,39 @@ hints, and performs additional constant propagation.
|
||||
|
||||
Verilator finally writes the C++ modules.
|
||||
|
||||
=head2 Key Classes Used in the Verilator Flow
|
||||
|
||||
The AST is represented at the top level by the class C<AstNode>. This abstract
|
||||
class has derived classes for the individual components (e.g. C<AstGenerate>
|
||||
for a generate block) or groups of components (e.g. C<AstNodeFTask> for
|
||||
functions and tasks, which in turn has C<AstFunc> and C<AstTask> as derived
|
||||
classes).
|
||||
|
||||
Each C<AstNode> has pointers to up to four children, accessed by the
|
||||
C<op1p> through C<op4p> methods. These methods are then abstracted in a
|
||||
specific Ast* node class to a more specific name. For example with the
|
||||
C<AstIf> node (for C<if> statements), C<ifsp> calls C<op1p> to give the
|
||||
pointer to the AST for the "then" block, while C<elsesp> calls C<op2p> to
|
||||
give the pointer to the AST for the "else" block, or NULL if there is not
|
||||
one.
|
||||
|
||||
C<AstNode> has the concept of a next and previous AST - for example the
|
||||
next and previous statements in a block. Pointers to the AST for these
|
||||
statements (if they exist) can be obtained using the C<back> and C<next>
|
||||
methods.
|
||||
|
||||
It is useful to remember that the derived class C<AstNetlist> is at the top
|
||||
of the tree, so checking for this class is the standard way to see if you
|
||||
are at the top of the tree.
|
||||
|
||||
By convention, each function/method uses the variable C<nodep> as a pointer
|
||||
to the C<AstNode> currently being processed.
|
||||
|
||||
The passes are implemented by AST visitor classes (see L</Visitor
|
||||
Functions>). These are implemented by subclasses of the abstract class,
|
||||
C<AstNVisitor>. Each pass creates an instance of the visitor class, which
|
||||
in turn implements a method to perform the pass.
|
||||
|
||||
=head2 Verilated Flow
|
||||
|
||||
The evaluation loop outputted by Verilator is designed to allow a single
|
||||
@@ -120,57 +157,182 @@ changed; if clear, checking those signals for changes may be skipped.
|
||||
To match the indentation of Verilator C++ sources, use 4 spaces per level,
|
||||
and leave tabs at 8 columns, so every other indent level is a tab stop.
|
||||
|
||||
In Emacs, use in your ~/.emacs
|
||||
All files should contain the magic header to insure standard indentation:
|
||||
|
||||
(add-hook 'c-mode-common-hook '(lambda ()
|
||||
(c-set-style "cc-mode"))))
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
|
||||
This sets indentation to the cc-mode defaults. (Verilator predates a
|
||||
CC-mode change of several years ago which overrides the defaults with GNU
|
||||
style indentation; the c-set-style undoes that.)
|
||||
|
||||
=head2 The C<astgen> script
|
||||
|
||||
Some of the code implementing passes is extremely repetitive, and must be
|
||||
implemented for each sub-class of C<AstNode>. However, while repetitive,
|
||||
there is more variability than can be handled in C++ macros.
|
||||
|
||||
In Verilator this is implemented by using a Perl script, C<astgen> to
|
||||
pre-process the C++ code. For example in C<V3Const.cpp> this is used to
|
||||
implement the C<visit()> functions for each binary operation using the
|
||||
TREEOP macro.
|
||||
|
||||
The original C++ source code is transformed into C++ code in the C<obj_opt>
|
||||
and C<obj_dbg> sub-directories (the former for the optimized version of
|
||||
verilator, the latter for the debug version). So for example C<V3Const.cpp>
|
||||
into C<V3Const__gen.cpp>.
|
||||
|
||||
=head2 Visitor Functions
|
||||
|
||||
There's three ways data is passed between visitor functions.
|
||||
The verilator uses the I<Visitor> design pattern to implement its
|
||||
refinement and optimization passes. This allows separation of the pass
|
||||
algorithm from the AST on which it operates. Wikipedia provides an
|
||||
introduction to the concept at
|
||||
L<http://en.wikipedia.org/wiki/Visitor_pattern>.
|
||||
|
||||
1. A visitor-class member variable. This is generally for passing "parent"
|
||||
information down to children. m_modp is a common example. It's set to
|
||||
NULL in the constructor, where that node (AstModule visitor) sets it, then
|
||||
the children are iterated, then it's cleared. Children under an AstModule
|
||||
will see it set, while nodes elsewhere will see it clear. If there can be
|
||||
nested items (for example an AstFor under an AstFor) the variable needs to
|
||||
be save-set-restored in the AstFor visitor, otherwise exiting the lower for
|
||||
will loose the upper for's setting.
|
||||
As noted above, all visitors are derived classes of C<AstNvisitor>. All
|
||||
derived classes of C<AstNode> implement the C<accept> method, which takes
|
||||
as argument a reference to an instance or a C<AstNVisitor> derived class
|
||||
and applies the visit method of the C<AstNVisitor> to the invoking AstNode
|
||||
instance (i.e. C<this>).
|
||||
|
||||
One possible difficulty is that a call to C<accept> may perform an edit
|
||||
which destroys the node it receives as argument. The
|
||||
C<acceptSubtreeReturnEdits> method of C<AstNode> is provided to apply
|
||||
C<accept> and return the resulting node, even if the original node is
|
||||
destroyed (if it is not destroyed it will just return the original node).
|
||||
|
||||
The behavior of the visitor classes is achieved by overloading the C<visit>
|
||||
function for the different C<AstNode> derived classes. If a specific
|
||||
implementation is not found, the system will look in turn for overloaded
|
||||
implementations up the inheritance hierarchy. For example calling C<accept>
|
||||
on C<AstIf> will look in turn for:
|
||||
|
||||
void visit (AstIf* nodep, AstNUser* vup)
|
||||
void visit (AstNodeIf* nodep, AstNUser* vup)
|
||||
void visit (AstNodeStmt* nodep, AstNUser* vup)
|
||||
void visit (AstNode* nodep, AstNUser* vup)
|
||||
|
||||
There are three ways data is passed between visitor functions.
|
||||
|
||||
=over 4
|
||||
|
||||
=item 1.
|
||||
|
||||
A visitor-class member variable. This is generally for passing "parent"
|
||||
information down to children. C<m_modp> is a common example. It's set to
|
||||
NULL in the constructor, where that node (C<AstModule> visitor) sets it,
|
||||
then the children are iterated, then it's cleared. Children under an
|
||||
C<AstModule> will see it set, while nodes elsewhere will see it clear. If
|
||||
there can be nested items (for example an C<AstFor> under an C<AstFor>) the
|
||||
variable needs to be save-set-restored in the C<AstFor> visitor, otherwise
|
||||
exiting the lower for will lose the upper for's setting.
|
||||
|
||||
=item 2.
|
||||
|
||||
User attributes. Each C<AstNode> (B<Note.> The AST node, not the visitor)
|
||||
has five user attributes, which may be accessed as an integer using the
|
||||
C<user1()> through C<user5()> methods, or as a pointer (of type
|
||||
C<AstNuser>) using the C<user1p()> through C<user5p()> methods (a common
|
||||
technique lifted from graph traversal packages).
|
||||
|
||||
2. User() attributes. Each node has 5 ->user() number or ->userp() pointer
|
||||
utility values (a common technique lifted from graph traversal packages).
|
||||
A visitor first clears the one it wants to use by calling
|
||||
AstNode::user#ClearTree(), then it can mark any node's user() with whatever
|
||||
data it wants. Readers just call nodep->user(), but may need to cast
|
||||
appropriately, so you'll often see nodep->userp()->castSOMETYPE(). At the
|
||||
top of each visitor are comments describing how the user() stuff applies to
|
||||
that visitor class. For example:
|
||||
C<AstNode::user#ClearTree()>, then it can mark any node's user() with whatever
|
||||
data it wants. Readers just call C<< nodep->user() >>, but may need to cast
|
||||
appropriately, so you'll often see C<< nodep->userp()->castSOMETYPE() >>. At
|
||||
the top of each visitor are comments describing how the C<user()> stuff
|
||||
applies to that visitor class. For example:
|
||||
|
||||
// NODE STATE
|
||||
// Cleared entire netlist
|
||||
// AstModule::user1p() // bool. True to inline this module
|
||||
|
||||
This says that at the AstNetlist user1ClearTree() is called. Each
|
||||
AstModule's is user1() is used to indicate if we're going to inline it.
|
||||
This says that at the C<AstNetlist> C<user1ClearTree()> is called. Each
|
||||
C<AstModule>'s C<user1()> is used to indicate if we're going to inline it.
|
||||
|
||||
These comments are important to make sure a user#() on a given AstNode type
|
||||
is never being used for two different purposes.
|
||||
These comments are important to make sure a C<user#()> on a given C<AstNode>
|
||||
type is never being used for two different purposes.
|
||||
|
||||
Note that calling user#ClearTree is fast, it doesn't walk the tree, so it's
|
||||
ok to call fairly often. For example, it's commonly called on every
|
||||
Note that calling C<user#ClearTree> is fast, it doesn't walk the tree, so
|
||||
it's ok to call fairly often. For example, it's commonly called on every
|
||||
module.
|
||||
|
||||
3. Parameters can be passed between the visitors in close to the "normal"
|
||||
function caller to callee way. This is the second "vup" parameter that is
|
||||
ignored on most of the visitor functions. V3Width does this, but it proved
|
||||
more messy than the above and is deprecated. (V3Width was nearly the first
|
||||
module written. Someday this scheme may be removed, as it slows the
|
||||
program down to have to pass vup everywhere.)
|
||||
=item 3.
|
||||
|
||||
Parameters can be passed between the visitors in close to the "normal"
|
||||
function caller to callee way. This is the second C<vup> parameter of type
|
||||
C<AstNuser> that is ignored on most of the visitor functions. V3Width does
|
||||
this, but it proved more messy than the above and is deprecated. (V3Width
|
||||
was nearly the first module written. Someday this scheme may be removed,
|
||||
as it slows the program down to have to pass vup everywhere.)
|
||||
|
||||
=back
|
||||
|
||||
=head2 Iterators
|
||||
|
||||
C<AstNode> provides a set of iterators to facilitate walking over the
|
||||
tree. Each takes two arguments, a visitor, C<v>, of type C<AstNVisitor> and
|
||||
an optional pointer user data, C<vup>, of type C<AstNuser*>. The second is
|
||||
one of the ways to pass parameters to visitors described in L</Visitor
|
||||
Functions>, but its use is no deprecated and should be used for new visitor
|
||||
classes.
|
||||
|
||||
=over 4
|
||||
|
||||
=item C<iterate()>
|
||||
|
||||
This just applies the C<accept> method of the C<AstNode> to the visitor
|
||||
function.
|
||||
|
||||
=item C<iterateAndNextIgnoreEdit>
|
||||
|
||||
Applies the C<accept> method of each C<AstNode> in a list (i.e. connected
|
||||
by C<nextp> and C<backp> pointers).
|
||||
|
||||
=item C<iterateAndNext>
|
||||
|
||||
Applies the C<accept> method of each C<AstNode> in a list. If a node is
|
||||
edited by the call to C<accept>, apply C<accept> again, until the node does
|
||||
not change.
|
||||
|
||||
=item C<iterateListBackwards>
|
||||
|
||||
Applies the C<accept> method of each C<AstNode> in a list, starting with
|
||||
the last one.
|
||||
|
||||
=item C<iterateChildren>
|
||||
|
||||
Apply the C<iterateAndNext> method on each child C<op1p> through C<op4p> in
|
||||
turn.
|
||||
|
||||
=item C<iterateChildrenBackwards>
|
||||
|
||||
Apply the C<iterateListBackwards> method on each child C<op1p> through
|
||||
C<op4p> in turn.
|
||||
|
||||
=back
|
||||
|
||||
=head2 Identifying derived classes
|
||||
|
||||
A common requirement is to identify the specific C<AstNode> class we are
|
||||
dealing with. For example a visitor might not implement separate C<visit>
|
||||
methods for C<AstIf> and C<AstGenIf>, but just a single method for the base
|
||||
class:
|
||||
|
||||
void visit (AstNodeIf* nodep, AstNUser* vup)
|
||||
|
||||
However that method might want to specify additional code if it is called
|
||||
for C<AstGenIf>. Verilator does this by providing a C<castSOMETYPE()>
|
||||
method for each possible node type, using C++ C<dynamic_cast>. This either
|
||||
returns a pointer to the object cast to that type (if it is of class
|
||||
C<SOMETYPE>, or a derived class of C<SOMETYPE>) or else NULL. So our
|
||||
C<visit> method could use:
|
||||
|
||||
if (nodep->castAstGenIf()) {
|
||||
<code specific to AstGenIf>
|
||||
}
|
||||
|
||||
A common test is for C<AstNetlist>, which is the node at the root of the
|
||||
AST.
|
||||
|
||||
=head1 TESTING
|
||||
|
||||
@@ -214,7 +376,8 @@ algorithmic stage. An example:
|
||||
|
||||
=over 4
|
||||
|
||||
"1:2:" indicates the hierarchy the VAR is op2p under the MODULE.
|
||||
"1:2:" indicates the hierarchy of the C<VAR> is the C<op2p> pointer under
|
||||
the C<MODULE>, which in turn is the C<op1p> pointer under the C<NETLIST>
|
||||
|
||||
"VAR" is the AstNodeType.
|
||||
|
||||
@@ -239,8 +402,35 @@ variable is an output.
|
||||
=head2 Debugging with GDB
|
||||
|
||||
The test_regress/driver.pl script accepts --debug --gdb to start Verilator
|
||||
under gdb. You can also use --debug --gdbbt to just backtrace and then
|
||||
exit gdb.
|
||||
under gdb and break when an error is hit or the program is about to exit.
|
||||
You can also use --debug --gdbbt to just backtrace and then exit gdb. To
|
||||
debug the Verilated executable, use --gdbsim.
|
||||
|
||||
If you wish to start verilator under GDB (or another debugger), then you
|
||||
can use --debug and look at the underlying invocation of verilator_dgb. For
|
||||
example
|
||||
|
||||
t/t_alw_dly.pl --debug
|
||||
|
||||
shows it invokes the command:
|
||||
|
||||
../verilator_bin_dbg --prefix Vt_alw_dly --x-assign unique --debug
|
||||
-cc -Mdir obj_dir/t_alw_dly --debug-check -f input.vc t/t_alw_dly.v
|
||||
|
||||
Start GDB, then C<start> with the remaining arguments.
|
||||
|
||||
gdb ../verilator_bin_dbg
|
||||
...
|
||||
(gdb) start --prefix Vt_alw_dly --x-assign unique --debug -cc -Mdir
|
||||
obj_dir/t_alw_dly --debug-check -f input.vc t/t_alw_dly.v
|
||||
> obj_dir/t_alw_dly/vlt_compile.log
|
||||
...
|
||||
Temporary breakpoint 1, main (argc=13, argv=0xbfffefa4, env=0xbfffefdc)
|
||||
at ../Verilator.cpp:615
|
||||
615 ios::sync_with_stdio();
|
||||
(gdb)
|
||||
|
||||
You can then continue execution with breakpoints as required.
|
||||
|
||||
To break at a specific edit number which changed a node (presumably to find
|
||||
what made a <e####> line in the tree dumps):
|
||||
@@ -249,8 +439,20 @@ what made a <e####> line in the tree dumps):
|
||||
|
||||
To print a node:
|
||||
|
||||
call nodep->dumpGdb() # aliased to "pn" in .gdbinit
|
||||
call nodep->dumpTreeGdb() # aliased to "pnt" in .gdbinit
|
||||
call nodep->dumpGdb() # aliased to "pn" in src/.gdbinit
|
||||
call nodep->dumpTreeGdb() # aliased to "pnt" in src/.gdbinit
|
||||
|
||||
When GDB halts, it is useful to understand that the backtrace will commonly
|
||||
show the iterator functions between each invocation of C<visit> in the
|
||||
backtrace. You will typically see a frame sequence something like
|
||||
|
||||
...
|
||||
visit()
|
||||
iterateChildren()
|
||||
iterateAndNext()
|
||||
accept()
|
||||
visit()
|
||||
...
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
|
||||
@@ -182,6 +182,7 @@ RAW_OBJS = \
|
||||
V3EmitCSyms.o \
|
||||
V3EmitMk.o \
|
||||
V3EmitV.o \
|
||||
V3EmitXml.o \
|
||||
V3Error.o \
|
||||
V3Expand.o \
|
||||
V3File.o \
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Break always into sensitivity active domains
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Break always into sensitivity block domains
|
||||
//
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Break always into sensitivity active domains
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Break always into sensitivity block domains
|
||||
//
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Collect and print statistics
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Assertion expansion
|
||||
//
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Collect and print statistics
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Assertion pre-expansion
|
||||
//
|
||||
|
||||
+3
-1
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Ast node structures
|
||||
//
|
||||
@@ -1014,7 +1015,8 @@ void AstNode::dumpTreeFile(const string& filename, bool append) {
|
||||
if (logsp->fail()) v3fatalSrc("Can't write "<<filename);
|
||||
*logsp<<"Tree Dump from <e"<<dec<<editCountLast()<<">";
|
||||
*logsp<<" to <e"<<dec<<editCountGbl()<<">"<<endl;
|
||||
if (editCountGbl()==editCountLast()) {
|
||||
if (editCountGbl()==editCountLast()
|
||||
&& !(v3Global.opt.dumpTree()>=9)) {
|
||||
*logsp<<endl;
|
||||
*logsp<<"No changes since last dump!\n";
|
||||
} else {
|
||||
|
||||
+40
-20
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Ast node structure
|
||||
//
|
||||
@@ -36,8 +36,9 @@
|
||||
// class V3AstNode;
|
||||
|
||||
// Hint class so we can choose constructors
|
||||
class AstLogicPacked {};
|
||||
class AstBitPacked {};
|
||||
class VFlagLogicPacked {};
|
||||
class VFlagBitPacked {};
|
||||
class VFlagChildDType {}; // Used by parser.y to select constructor that sets childDType
|
||||
|
||||
//######################################################################
|
||||
|
||||
@@ -253,7 +254,9 @@ public:
|
||||
// Internal types for mid-steps
|
||||
SCOPEPTR, CHARPTR,
|
||||
// Internal types, eliminated after parsing
|
||||
LOGIC_IMPLICIT
|
||||
LOGIC_IMPLICIT,
|
||||
// Leave last
|
||||
_ENUM_MAX
|
||||
};
|
||||
enum en m_e;
|
||||
const char* ascii() const {
|
||||
@@ -263,7 +266,8 @@ public:
|
||||
"real", "shortint", "shortreal", "time",
|
||||
"string",
|
||||
"VerilatedScope*", "char*",
|
||||
"LOGIC_IMPLICIT"
|
||||
"LOGIC_IMPLICIT",
|
||||
" MAX"
|
||||
};
|
||||
return names[m_e];
|
||||
};
|
||||
@@ -274,22 +278,27 @@ public:
|
||||
"double", "short int", "float", "long long",
|
||||
"const char*",
|
||||
"dpiScope", "const char*",
|
||||
""
|
||||
"",
|
||||
" MAX"
|
||||
};
|
||||
return names[m_e];
|
||||
};
|
||||
static void test() {
|
||||
UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).ascii()," MAX"),"Enum array mismatch");
|
||||
UASSERT(0==strcmp(AstBasicDTypeKwd(_ENUM_MAX).dpiType()," MAX"),"Enum array mismatch");
|
||||
}
|
||||
inline AstBasicDTypeKwd () : m_e(UNKNOWN) {}
|
||||
inline AstBasicDTypeKwd (en _e) : m_e(_e) {}
|
||||
explicit inline AstBasicDTypeKwd (int _e) : m_e(static_cast<en>(_e)) {}
|
||||
operator en () const { return m_e; }
|
||||
int width() const {
|
||||
switch (m_e) {
|
||||
case BIT: return 1;
|
||||
case BIT: return 1; // scalar, can't bit extract unless ranged
|
||||
case BYTE: return 8;
|
||||
case CHANDLE: return 64;
|
||||
case INT: return 32;
|
||||
case INTEGER: return 32;
|
||||
case LOGIC: return 1;
|
||||
case LOGIC: return 1; // scalar, can't bit extract unless ranged
|
||||
case LONGINT: return 64;
|
||||
case DOUBLE: return 64; // opaque
|
||||
case FLOAT: return 32; // opaque
|
||||
@@ -692,11 +701,14 @@ public:
|
||||
// Creating from raw data (sameHash functions)
|
||||
V3Hash() { setBoth(1,0); }
|
||||
V3Hash(uint32_t val) { setBoth(1,val); }
|
||||
V3Hash(void* vp) { setBoth(1,cvtToHash(vp)); }
|
||||
V3Hash(const void* vp) { setBoth(1,cvtToHash(vp)); }
|
||||
V3Hash(const string& name);
|
||||
V3Hash(V3Hash lh, V3Hash rh) {
|
||||
setBoth(1,lh.hshval()*31+rh.hshval());
|
||||
}
|
||||
V3Hash(V3Hash h1, V3Hash h2) {
|
||||
setBoth(1,h1.hshval()*31+h2.hshval()); }
|
||||
V3Hash(V3Hash h1, V3Hash h2, V3Hash h3) {
|
||||
setBoth(1,(h1.hshval()*31+h2.hshval())*31+h3.hshval()); }
|
||||
V3Hash(V3Hash h1, V3Hash h2, V3Hash h3, V3Hash h4) {
|
||||
setBoth(1,((h1.hshval()*31+h2.hshval())*31+h3.hshval())*31+h4.hshval()); }
|
||||
};
|
||||
ostream& operator<<(ostream& os, V3Hash rhs);
|
||||
|
||||
@@ -864,7 +876,6 @@ public:
|
||||
void numericFrom(AstNode* fromp) { numeric(fromp->numeric()); }
|
||||
void numeric(AstNumeric flag) { m_numeric = (int)flag; if (flag.isDouble()) width(64,64); }
|
||||
AstNumeric numeric() const { return AstNumeric(m_numeric); }
|
||||
void isSigned(bool flag) { numeric(flag ? AstNumeric::SIGNED : AstNumeric::UNSIGNED); }
|
||||
bool isUnsigned() const { return numeric().isUnsigned(); }
|
||||
void didWidth(bool flag) { m_didWidth=flag; }
|
||||
bool didWidth() const { return m_didWidth; }
|
||||
@@ -938,11 +949,14 @@ public:
|
||||
bool isAllOnesV(); // Verilog width rules apply
|
||||
|
||||
// METHODS - data type changes especially for initial creation
|
||||
void dtypeChgLogicBool() { numeric(AstNumeric::UNSIGNED); width(1,1); }
|
||||
void dtypeChgDouble() { numeric(AstNumeric::DOUBLE); }
|
||||
void dtypeChgSigned32() { numeric(AstNumeric::SIGNED); width(VL_WORDSIZE,VL_WORDSIZE); }
|
||||
void dtypeChgUInt32() { numeric(AstNumeric::UNSIGNED); width(VL_WORDSIZE,VL_WORDSIZE); }
|
||||
void dtypeChgUInt64() { numeric(AstNumeric::UNSIGNED); width(VL_QUADSIZE,VL_QUADSIZE); }
|
||||
void dtypeChgSigned(bool flag) { numeric(flag ? AstNumeric::SIGNED : AstNumeric::UNSIGNED); }
|
||||
void dtypeSetBitSized(int widthf, int widthMinf, AstNumeric numericf) { numeric(numericf); width(widthf,widthMinf); }
|
||||
void dtypeSetLogicSized(int widthf, int widthMinf, AstNumeric numericf) { numeric(numericf); width(widthf,widthMinf); }
|
||||
void dtypeSetLogicBool() { numeric(AstNumeric::UNSIGNED); width(1,1); }
|
||||
void dtypeSetDouble() { numeric(AstNumeric::DOUBLE); }
|
||||
void dtypeSetSigned32() { numeric(AstNumeric::SIGNED); width(VL_WORDSIZE,VL_WORDSIZE); }
|
||||
void dtypeSetUInt32() { numeric(AstNumeric::UNSIGNED); width(VL_WORDSIZE,VL_WORDSIZE); }
|
||||
void dtypeSetUInt64() { numeric(AstNumeric::UNSIGNED); width(VL_QUADSIZE,VL_QUADSIZE); }
|
||||
|
||||
// METHODS - dump and error
|
||||
void v3errorEnd(ostringstream& str) const;
|
||||
@@ -988,6 +1002,7 @@ public:
|
||||
virtual int instrCount() const { return 0; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(V3Hash::Illegal()); } // Not a node that supports it
|
||||
virtual bool same(AstNode* otherp) const { return true; }
|
||||
virtual bool hasDType() const { return false; } // Iff has a data type; dtype() must be non null
|
||||
virtual bool maybePointedTo() const { return false; } // Another AstNode* may have a pointer into this node, other then normal front/back/etc.
|
||||
virtual bool broken() const { return false; }
|
||||
|
||||
@@ -1024,6 +1039,7 @@ struct AstNodeMath : public AstNode {
|
||||
: AstNode(fl) {}
|
||||
ASTNODE_BASE_FUNCS(NodeMath)
|
||||
// METHODS
|
||||
virtual bool hasDType() const { return true; }
|
||||
virtual string emitVerilog() = 0; /// Format string for verilog writing; see V3EmitV
|
||||
virtual string emitC() = 0;
|
||||
virtual string emitSimpleOperator() { return ""; }
|
||||
@@ -1173,8 +1189,8 @@ struct AstNodeStmt : public AstNode {
|
||||
: AstNode(fl) {}
|
||||
ASTNODE_BASE_FUNCS(NodeStmt)
|
||||
// METHODS
|
||||
virtual void addNextStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here
|
||||
virtual void addBeforeStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here
|
||||
virtual void addNextStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here
|
||||
virtual void addBeforeStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here
|
||||
};
|
||||
|
||||
struct AstNodeAssign : public AstNodeStmt {
|
||||
@@ -1190,6 +1206,7 @@ struct AstNodeAssign : public AstNodeStmt {
|
||||
AstNode* lhsp() const { return op2p()->castNode(); } // op2 = Assign to
|
||||
void rhsp(AstNode* np) { setOp1p(np); }
|
||||
void lhsp(AstNode* np) { setOp2p(np); }
|
||||
virtual bool hasDType() const { return true; }
|
||||
virtual bool cleanRhs() { return true; }
|
||||
virtual int instrCount() const { return widthInstrs(); }
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
@@ -1286,6 +1303,7 @@ public:
|
||||
init();
|
||||
}
|
||||
ASTNODE_BASE_FUNCS(NodeVarRef)
|
||||
virtual bool hasDType() const { return true; }
|
||||
virtual bool broken() const;
|
||||
virtual int instrCount() const { return widthInstrs(); }
|
||||
virtual void cloneRelink();
|
||||
@@ -1332,6 +1350,7 @@ struct AstNodeDType : public AstNode {
|
||||
ASTNODE_BASE_FUNCS(NodeDType)
|
||||
// Accessors
|
||||
virtual void dump(ostream& str);
|
||||
virtual bool hasDType() const { return true; }
|
||||
virtual AstBasicDType* basicp() const = 0; // (Slow) recurse down to find basic data type
|
||||
virtual AstNodeDType* skipRefp() const = 0; // recurses over typedefs to next non-typeref type
|
||||
virtual int widthAlignBytes() const = 0; // (Slow) recurses - Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
||||
@@ -1352,6 +1371,7 @@ struct AstNodeSel : public AstNodeBiop {
|
||||
AstNode* bitp() const { return op2p()->castNode(); } // op2 = Msb selection expression
|
||||
void bitp(AstNode* nodep) { setOp2p(nodep); }
|
||||
int bitConst() const;
|
||||
virtual bool hasDType() const { return true; }
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
||||
+6
-5
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Ast node structures
|
||||
//
|
||||
@@ -264,7 +265,7 @@ AstNodeDType* AstNodeDType::dtypeDimensionp(int dimension) {
|
||||
if ((dim++)==dimension) {
|
||||
return dtypep;
|
||||
}
|
||||
dtypep = adtypep->dtypep();
|
||||
dtypep = adtypep->subDTypep();
|
||||
continue;
|
||||
}
|
||||
else if (AstBasicDType* adtypep = dtypep->castBasicDType()) {
|
||||
@@ -288,7 +289,7 @@ uint32_t AstNodeDType::arrayElements() {
|
||||
dtypep = dtypep->skipRefp(); // Skip AstRefDType/AstTypedef, or return same node
|
||||
if (AstArrayDType* adtypep = dtypep->castArrayDType()) {
|
||||
entries *= adtypep->elementsConst();
|
||||
dtypep = adtypep->dtypep();
|
||||
dtypep = adtypep->subDTypep();
|
||||
}
|
||||
else {
|
||||
// AstBasicDType - nothing below, 1
|
||||
@@ -307,7 +308,7 @@ pair<uint32_t,uint32_t> AstNodeDType::dimensions() {
|
||||
if (AstArrayDType* adtypep = dtypep->castArrayDType()) {
|
||||
if (adtypep->isPacked()) packed += 1;
|
||||
else unpacked += 1;
|
||||
dtypep = adtypep->dtypep();
|
||||
dtypep = adtypep->subDTypep();
|
||||
}
|
||||
else {
|
||||
// AstBasicDType - nothing below, 1
|
||||
@@ -524,7 +525,7 @@ void AstAttrOf::dump(ostream& str) {
|
||||
void AstBasicDType::dump(ostream& str) {
|
||||
this->AstNodeDType::dump(str);
|
||||
str<<" kwd="<<keyword().ascii();
|
||||
if (isRanged() && !rangep()) str<<" range=["<<msb()<<":"<<lsb()<<"]";
|
||||
if (isRanged() && !rangep()) str<<" range=["<<left()<<":"<<right()<<"]";
|
||||
if (implicit()) str<<" [IMPLICIT]";
|
||||
}
|
||||
void AstCCast::dump(ostream& str) {
|
||||
@@ -620,7 +621,7 @@ void AstVar::dump(ostream& str) {
|
||||
if (isConst()) str<<" [CONST]";
|
||||
if (isUsedClock()) str<<" [CLK]";
|
||||
if (isSigPublic()) str<<" [P]";
|
||||
if (isUsedLoopIdx()) str<<" [LOOP]";
|
||||
if (isUsedLoopIdx()) str<<" [LOOP]";
|
||||
if (attrClockEn()) str<<" [aCLKEN]";
|
||||
if (attrIsolateAssign()) str<<" [aISO]";
|
||||
if (attrFileDescr()) str<<" [aFD]";
|
||||
|
||||
+147
-106
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Ast node structure
|
||||
//
|
||||
@@ -50,32 +50,35 @@ public:
|
||||
:AstNodeMath(fl)
|
||||
,m_num(num) {
|
||||
if (m_num.isDouble()) {
|
||||
dtypeChgDouble();
|
||||
dtypeSetDouble();
|
||||
} else {
|
||||
width(m_num.width(), m_num.sized()?0:m_num.widthMin());
|
||||
numeric(m_num.isSigned() ? AstNumeric::SIGNED
|
||||
: AstNumeric::UNSIGNED);
|
||||
dtypeSetLogicSized(m_num.width(), m_num.sized()?0:m_num.widthMin(),
|
||||
m_num.isSigned() ? AstNumeric::SIGNED
|
||||
: AstNumeric::UNSIGNED);
|
||||
}
|
||||
}
|
||||
AstConst(FileLine* fl, uint32_t num)
|
||||
:AstNodeMath(fl)
|
||||
,m_num(V3Number(fl,32,num)) { width(m_num.width(), m_num.sized()?0:m_num.widthMin()); }
|
||||
,m_num(V3Number(fl,32,num)) { dtypeSetLogicSized(m_num.width(),
|
||||
m_num.sized()?0:m_num.widthMin(),
|
||||
AstNumeric::UNSIGNED); }
|
||||
class Unsized32 {}; // for creator type-overload selection
|
||||
AstConst(FileLine* fl, Unsized32, uint32_t num) // Unsized 32-bit integer of specified value
|
||||
:AstNodeMath(fl)
|
||||
,m_num(V3Number(fl,32,num)) { m_num.width(32,false); width(32,m_num.widthMin()); }
|
||||
,m_num(V3Number(fl,32,num)) { m_num.width(32,false); dtypeSetLogicSized(32,m_num.widthMin(),
|
||||
AstNumeric::UNSIGNED); }
|
||||
class RealDouble {}; // for creator type-overload selection
|
||||
AstConst(FileLine* fl, RealDouble, double num)
|
||||
:AstNodeMath(fl)
|
||||
,m_num(V3Number(fl,64)) { m_num.setDouble(num); dtypeChgDouble(); }
|
||||
,m_num(V3Number(fl,64)) { m_num.setDouble(num); dtypeSetDouble(); }
|
||||
class LogicFalse {};
|
||||
AstConst(FileLine* fl, LogicFalse) // Shorthand const 0, know the dtype should be a logic of size 1
|
||||
:AstNodeMath(fl)
|
||||
,m_num(V3Number(fl,1,0)) { dtypeChgLogicBool(); }
|
||||
,m_num(V3Number(fl,1,0)) { dtypeSetLogicBool(); }
|
||||
class LogicTrue {};
|
||||
AstConst(FileLine* fl, LogicTrue) // Shorthand const 1, know the dtype should be a logic of size 1
|
||||
:AstNodeMath(fl)
|
||||
,m_num(V3Number(fl,1,1)) { dtypeChgLogicBool(); }
|
||||
,m_num(V3Number(fl,1,1)) { dtypeSetLogicBool(); }
|
||||
|
||||
ASTNODE_NODE_FUNCS(Const, CONST)
|
||||
virtual string name() const { return num().ascii(); } // * = Value
|
||||
@@ -105,9 +108,9 @@ public:
|
||||
}
|
||||
void rewidth() {
|
||||
if (m_name.length()==0) {
|
||||
width(1,1); // 0 width isn't allowed due to historic special cases
|
||||
dtypeSetLogicSized(1,1,AstNumeric::UNSIGNED); // 0 width isn't allowed due to historic special cases
|
||||
} else {
|
||||
width(((int)m_name.length())*8, ((int)m_name.length())*8);
|
||||
dtypeSetLogicSized(((int)m_name.length())*8, ((int)m_name.length())*8, AstNumeric::UNSIGNED);
|
||||
}
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(ConstString, CONSTSTRING)
|
||||
@@ -139,8 +142,8 @@ public:
|
||||
ASTNODE_NODE_FUNCS(Range, RANGE)
|
||||
AstNode* msbp() const { return op2p()->castNode(); } // op2 = Msb expression
|
||||
AstNode* lsbp() const { return op3p()->castNode(); } // op3 = Lsb expression
|
||||
AstNode* msbEndianedp() const { return littleEndian()?lsbp():msbp(); } // How to show a declaration
|
||||
AstNode* lsbEndianedp() const { return littleEndian()?msbp():lsbp(); }
|
||||
AstNode* leftp() const { return littleEndian()?lsbp():msbp(); } // How to show a declaration
|
||||
AstNode* rightp() const { return littleEndian()?msbp():lsbp(); }
|
||||
int msbConst() const { AstConst* constp=msbp()->castConst(); return (constp?constp->toSInt():0); }
|
||||
int lsbConst() const { AstConst* constp=lsbp()->castConst(); return (constp?constp->toSInt():0); }
|
||||
int elementsConst() const { return (msbConst()>lsbConst()) ? msbConst()-lsbConst()+1 : lsbConst()-msbConst()+1; }
|
||||
@@ -159,7 +162,7 @@ struct AstTypedef : public AstNode {
|
||||
private:
|
||||
string m_name;
|
||||
public:
|
||||
AstTypedef(FileLine* fl, const string& name, AstNodeDType* dtp)
|
||||
AstTypedef(FileLine* fl, const string& name, VFlagChildDType, AstNodeDType* dtp)
|
||||
: AstNode(fl), m_name(name) {
|
||||
setOp1p(dtp);
|
||||
widthSignedFrom(dtp);
|
||||
@@ -167,9 +170,11 @@ public:
|
||||
ASTNODE_NODE_FUNCS(Typedef, TYPEDEF)
|
||||
AstNodeDType* dtypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
|
||||
void dtypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
AstNodeDType* subDTypep() const { return dtypep(); }
|
||||
// METHODS
|
||||
virtual string name() const { return m_name; }
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
virtual bool hasDType() const { return true; }
|
||||
void name(const string& flag) { m_name = flag; }
|
||||
};
|
||||
|
||||
@@ -193,7 +198,8 @@ private:
|
||||
string m_name;
|
||||
void* m_containerp; // In what scope is the name unique, so we can know what are duplicate definitions (arbitrary value)
|
||||
public:
|
||||
AstDefImplicitDType(FileLine* fl, const string& name, AstNode* containerp, AstNodeDType* dtp)
|
||||
AstDefImplicitDType(FileLine* fl, const string& name, AstNode* containerp,
|
||||
VFlagChildDType, AstNodeDType* dtp)
|
||||
: AstNodeDType(fl), m_name(name), m_containerp(containerp) {
|
||||
setOp1p(dtp);
|
||||
widthSignedFrom(dtp);
|
||||
@@ -217,6 +223,12 @@ struct AstArrayDType : public AstNodeDType {
|
||||
private:
|
||||
bool m_packed;
|
||||
public:
|
||||
AstArrayDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstRange* rangep, bool isPacked=false)
|
||||
: AstNodeDType(fl), m_packed(isPacked) {
|
||||
setOp1p(dtp);
|
||||
setOp2p(rangep);
|
||||
widthSignedFrom(dtp);
|
||||
}
|
||||
AstArrayDType(FileLine* fl, AstNodeDType* dtp, AstRange* rangep, bool isPacked=false)
|
||||
: AstNodeDType(fl), m_packed(isPacked) {
|
||||
setOp1p(dtp);
|
||||
@@ -228,6 +240,7 @@ public:
|
||||
AstNodeDType* dtypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
|
||||
AstNodeDType* dtypeSkipRefp() const { return dtypep()->skipRefp(); } // op1 = Range of variable
|
||||
void dtypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
AstNodeDType* subDTypep() const { return dtypep(); }
|
||||
AstRange* arrayp() const { return op2p()->castRange(); } // op2 = Array(s) of variable
|
||||
void arrayp(AstRange* nodep) { setOp2p(nodep); }
|
||||
// METHODS
|
||||
@@ -255,11 +268,11 @@ public:
|
||||
: AstNodeDType(fl) {
|
||||
init(kwd, signst, 0, NULL);
|
||||
}
|
||||
AstBasicDType(FileLine* fl, AstLogicPacked, int wantwidth)
|
||||
AstBasicDType(FileLine* fl, VFlagLogicPacked, int wantwidth)
|
||||
: AstNodeDType(fl) {
|
||||
init(AstBasicDTypeKwd::LOGIC, signedst_NOSIGNED, wantwidth, NULL);
|
||||
}
|
||||
AstBasicDType(FileLine* fl, AstBitPacked, int wantwidth)
|
||||
AstBasicDType(FileLine* fl, VFlagBitPacked, int wantwidth)
|
||||
: AstNodeDType(fl) {
|
||||
init(AstBasicDTypeKwd::BIT, signedst_NOSIGNED, wantwidth, NULL);
|
||||
}
|
||||
@@ -279,7 +292,7 @@ private:
|
||||
if (keyword().isSigned()) signst = signedst_SIGNED;
|
||||
else m_nosigned = true;
|
||||
}
|
||||
if (keyword().isDouble()) dtypeChgDouble();
|
||||
if (keyword().isDouble()) dtypeSetDouble();
|
||||
else setSignedState(signst);
|
||||
if (!rangep && wantwidth) { // Constant width
|
||||
m_msb = wantwidth - 1;
|
||||
@@ -320,8 +333,8 @@ public:
|
||||
bool isRanged() const { return rangep() || m_msb; }
|
||||
int msb() const { if (!rangep()) return m_msb; return rangep()->msbConst(); }
|
||||
int lsb() const { if (!rangep()) return 0; return rangep()->lsbConst(); }
|
||||
int msbEndianed() const { if (!rangep()) return m_msb; return littleEndian()?rangep()->lsbConst():rangep()->msbConst(); }
|
||||
int lsbEndianed() const { if (!rangep()) return 0; return littleEndian()?rangep()->msbConst():rangep()->lsbConst(); }
|
||||
int left() const { if (!rangep()) return m_msb; return littleEndian()?rangep()->lsbConst():rangep()->msbConst(); }
|
||||
int right() const { if (!rangep()) return 0; return littleEndian()?rangep()->msbConst():rangep()->lsbConst(); }
|
||||
int msbMaxSelect() const { return (lsb()<0 ? msb()-lsb() : msb()); } // Maximum value a [] select may index
|
||||
bool littleEndian() const { return (rangep() && rangep()->littleEndian()); }
|
||||
bool implicit() const { return m_implicit; }
|
||||
@@ -334,7 +347,8 @@ struct AstConstDType : public AstNodeDType {
|
||||
// const data type, ie "const some_dtype var_name [2:0]"
|
||||
// ConstDType are removed in V3LinkLValue and become AstVar::isConst.
|
||||
// When more generic types are supported AstConstDType will be propagated further.
|
||||
AstConstDType(FileLine* fl, AstNodeDType* dtp)
|
||||
public:
|
||||
AstConstDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp)
|
||||
: AstNodeDType(fl) {
|
||||
setOp1p(dtp);
|
||||
widthSignedFrom(dtp);
|
||||
@@ -342,6 +356,7 @@ struct AstConstDType : public AstNodeDType {
|
||||
ASTNODE_NODE_FUNCS(ConstDType, CONSTDTYPE)
|
||||
AstNodeDType* dtypep() const { return op1p()->castNodeDType(); } // op1 = Range of variable
|
||||
void dtypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
AstNodeDType* subDTypep() const { return dtypep(); }
|
||||
// METHODS
|
||||
virtual AstBasicDType* basicp() const { return dtypep()->basicp(); } // (Slow) recurse down to find basic data type
|
||||
virtual AstNodeDType* skipRefp() const { return (AstNodeDType*)this; }
|
||||
@@ -351,25 +366,25 @@ struct AstConstDType : public AstNodeDType {
|
||||
|
||||
struct AstRefDType : public AstNodeDType {
|
||||
private:
|
||||
AstNodeDType* m_defp; // data type pointed to, BELOW the AstTypedef
|
||||
AstNodeDType* m_subDTypep; // data type pointed to, BELOW the AstTypedef
|
||||
string m_name; // Name of an AstTypedef
|
||||
AstPackage* m_packagep; // Package hierarchy
|
||||
public:
|
||||
AstRefDType(FileLine* fl, const string& name)
|
||||
: AstNodeDType(fl), m_defp(NULL), m_name(name), m_packagep(NULL) {}
|
||||
: AstNodeDType(fl), m_subDTypep(NULL), m_name(name), m_packagep(NULL) {}
|
||||
AstRefDType(FileLine* fl, AstNodeDType* defp)
|
||||
: AstNodeDType(fl), m_defp(defp), m_packagep(NULL) {
|
||||
: AstNodeDType(fl), m_subDTypep(defp), m_packagep(NULL) {
|
||||
widthSignedFrom(defp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(RefDType, REFDTYPE)
|
||||
// METHODS
|
||||
virtual bool broken() const { return m_defp && !m_defp->brokeExists(); }
|
||||
virtual void cloneRelink() { if (m_defp && m_defp->clonep()) {
|
||||
m_defp = m_defp->clonep()->castNodeDType();
|
||||
virtual bool broken() const { return m_subDTypep && !m_subDTypep->brokeExists(); }
|
||||
virtual void cloneRelink() { if (m_subDTypep && m_subDTypep->clonep()) {
|
||||
m_subDTypep = m_subDTypep->clonep()->castNodeDType();
|
||||
}}
|
||||
virtual V3Hash sameHash() const { return V3Hash(skipRefp()); }
|
||||
virtual bool same(AstNode* samep) const {
|
||||
return skipRefp()->sameTree(samep->castRefDType()->skipRefp()); }
|
||||
virtual V3Hash sameHash() const { return V3Hash(skipRefp()); }
|
||||
virtual void dump(ostream& str=cout);
|
||||
virtual string name() const { return m_name; }
|
||||
virtual AstBasicDType* basicp() const { return defp() ? defp()->basicp() : NULL; }
|
||||
@@ -386,8 +401,9 @@ public:
|
||||
else { v3fatalSrc("Typedef not linked"); return NULL; }
|
||||
}
|
||||
AstNodeDType* dtypeSkipRefp() const { return defp()->skipRefp(); } // op1 = Range of variable
|
||||
AstNodeDType* defp() const { return m_defp; }
|
||||
void defp(AstNodeDType* nodep) { m_defp=nodep; }
|
||||
AstNodeDType* defp() const { return m_subDTypep; }
|
||||
AstNodeDType* subDTypep() const { return m_subDTypep; }
|
||||
void subDTypep(AstNodeDType* nodep) { m_subDTypep=nodep; }
|
||||
AstPackage* packagep() const { return m_packagep; }
|
||||
void packagep(AstPackage* nodep) { m_packagep=nodep; }
|
||||
};
|
||||
@@ -403,6 +419,7 @@ public:
|
||||
ASTNODE_NODE_FUNCS(EnumItem, ENUMITEM)
|
||||
virtual string name() const { return m_name; }
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
virtual bool hasDType() const { return true; }
|
||||
void name(const string& flag) { m_name = flag; }
|
||||
AstRange* rangep() const { return op1p()->castRange(); } // op1 = Range for name appending
|
||||
void rangep(AstNode* nodep) { addOp1p(nodep); }
|
||||
@@ -438,7 +455,8 @@ public:
|
||||
struct AstEnumDType : public AstNodeDType {
|
||||
// Parents: TYPEDEF/MODULE
|
||||
// Children: ENUMVALUEs
|
||||
AstEnumDType(FileLine* fl, AstNodeDType* dtp, AstNode* itemsp)
|
||||
public:
|
||||
AstEnumDType(FileLine* fl, VFlagChildDType, AstNodeDType* dtp, AstNode* itemsp)
|
||||
: AstNodeDType(fl)
|
||||
{ setOp1p(dtp); addNOp2p(itemsp); }
|
||||
ASTNODE_NODE_FUNCS(EnumDType, ENUMDTYPE)
|
||||
@@ -446,6 +464,7 @@ struct AstEnumDType : public AstNodeDType {
|
||||
void dtypep(AstNodeDType* nodep) { setOp1p(nodep); }
|
||||
AstEnumItem* itemsp() const { return op2p()->castEnumItem(); } // op2 = AstEnumItem's
|
||||
void addValuesp(AstNode* nodep) { addOp2p(nodep); }
|
||||
AstNodeDType* subDTypep() const { return dtypep(); }
|
||||
// METHODS
|
||||
virtual AstBasicDType* basicp() const { return dtypep()->basicp(); } // (Slow) recurse down to find basic data type
|
||||
virtual AstNodeDType* skipRefp() const { return dtypep()->skipRefp(); }
|
||||
@@ -500,7 +519,7 @@ struct AstWordSel : public AstNodeSel {
|
||||
// Select a single word from a multi-word wide value
|
||||
AstWordSel(FileLine* fl, AstNode* fromp, AstNode* bitp)
|
||||
:AstNodeSel(fl, fromp, bitp) {
|
||||
dtypeChgUInt32(); // Always used on IData arrays so returns word entities
|
||||
dtypeSetUInt32(); // Always used on IData arrays so returns word entities
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(WordSel, WORDSEL)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& from, const V3Number& bit) { V3ERROR_NA; }
|
||||
@@ -634,6 +653,16 @@ private:
|
||||
m_trace=false;
|
||||
}
|
||||
public:
|
||||
AstVar(FileLine* fl, AstVarType type, const string& name, VFlagChildDType, AstNodeDType* dtp)
|
||||
:AstNode(fl)
|
||||
, m_name(name) {
|
||||
init();
|
||||
combineType(type); setOp1p(dtp);
|
||||
if (dtp && dtp->basicp()) {
|
||||
numericFrom(dtp);
|
||||
width(dtp->basicp()->width(), 0);
|
||||
} else width(1, 0);
|
||||
}
|
||||
AstVar(FileLine* fl, AstVarType type, const string& name, AstNodeDType* dtp)
|
||||
:AstNode(fl)
|
||||
, m_name(name) {
|
||||
@@ -644,20 +673,20 @@ public:
|
||||
width(dtp->basicp()->width(), 0);
|
||||
} else width(1, 0);
|
||||
}
|
||||
AstVar(FileLine* fl, AstVarType type, const string& name, AstLogicPacked, int wantwidth)
|
||||
AstVar(FileLine* fl, AstVarType type, const string& name, VFlagLogicPacked, int wantwidth)
|
||||
:AstNode(fl)
|
||||
, m_name(name) {
|
||||
init();
|
||||
combineType(type);
|
||||
setOp1p(new AstBasicDType(fl, AstLogicPacked(), wantwidth));
|
||||
setOp1p(new AstBasicDType(fl, VFlagLogicPacked(), wantwidth));
|
||||
width(wantwidth,0);
|
||||
}
|
||||
AstVar(FileLine* fl, AstVarType type, const string& name, AstBitPacked, int wantwidth)
|
||||
AstVar(FileLine* fl, AstVarType type, const string& name, VFlagBitPacked, int wantwidth)
|
||||
:AstNode(fl)
|
||||
, m_name(name) {
|
||||
init();
|
||||
combineType(type);
|
||||
setOp1p(new AstBasicDType(fl, AstBitPacked(), wantwidth));
|
||||
setOp1p(new AstBasicDType(fl, VFlagBitPacked(), wantwidth));
|
||||
width(wantwidth,0);
|
||||
}
|
||||
AstVar(FileLine* fl, AstVarType type, const string& name, AstVar* examplep)
|
||||
@@ -674,6 +703,7 @@ public:
|
||||
ASTNODE_NODE_FUNCS(Var, VAR)
|
||||
virtual void dump(ostream& str);
|
||||
virtual string name() const { return m_name; } // * = Var name
|
||||
virtual bool hasDType() const { return true; }
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
virtual bool broken() const { return !dtypep(); }
|
||||
AstVarType varType() const { return m_varType; } // * = Type of variable
|
||||
@@ -903,6 +933,7 @@ public:
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
virtual string name() const {return scopep()->name()+"->"+varp()->name();} // * = Var name
|
||||
virtual void dump(ostream& str);
|
||||
virtual bool hasDType() const { return true; }
|
||||
AstVar* varp() const { return m_varp; } // [After Link] Pointer to variable
|
||||
AstScope* scopep() const { return m_scopep; } // Pointer to scope it's under
|
||||
AstNode* valuep() const { return op1p(); } // op1 = Calculation of value of variable, NULL=complicated
|
||||
@@ -1222,6 +1253,7 @@ struct AstFunc : public AstNodeFTask {
|
||||
addNOp1p(fvarsp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(Func, FUNC)
|
||||
virtual bool hasDType() const { return true; }
|
||||
};
|
||||
|
||||
struct AstTaskRef : public AstNodeFTaskRef {
|
||||
@@ -1240,6 +1272,7 @@ struct AstFuncRef : public AstNodeFTaskRef {
|
||||
AstFuncRef(FileLine* fl, const string& name, AstNode* pinsp)
|
||||
:AstNodeFTaskRef(fl, name, pinsp) {}
|
||||
ASTNODE_NODE_FUNCS(FuncRef, FUNCREF)
|
||||
virtual bool hasDType() const { return true; }
|
||||
};
|
||||
|
||||
struct AstDpiExport : public AstNode {
|
||||
@@ -1319,7 +1352,7 @@ struct AstSenGate : public AstNodeSenItem {
|
||||
// AND as applied to a sensitivity list and a gating expression
|
||||
// Performing this gating is optional; it may be removed by later optimizations
|
||||
AstSenGate(FileLine* fl, AstSenItem* sensesp, AstNode* rhsp) : AstNodeSenItem(fl) {
|
||||
dtypeChgLogicBool(); addOp1p(sensesp); setOp2p(rhsp);
|
||||
dtypeSetLogicBool(); addOp1p(sensesp); setOp2p(rhsp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(SenGate, SENGATE)
|
||||
virtual string emitVerilog() { return "(%l) %f&& (%r)"; }
|
||||
@@ -1451,7 +1484,7 @@ struct AstPull : public AstNode {
|
||||
private:
|
||||
bool m_direction;
|
||||
public:
|
||||
AstPull(FileLine* fileline, AstNode* lhsp, bool direction)
|
||||
AstPull(FileLine* fileline, AstNode* lhsp, bool direction)
|
||||
: AstNode(fileline) {
|
||||
setOp1p(lhsp);
|
||||
m_direction = direction;
|
||||
@@ -2069,8 +2102,8 @@ struct AstWhile : public AstNodeStmt {
|
||||
virtual int instrCount() const { return instrCountBranch(); }
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(AstNode* samep) const { return true; }
|
||||
virtual void addBeforeStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here
|
||||
virtual void addNextStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here
|
||||
virtual void addBeforeStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here
|
||||
virtual void addNextStmt(AstNode* newp, AstNode* belowp); // Stop statement searchback here
|
||||
};
|
||||
|
||||
struct AstBreak : public AstNodeStmt {
|
||||
@@ -2215,7 +2248,7 @@ struct AstChangeXor : public AstNodeBiComAsv {
|
||||
// Children: VARREF
|
||||
AstChangeXor(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
|
||||
: AstNodeBiComAsv(fl, lhsp, rhsp) {
|
||||
dtypeChgUInt32(); // Always used on, and returns word entities
|
||||
dtypeSetUInt32(); // Always used on, and returns word entities
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(ChangeXor, CHANGEXOR)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opChangeXor(lhs,rhs); }
|
||||
@@ -2339,8 +2372,8 @@ struct AstTraceDecl : public AstNodeStmt {
|
||||
private:
|
||||
string m_showname; // Name of variable
|
||||
uint32_t m_code; // Trace identifier code; converted to ASCII by trace routines
|
||||
int m_lsb; // Property of var the trace details
|
||||
int m_msb; // Property of var the trace details
|
||||
int m_right; // Property of var the trace details
|
||||
int m_left; // Property of var the trace details
|
||||
uint32_t m_arrayLsb; // Property of var the trace details
|
||||
uint32_t m_arrayMsb; // Property of var the trace details
|
||||
uint32_t m_codeInc; // Code increment
|
||||
@@ -2352,8 +2385,8 @@ public:
|
||||
m_code = 0;
|
||||
m_codeInc = varp->dtypep()->arrayElements() * varp->widthWords();
|
||||
AstBasicDType* bdtypep = varp->basicp();
|
||||
m_msb = bdtypep ? bdtypep->msbEndianed() : 0;
|
||||
m_lsb = bdtypep ? bdtypep->lsbEndianed() : 0;
|
||||
m_left = bdtypep ? bdtypep->left() : 0;
|
||||
m_right = bdtypep ? bdtypep->right() : 0;
|
||||
if (AstArrayDType* adtypep = varp->dtypeSkipRefp()->castArrayDType()) {
|
||||
m_arrayLsb = adtypep->arrayp()->lsbConst();
|
||||
m_arrayMsb = adtypep->arrayp()->msbConst();
|
||||
@@ -2366,14 +2399,15 @@ public:
|
||||
ASTNODE_NODE_FUNCS(TraceDecl, TRACEDECL)
|
||||
virtual string name() const { return m_showname; }
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
virtual bool hasDType() const { return true; }
|
||||
virtual bool same(AstNode* samep) const { return false; }
|
||||
string showname() const { return m_showname; } // * = Var name
|
||||
// Details on what we're tracing
|
||||
uint32_t code() const { return m_code; }
|
||||
void code(uint32_t code) { m_code=code; }
|
||||
uint32_t codeInc() const { return m_codeInc; }
|
||||
int msbEndianed() const { return m_msb; } // Note msb maybe < lsb if little endian
|
||||
int lsbEndianed() const { return m_lsb; }
|
||||
int left() const { return m_left; } // Note msb maybe < lsb if little endian
|
||||
int right() const { return m_right; }
|
||||
uint32_t arrayMsb() const { return m_arrayMsb; }
|
||||
uint32_t arrayLsb() const { return m_arrayLsb; }
|
||||
uint32_t arrayWidth() const { if (!arrayMsb()) return 0; return arrayMsb()-arrayLsb()+1; }
|
||||
@@ -2397,6 +2431,7 @@ public:
|
||||
virtual void cloneRelink() { if (m_declp->clonep()) m_declp = m_declp->clonep()->castTraceDecl(); }
|
||||
virtual void dump(ostream& str);
|
||||
virtual int instrCount() const { return 10+2*instrCountLd(); }
|
||||
virtual bool hasDType() const { return true; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(declp()); }
|
||||
virtual bool same(AstNode* samep) const {
|
||||
return declp()==samep->castTraceInc()->declp(); }
|
||||
@@ -2474,7 +2509,7 @@ private:
|
||||
bool m_dpiExport; // Is for dpiExport
|
||||
public:
|
||||
AstScopeName(FileLine* fl) : AstNodeMath(fl), m_dpiExport(false) {
|
||||
dtypeChgUInt64(); }
|
||||
dtypeSetUInt64(); }
|
||||
ASTNODE_NODE_FUNCS(ScopeName, SCOPENAME)
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(AstNode* samep) const { return m_dpiExport==samep->castScopeName()->m_dpiExport; }
|
||||
@@ -2535,7 +2570,7 @@ public:
|
||||
|
||||
struct AstTime : public AstNodeTermop {
|
||||
AstTime(FileLine* fl) : AstNodeTermop(fl) {
|
||||
dtypeChgUInt64(); }
|
||||
dtypeSetUInt64(); }
|
||||
ASTNODE_NODE_FUNCS(Time, TIME)
|
||||
virtual string emitVerilog() { return "%f$time"; }
|
||||
virtual string emitC() { return "VL_TIME_%nq()"; }
|
||||
@@ -2549,7 +2584,7 @@ struct AstTime : public AstNodeTermop {
|
||||
|
||||
struct AstTimeD : public AstNodeTermop {
|
||||
AstTimeD(FileLine* fl) : AstNodeTermop(fl) {
|
||||
dtypeChgDouble(); }
|
||||
dtypeSetDouble(); }
|
||||
ASTNODE_NODE_FUNCS(TimeD, TIMED)
|
||||
virtual string emitVerilog() { return "%f$realtime"; }
|
||||
virtual string emitC() { return "VL_TIME_D()"; }
|
||||
@@ -2598,7 +2633,7 @@ struct AstNegate : public AstNodeUniop {
|
||||
};
|
||||
struct AstNegateD : public AstNodeUniop {
|
||||
AstNegateD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgDouble(); }
|
||||
dtypeSetDouble(); }
|
||||
ASTNODE_NODE_FUNCS(NegateD, NEGATED)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opNegateD(lhs); }
|
||||
virtual string emitVerilog() { return "%f(- %l)"; }
|
||||
@@ -2611,7 +2646,7 @@ struct AstNegateD : public AstNodeUniop {
|
||||
};
|
||||
struct AstRedAnd : public AstNodeUniop {
|
||||
AstRedAnd(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(RedAnd, REDAND)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedAnd(lhs); }
|
||||
virtual string emitVerilog() { return "%f(& %l)"; }
|
||||
@@ -2621,7 +2656,7 @@ struct AstRedAnd : public AstNodeUniop {
|
||||
};
|
||||
struct AstRedOr : public AstNodeUniop {
|
||||
AstRedOr(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(RedOr, REDOR)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedOr(lhs); }
|
||||
virtual string emitVerilog() { return "%f(| %l)"; }
|
||||
@@ -2631,7 +2666,7 @@ struct AstRedOr : public AstNodeUniop {
|
||||
};
|
||||
struct AstRedXor : public AstNodeUniop {
|
||||
AstRedXor(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(RedXor, REDXOR)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedXor(lhs); }
|
||||
virtual string emitVerilog() { return "%f(^ %l)"; }
|
||||
@@ -2645,7 +2680,7 @@ struct AstRedXor : public AstNodeUniop {
|
||||
struct AstRedXnor : public AstNodeUniop {
|
||||
// AstRedXnors are replaced with AstRedXors in V3Const.
|
||||
AstRedXnor(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(RedXnor, REDXNOR)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedXnor(lhs); }
|
||||
virtual string emitVerilog() { return "%f(~^ %l)"; }
|
||||
@@ -2657,7 +2692,7 @@ struct AstRedXnor : public AstNodeUniop {
|
||||
|
||||
struct AstLogNot : public AstNodeUniop {
|
||||
AstLogNot(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(LogNot, LOGNOT)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opLogNot(lhs); }
|
||||
virtual string emitVerilog() { return "%f(! %l)"; }
|
||||
@@ -2729,7 +2764,7 @@ struct AstUnsigned : public AstNodeUniop {
|
||||
struct AstRToIS : public AstNodeUniop {
|
||||
// $rtoi(lhs)
|
||||
AstRToIS(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgSigned32(); }
|
||||
dtypeSetSigned32(); }
|
||||
ASTNODE_NODE_FUNCS(RToIS, RTOIS)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRToIS(lhs); }
|
||||
virtual string emitVerilog() { return "%f$rtoi(%l)"; }
|
||||
@@ -2740,7 +2775,7 @@ struct AstRToIS : public AstNodeUniop {
|
||||
};
|
||||
struct AstRToIRoundS : public AstNodeUniop {
|
||||
AstRToIRoundS(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgSigned32(); }
|
||||
dtypeSetSigned32(); }
|
||||
ASTNODE_NODE_FUNCS(RToIRoundS, RTOIROUNDS)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRToIRoundS(lhs); }
|
||||
virtual string emitVerilog() { return "%f$rtoi_rounded(%l)"; }
|
||||
@@ -2751,7 +2786,7 @@ struct AstRToIRoundS : public AstNodeUniop {
|
||||
};
|
||||
struct AstIToRD : public AstNodeUniop {
|
||||
AstIToRD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgDouble(); }
|
||||
dtypeSetDouble(); }
|
||||
ASTNODE_NODE_FUNCS(IToRD, ITORD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opIToRD(lhs); }
|
||||
virtual string emitVerilog() { return "%f$itor(%l)"; }
|
||||
@@ -2762,7 +2797,7 @@ struct AstIToRD : public AstNodeUniop {
|
||||
};
|
||||
struct AstRealToBits : public AstNodeUniop {
|
||||
AstRealToBits(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgUInt64(); }
|
||||
dtypeSetUInt64(); }
|
||||
ASTNODE_NODE_FUNCS(RealToBits, REALTOBITS)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRealToBits(lhs); }
|
||||
virtual string emitVerilog() { return "%f$realtobits(%l)"; }
|
||||
@@ -2773,7 +2808,7 @@ struct AstRealToBits : public AstNodeUniop {
|
||||
};
|
||||
struct AstBitsToRealD : public AstNodeUniop {
|
||||
AstBitsToRealD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgDouble(); }
|
||||
dtypeSetDouble(); }
|
||||
ASTNODE_NODE_FUNCS(BitsToRealD, BITSTOREALD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opBitsToRealD(lhs); }
|
||||
virtual string emitVerilog() { return "%f$bitstoreal(%l)"; }
|
||||
@@ -2807,7 +2842,7 @@ struct AstCountOnes : public AstNodeUniop {
|
||||
struct AstIsUnknown : public AstNodeUniop {
|
||||
// True if any unknown bits
|
||||
AstIsUnknown(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(IsUnknown, ISUNKNOWN)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opIsUnknown(lhs); }
|
||||
virtual string emitVerilog() { return "%f$isunknown(%l)"; }
|
||||
@@ -2818,7 +2853,7 @@ struct AstIsUnknown : public AstNodeUniop {
|
||||
struct AstOneHot : public AstNodeUniop {
|
||||
// True if only single bit set in vector
|
||||
AstOneHot(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(OneHot, ONEHOT)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opOneHot(lhs); }
|
||||
virtual string emitVerilog() { return "%f$onehot(%l)"; }
|
||||
@@ -2830,7 +2865,7 @@ struct AstOneHot : public AstNodeUniop {
|
||||
struct AstOneHot0 : public AstNodeUniop {
|
||||
// True if only single bit, or no bits set in vector
|
||||
AstOneHot0(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(OneHot0, ONEHOT0)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opOneHot0(lhs); }
|
||||
virtual string emitVerilog() { return "%f$onehot0(%l)"; }
|
||||
@@ -2847,6 +2882,7 @@ struct AstCast : public AstNode {
|
||||
if (dtp) { widthSignedFrom(dtp); }
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(Cast, CAST)
|
||||
virtual bool hasDType() const { return true; }
|
||||
virtual string emitVerilog() { return "((%r)'(%l))"; }
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
virtual bool cleanOut() { V3ERROR_NA; return true;} virtual bool cleanLhs() {return true;}
|
||||
@@ -2860,9 +2896,12 @@ struct AstCCast : public AstNodeUniop {
|
||||
private:
|
||||
int m_size;
|
||||
public:
|
||||
AstCCast(FileLine* fl, AstNode* lhsp, int setwidth) : AstNodeUniop(fl, lhsp) {
|
||||
AstCCast(FileLine* fl, AstNode* lhsp, int setwidth, int minwidth=-1) : AstNodeUniop(fl, lhsp) {
|
||||
m_size=setwidth;
|
||||
if (setwidth) { width(setwidth,setwidth); }
|
||||
if (setwidth) {
|
||||
if (minwidth==-1) minwidth=setwidth;
|
||||
dtypeSetLogicSized(setwidth,minwidth,AstNumeric::UNSIGNED);
|
||||
}
|
||||
}
|
||||
AstCCast(FileLine* fl, AstNode* lhsp, AstNode* typeFromp) : AstNodeUniop(fl, lhsp) {
|
||||
if (typeFromp) { widthSignedFrom(typeFromp); }
|
||||
@@ -2884,7 +2923,7 @@ public:
|
||||
struct AstCvtPackString : public AstNodeUniop {
|
||||
// Convert to Verilator Packed Pack (aka Pack)
|
||||
AstCvtPackString(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgUInt64(); } // Really, width should be dtypep -> STRING
|
||||
dtypeSetUInt64(); } // Really, width should be dtypep -> STRING
|
||||
ASTNODE_NODE_FUNCS(CvtPackString, CVTPACKSTRING)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { V3ERROR_NA; }
|
||||
virtual string emitVerilog() { return "%f$_CAST(%l)"; }
|
||||
@@ -2922,7 +2961,7 @@ struct AstFGetC : public AstNodeUniop {
|
||||
|
||||
struct AstCeilD : public AstNodeUniop {
|
||||
AstCeilD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgDouble(); }
|
||||
dtypeSetDouble(); }
|
||||
ASTNODE_NODE_FUNCS(CeilD, CEILD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) {
|
||||
out.setDouble(ceil(lhs.toDouble())); }
|
||||
@@ -2936,7 +2975,7 @@ struct AstCeilD : public AstNodeUniop {
|
||||
|
||||
struct AstExpD : public AstNodeUniop {
|
||||
AstExpD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgDouble(); }
|
||||
dtypeSetDouble(); }
|
||||
ASTNODE_NODE_FUNCS(ExpD, EXPD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) {
|
||||
out.setDouble(exp(lhs.toDouble())); }
|
||||
@@ -2950,7 +2989,7 @@ struct AstExpD : public AstNodeUniop {
|
||||
|
||||
struct AstFloorD : public AstNodeUniop {
|
||||
AstFloorD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgDouble(); }
|
||||
dtypeSetDouble(); }
|
||||
ASTNODE_NODE_FUNCS(FloorD, FLOORD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) {
|
||||
out.setDouble(floor(lhs.toDouble())); }
|
||||
@@ -2964,7 +3003,7 @@ struct AstFloorD : public AstNodeUniop {
|
||||
|
||||
struct AstLogD : public AstNodeUniop {
|
||||
AstLogD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgDouble(); }
|
||||
dtypeSetDouble(); }
|
||||
ASTNODE_NODE_FUNCS(LogD, LOGD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) {
|
||||
out.setDouble(log(lhs.toDouble())); }
|
||||
@@ -2978,7 +3017,7 @@ struct AstLogD : public AstNodeUniop {
|
||||
|
||||
struct AstLog10D : public AstNodeUniop {
|
||||
AstLog10D(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgDouble(); }
|
||||
dtypeSetDouble(); }
|
||||
ASTNODE_NODE_FUNCS(Log10D, LOG10D)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) {
|
||||
out.setDouble(log10(lhs.toDouble())); }
|
||||
@@ -2992,7 +3031,7 @@ struct AstLog10D : public AstNodeUniop {
|
||||
|
||||
struct AstSqrtD : public AstNodeUniop {
|
||||
AstSqrtD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
|
||||
dtypeChgDouble(); }
|
||||
dtypeSetDouble(); }
|
||||
ASTNODE_NODE_FUNCS(SqrtD, SQRTD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) {
|
||||
out.setDouble(sqrt(lhs.toDouble())); }
|
||||
@@ -3009,7 +3048,7 @@ struct AstSqrtD : public AstNodeUniop {
|
||||
|
||||
struct AstLogOr : public AstNodeBiop {
|
||||
AstLogOr(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(LogOr, LOGOR)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogOr(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f|| %r)"; }
|
||||
@@ -3022,7 +3061,7 @@ struct AstLogOr : public AstNodeBiop {
|
||||
};
|
||||
struct AstLogAnd : public AstNodeBiop {
|
||||
AstLogAnd(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(LogAnd, LOGAND)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogAnd(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f&& %r)"; }
|
||||
@@ -3035,7 +3074,7 @@ struct AstLogAnd : public AstNodeBiop {
|
||||
};
|
||||
struct AstLogIf : public AstNodeBiop {
|
||||
AstLogIf(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(LogIf, LOGIF)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; }
|
||||
virtual string emitVerilog() { return "%k(%l %f-> %r)"; }
|
||||
@@ -3048,7 +3087,7 @@ struct AstLogIf : public AstNodeBiop {
|
||||
};
|
||||
struct AstLogIff : public AstNodeBiCom {
|
||||
AstLogIff(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(LogIff, LOGIFF)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; }
|
||||
virtual string emitVerilog() { return "%k(%l %f<-> %r)"; }
|
||||
@@ -3109,7 +3148,7 @@ struct AstXnor : public AstNodeBiComAsv {
|
||||
};
|
||||
struct AstEq : public AstNodeBiCom {
|
||||
AstEq(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(Eq, EQ)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opEq(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f== %r)"; }
|
||||
@@ -3121,7 +3160,7 @@ struct AstEq : public AstNodeBiCom {
|
||||
};
|
||||
struct AstEqD : public AstNodeBiCom {
|
||||
AstEqD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(EqD, EQD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opEqD(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f== %r)"; }
|
||||
@@ -3135,7 +3174,7 @@ struct AstEqD : public AstNodeBiCom {
|
||||
};
|
||||
struct AstNeq : public AstNodeBiCom {
|
||||
AstNeq(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(Neq, NEQ)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opNeq(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f!= %r)"; }
|
||||
@@ -3147,7 +3186,7 @@ struct AstNeq : public AstNodeBiCom {
|
||||
};
|
||||
struct AstNeqD : public AstNodeBiCom {
|
||||
AstNeqD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(NeqD, NEQD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opNeqD(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f!= %r)"; }
|
||||
@@ -3161,7 +3200,7 @@ struct AstNeqD : public AstNodeBiCom {
|
||||
};
|
||||
struct AstLt : public AstNodeBiop {
|
||||
AstLt(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(Lt, LT)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLt(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f< %r)"; }
|
||||
@@ -3173,7 +3212,7 @@ struct AstLt : public AstNodeBiop {
|
||||
};
|
||||
struct AstLtD : public AstNodeBiop {
|
||||
AstLtD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(LtD, LTD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLtD(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f< %r)"; }
|
||||
@@ -3187,7 +3226,7 @@ struct AstLtD : public AstNodeBiop {
|
||||
};
|
||||
struct AstLtS : public AstNodeBiop {
|
||||
AstLtS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(LtS, LTS)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLtS(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f< %r)"; }
|
||||
@@ -3200,7 +3239,7 @@ struct AstLtS : public AstNodeBiop {
|
||||
};
|
||||
struct AstGt : public AstNodeBiop {
|
||||
AstGt(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(Gt, GT)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGt(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f> %r)"; }
|
||||
@@ -3212,7 +3251,7 @@ struct AstGt : public AstNodeBiop {
|
||||
};
|
||||
struct AstGtD : public AstNodeBiop {
|
||||
AstGtD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(GtD, GTD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGtD(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f> %r)"; }
|
||||
@@ -3226,7 +3265,7 @@ struct AstGtD : public AstNodeBiop {
|
||||
};
|
||||
struct AstGtS : public AstNodeBiop {
|
||||
AstGtS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(GtS, GTS)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGtS(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f> %r)"; }
|
||||
@@ -3239,7 +3278,7 @@ struct AstGtS : public AstNodeBiop {
|
||||
};
|
||||
struct AstGte : public AstNodeBiop {
|
||||
AstGte(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(Gte, GTE)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGte(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f>= %r)"; }
|
||||
@@ -3251,7 +3290,7 @@ struct AstGte : public AstNodeBiop {
|
||||
};
|
||||
struct AstGteD : public AstNodeBiop {
|
||||
AstGteD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(GteD, GTED)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGteD(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f>= %r)"; }
|
||||
@@ -3265,7 +3304,7 @@ struct AstGteD : public AstNodeBiop {
|
||||
};
|
||||
struct AstGteS : public AstNodeBiop {
|
||||
AstGteS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(GteS, GTES)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGteS(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f>= %r)"; }
|
||||
@@ -3278,7 +3317,7 @@ struct AstGteS : public AstNodeBiop {
|
||||
};
|
||||
struct AstLte : public AstNodeBiop {
|
||||
AstLte(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(Lte, LTE)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLte(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f<= %r)"; }
|
||||
@@ -3290,7 +3329,7 @@ struct AstLte : public AstNodeBiop {
|
||||
};
|
||||
struct AstLteD : public AstNodeBiop {
|
||||
AstLteD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(LteD, LTED)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLteD(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f<= %r)"; }
|
||||
@@ -3304,7 +3343,7 @@ struct AstLteD : public AstNodeBiop {
|
||||
};
|
||||
struct AstLteS : public AstNodeBiop {
|
||||
AstLteS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(LteS, LTES)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLteS(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f<= %r)"; }
|
||||
@@ -3318,7 +3357,7 @@ struct AstLteS : public AstNodeBiop {
|
||||
struct AstShiftL : public AstNodeBiop {
|
||||
AstShiftL(FileLine* fl, AstNode* lhsp, AstNode* rhsp, int setwidth=0)
|
||||
: AstNodeBiop(fl, lhsp, rhsp) {
|
||||
if (setwidth) { width(setwidth,setwidth); }
|
||||
if (setwidth) { dtypeSetLogicSized(setwidth,setwidth,AstNumeric::UNSIGNED); }
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(ShiftL, SHIFTL)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftL(lhs,rhs); }
|
||||
@@ -3332,7 +3371,7 @@ struct AstShiftL : public AstNodeBiop {
|
||||
struct AstShiftR : public AstNodeBiop {
|
||||
AstShiftR(FileLine* fl, AstNode* lhsp, AstNode* rhsp, int setwidth=0)
|
||||
: AstNodeBiop(fl, lhsp, rhsp) {
|
||||
if (setwidth) { width(setwidth,setwidth); }
|
||||
if (setwidth) { dtypeSetLogicSized(setwidth,setwidth,AstNumeric::UNSIGNED); }
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(ShiftR, SHIFTR)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftR(lhs,rhs); }
|
||||
@@ -3372,7 +3411,7 @@ struct AstAdd : public AstNodeBiComAsv {
|
||||
};
|
||||
struct AstAddD : public AstNodeBiComAsv {
|
||||
AstAddD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
|
||||
dtypeChgDouble(); }
|
||||
dtypeSetDouble(); }
|
||||
ASTNODE_NODE_FUNCS(AddD, ADDD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAddD(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f+ %r)"; }
|
||||
@@ -3398,7 +3437,7 @@ struct AstSub : public AstNodeBiop {
|
||||
};
|
||||
struct AstSubD : public AstNodeBiop {
|
||||
AstSubD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgDouble(); }
|
||||
dtypeSetDouble(); }
|
||||
ASTNODE_NODE_FUNCS(SubD, SUBD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opSubD(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f- %r)"; }
|
||||
@@ -3425,7 +3464,7 @@ struct AstMul : public AstNodeBiComAsv {
|
||||
};
|
||||
struct AstMulD : public AstNodeBiComAsv {
|
||||
AstMulD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiComAsv(fl, lhsp, rhsp) {
|
||||
dtypeChgDouble(); }
|
||||
dtypeSetDouble(); }
|
||||
ASTNODE_NODE_FUNCS(MulD, MULD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opMulD(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f* %r)"; }
|
||||
@@ -3465,7 +3504,7 @@ struct AstDiv : public AstNodeBiop {
|
||||
};
|
||||
struct AstDivD : public AstNodeBiop {
|
||||
AstDivD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgDouble(); }
|
||||
dtypeSetDouble(); }
|
||||
ASTNODE_NODE_FUNCS(DivD, DIVD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opDivD(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f/ %r)"; }
|
||||
@@ -3529,7 +3568,7 @@ struct AstPow : public AstNodeBiop {
|
||||
};
|
||||
struct AstPowD : public AstNodeBiop {
|
||||
AstPowD(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgDouble(); }
|
||||
dtypeSetDouble(); }
|
||||
ASTNODE_NODE_FUNCS(PowD, POWD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowD(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f** %r)"; }
|
||||
@@ -3555,7 +3594,7 @@ struct AstPowS : public AstNodeBiop {
|
||||
};
|
||||
struct AstEqCase : public AstNodeBiCom {
|
||||
AstEqCase(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(EqCase, EQCASE)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opCaseEq(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f=== %r)"; }
|
||||
@@ -3567,7 +3606,7 @@ struct AstEqCase : public AstNodeBiCom {
|
||||
};
|
||||
struct AstNeqCase : public AstNodeBiCom {
|
||||
AstNeqCase(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(NeqCase, NEQCASE)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opCaseNeq(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f!== %r)"; }
|
||||
@@ -3580,7 +3619,7 @@ struct AstNeqCase : public AstNodeBiCom {
|
||||
struct AstEqWild : public AstNodeBiop {
|
||||
// Note wildcard operator rhs differs from lhs
|
||||
AstEqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(EqWild, EQWILD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildEq(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f==? %r)"; }
|
||||
@@ -3592,7 +3631,7 @@ struct AstEqWild : public AstNodeBiop {
|
||||
};
|
||||
struct AstNeqWild : public AstNodeBiop {
|
||||
AstNeqWild(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
|
||||
dtypeChgLogicBool(); }
|
||||
dtypeSetLogicBool(); }
|
||||
ASTNODE_NODE_FUNCS(NeqWild, NEQWILD)
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildNeq(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %f!=? %r)"; }
|
||||
@@ -3720,6 +3759,7 @@ struct AstPslClocked : public AstNode {
|
||||
addOp3p(propp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(PslClocked, PSLCLOCKED)
|
||||
virtual bool hasDType() const { return true; } // Used under PslCover, which expects a bool child
|
||||
AstNodeSenItem* sensesp() const { return op1p()->castNodeSenItem(); } // op1 = Sensitivity list
|
||||
AstNode* disablep() const { return op2p(); } // op2 = disable
|
||||
AstNode* propp() const { return op3p(); } // op3 = property
|
||||
@@ -3786,6 +3826,7 @@ struct AstPslBool : public AstNode {
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(PslBool, PSLBOOL)
|
||||
AstNode* exprp() const { return op1p()->castNode(); } // op1= expression
|
||||
virtual bool hasDType() const { return true; }
|
||||
virtual bool isGateOptimizable() const { return false; } // Not relevant
|
||||
virtual bool isPredictOptimizable() const { return false; } // Not relevant
|
||||
virtual int instrCount() const { return 0; }
|
||||
@@ -4089,7 +4130,7 @@ public:
|
||||
AstCMath(FileLine* fl, const string& textStmt, int setwidth, bool cleanOut=true)
|
||||
: AstNodeMath(fl), m_cleanOut(cleanOut) {
|
||||
addNOp1p(new AstText(fl, textStmt, true));
|
||||
if (setwidth) { width(setwidth,setwidth); }
|
||||
if (setwidth) { dtypeSetLogicSized(setwidth,setwidth,AstNumeric::UNSIGNED); }
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(CMath, CMATH)
|
||||
virtual bool isGateOptimizable() const { return false; }
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Removal of named begin blocks
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Removal of named begin blocks
|
||||
//
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Branch prediction
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Branch prediction
|
||||
//
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Find broken links in tree
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Find broken links in tree
|
||||
//
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Break case statements up and add Unknown assigns
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Break case statements up and add Unknown assigns
|
||||
//
|
||||
|
||||
+2
-2
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Add C++ casts across expression size changes
|
||||
//
|
||||
@@ -77,8 +78,7 @@ private:
|
||||
AstNRelinker relinkHandle;
|
||||
nodep->unlinkFrBack(&relinkHandle);
|
||||
//
|
||||
AstCCast* castp = new AstCCast (nodep->fileline(), nodep, needsize);
|
||||
castp->width(needsize, nodep->widthMin());
|
||||
AstCCast* castp = new AstCCast (nodep->fileline(), nodep, needsize, nodep->widthMin());
|
||||
relinkHandle.relink(castp);
|
||||
//if (debug()>8) castp->dumpTree(cout,"-castins: ");
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Add C++ casts across expression size changes
|
||||
//
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Clock Domain Crossing Lint
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Break always into sensitivity block domains
|
||||
//
|
||||
|
||||
+45
-13
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Add temporaries, such as for changed nodes
|
||||
//
|
||||
@@ -59,6 +60,12 @@ private:
|
||||
AstScope* m_scopetopp; // Scope under TOPSCOPE
|
||||
AstCFunc* m_chgFuncp; // Change function we're building
|
||||
|
||||
// CONSTANTS
|
||||
enum MiscConsts {
|
||||
DETECTARRAY_MAX_INDEXES = 256 // How many indexes before error
|
||||
// Ok to increase this, but may result in much slower model
|
||||
};
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
@@ -66,14 +73,33 @@ private:
|
||||
return level;
|
||||
}
|
||||
|
||||
AstNode* aselIfNeeded(bool isArray, int index, AstNode* childp) {
|
||||
if (isArray) {
|
||||
return new AstArraySel(childp->fileline(), childp,
|
||||
new AstConst(childp->fileline(), index));
|
||||
} else {
|
||||
return childp;
|
||||
}
|
||||
}
|
||||
|
||||
void genChangeDet(AstVarScope* vscp) {
|
||||
#ifdef NEW_ORDERING
|
||||
vscp->v3fatalSrc("Not applicable\n");
|
||||
#endif
|
||||
AstVar* varp = vscp->varp();
|
||||
vscp->v3warn(IMPERFECTSCH,"Imperfect scheduling of variable: "<<vscp);
|
||||
if (!varp->dtypeSkipRefp()->castBasicDType()) {
|
||||
vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on arrayed variable (probably with UNOPTFLAT warning suppressed): "<<varp->prettyName());
|
||||
AstArrayDType* arrayp = varp->dtypeSkipRefp()->castArrayDType();
|
||||
bool isArray = arrayp;
|
||||
int msb = isArray ? arrayp->msb() : 0;
|
||||
int lsb = isArray ? arrayp->lsb() : 0;
|
||||
if (isArray && ((msb - lsb + 1) > DETECTARRAY_MAX_INDEXES)) {
|
||||
vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect more than "<<cvtToStr(DETECTARRAY_MAX_INDEXES)
|
||||
<<" array indexes (probably with UNOPTFLAT warning suppressed): "<<varp->prettyName());
|
||||
vscp->v3warn(E_DETECTARRAY, "... Could recompile with DETECTARRAY_MAX_INDEXES increased to at least "<<cvtToStr(msb-lsb+1));
|
||||
} else if (!isArray
|
||||
&& !varp->dtypeSkipRefp()->castBasicDType()) {
|
||||
if (debug()) varp->dumpTree(cout,"-DETECTARRAY-");
|
||||
vscp->v3warn(E_DETECTARRAY, "Unsupported: Can't detect changes on complex variable (probably with UNOPTFLAT warning suppressed): "<<varp->prettyName());
|
||||
} else {
|
||||
string newvarname = "__Vchglast__"+vscp->scopep()->nameDotless()+"__"+varp->shortName();
|
||||
// Create: VARREF(_last)
|
||||
@@ -84,17 +110,23 @@ private:
|
||||
m_topModp->addStmtp(newvarp);
|
||||
AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopetopp, newvarp);
|
||||
m_scopetopp->addVarp(newvscp);
|
||||
AstChangeDet* changep
|
||||
= new AstChangeDet (vscp->fileline(),
|
||||
new AstVarRef(vscp->fileline(), vscp, false),
|
||||
new AstVarRef(vscp->fileline(), newvscp, false),
|
||||
false);
|
||||
m_chgFuncp->addStmtsp(changep);
|
||||
AstAssign* initp
|
||||
= new AstAssign (vscp->fileline(),
|
||||
new AstVarRef(vscp->fileline(), newvscp, true),
|
||||
new AstVarRef(vscp->fileline(), vscp, false));
|
||||
m_chgFuncp->addFinalsp(initp);
|
||||
for (int index=lsb; index<=msb; ++index) {
|
||||
AstChangeDet* changep
|
||||
= new AstChangeDet (vscp->fileline(),
|
||||
aselIfNeeded(isArray, index,
|
||||
new AstVarRef(vscp->fileline(), vscp, false)),
|
||||
aselIfNeeded(isArray, index,
|
||||
new AstVarRef(vscp->fileline(), newvscp, false)),
|
||||
false);
|
||||
m_chgFuncp->addStmtsp(changep);
|
||||
AstAssign* initp
|
||||
= new AstAssign (vscp->fileline(),
|
||||
aselIfNeeded(isArray, index,
|
||||
new AstVarRef(vscp->fileline(), newvscp, true)),
|
||||
aselIfNeeded(isArray, index,
|
||||
new AstVarRef(vscp->fileline(), vscp, false)));
|
||||
m_chgFuncp->addFinalsp(initp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Pre C-Emit stage changes
|
||||
//
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Add temporaries, such as for clean nodes
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Pre C-Emit stage changes
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Break always into sensitivity active domains
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Break always into clock gated blocks
|
||||
//
|
||||
|
||||
+3
-2
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Clocking POS/NEGEDGE insertion
|
||||
//
|
||||
@@ -85,7 +86,7 @@ private:
|
||||
AstVar* varp = vscp->varp();
|
||||
if (!varp->width1()) varp->v3error("Unsupported: Clock edge on non-single bit signal: "<<varp->prettyName());
|
||||
string newvarname = ((string)"__Vclklast__"+vscp->scopep()->nameDotless()+"__"+varp->shortName());
|
||||
AstVar* newvarp = new AstVar (vscp->fileline(), AstVarType::MODULETEMP, newvarname, AstLogicPacked(), 1);
|
||||
AstVar* newvarp = new AstVar (vscp->fileline(), AstVarType::MODULETEMP, newvarname, VFlagLogicPacked(), 1);
|
||||
m_modp->addStmtp(newvarp);
|
||||
AstVarScope* newvscp = new AstVarScope(vscp->fileline(), m_scopep, newvarp);
|
||||
vscp->user1p(newvscp);
|
||||
@@ -103,7 +104,7 @@ private:
|
||||
AstVarScope* getCreateLocalVar(FileLine* fl, const string& name, AstVar* examplep, int width) {
|
||||
AstVar* newvarp;
|
||||
if (width) {
|
||||
newvarp = new AstVar (fl, AstVarType::BLOCKTEMP, name, AstLogicPacked(), width);
|
||||
newvarp = new AstVar (fl, AstVarType::BLOCKTEMP, name, VFlagLogicPacked(), width);
|
||||
} else {
|
||||
newvarp = new AstVar (fl, AstVarType::BLOCKTEMP, name, examplep); // No range; 1 bit.
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Clocking POS/NEGEDGE insertion
|
||||
//
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Combine common code into functions
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Combine common code into functions
|
||||
//
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Configuration Files
|
||||
//
|
||||
@@ -62,7 +63,7 @@ class V3ConfigIgnores {
|
||||
|
||||
IgnFiles m_ignWilds; // Ignores for each wildcarded filename
|
||||
IgnFiles m_ignFiles; // Ignores for each non-wildcarded filename
|
||||
|
||||
|
||||
static V3ConfigIgnores s_singleton; // Singleton (not via local static, as that's slow)
|
||||
|
||||
V3ConfigIgnores() { m_lastLineno = -1; }
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Configuration Files
|
||||
//
|
||||
|
||||
+7
-6
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Constant folding
|
||||
//
|
||||
@@ -150,7 +151,7 @@ private:
|
||||
// BIASV(CONSTa,BIASV(b...,BIASV(CONSTc,d...))) // hits operandAsvUp
|
||||
// BIASV(CONSTa,BIASV(CONSTc,BIASV(c...,d...))) // hits operandAsvConst
|
||||
// BIASV(BIASV(CONSTa,CONSTc),BIASV(c...,d...))) // hits normal constant propagation
|
||||
// BIASV(CONST_a_c,BIASV(c...,d...)))
|
||||
// BIASV(CONST_a_c,BIASV(c...,d...)))
|
||||
//
|
||||
// Idea for the future: All BiComAsvs could be lists, sorted by if they're constant
|
||||
AstNodeBiComAsv* bnodep = nodep->castNodeBiComAsv();
|
||||
@@ -385,7 +386,7 @@ private:
|
||||
else if ((nodep->msbConst() > bdtypep->msbMaxSelect())
|
||||
|| (nodep->lsbConst() > bdtypep->msbMaxSelect())) {
|
||||
// See also warning in V3Width
|
||||
nodep->v3error("Selection index out of range: "
|
||||
nodep->v3warn(SELRANGE, "Selection index out of range: "
|
||||
<<nodep->msbConst()<<":"<<nodep->lsbConst()
|
||||
<<" outside "<<bdtypep->msbMaxSelect()<<":0"
|
||||
<<(bdtypep->lsb()>=0 ? ""
|
||||
@@ -858,9 +859,9 @@ private:
|
||||
string name1 = ((string)"__Vconcswap"+cvtToStr(m_modp->varNumGetInc()));
|
||||
string name2 = ((string)"__Vconcswap"+cvtToStr(m_modp->varNumGetInc()));
|
||||
AstVar* temp1p = new AstVar(sel1p->fileline(), AstVarType::BLOCKTEMP, name1,
|
||||
AstLogicPacked(), msb1-lsb1+1);
|
||||
VFlagLogicPacked(), msb1-lsb1+1);
|
||||
AstVar* temp2p = new AstVar(sel2p->fileline(), AstVarType::BLOCKTEMP, name2,
|
||||
AstLogicPacked(), msb2-lsb2+1);
|
||||
VFlagLogicPacked(), msb2-lsb2+1);
|
||||
m_modp->addStmtp(temp1p);
|
||||
m_modp->addStmtp(temp2p);
|
||||
AstNodeAssign* asn1ap=nodep->cloneType
|
||||
@@ -1382,7 +1383,7 @@ private:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Pass2, remove dup edges
|
||||
for (AstNodeSenItem* nextp, * senp = nodep->sensesp()->castNodeSenItem();
|
||||
senp; senp=nextp) {
|
||||
@@ -1953,7 +1954,7 @@ public:
|
||||
PROC_V_EXPENSIVE,
|
||||
PROC_CPP
|
||||
};
|
||||
|
||||
|
||||
// CONSTUCTORS
|
||||
ConstVisitor(ProcMode pmode) {
|
||||
m_params = false;
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Propagate constants across AST
|
||||
//
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Netlist (top level) functions
|
||||
//
|
||||
@@ -216,7 +217,7 @@ private:
|
||||
ToggleEnt newent (above.m_comment+string("[")+cvtToStr(index_docs)+"]",
|
||||
new AstArraySel(varp->fileline(), above.m_varRefp->cloneTree(true), index_code),
|
||||
new AstArraySel(varp->fileline(), above.m_chgRefp->cloneTree(true), index_code));
|
||||
toggleVarRecurse(adtypep->dtypeSkipRefp(), depth+1,
|
||||
toggleVarRecurse(adtypep->subDTypep()->skipRefp(), depth+1,
|
||||
newent,
|
||||
varp, chgVarp);
|
||||
newent.cleanup();
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Coverage modules/signals together
|
||||
//
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Netlist (top level) functions
|
||||
//
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Coverage modules/signals together
|
||||
//
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Dead code elimination
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Dead branch elimination
|
||||
//
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Add temporaries, such as for delayed nodes
|
||||
//
|
||||
@@ -134,7 +135,7 @@ private:
|
||||
varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, oldvarscp->varp());
|
||||
varp->widthSignedFrom(oldvarscp);
|
||||
} else { // Used for vset and dimensions, so can zero init
|
||||
varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, AstBitPacked(), width);
|
||||
varp = new AstVar (oldvarscp->fileline(), AstVarType::BLOCKTEMP, name, VFlagBitPacked(), width);
|
||||
}
|
||||
addmodp->addStmtp(varp);
|
||||
m_modVarMap.insert(make_pair(make_pair(addmodp, name), varp));
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Pre C-Emit stage changes
|
||||
//
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Prevent very deep expressions
|
||||
//
|
||||
@@ -69,7 +70,7 @@ private:
|
||||
// though it's one bit wide, needs the mask in the upper bits.
|
||||
// (Someday we'll have a valid bitmask instead of widths....)
|
||||
// See t_func_crc for an example test that requires this
|
||||
AstLogicPacked(), nodep->width());
|
||||
VFlagLogicPacked(), nodep->width());
|
||||
if (!m_funcp) nodep->v3fatalSrc("Deep expression not under a function");
|
||||
m_funcp->addInitsp(varp);
|
||||
// Replace node tree with reference to var
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Prevent very deep expressions
|
||||
//
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Prevent very deep expressions
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Prevent very deep expressions
|
||||
//
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Rename scope references to module-local references
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Rename scope references to module-local references
|
||||
//
|
||||
|
||||
+19
-18
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit C++ for tree
|
||||
//
|
||||
@@ -33,7 +34,7 @@
|
||||
#include "V3EmitC.h"
|
||||
#include "V3EmitCBase.h"
|
||||
|
||||
#define VL_VALUE_STRING_MAX_WIDTH 1024 // We use a static char array in VL_VALUE_STRING
|
||||
#define VL_VALUE_STRING_MAX_WIDTH 8192 // We use a static char array in VL_VALUE_STRING
|
||||
|
||||
//######################################################################
|
||||
// Emit statements and math operators
|
||||
@@ -661,10 +662,10 @@ class EmitCImp : EmitCStmts {
|
||||
changep->lhsp()->iterateAndNext(*this);
|
||||
}
|
||||
else {
|
||||
AstVarRef* lhsp = changep->lhsp()->castVarRef();
|
||||
AstVarRef* rhsp = changep->rhsp()->castVarRef();
|
||||
if (!lhsp) changep->v3fatalSrc("Not ref?");
|
||||
if (!rhsp) changep->v3fatalSrc("Not ref?");
|
||||
AstNode* lhsp = changep->lhsp();
|
||||
AstNode* rhsp = changep->rhsp();
|
||||
if (!lhsp->castVarRef() && !lhsp->castArraySel()) changep->v3fatalSrc("Not ref?");
|
||||
if (!rhsp->castVarRef() && !rhsp->castArraySel()) changep->v3fatalSrc("Not ref?");
|
||||
for (int word=0; word<changep->lhsp()->widthWords(); word++) {
|
||||
if (!gotOne) {
|
||||
gotOne = true;
|
||||
@@ -888,7 +889,7 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
||||
puts(nodep->name());
|
||||
if (isArray) {
|
||||
for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp;
|
||||
arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) {
|
||||
arrayp = arrayp->subDTypep()->skipRefp()->castArrayDType()) {
|
||||
puts("["+cvtToStr(arrayp->elementsConst())+"]");
|
||||
}
|
||||
}
|
||||
@@ -909,7 +910,7 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
||||
if (nodep->isWide()) puts("W");
|
||||
puts("("+nodep->name());
|
||||
for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp;
|
||||
arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) {
|
||||
arrayp = arrayp->subDTypep()->skipRefp()->castArrayDType()) {
|
||||
puts("["+cvtToStr(arrayp->elementsConst())+"]");
|
||||
}
|
||||
puts(","+cvtToStr(basicp->msb())+","+cvtToStr(basicp->lsb()));
|
||||
@@ -931,7 +932,7 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
||||
puts(nodep->vlArgType(true,false));
|
||||
// This isn't very robust and may need cleanup for other data types
|
||||
for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp;
|
||||
arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) {
|
||||
arrayp = arrayp->subDTypep()->skipRefp()->castArrayDType()) {
|
||||
puts("["+cvtToStr(arrayp->elementsConst())+"]");
|
||||
}
|
||||
puts(";\n");
|
||||
@@ -957,7 +958,7 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
||||
puts(nodep->name());
|
||||
// This isn't very robust and may need cleanup for other data types
|
||||
for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp;
|
||||
arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) {
|
||||
arrayp = arrayp->subDTypep()->skipRefp()->castArrayDType()) {
|
||||
puts("["+cvtToStr(arrayp->elementsConst())+"]");
|
||||
}
|
||||
puts(","+cvtToStr(basicp->msb())+","+cvtToStr(basicp->lsb()));
|
||||
@@ -1062,7 +1063,7 @@ void EmitCStmts::emitOpName(AstNode* nodep, const string& format,
|
||||
++pos;
|
||||
switch (pos[0]) {
|
||||
case 'q': emitIQW(detailp); break;
|
||||
case 'w':
|
||||
case 'w':
|
||||
COMMA;
|
||||
puts(cvtToStr(detailp->widthMin()));
|
||||
needComma = true;
|
||||
@@ -1195,7 +1196,7 @@ void EmitCStmts::displayArg(AstNode* dispp, AstNode** elistp, bool isScan,
|
||||
return;
|
||||
}
|
||||
if (argp->widthMin() > VL_VALUE_STRING_MAX_WIDTH) {
|
||||
dispp->v3error("Exceeded limit of 1024 bits for any display arguments");
|
||||
dispp->v3error("Exceeded limit of "+cvtToStr(VL_VALUE_STRING_MAX_WIDTH)+" bits for any display arguments");
|
||||
}
|
||||
if (argp && argp->isWide()
|
||||
&& (fmtLetter=='d'||fmtLetter=='u')) {
|
||||
@@ -1340,7 +1341,7 @@ void EmitCImp::emitVarResets(AstNodeModule* modp) {
|
||||
int vects = 0;
|
||||
// This isn't very robust and may need cleanup for other data types
|
||||
for (AstArrayDType* arrayp=varp->dtypeSkipRefp()->castArrayDType(); arrayp;
|
||||
arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) {
|
||||
arrayp = arrayp->subDTypep()->skipRefp()->castArrayDType()) {
|
||||
int vecnum = vects++;
|
||||
if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier.");
|
||||
string ivar = string("__Vi")+cvtToStr(vecnum);
|
||||
@@ -1516,7 +1517,7 @@ void EmitCImp::emitSensitives() {
|
||||
int vects = 0;
|
||||
// This isn't very robust and may need cleanup for other data types
|
||||
for (AstArrayDType* arrayp=varp->dtypeSkipRefp()->castArrayDType(); arrayp;
|
||||
arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) {
|
||||
arrayp = arrayp->subDTypep()->skipRefp()->castArrayDType()) {
|
||||
int vecnum = vects++;
|
||||
if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier.");
|
||||
string ivar = string("__Vi")+cvtToStr(vecnum);
|
||||
@@ -2076,7 +2077,7 @@ class EmitCTrace : EmitCStmts {
|
||||
puts("vcdp->declArray");
|
||||
} else if (nodep->isQuad()) {
|
||||
puts("vcdp->declQuad ");
|
||||
} else if (nodep->msbEndianed() || nodep->lsbEndianed()) {
|
||||
} else if (nodep->left() || nodep->right()) {
|
||||
puts("vcdp->declBus ");
|
||||
} else {
|
||||
puts("vcdp->declBit ");
|
||||
@@ -2091,8 +2092,8 @@ class EmitCTrace : EmitCStmts {
|
||||
puts(",-1");
|
||||
}
|
||||
if (!nodep->isDouble() // When float/double no longer have widths this can go
|
||||
&& (nodep->msbEndianed() || nodep->lsbEndianed())) {
|
||||
puts(","+cvtToStr(nodep->msbEndianed())+","+cvtToStr(nodep->lsbEndianed()));
|
||||
&& (nodep->left() || nodep->right())) {
|
||||
puts(","+cvtToStr(nodep->left())+","+cvtToStr(nodep->right()));
|
||||
}
|
||||
puts(");");
|
||||
}
|
||||
@@ -2108,7 +2109,7 @@ class EmitCTrace : EmitCStmts {
|
||||
puts("vcdp->"+full+"Array");
|
||||
} else if (nodep->isQuad()) {
|
||||
puts("vcdp->"+full+"Quad ");
|
||||
} else if (nodep->declp()->msbEndianed() || nodep->declp()->lsbEndianed()) {
|
||||
} else if (nodep->declp()->left() || nodep->declp()->right()) {
|
||||
puts("vcdp->"+full+"Bus ");
|
||||
} else {
|
||||
puts("vcdp->"+full+"Bit ");
|
||||
@@ -2118,7 +2119,7 @@ class EmitCTrace : EmitCStmts {
|
||||
puts(",");
|
||||
emitTraceValue(nodep, arrayindex);
|
||||
if (!nodep->isDouble() // When float/double no longer have widths this can go
|
||||
&& (nodep->declp()->msbEndianed() || nodep->declp()->lsbEndianed() || emitTraceIsScBv(nodep))) {
|
||||
&& (nodep->declp()->left() || nodep->declp()->right() || emitTraceIsScBv(nodep))) {
|
||||
puts(","+cvtToStr(nodep->declp()->widthMin()));
|
||||
}
|
||||
puts(");\n");
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit C++ code for module tree
|
||||
//
|
||||
|
||||
+1
-69
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit C++ for tree
|
||||
//
|
||||
@@ -34,74 +34,6 @@
|
||||
#include "V3File.h"
|
||||
#include "V3Ast.h"
|
||||
|
||||
//######################################################################
|
||||
// V3OutCFile: A class for abstracting out SystemC/C++ details
|
||||
|
||||
class V3OutCFile : public V3OutFile {
|
||||
int m_private;
|
||||
public:
|
||||
V3OutCFile(const string& filename) : V3OutFile(filename) {
|
||||
resetPrivate();
|
||||
}
|
||||
virtual ~V3OutCFile() {}
|
||||
virtual void putsCellDecl(const string& classname, const string& cellname) {
|
||||
this->printf("%-19s\t%s;\n",
|
||||
(classname + "*").c_str(),cellname.c_str());
|
||||
}
|
||||
virtual void putsHeader() { puts("// Verilated -*- C++ -*-\n"); }
|
||||
virtual void putsIntTopInclude() { }
|
||||
// Print out public/privates
|
||||
void resetPrivate() { m_private = 0; }
|
||||
void putsPrivate(bool setPrivate) {
|
||||
if (setPrivate && m_private!=1) {
|
||||
puts("private:\n");
|
||||
m_private = 1;
|
||||
} else if (!setPrivate && m_private!=2) {
|
||||
puts("public:\n");
|
||||
m_private = 2;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class V3OutScFile : public V3OutCFile {
|
||||
public:
|
||||
V3OutScFile(const string& filename) : V3OutCFile(filename) {}
|
||||
virtual ~V3OutScFile() {}
|
||||
virtual void putsHeader() { puts("// Verilated -*- SystemC -*-\n"); }
|
||||
virtual void putsIntTopInclude() {
|
||||
puts("#include \"systemc.h\"\n");
|
||||
puts("#include \"verilated_sc.h\"\n");
|
||||
}
|
||||
};
|
||||
|
||||
class V3OutSpFile : public V3OutCFile {
|
||||
public:
|
||||
V3OutSpFile(const string& filename) : V3OutCFile(filename) {}
|
||||
virtual ~V3OutSpFile() {}
|
||||
virtual void putsHeader() { puts("// Verilated -*- SystemC -*-\n"); }
|
||||
virtual void putsIntTopInclude() {
|
||||
puts("#include \"systemperl.h\"\n");
|
||||
puts("#include \"verilated_sc.h\"\n");
|
||||
}
|
||||
};
|
||||
|
||||
class V3OutVFile : public V3OutFile {
|
||||
public:
|
||||
V3OutVFile(const string& filename) : V3OutFile(filename) {}
|
||||
virtual ~V3OutVFile() {}
|
||||
virtual void putsHeader() { puts("// Verilated -*- Verilog -*-\n"); }
|
||||
};
|
||||
|
||||
class V3OutMkFile : public V3OutFile {
|
||||
public:
|
||||
V3OutMkFile(const string& filename) : V3OutFile(filename) {}
|
||||
virtual ~V3OutMkFile() {}
|
||||
virtual void putsHeader() { puts("# Verilated -*- Makefile -*-\n"); }
|
||||
// No automatic indentation yet.
|
||||
void puts(const char* strg) { putsNoTracking(strg); }
|
||||
void puts(const string& strg) { putsNoTracking(strg); }
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// Base Visitor class -- holds output file pointer
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit C++ for tree
|
||||
//
|
||||
|
||||
+4
-3
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit C++ for tree
|
||||
//
|
||||
@@ -464,7 +465,7 @@ void EmitCSyms::emitSymImp() {
|
||||
bounds += " ,"; bounds += cvtToStr(adtypep->arrayp()->msbConst());
|
||||
bounds += ","; bounds += cvtToStr(adtypep->arrayp()->lsbConst());
|
||||
dim++;
|
||||
dtypep = adtypep->dtypep();
|
||||
dtypep = adtypep->subDTypep();
|
||||
}
|
||||
else break; // AstBasicDType - nothing below, 1
|
||||
}
|
||||
@@ -525,7 +526,7 @@ void EmitCSyms::emitDpiHdr() {
|
||||
puts("extern \"C\" {\n");
|
||||
puts("#endif\n");
|
||||
puts("\n");
|
||||
|
||||
|
||||
int firstExp = 0;
|
||||
int firstImp = 0;
|
||||
for (vector<AstCFunc*>::iterator it = m_dpis.begin(); it != m_dpis.end(); ++it) {
|
||||
@@ -571,7 +572,7 @@ void EmitCSyms::emitDpiImp() {
|
||||
puts("// or 2. Compile all __Dpi.cpp files in the same compiler run,\n");
|
||||
puts("// and #ifdefs already inserted here will sort everything out.\n");
|
||||
puts("\n");
|
||||
|
||||
|
||||
puts("#include \""+topClassName()+"__Dpi.h\"\n");
|
||||
puts("#include \""+topClassName()+".h\"\n");
|
||||
puts("\n");
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit Makefile
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit Makefile
|
||||
//
|
||||
|
||||
+14
-8
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit Verilog from tree
|
||||
//
|
||||
@@ -61,7 +62,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
||||
putsNoTracking(AstNode::quoteName(str));
|
||||
putsNoTracking("\"");
|
||||
}
|
||||
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
@@ -447,11 +448,11 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
||||
puts("[");
|
||||
if (nodep->msbp()->castConst() && nodep->lsbp()->castConst()) {
|
||||
// Looks nicer if we print [1:0] rather than [32'sh1:32sh0]
|
||||
puts(cvtToStr(nodep->msbEndianedp()->castConst()->toSInt())); puts(":");
|
||||
puts(cvtToStr(nodep->lsbEndianedp()->castConst()->toSInt())); puts("]");
|
||||
puts(cvtToStr(nodep->leftp()->castConst()->toSInt())); puts(":");
|
||||
puts(cvtToStr(nodep->rightp()->castConst()->toSInt())); puts("]");
|
||||
} else {
|
||||
nodep->msbEndianedp()->iterateAndNext(*this); puts(":");
|
||||
nodep->lsbEndianedp()->iterateAndNext(*this); puts("]");
|
||||
nodep->leftp()->iterateAndNext(*this); puts(":");
|
||||
nodep->rightp()->iterateAndNext(*this); puts("]");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstSel* nodep, AstNUser*) {
|
||||
@@ -490,7 +491,11 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
||||
}
|
||||
virtual void visit(AstConstDType* nodep, AstNUser*) {
|
||||
putfs(nodep,"const ");
|
||||
nodep->dtypep()->iterateAndNext(*this);
|
||||
nodep->subDTypep()->iterateAndNext(*this);
|
||||
}
|
||||
virtual void visit(AstArrayDType* nodep, AstNUser*) {
|
||||
nodep->subDTypep()->iterateAndNext(*this);
|
||||
nodep->arrayp()->iterateAndNext(*this);
|
||||
}
|
||||
virtual void visit(AstNodeFTaskRef* nodep, AstNUser*) {
|
||||
if (nodep->dotted()!="") { putfs(nodep,nodep->dotted()); puts("."); puts(nodep->prettyName()); }
|
||||
@@ -596,7 +601,7 @@ class EmitVStreamVisitor : public EmitVBaseVisitor {
|
||||
virtual void putbs(const string& str) { puts(str); }
|
||||
virtual void putfs(AstNode*, const string& str) { putbs(str); }
|
||||
virtual void putqs(AstNode*, const string& str) { putbs(str); }
|
||||
public:
|
||||
public:
|
||||
EmitVStreamVisitor(AstNode* nodep, ostream& os)
|
||||
: m_os(os) {
|
||||
nodep->accept(*this);
|
||||
@@ -635,7 +640,8 @@ public:
|
||||
FileLine* prefixFl() const { return m_prefixFl; }
|
||||
int column() const { return m_column; }
|
||||
EmitVPrefixedFormatter(ostream& os, const string& prefix, int flWidth)
|
||||
: V3OutFormatter("__STREAM", true), m_os(os), m_prefix(prefix), m_flWidth(flWidth) {
|
||||
: V3OutFormatter("__STREAM", V3OutFormatter::LA_VERILOG)
|
||||
, m_os(os), m_prefix(prefix), m_flWidth(flWidth) {
|
||||
m_column = 0;
|
||||
m_prefixFl = v3Global.rootp()->fileline(); // NETLIST's fileline instead of NULL to avoid NULL checks
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
//-*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit Verilog code for module tree
|
||||
//
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit Verilog from tree
|
||||
//
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2004-2012 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.
|
||||
//
|
||||
// Verilator is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
#include "V3Global.h"
|
||||
#include "V3EmitXml.h"
|
||||
#include "V3EmitCBase.h"
|
||||
|
||||
//######################################################################
|
||||
// Emit statements and math operators
|
||||
|
||||
class EmitXmlFileVisitor : public EmitCBaseVisitor {
|
||||
// MEMBERS
|
||||
V3OutFile* m_ofp;
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// Outfile methods
|
||||
V3OutFile* ofp() const { return m_ofp; }
|
||||
virtual void puts(const string& str) { ofp()->puts(str); }
|
||||
virtual void putbs(const string& str) { ofp()->putbs(str); }
|
||||
virtual void putfs(AstNode*, const string& str) { putbs(str); }
|
||||
virtual void putqs(AstNode*, const string& str) { putbs(str); }
|
||||
virtual void putsNoTracking(const string& str) { ofp()->putsNoTracking(str); }
|
||||
virtual void putsQuoted(const string& str) {
|
||||
// Quote \ and " for use inside C programs
|
||||
// Don't use to quote a filename for #include - #include doesn't \ escape.
|
||||
// Duplicate in V3File - here so we can print to string
|
||||
putsNoTracking("\"");
|
||||
putsNoTracking(AstNode::quoteName(str));
|
||||
putsNoTracking("\"");
|
||||
}
|
||||
|
||||
// XML methods
|
||||
void outputTag(AstNode* nodep, string tag) {
|
||||
if (tag=="") tag = V3Options::downcase(nodep->typeName());
|
||||
puts("<"+tag+" "+nodep->fileline()->xml());
|
||||
if (nodep->name()!="") { puts(" name="); putsQuoted(nodep->prettyName()); }
|
||||
}
|
||||
void outputChildrenEnd(AstNode* nodep, string tag) {
|
||||
if (tag=="") tag = V3Options::downcase(nodep->typeName());
|
||||
if (nodep->op1p() || nodep->op2p() || nodep->op3p() || nodep->op4p()) {
|
||||
puts(">\n");
|
||||
nodep->iterateChildren(*this);
|
||||
puts("</"+tag+">\n");
|
||||
} else {
|
||||
puts("/>\n");
|
||||
}
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
puts("<netlist>\n");
|
||||
nodep->iterateChildren(*this);
|
||||
puts("</netlist>\n");
|
||||
}
|
||||
virtual void visit(AstNodeModule* nodep, AstNUser*) {
|
||||
outputTag(nodep, "");
|
||||
if (nodep->level()==1 || nodep->level()==2) // ==2 because we don't add wrapper when in XML mode
|
||||
puts(" topModule=\"1\""); // IEEE vpiTopModule
|
||||
outputChildrenEnd(nodep, "");
|
||||
}
|
||||
virtual void visit(AstCell* nodep, AstNUser*) {
|
||||
outputTag(nodep, "instance"); // IEEE: vpiInstance
|
||||
puts(" defName="); putsQuoted(nodep->modName()); // IEEE vpiDefName
|
||||
outputChildrenEnd(nodep, "instance");
|
||||
}
|
||||
virtual void visit(AstPin* nodep, AstNUser*) {
|
||||
// What we call a pin in verilator is a port in the IEEE spec.
|
||||
outputTag(nodep, "port"); // IEEE: vpiPort
|
||||
if (nodep->modVarp()->isInOnly())
|
||||
puts(" direction=\"in\"");
|
||||
else if (nodep->modVarp()->isOutOnly())
|
||||
puts(" direction=\"out\"");
|
||||
else puts(" direction=\"inout\"");
|
||||
puts(" portIndex=\""+cvtToStr(nodep->pinNum())+"\""); // IEEE: vpiPortIndex
|
||||
// Children includes vpiHighConn and vpiLowConn; we don't support port bits (yet?)
|
||||
outputChildrenEnd(nodep, "port");
|
||||
}
|
||||
virtual void visit(AstAssignW* nodep, AstNUser*) {
|
||||
outputTag(nodep, "contAssign"); // IEEE: vpiContAssign
|
||||
outputChildrenEnd(nodep, "contAssign");
|
||||
}
|
||||
|
||||
// Data types
|
||||
virtual void visit(AstBasicDType* nodep, AstNUser*) {
|
||||
outputTag(nodep, "basicDType ");
|
||||
if (nodep->isRanged()) {
|
||||
puts(" left=\""+cvtToStr(nodep->left())+"\"");
|
||||
puts(" right=\""+cvtToStr(nodep->right())+"\"");
|
||||
}
|
||||
puts("/>\n");
|
||||
}
|
||||
|
||||
// Default
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
outputTag(nodep, "");
|
||||
outputChildrenEnd(nodep, "");
|
||||
}
|
||||
public:
|
||||
EmitXmlFileVisitor(AstNode* nodep, V3OutFile* ofp) {
|
||||
m_ofp = ofp;
|
||||
nodep->accept(*this);
|
||||
}
|
||||
virtual ~EmitXmlFileVisitor() {}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// Emit to a stream (perhaps stringstream)
|
||||
|
||||
class EmitXmlPrefixedFormatter : public V3OutFormatter {
|
||||
ostream& m_os;
|
||||
string m_prefix; // What to print at beginning of each line
|
||||
int m_flWidth; // Padding of fileline
|
||||
int m_column; // Rough location; need just zero or non-zero
|
||||
FileLine* m_prefixFl;
|
||||
// METHODS
|
||||
virtual void putcOutput(char chr) {
|
||||
if (chr == '\n') {
|
||||
m_column = 0;
|
||||
m_os<<chr;
|
||||
} else {
|
||||
if (m_column == 0) {
|
||||
m_column = 10;
|
||||
m_os<<m_prefixFl->ascii()+":";
|
||||
m_os<<V3OutFile::indentSpaces(m_flWidth-(m_prefixFl->ascii().length()+1));
|
||||
m_os<<" ";
|
||||
m_os<<m_prefix;
|
||||
}
|
||||
m_column++;
|
||||
m_os<<chr;
|
||||
}
|
||||
}
|
||||
public:
|
||||
void prefixFl(FileLine* fl) { m_prefixFl = fl; }
|
||||
FileLine* prefixFl() const { return m_prefixFl; }
|
||||
int column() const { return m_column; }
|
||||
EmitXmlPrefixedFormatter(ostream& os, const string& prefix, int flWidth)
|
||||
: V3OutFormatter("__STREAM", V3OutFormatter::LA_VERILOG)
|
||||
, m_os(os), m_prefix(prefix), m_flWidth(flWidth) {
|
||||
m_column = 0;
|
||||
m_prefixFl = v3Global.rootp()->fileline(); // NETLIST's fileline instead of NULL to avoid NULL checks
|
||||
}
|
||||
virtual ~EmitXmlPrefixedFormatter() {}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// EmitXml class functions
|
||||
|
||||
void V3EmitXml::emitxml() {
|
||||
UINFO(2,__FUNCTION__<<": "<<endl);
|
||||
// All-in-one file
|
||||
V3OutXmlFile of (v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+".xml");
|
||||
of.putsHeader();
|
||||
of.puts("<!-- DESCR" "IPTION: Verilator output: XML representation of netlist -->\n");
|
||||
of.puts("<verilator_xml>\n");
|
||||
{
|
||||
stringstream sstr;
|
||||
FileLine::fileNameNumMapDumpXml(sstr);
|
||||
of.puts(sstr.str());
|
||||
}
|
||||
EmitXmlFileVisitor visitor (v3Global.rootp(), &of);
|
||||
of.puts("</verilator_xml>\n");
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit XML code
|
||||
//
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2012 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.
|
||||
//
|
||||
// Verilator is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#ifndef _V3EMITXML_H_
|
||||
#define _V3EMITXML_H_ 1
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include "V3Error.h"
|
||||
#include "V3Ast.h"
|
||||
|
||||
//============================================================================
|
||||
|
||||
class V3EmitXml {
|
||||
public:
|
||||
static void emitxml();
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
+23
-14
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Error handling
|
||||
//
|
||||
@@ -67,11 +68,24 @@ V3ErrorCode::V3ErrorCode(const char* msgp) {
|
||||
//######################################################################
|
||||
// FileLineSingleton class functions
|
||||
|
||||
const string FileLineSingleton::filenameLetters(int no) {
|
||||
const int size = 1 + (64 / 4); // Each letter retires more than 4 bits of a > 64 bit number
|
||||
char out[size];
|
||||
char* op = out+size-1;
|
||||
*--op = '\0'; // We build backwards
|
||||
int num = no;
|
||||
do {
|
||||
*--op = 'a'+num%26;
|
||||
num /= 26;
|
||||
} while (num);
|
||||
return op;
|
||||
}
|
||||
|
||||
int FileLineSingleton::nameToNumber(const string& filename) {
|
||||
// Convert filenames to a filenameno
|
||||
// This lets us assign a nice small identifier for debug messages, but more
|
||||
// importantly lets us use a 4 byte int instead of 8 byte pointer in every FileLine.
|
||||
map<string,int>::const_iterator iter = m_namemap.find(filename);
|
||||
FileNameNumMap::const_iterator iter = m_namemap.find(filename);
|
||||
if (VL_LIKELY(iter != m_namemap.end())) return iter->second;
|
||||
int num = m_names.size();
|
||||
m_names.push_back(filename);
|
||||
@@ -79,6 +93,14 @@ int FileLineSingleton::nameToNumber(const string& filename) {
|
||||
return num;
|
||||
}
|
||||
|
||||
void FileLineSingleton::fileNameNumMapDumpXml(ostream& os) {
|
||||
os<<"<files>\n";
|
||||
for (FileNameNumMap::const_iterator it = m_namemap.begin(); it != m_namemap.end(); ++it) {
|
||||
os<<"<file id=\""<<filenameLetters(it->second)<<"\" filename=\""<<it->first<<"\"/>\n";
|
||||
}
|
||||
os<<"</files>\n";
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
// FileLine class functions
|
||||
|
||||
@@ -94,19 +116,6 @@ FileLine::FileLine(FileLine::EmptySecret) {
|
||||
}
|
||||
}
|
||||
|
||||
const string FileLine::filenameLetters() const {
|
||||
const int size = 1 + (64 / 4); // Each letter retires more than 4 bits of a > 64 bit number
|
||||
char out[size];
|
||||
char* op = out+size-1;
|
||||
*--op = '\0'; // We build backwards
|
||||
int num = m_filenameno;
|
||||
do {
|
||||
*--op = 'a'+num%26;
|
||||
num /= 26;
|
||||
} while (num);
|
||||
return op;
|
||||
}
|
||||
|
||||
string FileLine::lineDirectiveStrg(int enterExit) const {
|
||||
char numbuf[20]; sprintf(numbuf, "%d", lineno());
|
||||
char levelbuf[20]; sprintf(levelbuf, "%d", enterExit);
|
||||
|
||||
+16
-7
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Error handling
|
||||
//
|
||||
@@ -81,6 +81,7 @@ public:
|
||||
MULTIDRIVEN, // Driven from multiple blocks
|
||||
REALCVT, // Real conversion
|
||||
REDEFMACRO, // Redefining existing define macro
|
||||
SELRANGE, // Selection index out of range
|
||||
STMTDLY, // Delayed statement
|
||||
SYMRSVDWORD, // Symbol is Reserved Word
|
||||
SYNCASYNCNET, // Mixed sync + async reset
|
||||
@@ -120,7 +121,7 @@ public:
|
||||
"LITENDIAN", "MODDUP",
|
||||
"MULTIDRIVEN",
|
||||
"REALCVT", "REDEFMACRO",
|
||||
"STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET",
|
||||
"SELRANGE", "STMTDLY", "SYMRSVDWORD", "SYNCASYNCNET",
|
||||
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED",
|
||||
"VARHIDDEN", "WIDTH", "WIDTHCONCAT",
|
||||
" MAX"
|
||||
@@ -244,10 +245,10 @@ template< class T> std::string cvtToStr (const T& t) {
|
||||
ostringstream os; os<<t; return os.str();
|
||||
}
|
||||
|
||||
inline uint32_t cvtToHash(void* vp) {
|
||||
inline uint32_t cvtToHash(const void* vp) {
|
||||
// We can shove a 64 bit pointer into a 32 bit bucket
|
||||
// On 32 bit systems, lower is always 0, but who cares?
|
||||
union { void* up; struct {uint32_t upper; uint32_t lower;} l;} u;
|
||||
union { const void* up; struct {uint32_t upper; uint32_t lower;} l;} u;
|
||||
u.l.upper=0; u.l.lower=0; u.up=vp;
|
||||
return u.l.upper^u.l.lower;
|
||||
}
|
||||
@@ -257,7 +258,10 @@ inline uint32_t cvtToHash(void* vp) {
|
||||
class FileLine;
|
||||
|
||||
class FileLineSingleton {
|
||||
map<string,int> m_namemap; // filenameno for each filename
|
||||
// TYPES
|
||||
typedef map<string,int> FileNameNumMap;
|
||||
// MEMBERS
|
||||
FileNameNumMap m_namemap; // filenameno for each filename
|
||||
deque<string> m_names; // filename text for each filenameno
|
||||
// COSNTRUCTORS
|
||||
FileLineSingleton() { }
|
||||
@@ -268,6 +272,8 @@ protected:
|
||||
int nameToNumber(const string& filename);
|
||||
const string numberToName(int filenameno) const { return m_names[filenameno]; }
|
||||
void clear() { m_namemap.clear(); m_names.clear(); }
|
||||
void fileNameNumMapDumpXml(ostream& os);
|
||||
static const string filenameLetters(int fileno);
|
||||
};
|
||||
|
||||
class FileLine {
|
||||
@@ -319,10 +325,11 @@ public:
|
||||
int lineno () const { return m_lineno; }
|
||||
string ascii() const;
|
||||
const string filename () const { return singleton().numberToName(m_filenameno); }
|
||||
const string filenameLetters() const;
|
||||
const string filenameLetters() const { return singleton().filenameLetters(m_filenameno); }
|
||||
const string filebasename () const;
|
||||
const string filebasenameNoExt () const;
|
||||
const string profileFuncname() const;
|
||||
const string xml() const { return "fl=\""+filenameLetters()+cvtToStr(lineno())+"\""; }
|
||||
string lineDirectiveStrg(int enter_exit_level) const;
|
||||
void warnOn(V3ErrorCode code, bool flag) { m_warnOn.set(code,flag); } // Turn on/off warning messages on this line.
|
||||
void warnOff(V3ErrorCode code, bool flag) { warnOn(code,!flag); }
|
||||
@@ -348,13 +355,15 @@ public:
|
||||
defaultFileLine().warnOff(code, flag); }
|
||||
static bool globalWarnOff(const string& code, bool flag) {
|
||||
return defaultFileLine().warnOff(code, flag); }
|
||||
static void fileNameNumMapDumpXml(ostream& os) {
|
||||
singleton().fileNameNumMapDumpXml(os); }
|
||||
|
||||
// METHODS - Called from netlist
|
||||
// Merge warning disables from another fileline
|
||||
void modifyStateInherit(const FileLine* fromp);
|
||||
// Change the current fileline due to actions discovered after parsing
|
||||
// and may have side effects on other nodes sharing this FileLine.
|
||||
// Use only when this is intended
|
||||
// Use only when this is intended
|
||||
void modifyWarnOff(V3ErrorCode code, bool flag) { warnOff(code,flag); }
|
||||
|
||||
// OPERATORS
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Add temporaries, such as for expand nodes
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Expansion of wide operator macros to C operators
|
||||
//
|
||||
|
||||
+36
-16
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: File stream wrapper that understands indentation
|
||||
//
|
||||
@@ -436,7 +437,7 @@ private:
|
||||
dup2(fd_stdout[P_WR], 1);
|
||||
// And stderr comes from parent
|
||||
|
||||
execl("/bin/sh", "sh", "-c", command.c_str(), NULL);
|
||||
execl("/bin/sh", "sh", "-c", command.c_str(), (char*)NULL);
|
||||
// Don't use v3fatal, we don't share the common structures any more
|
||||
fprintf(stderr,"--pipe-filter: exec failed: %s\n",strerror(errno));
|
||||
_exit(10);
|
||||
@@ -546,8 +547,8 @@ bool V3InFilter::readWholefile(const string& filename, V3InFilter::StrList& outl
|
||||
//######################################################################
|
||||
// V3OutFormatter: A class for printing to a file, with automatic indentation of C++ code.
|
||||
|
||||
V3OutFormatter::V3OutFormatter(const string& filename, bool verilog)
|
||||
: m_filename(filename), m_verilog(verilog)
|
||||
V3OutFormatter::V3OutFormatter(const string& filename, V3OutFormatter::Language lang)
|
||||
: m_filename(filename), m_lang(lang)
|
||||
, m_lineno(1), m_column(0)
|
||||
, m_nobreak(false), m_prependIndent(true), m_indentLevel(0)
|
||||
, m_declSAlign(0), m_declNSAlign(0), m_declPadNum(0) {
|
||||
@@ -560,7 +561,7 @@ const char* V3OutFormatter::indentStr(int num) {
|
||||
static char str[MAXSPACE+20];
|
||||
char* cp = str;
|
||||
if (num>MAXSPACE) num=MAXSPACE;
|
||||
if (!m_verilog) { // verilogPrefixedTree doesn't want tabs
|
||||
if (!m_lang==LA_VERILOG) { // verilogPrefixedTree doesn't want tabs
|
||||
while (num>=8) {
|
||||
*cp++ = '\t';
|
||||
num -= 8;
|
||||
@@ -625,8 +626,13 @@ int V3OutFormatter::endLevels (const char *strg) {
|
||||
case ')':
|
||||
levels-=INDBLK;
|
||||
break;
|
||||
case '<':
|
||||
if (m_lang==LA_XML) {
|
||||
if (cp[1] == '/') levels-=INDBLK;
|
||||
}
|
||||
break;
|
||||
case 'e':
|
||||
if (m_verilog && tokenEnd(cp)) {
|
||||
if (m_lang==LA_VERILOG && tokenEnd(cp)) {
|
||||
levels-=INDBLK;
|
||||
}
|
||||
break;
|
||||
@@ -668,39 +674,53 @@ void V3OutFormatter::puts (const char *strg) {
|
||||
case '{':
|
||||
indentInc();
|
||||
break;
|
||||
case '}':
|
||||
indentDec();
|
||||
break;
|
||||
case '(':
|
||||
indentInc();
|
||||
m_parenVec.push(m_column);
|
||||
break;
|
||||
case '}':
|
||||
indentDec();
|
||||
break;
|
||||
case ')':
|
||||
if (!m_parenVec.empty()) m_parenVec.pop();
|
||||
indentDec();
|
||||
break;
|
||||
case '<':
|
||||
if (m_lang==LA_XML) {
|
||||
if (cp[1] == '/') {} // Zero as the > will result in net decrease by one
|
||||
else if (cp[1] == '!' || cp[1] == '?') { indentInc(); } // net same indent
|
||||
else { indentInc(); indentInc(); } // net increase by one
|
||||
}
|
||||
break;
|
||||
case '>':
|
||||
if (m_lang==LA_XML) {
|
||||
indentDec();
|
||||
if (cp>strg && cp[-1]=='/') indentDec(); // < ..... /> stays same level
|
||||
}
|
||||
break;
|
||||
case 'b':
|
||||
if (wordstart && m_verilog && tokenStart(cp,"begin")) {
|
||||
if (wordstart && m_lang==LA_VERILOG && tokenStart(cp,"begin")) {
|
||||
indentInc();
|
||||
}
|
||||
wordstart = false;
|
||||
break;
|
||||
case 'c':
|
||||
if (wordstart && m_verilog && (tokenStart(cp,"case")
|
||||
|| tokenStart(cp,"casex")
|
||||
|| tokenStart(cp,"casez"))) {
|
||||
if (wordstart && m_lang==LA_VERILOG
|
||||
&& (tokenStart(cp,"case")
|
||||
|| tokenStart(cp,"casex")
|
||||
|| tokenStart(cp,"casez"))) {
|
||||
indentInc();
|
||||
}
|
||||
wordstart = false;
|
||||
break;
|
||||
case 'e':
|
||||
if (wordstart && m_verilog && tokenEnd(cp)) {
|
||||
if (wordstart && m_lang==LA_VERILOG && tokenEnd(cp)) {
|
||||
indentDec();
|
||||
}
|
||||
wordstart = false;
|
||||
break;
|
||||
case 'm':
|
||||
if (wordstart && m_verilog && tokenStart(cp,"module")) {
|
||||
if (wordstart && m_lang==LA_VERILOG && tokenStart(cp,"module")) {
|
||||
indentInc();
|
||||
}
|
||||
wordstart = false;
|
||||
@@ -801,8 +821,8 @@ void V3OutFormatter::printf (const char *fmt...) {
|
||||
//######################################################################
|
||||
// V3OutFormatter: A class for printing to a file, with automatic indentation of C++ code.
|
||||
|
||||
V3OutFile::V3OutFile(const string& filename)
|
||||
: V3OutFormatter(filename, false) {
|
||||
V3OutFile::V3OutFile(const string& filename, V3OutFormatter::Language lang)
|
||||
: V3OutFormatter(filename, lang) {
|
||||
if ((m_fp = V3File::new_fopen_w(filename.c_str())) == NULL) {
|
||||
v3fatal("Cannot write "<<filename);
|
||||
}
|
||||
|
||||
+86
-5
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: File stream wrapper that understands indentation
|
||||
//
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
typedef list<string> StrList;
|
||||
|
||||
// METHODS
|
||||
// Read file contents and return it. Return true on success.
|
||||
// Read file contents and return it. Return true on success.
|
||||
bool readWholefile(const string& filename, StrList& outl);
|
||||
|
||||
// CONSTRUCTORS
|
||||
@@ -105,11 +105,17 @@ public:
|
||||
enum AlignClass {
|
||||
AL_AUTO = 0,
|
||||
AL_STATIC = 1};
|
||||
enum Language {
|
||||
LA_C = 0,
|
||||
LA_VERILOG = 1,
|
||||
LA_MK = 2,
|
||||
LA_XML = 3,
|
||||
};
|
||||
|
||||
private:
|
||||
// MEMBERS
|
||||
string m_filename;
|
||||
bool m_verilog; // Indenting Verilog code
|
||||
Language m_lang; // Indenting Verilog code
|
||||
int m_lineno;
|
||||
int m_column;
|
||||
int m_nobreak; // Basic operator or begin paren, don't break next
|
||||
@@ -125,7 +131,7 @@ private:
|
||||
void putcNoTracking(char chr);
|
||||
|
||||
public:
|
||||
V3OutFormatter(const string& filename, bool verilog);
|
||||
V3OutFormatter(const string& filename, Language lang);
|
||||
virtual ~V3OutFormatter() {}
|
||||
// ACCESSORS
|
||||
int column() const { return m_column; }
|
||||
@@ -166,11 +172,86 @@ class V3OutFile : public V3OutFormatter {
|
||||
// MEMBERS
|
||||
FILE* m_fp;
|
||||
public:
|
||||
V3OutFile(const string& filename);
|
||||
V3OutFile(const string& filename, V3OutFormatter::Language lang);
|
||||
virtual ~V3OutFile();
|
||||
private:
|
||||
// CALLBACKS
|
||||
virtual void putcOutput(char chr) { fputc(chr, m_fp); }
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// V3OutCFile: A class for abstracting out SystemC/C++ details
|
||||
|
||||
class V3OutCFile : public V3OutFile {
|
||||
int m_private;
|
||||
public:
|
||||
V3OutCFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_C) {
|
||||
resetPrivate();
|
||||
}
|
||||
virtual ~V3OutCFile() {}
|
||||
virtual void putsCellDecl(const string& classname, const string& cellname) {
|
||||
this->printf("%-19s\t%s;\n",
|
||||
(classname + "*").c_str(),cellname.c_str());
|
||||
}
|
||||
virtual void putsHeader() { puts("// Verilated -*- C++ -*-\n"); }
|
||||
virtual void putsIntTopInclude() { }
|
||||
// Print out public/privates
|
||||
void resetPrivate() { m_private = 0; }
|
||||
void putsPrivate(bool setPrivate) {
|
||||
if (setPrivate && m_private!=1) {
|
||||
puts("private:\n");
|
||||
m_private = 1;
|
||||
} else if (!setPrivate && m_private!=2) {
|
||||
puts("public:\n");
|
||||
m_private = 2;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class V3OutScFile : public V3OutCFile {
|
||||
public:
|
||||
V3OutScFile(const string& filename) : V3OutCFile(filename) {}
|
||||
virtual ~V3OutScFile() {}
|
||||
virtual void putsHeader() { puts("// Verilated -*- SystemC -*-\n"); }
|
||||
virtual void putsIntTopInclude() {
|
||||
puts("#include \"systemc.h\"\n");
|
||||
puts("#include \"verilated_sc.h\"\n");
|
||||
}
|
||||
};
|
||||
|
||||
class V3OutSpFile : public V3OutCFile {
|
||||
public:
|
||||
V3OutSpFile(const string& filename) : V3OutCFile(filename) {}
|
||||
virtual ~V3OutSpFile() {}
|
||||
virtual void putsHeader() { puts("// Verilated -*- SystemC -*-\n"); }
|
||||
virtual void putsIntTopInclude() {
|
||||
puts("#include \"systemperl.h\"\n");
|
||||
puts("#include \"verilated_sc.h\"\n");
|
||||
}
|
||||
};
|
||||
|
||||
class V3OutVFile : public V3OutFile {
|
||||
public:
|
||||
V3OutVFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_VERILOG) {}
|
||||
virtual ~V3OutVFile() {}
|
||||
virtual void putsHeader() { puts("// Verilated -*- Verilog -*-\n"); }
|
||||
};
|
||||
|
||||
class V3OutXmlFile : public V3OutFile {
|
||||
public:
|
||||
V3OutXmlFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_XML) {}
|
||||
virtual ~V3OutXmlFile() {}
|
||||
virtual void putsHeader() { puts("<?xml version=\"1.0\" ?>\n"); }
|
||||
};
|
||||
|
||||
class V3OutMkFile : public V3OutFile {
|
||||
public:
|
||||
V3OutMkFile(const string& filename) : V3OutFile(filename, V3OutFormatter::LA_MK) {}
|
||||
virtual ~V3OutMkFile() {}
|
||||
virtual void putsHeader() { puts("# Verilated -*- Makefile -*-\n"); }
|
||||
// No automatic indentation yet.
|
||||
void puts(const char* strg) { putsNoTracking(strg); }
|
||||
void puts(const string& strg) { putsNoTracking(strg); }
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Gate optimizations, such as wire elimination
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Break always into sensitivity block domains
|
||||
//
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Generated Clock repairs
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
//-*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Generated Clock Repairs
|
||||
//
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Common headers
|
||||
//
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user