Compare commits

...
55 Commits
Author SHA1 Message Date
Wilson Snyder 0029d068c7 Version bump 2012-04-15 16:21:31 -04:00
Wilson Snyder de388b3dc8 Part of last commit 2012-04-15 16:14:18 -04:00
Wilson Snyder fb904d53cd Add doxygen comments, bug482 2012-04-15 15:44:32 -04:00
Wilson Snyder 600cc02de3 Commentary 2012-04-15 15:08:13 -04:00
Wilson Snyder 946d0cd219 Add readme.pdf and internal.pdf 2012-04-15 14:51:04 -04:00
Wilson Snyder 4d0b964e36 Internals: Merge from dtype. Create subDTypep. No functional change intended. 2012-04-14 12:43:03 -04:00
Wilson Snyder 2b12ab4d5a Internals: Merge from dtype. Add hasDType; still unused. No functional change. 2012-04-14 11:03:38 -04:00
Wilson Snyder 8114957e6d Internals: Merge from dtype. Rename isSigned to dtypeChgSigned. No functional change. 2012-04-14 10:45:24 -04:00
Wilson Snyder 50edef4ab2 Add Emacs indentation line. No functional change 2012-04-12 21:08:20 -04:00
Wilson Snyder e5a991988f Tests added 2012-04-12 20:13:35 -04:00
Wilson Snyder e85eb6d0f4 Tests: Add t_enum_type_methods, bug473 2012-04-12 18:21:08 -04:00
Wilson Snyder 6949f35f22 Tests: Add t_array_query, t_sv_conditional, bug473 2012-04-12 18:15:39 -04:00
Wilson Snyder e0391b93c4 Commentary 2012-04-12 06:48:02 -04:00
Wilson Snyder 4a5e775a2b Fix change detections on arrays. 2012-04-09 20:17:51 -04:00
Wilson Snyder 323f019350 Tests: Add t_interface, bug481. Merge from JERAS/test_sv. 2012-04-08 18:13:56 -04:00
Wilson Snyder 98053c2d4c Tests: Add t_param_type, bug480. Merge from JERAS/test_sv. 2012-04-08 17:59:46 -04:00
Wilson Snyder aab338760c Increase VL_VALUE_STRING_MAX_WIDTH, bug479 2012-04-05 21:46:55 -04:00
Wilson Snyder ab9a2b1728 Internal: Prevent possible buffer overrun 2012-04-05 21:46:03 -04:00
Wilson Snyder 6a38d3bcf3 Add SELRANGE as warning instead of error, bug477. 2012-04-04 21:55:20 -04:00
Wilson Snyder 76f3cbdf4c Merge branch 'master' of ssh://git-verilator-wsnyder/git/verilator 2012-04-02 22:05:40 -04:00
Wilson Snyder d45d58b6bf Fix real constant parameter functions, bug475. 2012-04-02 21:58:40 -04:00
Wilson Snyder f32a422330 Tests: New test 2012-04-02 19:38:42 -04:00
Wilson Snyder 74d4be28dd Commentary 2012-04-02 07:17:37 -04:00
Wilson Snyder b4a31bd292 Internals: Merge AstCCast minwidth set. No functional change intended 2012-04-01 21:17:58 -04:00
Wilson Snyder cc1adf9b38 Internals: merge V3Hashed cleanups. No functional change intended 2012-04-01 21:04:28 -04:00
Wilson Snyder 1601b3b6b0 Internals: Merge VFlagChildDtype calls. No functional change intended. 2012-03-31 11:22:19 -04:00
Wilson Snyder 61cbdd1a19 Internals: Merge VFlag rename. No functional change. 2012-03-31 11:10:34 -04:00
Wilson Snyder a3ee6131a3 Internals: Merge using dtypeSetLogicSized. No functional change intended 2012-03-31 10:53:53 -04:00
Wilson Snyder 6dfddaa453 Internals: Rename dtypeChg to dtypeSet. No functional change 2012-03-31 10:19:27 -04:00
Wilson Snyder de696b7092 Debug: Print dtype big endian correctly 2012-03-30 21:50:37 -04:00
Wilson Snyder 9165233657 Fix OpenSolaris compile error. 2012-03-30 07:26:00 -04:00
Wilson Snyder aa3a417e97 Tests: Add t_dpi_accessors 2012-03-27 20:06:59 -04:00
Wilson Snyder 996f48fcf0 Fix processing unused parametrized modules, bug470. 2012-03-24 15:54:06 -04:00
Wilson Snyder 81d83f629f Tests: default_nettype is ok 2012-03-24 15:15:32 -04:00
Wilson Snyder 5e3b0bf348 tests: Add unsupported as target type; additional tests 2012-03-24 11:10:17 -04:00
Wilson Snyder 4a31463299 Fix genvar and begin under generate, bug461. 2012-03-23 08:49:47 -04:00
Wilson Snyder 8a5471e175 Tests: skip test for bug462 2012-03-22 22:35:24 -04:00
Wilson Snyder 605fd9f8e1 Tests: Skip test for bug461 2012-03-22 22:15:35 -04:00
Wilson Snyder 2bda43875d Support += and -= in standard for loops, bug463. 2012-03-22 21:02:38 -04:00
Wilson Snyder 11edc9e7a7 Debug: Add --dump-treei option 2012-03-20 22:45:35 -04:00
Wilson Snyder 3b9b823511 tests: Fix missing manifest from earlier test commit 2012-03-20 22:45:00 -04:00
Wilson Snyder da0ecf59c6 Tests: Rename t_mem_packed_assign_bad since fails 2012-03-20 20:55:16 -04:00
Wilson Snyder e5b1fdf668 Tests: Added additional SystemVerilog tests.
Squashed commit of the following:

commit c1eeda7d472fc14a0ffd5c1712ae7f7c614073a1
Author: Iztok Jeras <[email protected]>
Date:   Tue Mar 20 16:39:44 2012 +0100

- fixed assignment operator in t_array_packed_write_read.v from = to <=
- added tests for enumerations (existing tests do not use methods like
next(), num(), ...)
- added t_sv_bus_mux_demux test, with packed arrays, structures and unions
2012-03-20 19:28:35 -04:00
Wilson Snyder 204fb82975 Add very experimental --xml option 2012-03-20 16:13:10 -04:00
Wilson Snyder 37839e2709 Cleanup trailing whitespace. No functional change 2012-03-20 16:01:53 -04:00
Wilson Snyder dbaedb5995 Internals: Add XML output internals, unused. No functional change. 2012-03-20 15:57:29 -04:00
Wilson Snyder 0a832e90bd Internals: Rename left/right to match IEEE. No functional change. 2012-03-19 21:32:05 -04:00
Wilson Snyder b4e908d04d Fix warning on gcc 4.6.1 2012-03-16 18:06:32 -04:00
Wilson Snyder 4619d29b78 Commentary; bug457 2012-03-15 18:44:08 -04:00
Wilson Snyder c63b697636 Fix signed array warning, bug456. 2012-03-12 20:29:00 -04:00
Wilson Snyder 06d29d6fda Commentary 2012-03-10 10:56:48 -05:00
Wilson Snyder c0f7bc4b5e Tests: Parameter bug case 2012-03-09 19:35:37 -05:00
Wilson Snyder 7139c9ae59 Fix and document --gdb option, bug454. 2012-03-09 18:37:38 -05:00
Wilson Snyder 0ae00fc921 Commentary; bug452. 2012-03-08 18:36:51 -05:00
Wilson Snyder fe456cb83d Devel version 2012-03-07 23:02:24 -05:00
314 changed files with 8549 additions and 1375 deletions
+2 -1
View File
@@ -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*
+25 -2
View File
@@ -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
+1
View File
@@ -35,3 +35,4 @@ nodist/
/simv.daidir/
/vc_hdrs.h$
/csrc/
doxygen-doc/.*
+37 -11
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+6
View File
@@ -0,0 +1,6 @@
/*! \mainpage Verilator Doxygen Documentation
*
* \section intro_sec Introduction
*
* This is a full doxygen analysis of the Verilator source tree.
*/
+1772
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -1,4 +1,3 @@
// -*- C++ -*-
//*************************************************************************
//
// Code available from: http://www.veripool.org/verilator
+1 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -1,4 +1,4 @@
// -*- SystemC -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//=============================================================================
//
// THIS MODULE IS PUBLICLY LICENSED
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- SystemC -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//=============================================================================
//
// THIS MODULE IS PUBLICLY LICENSED
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- SystemC -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//=============================================================================
//
// THIS MODULE IS PUBLICLY LICENSED
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- SystemC -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//=============================================================================
//
// THIS MODULE IS PUBLICLY LICENSED
+1 -1
View File
@@ -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 -1
View File
@@ -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 -1
View File
@@ -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
View File
@@ -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
+1
View File
@@ -182,6 +182,7 @@ RAW_OBJS = \
V3EmitCSyms.o \
V3EmitMk.o \
V3EmitV.o \
V3EmitXml.o \
V3Error.o \
V3Expand.o \
V3File.o \
+1
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Break always into sensitivity active domains
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Break always into sensitivity block domains
//
+1
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Break always into sensitivity active domains
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Break always into sensitivity block domains
//
+1
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Collect and print statistics
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Assertion expansion
//
+1
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Collect and print statistics
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Assertion pre-expansion
//
+3 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Removal of named begin blocks
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Removal of named begin blocks
//
+1
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Branch prediction
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Branch prediction
//
+1
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Find broken links in tree
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Find broken links in tree
//
+1
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Break case statements up and add Unknown assigns
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Break case statements up and add Unknown assigns
//
+2 -2
View File
@@ -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
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Add C++ casts across expression size changes
//
+1
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Clock Domain Crossing Lint
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Break always into sensitivity block domains
//
+45 -13
View File
@@ -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
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Pre C-Emit stage changes
//
+1
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Add temporaries, such as for clean nodes
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Pre C-Emit stage changes
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Break always into sensitivity active domains
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Break always into clock gated blocks
//
+3 -2
View File
@@ -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
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Clocking POS/NEGEDGE insertion
//
+1
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Combine common code into functions
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Combine common code into functions
//
+2 -1
View File
@@ -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
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Configuration Files
//
+7 -6
View File
@@ -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
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Propagate constants across AST
//
+2 -1
View File
@@ -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
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Coverage modules/signals together
//
+1
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Netlist (top level) functions
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Coverage modules/signals together
//
+1
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Dead code elimination
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Dead branch elimination
//
+2 -1
View File
@@ -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
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Pre C-Emit stage changes
//
+2 -1
View File
@@ -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
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Prevent very deep expressions
//
+1
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Prevent very deep expressions
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Prevent very deep expressions
//
+1
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Rename scope references to module-local references
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Rename scope references to module-local references
//
+19 -18
View File
@@ -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
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Emit C++ code for module tree
//
+1 -69
View File
@@ -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
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Emit C++ for tree
//
+4 -3
View File
@@ -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
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Emit Makefile
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Emit Makefile
//
+14 -8
View File
@@ -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
View File
@@ -1,4 +1,4 @@
//-*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Emit Verilog code for module tree
//
+197
View File
@@ -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");
}
+37
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Add temporaries, such as for expand nodes
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Expansion of wide operator macros to C operators
//
+36 -16
View File
@@ -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
View File
@@ -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
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Gate optimizations, such as wire elimination
//
+1 -1
View File
@@ -1,4 +1,4 @@
// -*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Break always into sensitivity block domains
//
+1
View File
@@ -1,3 +1,4 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Generated Clock repairs
//
+1 -1
View File
@@ -1,4 +1,4 @@
//-*- C++ -*-
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Generated Clock Repairs
//
+1 -1
View File
@@ -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