mirror of
https://github.com/verilator/verilator.git
synced 2026-10-02 16:13:34 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
34e8de56bc | ||
|
|
8a7864ebaa | ||
|
|
9e5fb5467f | ||
|
|
fb34bf7222 | ||
|
|
4591f35b7c | ||
|
|
f0a06182ca | ||
|
|
d9e47a6293 | ||
|
|
a555f87705 | ||
|
|
826b997166 | ||
|
|
d34bc6f304 | ||
|
|
5771ea48ef | ||
|
|
a4f3199427 | ||
|
|
e6a43fc127 | ||
|
|
701bd38d01 | ||
|
|
1a8c8bec0d | ||
|
|
20aa21d4b6 | ||
|
|
8c6adeb85a | ||
|
|
09b7ba1317 | ||
|
|
0703843ac1 | ||
|
|
d962dfe48c | ||
|
|
d6884db439 | ||
|
|
fdcbedef8f | ||
|
|
8afd19648f | ||
|
|
3017f12238 | ||
|
|
23ee0342c6 | ||
|
|
499f98a51c | ||
|
|
3073db4e81 | ||
|
|
5703377a5f | ||
|
|
b85aa872cc | ||
|
|
5a1a5a7d97 | ||
|
|
52912c6329 | ||
|
|
056f72f27f | ||
|
|
bb038e86a2 | ||
|
|
cc6c71eb37 | ||
|
|
de4358f8d8 | ||
|
|
d6e9c72424 | ||
|
|
96608fb18d | ||
|
|
280b826d6d | ||
|
|
538d3d46f4 | ||
|
|
66b8ec8935 | ||
|
|
4f30025aa0 | ||
|
|
faad36a3ef | ||
|
|
0b461599d1 | ||
|
|
0cbab84143 | ||
|
|
a4e2a770f6 | ||
|
|
36e84973ec | ||
|
|
f6c8888ee2 | ||
|
|
f2bf6a037b | ||
|
|
9dade8fbd9 | ||
|
|
d2d38edf06 | ||
|
|
e0abd238e3 | ||
|
|
7edcc08886 | ||
|
|
0c73b547f1 | ||
|
|
73c3d4bb50 | ||
|
|
77f063367a | ||
|
|
8e812058cb | ||
|
|
506c36beed | ||
|
|
0110f0193e | ||
|
|
7b870f4b2a | ||
|
|
aa2630f837 | ||
|
|
e137e93f94 | ||
|
|
215bdfccc2 | ||
|
|
956a0a9c99 | ||
|
|
ab83717b7d | ||
|
|
61e876e4bf | ||
|
|
9ca3dbc140 | ||
|
|
a02e2e25bb | ||
|
|
a9281f2c37 | ||
|
|
95395a8b87 | ||
|
|
ecdbd72fa1 | ||
|
|
3a2f8224e4 | ||
|
|
15841fe5f6 | ||
|
|
7e5a7b65a0 | ||
|
|
549bf876e4 | ||
|
|
bd60cf12f8 | ||
|
|
61fbab1910 | ||
|
|
957f495314 | ||
|
|
280eb48ba4 | ||
|
|
ebe5711b40 | ||
|
|
a16477d84f | ||
|
|
f6fb2362c6 | ||
|
|
170427bba1 | ||
|
|
93531e520a | ||
|
|
aa2db8fdde | ||
|
|
7c3c2af90b | ||
|
|
6dca9b4ba4 | ||
|
|
ede37bb9d8 | ||
|
|
4a1729eaab | ||
|
|
b1565f5b89 | ||
|
|
4fb8dcfd4e | ||
|
|
16d1f2b835 | ||
|
|
73594e5aa5 | ||
|
|
c0a365bd34 | ||
|
|
45940ff820 | ||
|
|
d545ae242c | ||
|
|
e862aaf2e1 |
@@ -7,7 +7,7 @@
|
||||
*.1
|
||||
*.tmp
|
||||
*.tex
|
||||
Makefile
|
||||
/Makefile
|
||||
README
|
||||
config.cache
|
||||
config.status
|
||||
@@ -3,6 +3,143 @@ Revision history for Verilator
|
||||
The contributors that suggested a given feature are shown in []. [by ...]
|
||||
indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
* Verilator 3.670 2008/07/23
|
||||
|
||||
** Add --x-assign=fast option, and make it the default.
|
||||
This chooses performance over reset debugging. See the manual.
|
||||
|
||||
** Add --autoflush, for flushing streams after $display. [Steve Tong]
|
||||
|
||||
** Add CASEZWITHX lint warning and if disabled fix handling of casez with Xs.
|
||||
|
||||
*** Add $feof, $fgetc, $fgets, $fflush, $fscanf, $sscanf. [Holger Waechtler]
|
||||
|
||||
*** Add $stime. [Holger Waechtler]
|
||||
|
||||
*** Add $random.
|
||||
|
||||
*** Add --Wfuture-, for improving forward compatibility.
|
||||
|
||||
**** Fix verilator_includer not being installed properly. [Holger Waechtler]
|
||||
|
||||
**** Fix IMPURE errors due to X-assignment temporary variables. [Steve Tong]
|
||||
|
||||
**** Fix "lvalue" errors with public functions; bug25. [CY Wang]
|
||||
|
||||
**** Add WIDTH warning to $fopen etc file descriptors.
|
||||
|
||||
**** Internal changes to how $displays get compiled and executed.
|
||||
|
||||
* Verilator 3.665 2008/06/25
|
||||
|
||||
**** Ignore "// verilator" comments alone on endif lines. [Rodney Sinclair]
|
||||
|
||||
**** "Make install" now installs verilator_includer and verilator_profcfunc.
|
||||
|
||||
**** Fix tracing missing changes on undriven public wires. [Rodney Sinclair]
|
||||
|
||||
**** Fix syntax error when "`include `defname" is ifdefed. [John Dickol]
|
||||
|
||||
**** Fix error when macro call has commas in concatenate. [John Dickol]
|
||||
|
||||
**** Fix compile errors under Fedora 9, GCC 4.3.0. [by Jeremy Bennett]
|
||||
|
||||
**** Fix Makefile to find headers/libraries under prefix. [by Holger Waechtler]
|
||||
|
||||
* Verilator 3.664 2008/05/08
|
||||
|
||||
**** Fix missing file in kit.
|
||||
|
||||
* Verilator 3.663 2008/05/07
|
||||
|
||||
**** Add DESTDIR to Makefiles to assist RPM construction. [Gunter Dannoritzer]
|
||||
|
||||
**** Fix compiler warnings under GCC 4.2.1.
|
||||
|
||||
**** Fix preprocessor `else after series of `elsif. [Mark Nodine]
|
||||
|
||||
**** Fix parametrized defines calling define with comma. [Joshua Wise]
|
||||
|
||||
**** Fix comma separated list of primitives. [by Bryan Brady]
|
||||
|
||||
* Verilator 3.662 2008/04/25
|
||||
|
||||
*** Add Verilog 2005 $clog2() function.
|
||||
This is useful in calculating bus-widths from parameters.
|
||||
|
||||
*** Support /**/ comments in -f option files. [Stefan Thiede]
|
||||
|
||||
**** Add error message when modules have duplicate names. [Stefan Thiede]
|
||||
|
||||
**** Support defines terminated in EOF, though against spec. [Stefan Thiede]
|
||||
|
||||
**** Support optional argument to $finish and $stop. [by Stefan Thiede]
|
||||
|
||||
**** Support ranges on gate primitive instantiations. [Stefan Thiede]
|
||||
|
||||
**** Ignore old standard(ish) Verilog-XL defines. [by Stefan Thiede]
|
||||
|
||||
**** Fix "always @ ((a) or (b))" syntax error. [by Niranjan Prabhu]
|
||||
|
||||
**** Fix "output reg name=expr;" syntax error. [Martin Scharrer]
|
||||
|
||||
**** Fix multiple .v files being read in random order. [Stefan Thiede]
|
||||
|
||||
**** Fix internal error when params get non-constants. [Johan Wouters]
|
||||
|
||||
**** Fix bug introduced in 3.661 with parametrized defines.
|
||||
|
||||
* Verilator 3.661 2008/04/04
|
||||
|
||||
*** The --enable-defenv configure option added in 3.660 is now the default.
|
||||
This hard-codes a default for VERILATOR_ROOT etc in the executables.
|
||||
|
||||
*** Add --language option for supporting older code. [Stefan Thiede]
|
||||
|
||||
*** Add --top-module option to select between multiple tops. [Stefan Thiede]
|
||||
|
||||
*** Unsized concatenates now give WIDTHCONCAT warnings. [Jonathan Kimmitt]
|
||||
Previously they threw fatal errors, which in most cases is correct
|
||||
according to spec, but can be incorrect in presence of parameter values.
|
||||
|
||||
**** Support functions with "input integer". [Johan Wouters]
|
||||
|
||||
**** Ignore delays attached to gate UDPs. [Stefan Thiede]
|
||||
|
||||
**** Fix SystemVerilog parameterized defines with `` expansion,
|
||||
and fix extra whitespace inserted on substitution. [Vladimir Matveyenko]
|
||||
|
||||
**** Fix no-module include files on command line. [Stefan Thiede]
|
||||
|
||||
**** Fix dropping of backslash quoted-quote at end of $display.
|
||||
|
||||
**** Fix task output pin connected to non-variables. [Jonathan Kimmitt]
|
||||
|
||||
**** Fix missing test_v in install datadir. [Holger Waechtler]
|
||||
|
||||
**** Fix internal error after MSB < LSB error reported to user. [Stefan Thiede]
|
||||
|
||||
* Verilator 3.660 2008/03/23
|
||||
|
||||
*** Add support for hard-coding VERILATOR_ROOT etc in the executables,
|
||||
to enable easier use of Verilator RPMs. [Gunter Dannoritzer]
|
||||
|
||||
*** Allow multiple .v files on command line. [Stefan Thiede]
|
||||
|
||||
*** Convert re-defining macro error to warning. [Stefan Thiede]
|
||||
|
||||
*** Add --error-limit option. [Stefan Thiede]
|
||||
|
||||
*** Allow __ in cell names by quoting them in C. [Stefan Thiede]
|
||||
|
||||
**** Fix genvar to be signed, so "< 0" works properly. [Niranjan Prabhu]
|
||||
|
||||
**** Fix assignments to inputs inside functions/tasks. [Patricio Kaplan]
|
||||
|
||||
**** Fix definitions in main file.v, referenced in library. [Stefan Thiede]
|
||||
|
||||
**** Fix undefined assigns to be implicit warnings. [Stefan Thiede]
|
||||
|
||||
* Verilator 3.658 2008/02/25
|
||||
|
||||
**** Fix unistd compile error in 3.657. [Patricio Kaplan, Jonathan Kimmitt]
|
||||
@@ -1142,8 +1279,6 @@ of input ports exists for tracing.
|
||||
**** First code written.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
$Id$
|
||||
----------------------------------------------------------------------
|
||||
|
||||
This uses outline mode in Emacs. See C-h m [M-x describe-mode].
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
^CVS/
|
||||
/CVS/
|
||||
\.git/
|
||||
\.svn/
|
||||
\.(bak|old)/
|
||||
\.(bak|old)$
|
||||
\bMakefile$
|
||||
\.tar\.
|
||||
.*\.tgz
|
||||
.*\.log
|
||||
.*\.tmp
|
||||
.*\.tex
|
||||
.*\.key
|
||||
.*\.vcd
|
||||
/obj_dir/
|
||||
/obj_dbg/
|
||||
/obj_opt/
|
||||
/INCA_libs/
|
||||
/logs/
|
||||
Makefile
|
||||
src/Makefile_obj
|
||||
include/verilated.mk
|
||||
config.cache
|
||||
config.status
|
||||
verilator_bin.*
|
||||
autom4te\.cache/
|
||||
nodist/
|
||||
+80
-40
@@ -1,24 +1,23 @@
|
||||
# $Id$
|
||||
#*****************************************************************************
|
||||
# DESCRIPTION: Verilator top level: Makefile pre-configure version
|
||||
#
|
||||
# This file is part of Verilator.
|
||||
#
|
||||
#
|
||||
# This file is part of Verilator.
|
||||
#
|
||||
# Author: Wilson Snyder <[email protected]>
|
||||
#
|
||||
# Code available from: http://www.veripool.com/verilator
|
||||
#
|
||||
#
|
||||
# Code available from: http://www.veripool.org/verilator
|
||||
#
|
||||
#*****************************************************************************
|
||||
#
|
||||
#
|
||||
# Copyright 2003-2008 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
#
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
#
|
||||
#****************************************************************************/
|
||||
#
|
||||
# make all to compile and build Verilator.
|
||||
@@ -38,7 +37,7 @@
|
||||
# source and built the program without creating any other files,
|
||||
# `make distclean' should leave only the files that were in the
|
||||
# distribution.
|
||||
#
|
||||
#
|
||||
# make maintainer-clean
|
||||
# Delete everything from the current directory that can be
|
||||
# reconstructed with this Makefile. This typically includes
|
||||
@@ -61,6 +60,9 @@ MAKEINFO = makeinfo
|
||||
TEXI2DVI = texi2dvi
|
||||
PERL = @PERL@
|
||||
|
||||
# Destination prefix for RPMs
|
||||
DESTDIR =
|
||||
|
||||
#### Don't edit: You're much better using configure switches to set these
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
@@ -78,8 +80,12 @@ datadir = @datadir@
|
||||
infodir = @infodir@
|
||||
|
||||
# Directory in which to install package specific files
|
||||
# Generally ${prefix}/share/verilator
|
||||
pkgdatadir = @pkgdatadir@
|
||||
|
||||
# Directory in which to install data across multiple architectures
|
||||
datarootdir = @datarootdir@
|
||||
|
||||
#### End of system configuration section. ####
|
||||
######################################################################
|
||||
|
||||
@@ -94,21 +100,28 @@ DISTDEP = info Makefile
|
||||
# Files to distribute.
|
||||
DISTBIN = $(wildcard bin/verilator-*)
|
||||
|
||||
DISTFILES_INC = $(INFOS) .cvsignore COPYING *.in *.ac \
|
||||
DISTFILES_INC = $(INFOS) .gitignore COPYING *.in *.ac \
|
||||
Changes README TODO \
|
||||
MANIFEST.SKIP \
|
||||
bin/* \
|
||||
install-sh configure mkinstalldirs *.texi \
|
||||
include/verilated.[chv]* \
|
||||
include/verilatedos.[chv]* \
|
||||
include/*.in \
|
||||
src/.cvsignore src/*.in src/*.cpp src/*.[chly] src/astgen src/flexfix \
|
||||
include/.*ignore \
|
||||
.*attributes */.*attributes */*/.*attributes \
|
||||
src/.*ignore src/*.in src/*.cpp src/*.[chly] src/astgen src/*fix \
|
||||
src/*.pl \
|
||||
test_*/.cvsignore test_*/Makefile* test_*/*.cpp \
|
||||
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
|
||||
test_*/*.pl test_*/*.v test_*/*.vc test_*/vlint \
|
||||
test_verilated/vgen*.pl \
|
||||
test_regress/t/*.v* \
|
||||
test_regress/t/*.pl \
|
||||
test_regress/t/*.cpp \
|
||||
test_regress/t/*.h \
|
||||
test_regress/t/*.dat \
|
||||
test_regress/t/*.mem \
|
||||
test_regress/t/*.out \
|
||||
test_regress/t/*.pl \
|
||||
test_regress/t/*.v* \
|
||||
verilator.* \
|
||||
|
||||
INST_PROJ_FILES = \
|
||||
@@ -124,8 +137,10 @@ INST_PROJ_BIN_FILES = \
|
||||
|
||||
DISTFILES := $(DISTFILES_INC)
|
||||
|
||||
VL_INST_MAN_FILES = verilator.1
|
||||
|
||||
all: all_nomsg msg_test
|
||||
all_nomsg: verilator_exe
|
||||
all_nomsg: verilator_exe $(VL_INST_MAN_FILES)
|
||||
|
||||
.PHONY:verilator_exe
|
||||
verilator_exe verilator_bin verilator_bin_dbg:
|
||||
@@ -140,6 +155,7 @@ msg_test:
|
||||
@echo "Type 'make test' to test."
|
||||
@echo
|
||||
|
||||
.PHONY:test
|
||||
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
|
||||
test: test_vcs test_c test_sc test_sp test_verilated test_regress
|
||||
else
|
||||
@@ -184,16 +200,18 @@ verilator.html: bin/verilator
|
||||
verilator.pdf: bin/verilator $(DISTCONFIG)
|
||||
pod2latex --full --out verilator.tex 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.com}\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
|
||||
mv verilator2.tex verilator.tex
|
||||
pdflatex verilator.tex
|
||||
pdflatex verilator.tex
|
||||
-rm -f verilator.toc verilator.aux verilator.idx
|
||||
-rm -f verilator.toc verilator.aux verilator.idx verilator.out
|
||||
|
||||
INSTALL: install.texi
|
||||
$(MAKEINFO) -I$(srcdir) $(srcdir)/install.texi --output=$@ \
|
||||
@@ -203,21 +221,38 @@ README: readme.texi
|
||||
$(MAKEINFO) -I$(srcdir) $(srcdir)/readme.texi --output=$@ \
|
||||
--no-headers --no-validate
|
||||
|
||||
installdirs:
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(bindir) $(infodir)
|
||||
|
||||
# See uninstall also
|
||||
VL_INST_BIN_FILES = verilator
|
||||
VL_INST_BIN_FILES = verilator verilator_bin verilator_bin_dbg \
|
||||
verilator_includer verilator_profcfunc
|
||||
# Some scripts go into both the search path and pkgdatadir,
|
||||
# so they can be found by the user, and under $VERILATOR_ROOT.
|
||||
installbin:
|
||||
( cd bin ; $(INSTALL_PROGRAM) verilator $(bindir)/verilator )
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(bindir)
|
||||
( cd bin ; $(INSTALL_PROGRAM) verilator $(DESTDIR)$(bindir)/verilator )
|
||||
( cd bin ; $(INSTALL_PROGRAM) verilator_includer $(DESTDIR)$(bindir)/verilator_includer )
|
||||
( cd bin ; $(INSTALL_PROGRAM) verilator_profcfunc $(DESTDIR)$(bindir)/verilator_profcfunc )
|
||||
( $(INSTALL_PROGRAM) verilator_bin $(DESTDIR)$(bindir)/verilator_bin )
|
||||
( $(INSTALL_PROGRAM) verilator_bin_dbg $(DESTDIR)$(bindir)/verilator_bin_dbg )
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/bin
|
||||
( cd bin ; $(INSTALL_PROGRAM) verilator_includer $(DESTDIR)$(pkgdatadir)/bin/verilator_includer )
|
||||
|
||||
VL_INST_MAN_FILES = verilator.1
|
||||
installman:
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(mandir)/man1
|
||||
for p in $(VL_INST_MAN_FILES) ; do \
|
||||
$(INSTALL_PROGRAM) $$p $(mandir)/man1/$$p; \
|
||||
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(mandir)/man1/$$p; \
|
||||
done
|
||||
|
||||
install: all_nomsg installdirs installbin installman install-msg
|
||||
installdata:
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples
|
||||
cp -r include $(DESTDIR)$(pkgdatadir)
|
||||
cp -r src $(DESTDIR)$(pkgdatadir)
|
||||
cp -r test_c $(DESTDIR)$(pkgdatadir)/examples
|
||||
cp -r test_sc $(DESTDIR)$(pkgdatadir)/examples
|
||||
cp -r test_sp $(DESTDIR)$(pkgdatadir)/examples
|
||||
cp -r test_v $(DESTDIR)$(pkgdatadir)/examples
|
||||
|
||||
VL_INST_DATA_FILES = verilator.1
|
||||
install: all_nomsg installbin installman installdata install-msg
|
||||
|
||||
install-here: installman ftp
|
||||
|
||||
@@ -232,8 +267,8 @@ install-project: dist
|
||||
for p in verilator.1 ; do \
|
||||
$(INSTALL_PROGRAM) -m 0666 $$p $(DIRPROJECT_PREFIX)/man/man1/$$p; \
|
||||
done
|
||||
$(INST_PROJ_CVS) $(DISTNAME).tar.gz $(DIRPROJECT)/hw/utils/verilator/verilator.tgz
|
||||
rm $(DISTNAME).tar.gz
|
||||
$(INST_PROJ_CVS) $(DISTNAME).tgz $(DIRPROJECT)/hw/utils/verilator/verilator.tgz
|
||||
rm $(DISTNAME).tgz
|
||||
|
||||
install-project-quick:
|
||||
@echo "Install-project-quick (no strip) to $(DIRPROJECT)"
|
||||
@@ -246,9 +281,6 @@ install-project-quick:
|
||||
endif
|
||||
|
||||
ftp: info
|
||||
echo "http://www.veripool.com/verilator3.html"
|
||||
cp verilator.html verilator_man.html
|
||||
ftp_tree --password $(VERIPOOL_PW) --user $(VERIPOOL_USER) verilator_man.html webftp.veripool.com:/web
|
||||
|
||||
install-msg:
|
||||
@echo "Installed!"
|
||||
@@ -261,8 +293,9 @@ install-msg:
|
||||
@echo
|
||||
|
||||
uninstall:
|
||||
-cd $(mandir)/man1 && rm -f $(VL_INST_MAN_FILES)
|
||||
-cd $(bindir) && rm -f $(VL_INST_BIN_FILES)
|
||||
-cd $(DESTDIR)$(mandir)/man1 && rm -f $(VL_INST_MAN_FILES)
|
||||
-cd $(DESTDIR)$(bindir) && rm -f $(VL_INST_BIN_FILES)
|
||||
-rm -f $(DESTDIR)$(pkgdatadir)
|
||||
|
||||
# autoheader might not change config_build.h.in, so touch a stamp file.
|
||||
IN_WILD := ${srcdir}/*.in ${srcdir}/*/*.in ${srcdir}/*/*/*.in \
|
||||
@@ -287,7 +320,7 @@ configure: configure.ac
|
||||
maintainer-clean::
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "rebuilding the deleted files requires makeinfo."
|
||||
rm -f *.info* $(INFOS) faq.html verilator.html configure bin/*
|
||||
rm -f *.info* $(INFOS) faq.html verilator.html configure
|
||||
|
||||
clean mostlyclean distclean maintainer-clean maintainer-copy::
|
||||
for dir in $(SUBDIRS); do \
|
||||
@@ -296,7 +329,7 @@ clean mostlyclean distclean maintainer-clean maintainer-copy::
|
||||
done
|
||||
|
||||
clean mostlyclean distclean maintainer-clean::
|
||||
rm -f $(SCRIPTS) *.tmp
|
||||
rm -f $(SCRIPTS) *.tmp
|
||||
rm -f *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.kys *.log
|
||||
rm -f *.pg *.pgs *.toc *.tp *.tps *.vr *.vrs *.idx
|
||||
rm -f *.ev *.evs *.ov *.ovs *.cv *.cvs *.ma *.mas
|
||||
@@ -312,6 +345,13 @@ TAGFILES=${srcdir}/*/*.cpp ${srcdir}/*/*.h ${srcdir}/*/[a-z]*.in \
|
||||
TAGS: $(TAGFILES)
|
||||
etags $(TAGFILES)
|
||||
|
||||
######################################################################
|
||||
# Test targets
|
||||
|
||||
dist-file-list:
|
||||
@echo "begin-dist-file-list:"; # Scripts look for this
|
||||
@echo $(wildcard $(DISTFILES))
|
||||
@echo "end-dist-file-list:"; # Scripts look for this
|
||||
|
||||
######################################################################
|
||||
# Distributions
|
||||
@@ -320,7 +360,7 @@ DISTCONFIG = src/config_build.h.in
|
||||
|
||||
DISTTITLE := $(shell sed -e '/DTVERSION/!d' -e 's/[^0-9]*\([0-9.a-z]*\).*/verilator-\1/' -e 's/v/V/' -e q $(DISTCONFIG))
|
||||
DISTNAME := $(shell sed -e '/DTVERSION/!d' -e 's/[^0-9]*\([0-9.a-z]*\).*/verilator-\1/' -e q $(DISTCONFIG))
|
||||
DISTDATEPRE := $(shell sed -e '/DTVERSION/!d' -e 's/.*\([0-3]\?[0-9].[0-3]\?[0-9].[1-2][0-9][0-9][0-9]\).*/\1/' -e q $(DISTCONFIG))
|
||||
DISTDATEPRE := $(shell sed -e '/DTVERSION/!d' -e 's/.*\([1-2][0-9][0-9][0-9].[0-9]*[0-9].[0-9]*[0-9]\).*/\1/' -e q $(DISTCONFIG))
|
||||
|
||||
DISTTAGNAME := $(subst .,_,$(subst -,_,$(DISTNAME)))
|
||||
DISTDATE := $(subst /,-,$(DISTDATEPRE))
|
||||
@@ -339,14 +379,14 @@ dist: $(DISTDEP) maintainer-copy
|
||||
chmod -R a+r $(DISTNAME)
|
||||
tar chf $(DISTNAME).tar $(DISTNAME)
|
||||
gzip --force --best $(DISTNAME).tar
|
||||
mv $(DISTNAME).tar.gz $(DISTNAME).tgz
|
||||
rm -fr $(DISTNAME)
|
||||
|
||||
maintainer-diff:
|
||||
svnorcvs diff $(DISTTAGNAME)
|
||||
|
||||
preexist:
|
||||
test ! -r ~/src/kits/$(DISTNAME).tar.gz
|
||||
svnorcvs nexists $(DISTTAGNAME)
|
||||
|
||||
maintainer-dist: preexist dist tag
|
||||
cp *.gz ~/backpack
|
||||
cp *.gz ~/src/kits
|
||||
svnorcvs release $(DISTNAME).tgz
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: List of To Do issues.
|
||||
//
|
||||
// Copyright 2004-2008 by Wilson Snyder. This program is free software; you can
|
||||
@@ -7,7 +6,7 @@
|
||||
|
||||
|
||||
Features:
|
||||
Finish 3.400 new ordering fixes
|
||||
Finish 3.400 new ordering fixes
|
||||
Latch optimizations {Need here}
|
||||
Task I/Os connecting to non-simple variables.
|
||||
Fix nested casez statements expanding into to huge C++. [JeanPaul Vanitegem]
|
||||
@@ -50,7 +49,7 @@ Testing:
|
||||
|
||||
Usability:
|
||||
Better reporting of unopt problems, including what lines of code
|
||||
Report more errors (all of them?) before exiting [Eugene Weber]
|
||||
Report more errors (all of them?) before exiting [Eugene Weber]
|
||||
|
||||
Internal Code:
|
||||
Eliminate the AstNUser* passed to all visitors; its only needed in V3Width,
|
||||
@@ -69,7 +68,7 @@ Performance:
|
||||
Multithreaded execution
|
||||
Bit-multiply for faster bit swapping and a=b[1,3,2] random bit reorderings.
|
||||
Move _last sets and all other combo logic inside master
|
||||
if() that triggers on all possible sense items
|
||||
if() that triggers on all possible sense items
|
||||
Rewrite and combine V3Life, V3Subst
|
||||
If block temp only ever set in one place to constant, propagate it
|
||||
Used in t_mem for array delayed assignments
|
||||
@@ -139,15 +138,15 @@ Selectable SystemC types based on widths (see notes below)
|
||||
c) a conditional whose possible values are (a) or (b)
|
||||
|
||||
2) One can lose that fact that a node is a tristate node. This happens
|
||||
if a tristate node is assigned to a 'standard' node, or is used on
|
||||
if a tristate node is assigned to a 'standard' node, or is used on
|
||||
RHS of a conditional. The following infer tristate signals:
|
||||
a) inout <SIGNAL>
|
||||
b) tri <SIGNAL>
|
||||
a) inout <SIGNAL>
|
||||
b) tri <SIGNAL>
|
||||
c) assigning to 'Z' (maybe through a conditional)
|
||||
Note: tristate-ness of an output port determined only by
|
||||
statements in the module (not the instances it calls)
|
||||
|
||||
|
||||
4) Tristate variables can't be multidimensional arrays
|
||||
5) Only check tristate contention between modules (not within!)
|
||||
5) Only check tristate contention between modules (not within!)
|
||||
6) Only simple compares with 'Z' are allowed (===)
|
||||
|
||||
|
||||
+227
-104
@@ -1,7 +1,6 @@
|
||||
: # -*-Mode: perl;-*- use perl, wherever it is
|
||||
eval 'exec perl -wS $0 ${1+"$@"}'
|
||||
if 0;
|
||||
# $Id$
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2003-2008 by Wilson Snyder. This program is free software; you can
|
||||
@@ -34,27 +33,7 @@ use Config;
|
||||
use Cwd qw(abs_path getcwd);
|
||||
|
||||
use strict;
|
||||
use vars qw ($Debug %Vars $Opt $Opt_Make_Dir $Opt_Sp @Opt_Verilator_Sw
|
||||
$Opt_Trace
|
||||
%Modules
|
||||
);
|
||||
|
||||
#######################################################################
|
||||
# Global constants -- Configuration info
|
||||
|
||||
# Where to find real executables
|
||||
# We could find it by using $RealBin, but we require this path
|
||||
# so that when the user runs make, they will have it and not get strange error.
|
||||
$ENV{VERILATOR_ROOT} or die "%Error: verilator: VERILATOR_ROOT needs to be in environment\n";
|
||||
print "export VERILATOR_ROOT=$ENV{VERILATOR_ROOT}\n" if $Debug;
|
||||
|
||||
# Read by verilator for populating makefile
|
||||
if (!defined $ENV{SYSTEMC_ARCH}) {
|
||||
$ENV{SYSTEMC_ARCH} ||= (($Config{osname} =~ /solaris/i && "gccsparcOS5")
|
||||
|| ($Config{osname} =~ /cygwin/i && "cygwin")
|
||||
|| "linux");
|
||||
print "export SYSTEMC_ARCH=$ENV{SYSTEMC_ARCH}\n" if $Debug;
|
||||
}
|
||||
use vars qw ($Debug @Opt_Verilator_Sw);
|
||||
|
||||
#######################################################################
|
||||
#######################################################################
|
||||
@@ -65,7 +44,6 @@ autoflush STDERR 1;
|
||||
|
||||
$Debug = 0;
|
||||
my $opt_gdb;
|
||||
$Opt_Sp = undef;
|
||||
|
||||
# No arguments can't do anything useful. Give help
|
||||
if ($#ARGV < 0) {
|
||||
@@ -84,34 +62,15 @@ if (! GetOptions (
|
||||
# Major operating modes
|
||||
"help" => \&usage,
|
||||
"debug:s" => \&debug,
|
||||
"version!" => \&version,
|
||||
# "version!" => \&version, # Also passthru'ed
|
||||
# Switches
|
||||
"gdb=s" => \$opt_gdb, # Undocumented debugging
|
||||
"trace!" => \$Opt_Trace,
|
||||
"sp!" => sub {$Opt_Sp = 'sp';},
|
||||
"sc!" => sub {$Opt_Sp = 'sc';},
|
||||
"cc!" => sub {$Opt_Sp = 0;},
|
||||
"lint-only!" => sub {$Opt_Sp = 0;},
|
||||
#"ignc!" => ..., # Undocumented debugging, disable $c but don't complain
|
||||
# Additional parameters
|
||||
"<>" => sub {}, # Ignored
|
||||
)) {
|
||||
pod2usage(-exitstatus=>2, -verbose=>0);
|
||||
}
|
||||
|
||||
# Check configuration
|
||||
if ($Opt_Sp) {
|
||||
(defined $ENV{SYSTEMC}) or die "%Error: verilator: Need \$SYSTEMC in environment\nProbably System-C isn't installed, see http://www.systemc.org\n";
|
||||
}
|
||||
if ($Opt_Sp eq 'sp' || $Opt_Trace) {
|
||||
if (!defined $ENV{SYSTEMPERL}) {
|
||||
my $try = "$ENV{W}/hw/utils/perltools/SystemC";
|
||||
$ENV{SYSTEMPERL} = $try if -d $try;
|
||||
}
|
||||
(defined $ENV{SYSTEMPERL}) or die "%Error: verilator: Need \$SYSTEMPERL in environment for --sp or --trace\nProbably System-Perl isn't installed, see http://www.veripool.com/systemperl.html\n";
|
||||
(-d "$ENV{SYSTEMPERL}/src") or die "%Error: verilator: \$SYSTEMPERL environment var doesn't seem to point to System-Perl kit\n";
|
||||
}
|
||||
|
||||
# Determine runtime flags
|
||||
my $vcmd =(($opt_gdb?"$opt_gdb ":"")
|
||||
.verilator_bin()
|
||||
@@ -124,8 +83,6 @@ run ($vcmd);
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub usage {
|
||||
bin_version();
|
||||
print '$Revision$$Date$ ', "\n";
|
||||
pod2usage(-exitstatus=>2, -verbose=>2);
|
||||
}
|
||||
|
||||
@@ -135,23 +92,16 @@ sub debug {
|
||||
$Debug = $level||3;
|
||||
}
|
||||
|
||||
sub version {
|
||||
bin_version();
|
||||
exit (0);
|
||||
}
|
||||
|
||||
sub bin_version {
|
||||
($ENV{VERILATOR_ROOT}) or print "%Warning: Unknown rev: VERILATOR_ROOT undefined\n";
|
||||
run (verilator_bin()." --version");
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#######################################################################
|
||||
# Builds
|
||||
|
||||
sub verilator_bin {
|
||||
my $bin = "$ENV{VERILATOR_ROOT}/".($ENV{VERILATOR_BIN}||"verilator_bin");
|
||||
if ($Debug && -x "${bin}_dbg") { $bin = "${bin}_dbg"; }
|
||||
my $bin = "";
|
||||
# Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path
|
||||
$bin .= $ENV{VERILATOR_ROOT}."/" if defined($ENV{VERILATOR_ROOT});
|
||||
$bin .= ($ENV{VERILATOR_BIN}||"verilator_bin");
|
||||
if ($Debug) { $bin = "${bin}_dbg"; }
|
||||
return $bin;
|
||||
}
|
||||
|
||||
@@ -166,8 +116,11 @@ sub run {
|
||||
system($command);
|
||||
my $status = $?;
|
||||
if ($status) {
|
||||
if ($! =~ /no such file or directory/i) {
|
||||
warn "%Error: verilator: Misinstalled, or VERILATOR_ROOT might need to be in environment\n";
|
||||
}
|
||||
if ($Debug) { # For easy rerunning
|
||||
warn "%Error: export VERILATOR_ROOT=$ENV{VERILATOR_ROOT}\n";
|
||||
warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n";
|
||||
warn "%Error: $command\n";
|
||||
}
|
||||
die "%Error: Command Failed $command\n";
|
||||
@@ -206,7 +159,7 @@ code, lints it, and optionally adds coverage and waveform tracing code.
|
||||
For C++ and SystemC formats, it outputs .cpp and .h files. For SystemPerl
|
||||
format, it outputs .sp files for the SystemPerl preprocessor, which greatly
|
||||
simplifies writing SystemC code and is available at
|
||||
L<http://www.veripool.com>.
|
||||
L<http://www.veripool.org>.
|
||||
|
||||
The files created by Verilator are then compiled with C++. The user writes
|
||||
a little C++ wrapper file, which instantiates the top level module, and
|
||||
@@ -224,6 +177,7 @@ descriptions in the next sections for more information.
|
||||
{file.c/cc/cpp} Optional C++ files to link in
|
||||
|
||||
--assert Enable all assertions
|
||||
--autoflush Flush streams after all $displays
|
||||
--bin <filename> Override Verilator binary
|
||||
--cc Create C++ output
|
||||
--compiler <compiler-name> Tune for specified C++ compiler
|
||||
@@ -235,12 +189,14 @@ descriptions in the next sections for more information.
|
||||
--debug-check Enable debugging assertions
|
||||
--dump-tree Enable dumping .tree files
|
||||
-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
|
||||
--help Display this help.
|
||||
-I<dir> Directory to search for includes
|
||||
--inhibit-sim Create function to turn off sim
|
||||
--inline-mult <value> Tune module inlining
|
||||
--language <lang> Language standard to parse
|
||||
--lint-only Lint, but do not make output
|
||||
--MMD Create .d dependency files
|
||||
--MP Create phony dependency targets
|
||||
@@ -261,12 +217,14 @@ descriptions in the next sections for more information.
|
||||
--sc Create SystemC output
|
||||
--sp Create SystemPerl output
|
||||
--stats Create statistics file
|
||||
--top-module <topname> Name of top level input module
|
||||
--trace Enable waveform creation
|
||||
--trace-depth <levels> Depth of tracing
|
||||
-U<var> Undefine preprocessor define
|
||||
--underline-zero Zero signals with leading _'s
|
||||
-v <filename> Verilog library
|
||||
-Werror-<message> Convert warning to error
|
||||
-Wfuture-<message> Disable unknown message warnings
|
||||
-Wno-<message> Disable warning
|
||||
-x-assign <mode> Initially assign Xs to this value
|
||||
-y <dir> Directory to search for modules
|
||||
@@ -296,6 +254,14 @@ linking with make rules you write yourself.
|
||||
Enable all assertions, includes enabling the --psl flag. (If psl is not
|
||||
desired, but other assertions are, use --assert --nopsl.)
|
||||
|
||||
See also --x-assign; setting "--x-assign unique" may be desirable.
|
||||
|
||||
=item --autoflush
|
||||
|
||||
After every $display or $fdisplay, flush the output stream. This insures
|
||||
that messages will appear immediately but may reduce performance. Defaults
|
||||
off, which will buffer output as provided by the normal C stdio calls.
|
||||
|
||||
=item --bin I<filename>
|
||||
|
||||
Rarely needed. Override the default filename for Verilator itself. When a
|
||||
@@ -393,6 +359,11 @@ Preprocess the source code, but do not compile, as with 'gcc -E'. Output
|
||||
is written to standard out. Beware of enabling debugging messages, as they
|
||||
will also go to standard out.
|
||||
|
||||
=item --error-limit <value>
|
||||
|
||||
After this number of errors or warnings are encountered, exit. Defaults to
|
||||
50.
|
||||
|
||||
=item --exe
|
||||
|
||||
Generate a executable. You will also need to pass additional .cpp files on
|
||||
@@ -418,6 +389,14 @@ values, or a value <= 1 will inline everything, will lead to longer compile
|
||||
times, but potentially faster runtimes. This setting is ignored for very
|
||||
small modules; they will always be inlined, if allowed.
|
||||
|
||||
=item --language I<value>
|
||||
|
||||
Select the language to be used when first processing each Verilog file.
|
||||
The language value must be "1364-1995", "1364-2001", "1364-2001",
|
||||
"1364-2005", or "1800-2005". This should only be used for legacy code, as
|
||||
the preferable option is to edit the code to repair new keywords, or add
|
||||
appropriate `begin_keywords.
|
||||
|
||||
=item --lint-only
|
||||
|
||||
Check the files for lint violations only, do not create any other output.
|
||||
@@ -490,8 +469,9 @@ the backward-compatible default of sc_bv's.
|
||||
|
||||
=item --prefix I<topname>
|
||||
|
||||
Specifies the name of the top level class. Defaults to the name of the top
|
||||
level Verilog module.
|
||||
Specifies the name of the top level class and makefile. Defaults to V
|
||||
prepended to the name of the --top-module switch, or V prepended to the
|
||||
first Verilog filename passed on the command line.
|
||||
|
||||
=item --profile-cfuncs
|
||||
|
||||
@@ -537,11 +517,22 @@ Specifies SystemPerl output mode; see also --cc and -sc.
|
||||
|
||||
Creates a dump file with statistics on the design in {prefix}__stats.txt.
|
||||
|
||||
=item --top-module I<topname>
|
||||
|
||||
When the input Verilog contains more than one top level module, specifies
|
||||
the name of the top level Verilog module to become the top, and sets the
|
||||
default for if --prefix is not used. This is not needed with standard
|
||||
designs with only one top.
|
||||
|
||||
=item --trace
|
||||
|
||||
Adds waveform tracing code to the model, this will create additional
|
||||
{prefix}__Trace*.cpp files you will need to add to your Makefiles, if
|
||||
you're not using the ones generated for you.
|
||||
Adds waveform tracing code to the model. Verilator will generate
|
||||
additional {prefix}__Trace*.cpp files that will need to be compiled. In
|
||||
addition Sp.cpp (for SystemC traces) or SpTraceVcdC.c (for C++ only) from
|
||||
the SystemPerl kit's src directory must be compiled and linked in. If
|
||||
using the Verilator generated Makefiles, these will be added as source
|
||||
targets for you. If you're not using the Verilator makefiles, you will
|
||||
need to add these to your Makefile manually.
|
||||
|
||||
Having tracing compiled in may result in some small performance losses,
|
||||
even when waveforms are not turned on during model execution.
|
||||
@@ -566,6 +557,14 @@ Convert the specified warning message into a error message. This is
|
||||
generally to discourage users from violating important site-wide rules, for
|
||||
example C<-Werror-NOUNOPTFLAT>.
|
||||
|
||||
=item -Wfuture-I<message>
|
||||
|
||||
Suppress unknown Verilator comments or warning messages with the given
|
||||
message code. This is used to allow code written with pragmas for a later
|
||||
version of Verilator to run under a older version; add -Wfuture- arguments
|
||||
for each message code or comment that the new version supports which the
|
||||
older version does not support.
|
||||
|
||||
=item -Wno-I<message>
|
||||
|
||||
Disable the specified warning message.
|
||||
@@ -573,9 +572,9 @@ Disable the specified warning message.
|
||||
=item -Wno-lint
|
||||
|
||||
Disable all lint related warning messages. This is equivelent to
|
||||
"-Wno-CASEINCOMPLETE -Wno-CASEOVERLAP -Wno-CASEX -Wno-CMPCONST
|
||||
-Wno-IMPLICIT -Wno-UNDRIVEN -Wno-UNSIGNED -Wno-UNUSED -Wno-VARHIDDEN
|
||||
-Wno-WIDTH".
|
||||
"-Wno-CASEINCOMPLETE -Wno-CASEOVERLAP -Wno-CASEX -Wno-CASEZWITHX
|
||||
-Wno-CMPCONST -Wno-IMPLICIT -Wno-UNDRIVEN -Wno-UNSIGNED -Wno-UNUSED
|
||||
-Wno-VARHIDDEN -Wno-WIDTH".
|
||||
|
||||
It is strongly recommended you cleanup your code rather than using this
|
||||
option, it is only intended to be use when running test-cases of code
|
||||
@@ -585,14 +584,18 @@ received from third parties.
|
||||
|
||||
=item -x-assign 1
|
||||
|
||||
=item -x-assign unique (default)
|
||||
=item -x-assign fast (default)
|
||||
|
||||
=item -x-assign unique
|
||||
|
||||
Controls the two-state value that is replaced when an assignment to X is
|
||||
encountered. -x-assign=0 converts all Xs to 0s, this is the fastest.
|
||||
-x-assign=1 converts all Xs to 1s, this is nearly as fast, but more likely
|
||||
to find reset bugs as active high logic will fire. The default,
|
||||
-x-assign=func will call a function to determine the value, this allows
|
||||
randomization of all Xs and is the slowest, but safest.
|
||||
encountered. -x-assign=fast, the default, converts all Xs to whatever is
|
||||
best for performance. -x-assign=0 converts all Xs to 0s, and is also fast.
|
||||
-x-assign=1 converts all Xs to 1s, this is nearly as fast as 0, but more
|
||||
likely to find reset bugs as active high logic will fire. -x-assign=unique
|
||||
will call a function to determine the value, this allows randomization of
|
||||
all Xs to find reset bugs and is the slowest, but safest for finding reset
|
||||
bugs in code.
|
||||
|
||||
=back
|
||||
|
||||
@@ -766,10 +769,10 @@ the test_sp directory in the distribution for an example.
|
||||
|
||||
=head1 BENCHMARKING & OPTIMIZATION
|
||||
|
||||
For best performance, run Verilator with the "-O3 -x-assign=0 --noassert"
|
||||
flags. The -O3 flag will require longer compile times, and -x-assign=0 may
|
||||
increase the risk of reset bugs in trade for performance; see the above
|
||||
documentation for these flags.
|
||||
For best performance, run Verilator with the "-O3 -x-assign=fast
|
||||
--noassert" flags. The -O3 flag will require longer compile times, and
|
||||
-x-assign=fast may increase the risk of reset bugs in trade for
|
||||
performance; see the above documentation for these flags.
|
||||
|
||||
Minor Verilog code changes can also give big wins. You should not have any
|
||||
UNOPTFLAT warnings from Verilator. Fixing these warnings can result in
|
||||
@@ -872,14 +875,16 @@ After running Make, the C++ compiler should produce the following:
|
||||
|
||||
Required for SystemC output mode. If set, specifies the directory
|
||||
containing the SystemC distribution. This is used to find the SystemC
|
||||
include files.
|
||||
include files. If not specified, it will come from a default optionally
|
||||
specified at configure time (before Verilator was compiled).
|
||||
|
||||
=item SYSTEMC_ARCH
|
||||
|
||||
Specifies the architecture name used by the SystemC kit. This is the part
|
||||
after the dash in the lib-{...} directory name created by a 'make' in the
|
||||
SystemC distribution. If not set, Verilator will try to intuit the proper
|
||||
setting.
|
||||
setting, or use the default optionally specified at configure time (before
|
||||
Verilator was compiled). .
|
||||
|
||||
=item SYSTEMC_CXX_FLAGS
|
||||
|
||||
@@ -889,7 +894,9 @@ building the SystemC model.
|
||||
=item SYSTEMPERL
|
||||
|
||||
Specifies the directory containing the Verilog-Perl distribution kit. This
|
||||
is used to find the Verilog-Perl library and include files.
|
||||
is used to find the Verilog-Perl library and include files. If not
|
||||
specified, it will come from a default optionally specified at configure
|
||||
time (before Verilator was compiled).
|
||||
|
||||
=item VCS_HOME
|
||||
|
||||
@@ -905,7 +912,9 @@ for debugging and selecting between multiple operating system builds.
|
||||
=item VERILATOR_ROOT
|
||||
|
||||
Specifies the directory containing the distribution kit. This is used to
|
||||
find the executable, Perl library, and include files.
|
||||
find the executable, Perl library, and include files. If not specified, it
|
||||
will come from a default optionally specified at configure time (before
|
||||
Verilator was compiled).
|
||||
|
||||
=back
|
||||
|
||||
@@ -930,7 +939,7 @@ example:
|
||||
unsigned int main_time = 0; // Current simulation time
|
||||
|
||||
double sc_time_stamp () { // Called by $time in Verilog
|
||||
return main_time;
|
||||
return main_time;
|
||||
}
|
||||
|
||||
int main() {
|
||||
@@ -1018,6 +1027,8 @@ declarations inside port lists.
|
||||
Verilator supports the `begin_keywords and `end_keywords compiler
|
||||
directives.
|
||||
|
||||
Verilator supports $clog2.
|
||||
|
||||
Verilator partially supports the uwire keyword.
|
||||
|
||||
=head1 SYSTEMVERILOG (IEEE 1800-2005) SUPPORT
|
||||
@@ -1309,10 +1320,9 @@ Wide variables over 64 bits cannot be function returns, to avoid exposing
|
||||
complexities. However, wide variables can be input/outputs; they will be
|
||||
passed as references to an array of 32 bit numbers.
|
||||
|
||||
This feature is still somewhat experimental. Generally, only the values of
|
||||
stored state (flops) should be written, as the model will NOT notice
|
||||
changes made to variables in these functions. (Same as when a signal is
|
||||
declared public.)
|
||||
Generally, only the values of stored state (flops) should be written, as
|
||||
the model will NOT notice changes made to variables in these functions.
|
||||
(Same as when a signal is declared public.)
|
||||
|
||||
=item /*verilator public_flat*/ (variable)
|
||||
|
||||
@@ -1546,8 +1556,8 @@ Verilator does not perform warning checking on uwires, it treats the uwire
|
||||
keyword as if it were the normal wire keyword.
|
||||
|
||||
=item $bits, $countones, $error, $fatal, $finish, $info, $isunknown,
|
||||
$onehot, $onehot0, $readmemb, $readmemh, $signed, $stop, $time, $unsigned,
|
||||
$warning.
|
||||
$onehot, $onehot0, $readmemb, $readmemh, $signed, $stime, $stop, $time,
|
||||
$unsigned, $warning.
|
||||
|
||||
Generally supported.
|
||||
|
||||
@@ -1561,7 +1571,11 @@ argument (as with C's printf), you cannot simply list variables standalone.
|
||||
The sized display functions are rarely used and so not supported. Replace
|
||||
them with a $write with the appropriate format specifier.
|
||||
|
||||
=item $fopen, $fclose, $fdisplay, $fwrite
|
||||
=item $finish, $stop
|
||||
|
||||
The rarely used optional parameter to $finish and $stop is ignored.
|
||||
|
||||
=item $fopen, $fclose, $fdisplay, $feof, $fflush, $fgetc, $fgets, $fscanf, $fwrite
|
||||
|
||||
File descriptors passed to the file PLI calls must be file descriptors, not
|
||||
MCDs, which includes the mode parameter to $fopen being mandatory.
|
||||
@@ -1571,11 +1585,22 @@ are 32 bits while FILE*s may be 64 bits, the descriptor must be stored in a
|
||||
reg [63:0] rather than an integer. The define `verilator_file_descriptor in
|
||||
verilated.v can be used to hide this difference.
|
||||
|
||||
=item $fscanf, $sscanf
|
||||
|
||||
Only integer formats are supported; %e, %f, %m, %r, %v, and %z are not
|
||||
supported.
|
||||
|
||||
=item $fullskew, $hold, $nochange, $period, $recovery, $recrem, $removal,
|
||||
$setup, $setuphold, $skew, $timeskew, $width
|
||||
|
||||
All specify blocks and timing checks are ignored.
|
||||
|
||||
=item $random
|
||||
|
||||
$random does not support the optional argument to set the seed. Use the
|
||||
srand function in C to accomplish this, and note there is only one random
|
||||
number generator (not one per module).
|
||||
|
||||
=item $readmemb, $readmemh
|
||||
|
||||
Read memory commands should work properly. Note Verilator and the Verilog
|
||||
@@ -1660,6 +1685,16 @@ L<http://www.sunburst-design.com/papers/CummingsSNUG1999Boston_FullParallelCase_
|
||||
Ignoring this warning will only suppress the lint check, it will simulate
|
||||
correctly.
|
||||
|
||||
=item CASEWITHX
|
||||
|
||||
Warns that a case statement contains a constant with a C<x>. Verilator is
|
||||
two-state so interpret such items as always false. Note a common error is
|
||||
to use a C<X> in a case or casez statement item; often what the user
|
||||
instead insteaded is to use a casez with C<?>.
|
||||
|
||||
Ignoring this warning will only suppress the lint check, it will simulate
|
||||
correctly.
|
||||
|
||||
=item CMPCONST
|
||||
|
||||
Warns that you are comparing a value in a way that will always be constant.
|
||||
@@ -1700,7 +1735,7 @@ output from a sub-module.) While legal in Verilog, implicit declarations
|
||||
only work for single bit wide signals (not buses), do not allow using a
|
||||
signal before it is implicitly declared by a cell, and can lead to dangling
|
||||
nets. A better option is the /*AUTOWIRE*/ feature of Verilog-Mode for
|
||||
Emacs, available from L<http://www.veripool.com/>
|
||||
Emacs, available from L<http://www.veripool.org/>
|
||||
|
||||
Ignoring this warning will only suppress the lint check, it will simulate
|
||||
correctly.
|
||||
@@ -1734,6 +1769,23 @@ not really needed. The best solution is to insure that each module is in a
|
||||
unique file by the same name. Otherwise, make sure all library files are
|
||||
read in as libraries with -v, instead of automatically with -y.
|
||||
|
||||
=item REDEFMACRO
|
||||
|
||||
Warns that you have redefined the same macro with a different value, for
|
||||
example:
|
||||
|
||||
`define MACRO def1
|
||||
//...
|
||||
`define MACRO otherdef
|
||||
|
||||
The best solution is to use a different name for the second macro. If this
|
||||
is not possible, add a undef to indicate the code is overriding the value:
|
||||
|
||||
`define MACRO def1
|
||||
//...
|
||||
`undef MACRO
|
||||
`define MACRO otherdef
|
||||
|
||||
=item STMTDLY
|
||||
|
||||
Warns that you have a statement with a delayed time in front of it, for
|
||||
@@ -1891,6 +1943,24 @@ The best fix, which clarifies intent and will also make all tools happy is:
|
||||
Ignoring this warning will only suppress the lint check, it will simulate
|
||||
correctly.
|
||||
|
||||
=item WIDTHCONCAT
|
||||
|
||||
Warns that based on width rules of Verilog, a concatenate or replication
|
||||
has a undeterminate width. In most cases this violates the Verilog rule
|
||||
that widths inside concatenates and replicates must be sized, and should be
|
||||
fixed in the code.
|
||||
|
||||
wire [63:0] concat = {1,2};
|
||||
|
||||
An example where this is technically legal (though still bad form) is:
|
||||
|
||||
parameter PAR = 1;
|
||||
wire [63:0] concat = {PAR,PAR};
|
||||
|
||||
The correct fix is to either size the 1 ("32'h1"), or add the width to the
|
||||
parameter definition ("parameter [31:0]"), or add the width to the
|
||||
parameter usage ("{PAR[31:0],PAR[31:0]}".
|
||||
|
||||
=back
|
||||
|
||||
The following describes the less obvious errors:
|
||||
@@ -1944,11 +2014,14 @@ Visual C++ Version 7 or newer, but this is not tested by the author.
|
||||
|
||||
=item Can you provide binaries?
|
||||
|
||||
At this time I'd prefer to get patches out quickly than have to generate
|
||||
myriad binaries for many different OS flavors. People have generally
|
||||
requested binaries when they are having problems with their C++
|
||||
compiler. Alas, binaries won't help this, as in the end a fully working C++
|
||||
compiler is required to compile the output of Verilator.
|
||||
Verilator is available as a RPM for SuSE and perhaps other systems; this is
|
||||
done by porters and may slightly lag the primary distribution. If there
|
||||
isn't a binary build for your distribution, how about you set one up?
|
||||
Please contact the authors for assistance.
|
||||
|
||||
Note people sometimes request binaries when they are having problems with
|
||||
their C++ compiler. Alas, binaries won't help this, as in the end a fully
|
||||
working C++ compiler is required to compile the output of Verilator.
|
||||
|
||||
=item How can it be faster than (name-the-simulator)?
|
||||
|
||||
@@ -2031,15 +2104,24 @@ the "verilator" define for you, so just wrap the code in a ifndef region:
|
||||
|
||||
=item Why do I get "unexpected `do'" or "unexpected `bit'" errors?
|
||||
|
||||
Do, bit, ref, and other words are now SystemVerilog keywords. You should
|
||||
change your code to not use them to insure it works with newer tools.
|
||||
Alternatively, surround them by the Verilog 2005/SystemVerilog
|
||||
Do, bit, ref, return, and other words are now SystemVerilog keywords. You
|
||||
should change your code to not use them to insure it works with newer
|
||||
tools. Alternatively, surround them by the Verilog 2005/SystemVerilog
|
||||
begin_keywords pragma to indicate Verilog 2001 code.
|
||||
|
||||
`begin_keywords "1364-2001"
|
||||
integer bit; initial bit = 1;
|
||||
`end_keywords
|
||||
|
||||
If you want the whole file to be parsed as Verilog 2001, just create a
|
||||
file with
|
||||
|
||||
`begin_keywords "1364-2001"
|
||||
|
||||
and add it before other Verilog files on the command line. (Note this will
|
||||
also change the default for --prefix, so if you're not using --prefix, you
|
||||
will now need to.)
|
||||
|
||||
=item How do I prevent my assertions from firing during reset?
|
||||
|
||||
Call Verilated::assertOn(false) before you first call the model, then turn
|
||||
@@ -2079,7 +2161,7 @@ use GCC 2.95, or GCC 3.4 you'll have faster builds. Two ways to cheat are
|
||||
to compile on parallel machines and avoid compilations altogether. See the
|
||||
--output-split option, and the web for the ccache, distcc and icecream
|
||||
packages, and the Make::Cache package available from
|
||||
L<http://www.veripool.com/>. Make::Cache will skip GCC runs between
|
||||
L<http://www.veripool.org/>. Make::Cache will skip GCC runs between
|
||||
identical source builds, even across different users.
|
||||
|
||||
=item Why do so many files need to recompile when I add a signal?
|
||||
@@ -2089,11 +2171,49 @@ uses one large symbol table, as that results in 2-3 less assembly
|
||||
instructions for each signal access. This makes the execution time 10-15%
|
||||
faster, but can result in more compilations when something changes.
|
||||
|
||||
=item How do I access functions/tasks in C?
|
||||
|
||||
Write a Verilog function or task with input/outputs that match what you
|
||||
want to call in with C. Then mark that function public.
|
||||
|
||||
Verilog inputs of one bit become C++ bool inputs. Inputs 32 bits or
|
||||
smaller become C uint32_t inputs, 64-32 bits become C uint64_t inputs, and
|
||||
wider signals become arrays of 32 bits. Outputs are passed as references
|
||||
to bool, uint32_t, uint64_t or uint32_t[] arrays.
|
||||
|
||||
Signals wider than 64 bits are passed as an array of 32-bit uint32_t's.
|
||||
Thus to read bits 31:0, access signal[0], and for bits 63:32, access
|
||||
signal[1]. Unused bits (for example bit numbers 65-96 of a 65 bit vector)
|
||||
will always be zero. if you change the value you must make sure to pack
|
||||
zeros in the unused bits or core-dumps may result. (Because Verilator
|
||||
strips array bound checks where it believes them to be unnecessary.)
|
||||
|
||||
In the SYSTEMC example above, if you had in our.v:
|
||||
|
||||
task publicSetBool;
|
||||
// verilator public
|
||||
input in_bool;
|
||||
var_bool = in_bool;
|
||||
endtask
|
||||
|
||||
From the sc_main.cpp file, you'd then:
|
||||
|
||||
#include "Vour.h"
|
||||
#include "Vour_our.h"
|
||||
top->v.publicSetBool(value);
|
||||
|
||||
See additional notes under the /*verilator public*/ section.
|
||||
|
||||
=item How do I access signals in C?
|
||||
|
||||
First, declare the signals you will be accessing with a /*verilator
|
||||
public*/ comment before the closing semicolon. Then scope into the C++
|
||||
class to read the value of the signal, as you would any other member variable.
|
||||
The best thing is to make a Verilator public task or function accessor that
|
||||
can read or write that signal, as described in the previous FAQ. This will
|
||||
allow Verilator to better optimize the model.
|
||||
|
||||
If you really want raw access to the signals, declare the signals you will
|
||||
be accessing with a /*verilator public*/ comment before the closing
|
||||
semicolon. Then scope into the C++ class to read the value of the signal,
|
||||
as you would any other member variable.
|
||||
|
||||
Signals are the smallest of 8 bit chars, 16 bit shorts, 32 bit longs, or 64
|
||||
bit long longs that fits the width of the signal. Generally, you can use
|
||||
@@ -2164,7 +2284,10 @@ outputs. Now, the following should fail:
|
||||
cd test_regress
|
||||
t/t_BUG.pl
|
||||
|
||||
Finally, Mail the bug report to C<[email protected]>.
|
||||
Finally, report the bug using the bug tracker at
|
||||
L<http://www.veripool.org/verilator>. The bug will become publicly
|
||||
visible; if this is unacceptable, mail the bug report to
|
||||
C<[email protected]>.
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
@@ -2217,7 +2340,7 @@ Eugene Weber, Leon Wildman, and Mat Zeno.
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
The latest version is available from L<http://www.veripool.com/>.
|
||||
The latest version is available from L<http://www.veripool.org/>.
|
||||
|
||||
Copyright 2003-2008 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
: # -*-Mode: perl;-*- use perl, wherever it is
|
||||
eval 'exec perl -wS $0 ${1+"$@"}'
|
||||
if 0;
|
||||
# $Id$
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2005-2008 by Wilson Snyder <[email protected]>. This
|
||||
@@ -115,7 +114,6 @@ sub filter {
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub usage {
|
||||
print '$Id$ ', "\n";
|
||||
pod2usage(-verbose=>2, -exitval => 2);
|
||||
exit (1);
|
||||
}
|
||||
@@ -130,7 +128,7 @@ sub parameter {
|
||||
$Opt_A = $param;
|
||||
} elsif (!defined $Opt_B) {
|
||||
$Opt_B = $param;
|
||||
} else {
|
||||
} else {
|
||||
die "%Error: Unknown parameter: $param\n";
|
||||
}
|
||||
}
|
||||
@@ -178,7 +176,7 @@ Displays this message and program version and exits.
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
The latest version is available from L<http://www.veripool.com/>.
|
||||
The latest version is available from L<http://www.veripool.org/verilator>.
|
||||
|
||||
Copyright 2005-2008 by Wilson Snyder. This package is free software; you
|
||||
can redistribute it and/or modify it under the terms of either the GNU
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
: # -*-Mode: perl;-*- use perl, wherever it is
|
||||
eval 'exec perl -wS $0 ${1+"$@"}'
|
||||
if 0;
|
||||
# $Id$
|
||||
# DESCRIPTION: Print include statements for each ARGV
|
||||
#
|
||||
# Copyright 2003-2008 by Wilson Snyder. This program is free software; you can
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
: # -*-Mode: perl;-*- use perl, wherever it is
|
||||
eval 'exec perl -wS $0 ${1+"$@"}'
|
||||
if 0;
|
||||
# $Id$
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2007-2008 by Wilson Snyder <[email protected]>. This
|
||||
@@ -50,7 +49,6 @@ profcfunc($Opt_File);
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub usage {
|
||||
print '$Id$ ', "\n";
|
||||
pod2usage(-verbose=>2, -exitval => 2);
|
||||
exit (1);
|
||||
}
|
||||
@@ -63,7 +61,7 @@ sub parameter {
|
||||
my $param = shift;
|
||||
if (!defined $Opt_File) {
|
||||
$Opt_File = $param;
|
||||
} else {
|
||||
} else {
|
||||
die "%Error: Unknown parameter: $param\n";
|
||||
}
|
||||
}
|
||||
@@ -189,7 +187,7 @@ Displays this message and program version and exits.
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
The latest version is available from L<http://www.veripool.com/>.
|
||||
The latest version is available from L<http://www.veripool.org/>.
|
||||
|
||||
Copyright 2007-2008 by Wilson Snyder. This package is free software; you
|
||||
can redistribute it and/or modify it under the terms of either the GNU
|
||||
|
||||
+19
-3
@@ -1,20 +1,36 @@
|
||||
dnl $Id$
|
||||
dnl DESCRIPTION: Process this file with autoconf to produce a configure script.
|
||||
dnl Copyright 2003-2008 by Wilson Snyder. This program is free software; you can
|
||||
dnl redistribute it and/or modify it under the terms of either the GNU
|
||||
dnl General Public License or the Perl Artistic License.
|
||||
|
||||
AC_REVISION($Revision$)dnl
|
||||
AC_INIT(src/Verilator.cpp)
|
||||
AC_CONFIG_HEADER(src/config_build.h)
|
||||
|
||||
dnl Special Substitutions
|
||||
AC_ARG_ENABLE(defenv,
|
||||
[AS_HELP_STRING([--disable-defenv], [disable hardcoded default environment variables])],
|
||||
CFG_WITH_DEFENV=$enableval,
|
||||
CFG_WITH_DEFENV=yes)
|
||||
AC_SUBST(CFG_WITH_DEFENV)
|
||||
|
||||
dnl Compiler flags
|
||||
CXX=g++
|
||||
CFLAGS=-I${includedir}
|
||||
CPPFLAGS=-I${includedir}
|
||||
CXXFLAGS=-I${includedir}
|
||||
LDFLAGS=-L${libdir}
|
||||
|
||||
dnl Checks for programs.
|
||||
CXX=g++
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_PROG_INSTALL
|
||||
|
||||
AC_LANG_PUSH(C++)
|
||||
AC_MSG_CHECKING([that C++ compiler can compile simple program])
|
||||
AC_TRY_RUN([int main() { return 0; }],
|
||||
AC_MSG_RESULT(yes),
|
||||
AC_MSG_RESULT(no);AC_MSG_ERROR([a working C++ compiler is required]))
|
||||
|
||||
AC_PATH_PROG(PERL,perl)
|
||||
if test "x$PERL" = "x" ; then
|
||||
AC_MSG_ERROR([Cannot find "perl" in your PATH, please install it])
|
||||
|
||||
+467
-96
@@ -1,4 +1,4 @@
|
||||
// $Id$ -*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2008 by Wilson Snyder. This program is free software; you can
|
||||
@@ -9,7 +9,7 @@
|
||||
// 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.
|
||||
//
|
||||
//
|
||||
//=========================================================================
|
||||
///
|
||||
/// \file
|
||||
@@ -18,13 +18,12 @@
|
||||
/// This file must be compiled and linked against all objects
|
||||
/// created from Verilator.
|
||||
///
|
||||
/// Code available from: http://www.veripool.com/verilator
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
//=========================================================================
|
||||
|
||||
#include "verilated.h"
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <cctype>
|
||||
|
||||
#define VL_VALUE_STRING_MAX_WIDTH 1024 ///< Max static char array for VL_VALUE_STRING
|
||||
|
||||
@@ -80,23 +79,43 @@ IData VL_RAND32() {
|
||||
#endif
|
||||
}
|
||||
|
||||
IData VL_RAND_RESET_I(int outBits) {
|
||||
IData VL_RANDOM_I(int obits) {
|
||||
return VL_RAND32() & VL_MASK_I(obits);
|
||||
}
|
||||
|
||||
QData VL_RANDOM_Q(int obits) {
|
||||
QData data = ((QData)VL_RAND32()<<VL_ULL(32)) | (QData)VL_RAND32();
|
||||
return data & VL_MASK_Q(obits);
|
||||
}
|
||||
|
||||
WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp) {
|
||||
for (int i=0; i<VL_WORDS_I(obits); i++) {
|
||||
if (i<(VL_WORDS_I(obits)-1)) {
|
||||
outwp[i] = VL_RAND32();
|
||||
} else {
|
||||
outwp[i] = VL_RAND32() & VL_MASK_I(obits);
|
||||
}
|
||||
}
|
||||
return outwp;
|
||||
}
|
||||
|
||||
IData VL_RAND_RESET_I(int obits) {
|
||||
if (Verilated::randReset()==0) return 0;
|
||||
IData data = ~0;
|
||||
if (Verilated::randReset()!=1) { // if 2, randomize
|
||||
data = VL_RAND32();
|
||||
data = VL_RANDOM_I(obits);
|
||||
}
|
||||
if (outBits<32) data &= VL_MASK_I(outBits);
|
||||
if (obits<32) data &= VL_MASK_I(obits);
|
||||
return data;
|
||||
}
|
||||
|
||||
QData VL_RAND_RESET_Q(int outBits) {
|
||||
QData VL_RAND_RESET_Q(int obits) {
|
||||
if (Verilated::randReset()==0) return 0;
|
||||
QData data = VL_ULL(~0);
|
||||
if (Verilated::randReset()!=1) { // if 2, randomize
|
||||
data = ((QData)VL_RAND32()<<VL_ULL(32)) | (QData)VL_RAND32();
|
||||
data = VL_RANDOM_Q(obits);
|
||||
}
|
||||
if (outBits<64) data &= VL_MASK_Q(outBits);
|
||||
if (obits<64) data &= VL_MASK_Q(obits);
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -119,94 +138,351 @@ WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp) {
|
||||
//===========================================================================
|
||||
// Formatting
|
||||
|
||||
const char* VL_VALUE_FORMATTED_Q(int obits, char fmt, bool drop0, QData ld) {
|
||||
// Convert value into %b/%o/%x/%s/%u/%d formatted string
|
||||
// Note uses a single buffer; presumes only one call per printf
|
||||
static VL_THREAD char str[VL_VALUE_STRING_MAX_WIDTH];
|
||||
char* strp = &str[0];
|
||||
int lsb=obits-1;
|
||||
if (drop0) while (lsb && !VL_BITISSET_Q(ld,lsb)) lsb--;
|
||||
switch (fmt) {
|
||||
case 'd':
|
||||
sprintf(str,"%lld",(vlsint64_t)(VL_EXTENDS_QQ(obits,obits,ld)));
|
||||
return str;
|
||||
case 'u':
|
||||
sprintf(str,"%llu",ld);
|
||||
return str;
|
||||
case 's':
|
||||
for (; lsb>=0; lsb--) {
|
||||
lsb = (lsb / 8) * 8; // Next digit
|
||||
IData charval = (ld>>VL_BITBIT_Q(lsb)) & 0xff;
|
||||
*strp++ = (charval==0)?' ':charval;
|
||||
// Do a va_arg returning a quad, assuming input argument is anything less than wide
|
||||
#define _VL_VA_ARG_Q(ap, bits) (((bits) <= VL_WORDSIZE) ? va_arg(ap,IData) : va_arg(ap,QData))
|
||||
|
||||
void _vl_vsformat(string& output, const char* formatp, va_list ap) {
|
||||
// Format a Verilog $write style format into the output list
|
||||
// The format must be pre-processed (and lower cased) by Verilator
|
||||
// Arguments are in "width, arg-value (or WDataIn* if wide)" form
|
||||
//
|
||||
// Note uses a single buffer internally; presumes only one usage per printf
|
||||
// Note also assumes variables < 64 are not wide, this assumption is
|
||||
// sometimes not true in low-level routines written here in verilated.cpp
|
||||
static VL_THREAD char tmp[VL_VALUE_STRING_MAX_WIDTH];
|
||||
bool inPct = false;
|
||||
bool widthSet = false;
|
||||
int width = 0;
|
||||
const char* pos = formatp;
|
||||
for (; *pos; ++pos) {
|
||||
if (!inPct && pos[0]=='%') {
|
||||
inPct = true;
|
||||
widthSet = false;
|
||||
width = 0;
|
||||
} else if (!inPct) { // Normal text
|
||||
// Fast-forward to next escape and add to output
|
||||
const char *ep = pos;
|
||||
while (ep[0] && ep[0]!='%') ep++;
|
||||
if (ep != pos) {
|
||||
output += string(pos, ep-pos);
|
||||
pos += ep-pos-1;
|
||||
}
|
||||
} else { // Format character
|
||||
inPct = false;
|
||||
char fmt = pos[0];
|
||||
switch (fmt) {
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
inPct = true; // Get more digits
|
||||
widthSet = true;
|
||||
width = width*10 + (fmt - '0');
|
||||
break;
|
||||
case '%':
|
||||
output += '%';
|
||||
break;
|
||||
case 'S': { // "C" string
|
||||
const char* cstrp = va_arg(ap, const char*);
|
||||
output += cstrp;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// Deal with all read-and-print somethings
|
||||
const int lbits = va_arg(ap, int);
|
||||
QData ld = 0;
|
||||
WDataInP lwp;
|
||||
if (lbits <= VL_QUADSIZE) {
|
||||
WData qlwp[2];
|
||||
ld = _VL_VA_ARG_Q(ap, lbits);
|
||||
VL_SET_WQ(qlwp,ld);
|
||||
lwp = qlwp;
|
||||
} else {
|
||||
lwp = va_arg(ap,WDataInP);
|
||||
ld = lwp[0];
|
||||
if (fmt == 'u' || fmt == 'd') fmt = 'x'; // Not supported, but show something
|
||||
}
|
||||
int lsb=lbits-1;
|
||||
if (widthSet && width==0) while (lsb && !VL_BITISSET_W(lwp,lsb)) lsb--;
|
||||
switch (fmt) {
|
||||
case 'c': {
|
||||
IData charval = ld & 0xff;
|
||||
output += charval;
|
||||
break;
|
||||
}
|
||||
case 's':
|
||||
for (; lsb>=0; lsb--) {
|
||||
lsb = (lsb / 8) * 8; // Next digit
|
||||
IData charval = (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 0xff;
|
||||
output += (charval==0)?' ':charval;
|
||||
}
|
||||
break;
|
||||
case 'd': { // Signed decimal
|
||||
int digits=sprintf(tmp,"%lld",(vlsint64_t)(VL_EXTENDS_QQ(lbits,lbits,ld)));
|
||||
int needmore = width-digits;
|
||||
if (needmore>0) output.append(needmore,' '); // Pre-pad spaces
|
||||
output += tmp;
|
||||
break;
|
||||
}
|
||||
case 'u': { // Unsigned decimal
|
||||
int digits=sprintf(tmp,"%llu",ld);
|
||||
int needmore = width-digits;
|
||||
if (needmore>0) output.append(needmore,' '); // Pre-pad spaces
|
||||
output += tmp;
|
||||
break;
|
||||
}
|
||||
case 'b':
|
||||
for (; lsb>=0; lsb--) {
|
||||
output += ((lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 1) + '0';
|
||||
}
|
||||
break;
|
||||
case 'o':
|
||||
for (; lsb>=0; lsb--) {
|
||||
lsb = (lsb / 3) * 3; // Next digit
|
||||
// Octal numbers may span more than one wide word,
|
||||
// so we need to grab each bit separately and check for overrun
|
||||
// Octal is rare, so we'll do it a slow simple way
|
||||
output += ('0'
|
||||
+ ((VL_BITISSETLIMIT_W(lwp, lbits, lsb+0)) ? 1 : 0)
|
||||
+ ((VL_BITISSETLIMIT_W(lwp, lbits, lsb+1)) ? 2 : 0)
|
||||
+ ((VL_BITISSETLIMIT_W(lwp, lbits, lsb+2)) ? 4 : 0));
|
||||
}
|
||||
break;
|
||||
case 'x':
|
||||
for (; lsb>=0; lsb--) {
|
||||
lsb = (lsb / 4) * 4; // Next digit
|
||||
IData charval = (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 0xf;
|
||||
output += "0123456789abcdef"[charval];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
string msg = string("%%Error: Unknown _vl_vsformat code: ")+pos[0]+"\n";
|
||||
vl_fatal(__FILE__,__LINE__,"",msg.c_str());
|
||||
break;
|
||||
} // switch
|
||||
}
|
||||
} // switch
|
||||
}
|
||||
*strp++ = '\0';
|
||||
return str;
|
||||
case 'b':
|
||||
for (; lsb>=0; lsb--) {
|
||||
*strp++ = ((ld>>VL_BITBIT_Q(lsb)) & 1) + '0';
|
||||
}
|
||||
*strp++ = '\0';
|
||||
return str;
|
||||
case 'o':
|
||||
for (; lsb>=0; lsb--) {
|
||||
lsb = (lsb / 3) * 3; // Next digit
|
||||
*strp++ = ((ld>>VL_BITBIT_Q(lsb)) & 7) + '0';
|
||||
}
|
||||
*strp++ = '\0';
|
||||
return str;
|
||||
default:
|
||||
for (; lsb>=0; lsb--) {
|
||||
lsb = (lsb / 4) * 4; // Next digit
|
||||
IData charval = (ld>>VL_BITBIT_Q(lsb)) & 0xf;
|
||||
*strp++ = (charval + ((charval < 10) ? '0':('a'-10)));
|
||||
}
|
||||
*strp++ = '\0';
|
||||
return str;
|
||||
}
|
||||
*strp++ = '\0';
|
||||
return str;
|
||||
}
|
||||
|
||||
const char* VL_VALUE_FORMATTED_W(int obits, char fmt, bool drop0, WDataInP lwp) {
|
||||
// Convert value into %b/%o/%x/%s/%u/%d formatted string
|
||||
// Note uses a single buffer; presumes only one call per printf
|
||||
static VL_THREAD char str[VL_VALUE_STRING_MAX_WIDTH];
|
||||
char* strp = &str[0];
|
||||
int lsb=obits-1;
|
||||
if (drop0) while (lsb && !VL_BITISSET_W(lwp,lsb)) lsb--;
|
||||
switch (fmt) {
|
||||
case 's':
|
||||
for (; lsb>=0; lsb--) {
|
||||
lsb = (lsb / 8) * 8; // Next digit
|
||||
IData charval = (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 0xff;
|
||||
*strp++ = (charval==0)?' ':charval;
|
||||
}
|
||||
*strp++ = '\0';
|
||||
return str;
|
||||
case 'b':
|
||||
for (; lsb>=0; lsb--) {
|
||||
*strp++ = ((lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 1) + '0';
|
||||
}
|
||||
*strp++ = '\0';
|
||||
return str;
|
||||
case 'o':
|
||||
for (; lsb>=0; lsb--) {
|
||||
lsb = (lsb / 3) * 3; // Next digit
|
||||
*strp++ = ((lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 7) + '0';
|
||||
}
|
||||
*strp++ = '\0';
|
||||
return str;
|
||||
default:
|
||||
for (; lsb>=0; lsb--) {
|
||||
lsb = (lsb / 4) * 4; // Next digit
|
||||
IData charval = (lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 0xf;
|
||||
*strp++ = (charval + ((charval < 10) ? '0':('a'-10)));
|
||||
}
|
||||
*strp++ = '\0';
|
||||
return str;
|
||||
static inline bool _vl_vsss_eof(FILE* fp, int& floc) {
|
||||
return fp ? feof(fp) : (floc<0);
|
||||
}
|
||||
static inline void _vl_vsss_advance(FILE* fp, int& floc) {
|
||||
if (fp) fgetc(fp);
|
||||
else floc -= 8;
|
||||
}
|
||||
static inline int _vl_vsss_peek(FILE* fp, int& floc, WDataInP fromp) {
|
||||
// Get a character without advancing
|
||||
if (fp) {
|
||||
int data = fgetc(fp);
|
||||
if (data == EOF) return EOF;
|
||||
ungetc(data,fp);
|
||||
return data;
|
||||
} else {
|
||||
if (floc < 0) return EOF;
|
||||
floc = floc & ~7; // Align to closest character
|
||||
int data = (fromp[VL_BITWORD_I(floc)] >> VL_BITBIT_I(floc)) & 0xff;
|
||||
return data;
|
||||
}
|
||||
*strp++ = '\0';
|
||||
return str;
|
||||
}
|
||||
static inline void _vl_vsss_skipspace(FILE* fp, int& floc, WDataInP fromp) {
|
||||
while (1) {
|
||||
int c = _vl_vsss_peek(fp, floc, fromp);
|
||||
if (c==EOF || !isspace(c)) return;
|
||||
_vl_vsss_advance(fp, floc);
|
||||
}
|
||||
}
|
||||
static inline void _vl_vsss_read(FILE* fp, int& floc, WDataInP fromp,
|
||||
char* tmpp, const char* acceptp) {
|
||||
// Read into tmp, consisting of characters from acceptp list
|
||||
char* cp = tmpp;
|
||||
while (1) {
|
||||
int c = _vl_vsss_peek(fp, floc, fromp);
|
||||
if (c==EOF || isspace(c)) break;
|
||||
if (acceptp!=NULL // String - allow anything
|
||||
&& NULL==strchr(acceptp, c)) break;
|
||||
if (acceptp!=NULL) c = tolower(c); // Non-strings we'll simplify
|
||||
*cp++ = c;
|
||||
_vl_vsss_advance(fp, floc);
|
||||
}
|
||||
*cp++ = '\0';
|
||||
//VL_PRINTF("\t_read got='%s'\n", tmpp);
|
||||
}
|
||||
static inline void _vl_vsss_setbit(WDataOutP owp, int obits, int lsb, int nbits, IData ld) {
|
||||
for (; nbits && lsb<obits; nbits--, lsb++, ld>>=1) {
|
||||
VL_ASSIGNBIT_WI(0, lsb, owp, ld & 1);
|
||||
}
|
||||
}
|
||||
|
||||
IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||
int fbits, WDataInP fromp, // Else if a sscanf
|
||||
const char* formatp, va_list ap) {
|
||||
// Read a Verilog $sscanf/$fscanf style format into the output list
|
||||
// The format must be pre-processed (and lower cased) by Verilator
|
||||
// Arguments are in "width, arg-value (or WDataIn* if wide)" form
|
||||
static VL_THREAD char tmp[VL_VALUE_STRING_MAX_WIDTH];
|
||||
int floc = fbits - 1;
|
||||
IData got = 0;
|
||||
bool inPct = false;
|
||||
const char* pos = formatp;
|
||||
for (; *pos && !_vl_vsss_eof(fp,floc); ++pos) {
|
||||
//VL_PRINTF("_vlscan fmt='%c' floc=%d file='%c'\n", pos[0], floc, _vl_vsss_peek(fp,floc,fromp));
|
||||
if (!inPct && pos[0]=='%') {
|
||||
inPct = true;
|
||||
} else if (!inPct && isspace(pos[0])) { // Format spaces
|
||||
while (isspace(pos[1])) pos++;
|
||||
_vl_vsss_skipspace(fp,floc,fromp);
|
||||
} else if (!inPct) { // Expected Format
|
||||
_vl_vsss_skipspace(fp,floc,fromp);
|
||||
int c = _vl_vsss_peek(fp,floc,fromp);
|
||||
if (c != pos[0]) goto done;
|
||||
else _vl_vsss_advance(fp,floc);
|
||||
} else { // Format character
|
||||
// Skip loading spaces
|
||||
inPct = false;
|
||||
char fmt = pos[0];
|
||||
switch (fmt) {
|
||||
case '%': {
|
||||
int c = _vl_vsss_peek(fp,floc,fromp);
|
||||
if (c != '%') goto done;
|
||||
else _vl_vsss_advance(fp,floc);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// Deal with all read-and-scan somethings
|
||||
// Note LSBs are preserved if there's an overflow
|
||||
const int obits = va_arg(ap, int);
|
||||
int lsb = 0;
|
||||
WData qowp[2];
|
||||
WDataOutP owp = qowp;
|
||||
if (obits > VL_QUADSIZE) {
|
||||
owp = va_arg(ap,WDataOutP);
|
||||
}
|
||||
for (int i=0; i<VL_WORDS_I(obits); i++) owp[i] = 0;
|
||||
switch (fmt) {
|
||||
case 'c': {
|
||||
int c = _vl_vsss_peek(fp,floc,fromp);
|
||||
if (c==EOF) goto done;
|
||||
else _vl_vsss_advance(fp,floc);
|
||||
owp[0] = c;
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
_vl_vsss_skipspace(fp,floc,fromp);
|
||||
_vl_vsss_read(fp,floc,fromp, tmp, NULL);
|
||||
if (!tmp[0]) goto done;
|
||||
int pos = strlen(tmp)-1;
|
||||
for (int i=0; i<obits && pos>=0; pos--) {
|
||||
_vl_vsss_setbit(owp,obits,lsb, 8, tmp[pos]); lsb+=8;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'd': { // Signed decimal
|
||||
_vl_vsss_skipspace(fp,floc,fromp);
|
||||
_vl_vsss_read(fp,floc,fromp, tmp, "0123456789+-xz?_");
|
||||
if (!tmp[0]) goto done;
|
||||
vlsint64_t ld;
|
||||
sscanf(tmp,"%lld",&ld);
|
||||
VL_SET_WQ(owp,ld);
|
||||
break;
|
||||
}
|
||||
case 'u': { // Unsigned decimal
|
||||
_vl_vsss_skipspace(fp,floc,fromp);
|
||||
_vl_vsss_read(fp,floc,fromp, tmp, "0123456789+-xz?_");
|
||||
if (!tmp[0]) goto done;
|
||||
QData ld;
|
||||
sscanf(tmp,"%llu",&ld);
|
||||
VL_SET_WQ(owp,ld);
|
||||
break;
|
||||
}
|
||||
case 'b': {
|
||||
_vl_vsss_skipspace(fp,floc,fromp);
|
||||
_vl_vsss_read(fp,floc,fromp, tmp, "01xz?_");
|
||||
if (!tmp[0]) goto done;
|
||||
int pos = strlen(tmp)-1;
|
||||
for (int i=0; i<obits && pos>=0; pos--) {
|
||||
switch(tmp[pos]) {
|
||||
case 'x': case 'z': case '?': //FALLTHRU
|
||||
case '0': lsb++; break;
|
||||
case '1': _vl_vsss_setbit(owp,obits,lsb, 1, 1); lsb++; break;
|
||||
case '_': break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'o': {
|
||||
_vl_vsss_skipspace(fp,floc,fromp);
|
||||
_vl_vsss_read(fp,floc,fromp, tmp, "01234567xz?_");
|
||||
if (!tmp[0]) goto done;
|
||||
int pos = strlen(tmp)-1;
|
||||
for (int i=0; i<obits && pos>=0; pos--) {
|
||||
switch(tmp[pos]) {
|
||||
case 'x': case 'z': case '?': //FALLTHRU
|
||||
case '0': lsb+=3; break;
|
||||
case '1': _vl_vsss_setbit(owp,obits,lsb, 3, 1); lsb+=3; break;
|
||||
case '2': _vl_vsss_setbit(owp,obits,lsb, 3, 2); lsb+=3; break;
|
||||
case '3': _vl_vsss_setbit(owp,obits,lsb, 3, 3); lsb+=3; break;
|
||||
case '4': _vl_vsss_setbit(owp,obits,lsb, 3, 4); lsb+=3; break;
|
||||
case '5': _vl_vsss_setbit(owp,obits,lsb, 3, 5); lsb+=3; break;
|
||||
case '6': _vl_vsss_setbit(owp,obits,lsb, 3, 6); lsb+=3; break;
|
||||
case '7': _vl_vsss_setbit(owp,obits,lsb, 3, 7); lsb+=3; break;
|
||||
case '_': break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'x': {
|
||||
_vl_vsss_skipspace(fp,floc,fromp);
|
||||
_vl_vsss_read(fp,floc,fromp, tmp, "0123456789abcdefxz?_");
|
||||
if (!tmp[0]) goto done;
|
||||
int pos = strlen(tmp)-1;
|
||||
for (int i=0; i<obits && pos>=0; pos--) {
|
||||
switch(tmp[pos]) {
|
||||
case 'x': case 'z': case '?': //FALLTHRU
|
||||
case '0': lsb+=4; break;
|
||||
case '1': _vl_vsss_setbit(owp,obits,lsb, 4, 1); lsb+=4; break;
|
||||
case '2': _vl_vsss_setbit(owp,obits,lsb, 4, 2); lsb+=4; break;
|
||||
case '3': _vl_vsss_setbit(owp,obits,lsb, 4, 3); lsb+=4; break;
|
||||
case '4': _vl_vsss_setbit(owp,obits,lsb, 4, 4); lsb+=4; break;
|
||||
case '5': _vl_vsss_setbit(owp,obits,lsb, 4, 5); lsb+=4; break;
|
||||
case '6': _vl_vsss_setbit(owp,obits,lsb, 4, 6); lsb+=4; break;
|
||||
case '7': _vl_vsss_setbit(owp,obits,lsb, 4, 7); lsb+=4; break;
|
||||
case '8': _vl_vsss_setbit(owp,obits,lsb, 4, 8); lsb+=4; break;
|
||||
case '9': _vl_vsss_setbit(owp,obits,lsb, 4, 9); lsb+=4; break;
|
||||
case 'a': _vl_vsss_setbit(owp,obits,lsb, 4, 10); lsb+=4; break;
|
||||
case 'b': _vl_vsss_setbit(owp,obits,lsb, 4, 11); lsb+=4; break;
|
||||
case 'c': _vl_vsss_setbit(owp,obits,lsb, 4, 12); lsb+=4; break;
|
||||
case 'd': _vl_vsss_setbit(owp,obits,lsb, 4, 13); lsb+=4; break;
|
||||
case 'e': _vl_vsss_setbit(owp,obits,lsb, 4, 14); lsb+=4; break;
|
||||
case 'f': _vl_vsss_setbit(owp,obits,lsb, 4, 15); lsb+=4; break;
|
||||
case '_': break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
string msg = string("%%Error: Unknown _vl_vsscanf code: ")+pos[0]+"\n";
|
||||
vl_fatal(__FILE__,__LINE__,"",msg.c_str());
|
||||
break;
|
||||
} // switch
|
||||
|
||||
got++;
|
||||
// Reload data if non-wide (if wide, we put it in the right place directly)
|
||||
if (obits <= VL_BYTESIZE) {
|
||||
CData* p = va_arg(ap,CData*); *p = owp[0];
|
||||
} else if (obits <= VL_SHORTSIZE) {
|
||||
SData* p = va_arg(ap,SData*); *p = owp[0];
|
||||
} else if (obits <= VL_WORDSIZE) {
|
||||
IData* p = va_arg(ap,IData*); *p = owp[0];
|
||||
} else if (obits <= VL_QUADSIZE) {
|
||||
QData* p = va_arg(ap,QData*); *p = VL_SET_QW(owp);
|
||||
}
|
||||
}
|
||||
} // switch
|
||||
}
|
||||
}
|
||||
done:
|
||||
return got;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
@@ -228,6 +504,40 @@ void _VL_VINT_TO_STRING(int obits, char* destoutp, WDataInP sourcep) {
|
||||
while (isspace(*(destp-1)) && destp>destoutp) *--destp = '\0'; // Drop trailing spaces
|
||||
}
|
||||
|
||||
void _VL_STRING_TO_VINT(int obits, void* destp, int srclen, const char* srcp) {
|
||||
// Convert C string to Verilog format
|
||||
int bytes = VL_BYTES_I(obits);
|
||||
char* op = ((char*)(destp));
|
||||
if (srclen > bytes) srclen = bytes; // Don't overflow destination
|
||||
int i;
|
||||
for (i=0; i<srclen; i++) { *op++ = srcp[srclen-1-i]; }
|
||||
for (; i<bytes; i++) { *op++ = 0; }
|
||||
}
|
||||
|
||||
IData VL_FGETS_IXQ(int obits, void* destp, QData fpq) {
|
||||
FILE* fp = VL_CVT_Q_FP(fpq);
|
||||
if (VL_UNLIKELY(!fp)) return 0;
|
||||
|
||||
// The string needs to be padded with 0's in unused spaces in front of
|
||||
// any read data. This means we can't know in what location the first
|
||||
// character will finally live, so we need to copy. Yuk.
|
||||
IData bytes = VL_BYTES_I(obits);
|
||||
char buffer[bytes];
|
||||
|
||||
// We don't use fgets, as we must read \0s.
|
||||
IData got = 0;
|
||||
char* cp = buffer;
|
||||
while (got < bytes) {
|
||||
int c = getc(fp);
|
||||
if (c==EOF) break;
|
||||
*cp++ = c; got++;
|
||||
if (c=='\n') break;
|
||||
}
|
||||
|
||||
_VL_STRING_TO_VINT(obits, destp, got, buffer);
|
||||
return got;
|
||||
}
|
||||
|
||||
QData VL_FOPEN_QI(QData filename, IData mode) {
|
||||
IData fnw[2]; VL_SET_WQ(fnw, filename);
|
||||
return VL_FOPEN_WI(2, fnw, mode);
|
||||
@@ -240,6 +550,67 @@ QData VL_FOPEN_WI(int fnwords, WDataInP filenamep, IData mode) {
|
||||
return VL_CVT_FP_Q(fopen(filenamez,modez));
|
||||
}
|
||||
|
||||
void VL_WRITEF(const char* formatp, ...) {
|
||||
va_list ap;
|
||||
va_start(ap,formatp);
|
||||
string output;
|
||||
_vl_vsformat(output, formatp, ap);
|
||||
va_end(ap);
|
||||
|
||||
// Users can redefine VL_PRINTF if they wish.
|
||||
VL_PRINTF("%s", output.c_str());
|
||||
}
|
||||
|
||||
void VL_FWRITEF(QData fpq, const char* formatp, ...) {
|
||||
FILE* fp = VL_CVT_Q_FP(fpq);
|
||||
if (VL_UNLIKELY(!fp)) return;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap,formatp);
|
||||
string output;
|
||||
_vl_vsformat(output, formatp, ap);
|
||||
va_end(ap);
|
||||
|
||||
fputs(output.c_str(), fp);
|
||||
}
|
||||
|
||||
IData VL_FSCANF_IX(QData fpq, const char* formatp, ...) {
|
||||
FILE* fp = VL_CVT_Q_FP(fpq);
|
||||
if (VL_UNLIKELY(!fp)) return 0;
|
||||
|
||||
va_list ap;
|
||||
va_start(ap,formatp);
|
||||
IData got = _vl_vsscanf(fp, 0, NULL, formatp, ap);
|
||||
va_end(ap);
|
||||
return got;
|
||||
}
|
||||
|
||||
IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...) {
|
||||
IData fnw[2]; VL_SET_WI(fnw, ld);
|
||||
|
||||
va_list ap;
|
||||
va_start(ap,formatp);
|
||||
IData got = _vl_vsscanf(NULL, lbits, fnw, formatp, ap);
|
||||
va_end(ap);
|
||||
return got;
|
||||
}
|
||||
IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...) {
|
||||
IData fnw[2]; VL_SET_WQ(fnw, ld);
|
||||
|
||||
va_list ap;
|
||||
va_start(ap,formatp);
|
||||
IData got = _vl_vsscanf(NULL, lbits, fnw, formatp, ap);
|
||||
va_end(ap);
|
||||
return got;
|
||||
}
|
||||
IData VL_SSCANF_IWX(int lbits, WDataInP lwp, const char* formatp, ...) {
|
||||
va_list ap;
|
||||
va_start(ap,formatp);
|
||||
IData got = _vl_vsscanf(NULL, lbits, lwp, formatp, ap);
|
||||
va_end(ap);
|
||||
return got;
|
||||
}
|
||||
|
||||
void VL_READMEM_Q(bool hex, int width, int depth, int array_lsb, int,
|
||||
QData ofilename, void* memp, IData start, IData end) {
|
||||
IData fnw[2]; VL_SET_WQ(fnw, ofilename);
|
||||
@@ -276,7 +647,7 @@ void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
|
||||
else if (c=='\t' || c==' ' || c=='\r' || c=='\f') { if (innum) reading_addr=false; innum=false; }
|
||||
// Skip // comments and detect /* comments
|
||||
else if (ignore_to_cmt && lastc=='*' && c=='/') {
|
||||
ignore_to_cmt = false; if (innum) reading_addr=false; innum=false;
|
||||
ignore_to_cmt = false; if (innum) reading_addr=false; innum=false;
|
||||
} else if (!ignore_to_eol && !ignore_to_cmt) {
|
||||
if (lastc=='/' && c=='*') { ignore_to_cmt = true; }
|
||||
else if (lastc=='/' && c=='/') { ignore_to_eol = true; }
|
||||
@@ -355,7 +726,7 @@ const char* Verilated::catName(const char* n1, const char* n2) {
|
||||
// Used by symbol table creation to make module names
|
||||
static char* strp = NULL;
|
||||
static int len = -1;
|
||||
int newlen = strlen(n1)+strlen(n2)+2;
|
||||
int newlen = strlen(n1)+strlen(n2)+2;
|
||||
if (newlen > len) {
|
||||
if (strp) delete [] strp;
|
||||
strp = new char[newlen];
|
||||
|
||||
+106
-46
@@ -1,4 +1,4 @@
|
||||
// $Id$ -*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2008 by Wilson Snyder. This program is free software; you can
|
||||
@@ -9,7 +9,7 @@
|
||||
// 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.
|
||||
//
|
||||
//
|
||||
//*************************************************************************
|
||||
///
|
||||
/// \file
|
||||
@@ -19,7 +19,7 @@
|
||||
/// all C++ files it generates. It contains standard macros and
|
||||
/// classes required by the Verilated code.
|
||||
///
|
||||
/// Code available from: http://www.veripool.com/verilator
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
//*************************************************************************
|
||||
|
||||
@@ -29,11 +29,11 @@
|
||||
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <cassert>
|
||||
#include <cstdarg>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
@@ -129,7 +129,7 @@ struct Verilated {
|
||||
// Extern Vars
|
||||
// Below two are used as bool, but having as uint32_t avoids conversion time
|
||||
private:
|
||||
static int s_randReset; ///< Random reset: 0=all 0s, 1=all 1s, 2=random
|
||||
static int s_randReset; ///< Random reset: 0=all 0s, 1=all 1s, 2=random
|
||||
static int s_debug; ///< See accessors... only when VL_DEBUG set
|
||||
static bool s_calcUnusedSigs; ///< Waves file on, need all signals calculated
|
||||
static bool s_gotFinish; ///< A $finish statement executed
|
||||
@@ -152,7 +152,7 @@ public:
|
||||
#endif
|
||||
/// Internal: Create a new module name by concatenating two strings
|
||||
static const char* catName(const char* n1, const char* n2); // Returns new'ed data
|
||||
/// Enable calculation of unused signals
|
||||
/// Enable calculation of unused signals
|
||||
static void calcUnusedSigs(bool flag) { s_calcUnusedSigs=flag; }
|
||||
static bool calcUnusedSigs() { return s_calcUnusedSigs; } ///< Return calcUnusedSigs value
|
||||
/// Did the simulation $finish?
|
||||
@@ -165,7 +165,7 @@ public:
|
||||
/// Enable/disable assertions
|
||||
static void assertOn(bool flag) { s_assertOn=flag; }
|
||||
static bool assertOn() { return s_assertOn; }
|
||||
};
|
||||
};
|
||||
|
||||
//=========================================================================
|
||||
// Extern functions -- User may override -- See verilated.cpp
|
||||
@@ -179,21 +179,21 @@ extern void vl_fatal (const char* filename, int linenum, const char* hier,
|
||||
const char* msg);
|
||||
|
||||
//=========================================================================
|
||||
// Extern functions -- Init time only, so slow is fine
|
||||
// Extern functions -- Slow path
|
||||
|
||||
extern IData VL_RANDOM_I(int obits); ///< Randomize a signal
|
||||
extern QData VL_RANDOM_Q(int obits); ///< Randomize a signal
|
||||
extern WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp); ///< Randomize a signal
|
||||
|
||||
/// Init time only, so slow is fine
|
||||
extern IData VL_RAND_RESET_I(int obits); ///< Random reset a signal
|
||||
extern QData VL_RAND_RESET_Q(int obits); ///< Random reset a signal
|
||||
extern WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp); ///< Random reset a signal
|
||||
extern WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp); ///< Zero reset a signal
|
||||
|
||||
/// Return string with formated Verilog value
|
||||
extern const char* VL_VALUE_FORMATTED_W(int obits, char fmt, bool drop0, WDataInP lwp);
|
||||
extern const char* VL_VALUE_FORMATTED_Q(int obits, char fmt, bool drop0, QData ld);
|
||||
inline const char* VL_VALUE_FORMATTED_I(int obits, char fmt, bool drop0, IData ld) {
|
||||
return VL_VALUE_FORMATTED_Q(obits,fmt,drop0,ld);
|
||||
}
|
||||
|
||||
/// File I/O
|
||||
extern IData VL_FGETS_IXQ(int sbits, void* strgp, QData fpq);
|
||||
|
||||
extern QData VL_FOPEN_WI(int fnwords, WDataInP ofilename, IData mode);
|
||||
extern QData VL_FOPEN_QI(QData ofilename, IData mode);
|
||||
inline QData VL_FOPEN_II(IData ofilename, IData mode) { return VL_FOPEN_QI(ofilename,mode); }
|
||||
@@ -206,6 +206,14 @@ inline void VL_READMEM_I(bool hex, int width, int depth, int array_lsb, int fnwo
|
||||
IData ofilename, void* memp, IData start, IData end) {
|
||||
VL_READMEM_Q(hex, width,depth,array_lsb,fnwords, ofilename,memp,start,end); }
|
||||
|
||||
extern void VL_WRITEF(const char* formatp, ...);
|
||||
extern void VL_FWRITEF(QData fpq, const char* formatp, ...);
|
||||
|
||||
extern IData VL_FSCANF_IX(QData fpq, const char* formatp, ...);
|
||||
extern IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...);
|
||||
extern IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...);
|
||||
extern IData VL_SSCANF_IWX(int lbits, WDataInP lwp, const char* formatp, ...);
|
||||
|
||||
//=========================================================================
|
||||
// Base macros
|
||||
|
||||
@@ -213,9 +221,12 @@ inline void VL_READMEM_I(bool hex, int width, int depth, int array_lsb, int fnwo
|
||||
#define VL_BITISSET_I(data,bit) (data & (VL_UL(1)<<VL_BITBIT_I(bit)))
|
||||
#define VL_BITISSET_Q(data,bit) (data & (VL_ULL(1)<<VL_BITBIT_Q(bit)))
|
||||
#define VL_BITISSET_W(data,bit) (data[VL_BITWORD_I(bit)] & (VL_UL(1)<<VL_BITBIT_I(bit)))
|
||||
#define VL_BITISSETLIMIT_W(data,width,bit) (((bit)<(width)) && data[VL_BITWORD_I(bit)] & (VL_UL(1)<<VL_BITBIT_I(bit)))
|
||||
|
||||
/// Create two 32-bit words from quadword
|
||||
#define VL_SET_WQ(decl,data) { decl[0]=(data); decl[1]=((data)>>VL_WORDSIZE); }
|
||||
#define VL_SET_WQ(owp,data) { owp[0]=(data); owp[1]=((data)>>VL_WORDSIZE); }
|
||||
#define VL_SET_WI(owp,data) { owp[0]=(data); owp[1]=0; }
|
||||
#define VL_SET_QW(lwp) ( ((QData)(lwp[0])) | ((QData)(lwp[1])<<((QData)(VL_WORDSIZE)) ))
|
||||
|
||||
// Use a union to avoid cast-to-different-size warnings
|
||||
/// Return FILE* from QData
|
||||
@@ -236,7 +247,7 @@ static inline QData VL_EXTENDSIGN_Q(int lbits, QData lhs) { return (-((lhs)&(VL
|
||||
|
||||
// Debugging prints
|
||||
static inline void _VL_DEBUG_PRINT_W(int lbits, WDataInP iwp) {
|
||||
printf(" Data: w%d: ", lbits);
|
||||
printf(" Data: w%d: ", lbits);
|
||||
for (int i=VL_WORDS_I(lbits)-1; i>=0; i--) { printf("%08x ",iwp[i]); }
|
||||
printf("\n");
|
||||
}
|
||||
@@ -460,43 +471,92 @@ static inline IData VL_REDOR_W(int words, WDataInP lwp) {
|
||||
}
|
||||
|
||||
// EMIT_RULE: VL_REDXOR: oclean=dirty; obits=1;
|
||||
static inline IData VL_REDXOR_W(int words, WDataInP lwp) {
|
||||
IData r = lwp[0];
|
||||
for (int i=1; i < words; i++) r ^= lwp[i];
|
||||
r=(r^(r>>1));
|
||||
r=(r^(r>>2));
|
||||
r=(r^(r>>4));
|
||||
r=(r^(r>>8));
|
||||
r=(r^(r>>16));
|
||||
return r;
|
||||
}
|
||||
static inline IData VL_REDXOR_2(IData r) {
|
||||
// Experiments show VL_REDXOR_2 is faster than __builtin_parityl
|
||||
r=(r^(r>>1));
|
||||
return r;
|
||||
}
|
||||
static inline IData VL_REDXOR_4(IData r) {
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(VL_NO_BUILTINS)
|
||||
return __builtin_parityl(r);
|
||||
#else
|
||||
r=(r^(r>>1)); r=(r^(r>>2));
|
||||
return r;
|
||||
#endif
|
||||
}
|
||||
static inline IData VL_REDXOR_8(IData r) {
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(VL_NO_BUILTINS)
|
||||
return __builtin_parityl(r);
|
||||
#else
|
||||
r=(r^(r>>1)); r=(r^(r>>2)); r=(r^(r>>4));
|
||||
return r;
|
||||
#endif
|
||||
}
|
||||
static inline IData VL_REDXOR_16(IData r) {
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(VL_NO_BUILTINS)
|
||||
return __builtin_parityl(r);
|
||||
#else
|
||||
r=(r^(r>>1)); r=(r^(r>>2)); r=(r^(r>>4)); r=(r^(r>>8));
|
||||
return r;
|
||||
#endif
|
||||
}
|
||||
static inline IData VL_REDXOR_32(IData r) {
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(VL_NO_BUILTINS)
|
||||
return __builtin_parityl(r);
|
||||
#else
|
||||
r=(r^(r>>1)); r=(r^(r>>2)); r=(r^(r>>4)); r=(r^(r>>8)); r=(r^(r>>16));
|
||||
return r;
|
||||
#endif
|
||||
}
|
||||
static inline IData VL_REDXOR_64(QData r) {
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(VL_NO_BUILTINS)
|
||||
return __builtin_parityll(r);
|
||||
#else
|
||||
r=(r^(r>>1)); r=(r^(r>>2)); r=(r^(r>>4)); r=(r^(r>>8)); r=(r^(r>>16)); r=(r^(r>>32));
|
||||
return r;
|
||||
#endif
|
||||
}
|
||||
static inline IData VL_REDXOR_W(int words, WDataInP lwp) {
|
||||
IData r = lwp[0];
|
||||
for (int i=1; i < words; i++) r ^= lwp[i];
|
||||
return VL_REDXOR_32(r);
|
||||
}
|
||||
|
||||
static inline IData VL_CLOG2_I(IData lhs) {
|
||||
// Perhaps can do better using fls GCC4 builtins
|
||||
int n=1;
|
||||
IData chk;
|
||||
if (!lhs) return 0;
|
||||
chk = lhs >> VL_UL(16); if (chk) { n += 16; lhs = chk; }
|
||||
chk = lhs >> VL_UL(8); if (chk) { n += 8; lhs = chk; }
|
||||
chk = lhs >> VL_UL(4); if (chk) { n += 4; lhs = chk; }
|
||||
chk = lhs >> VL_UL(2); if (chk) { n += 2; lhs = chk; }
|
||||
chk = lhs >> VL_UL(1); if (chk) { n += 1; lhs = chk; }
|
||||
return n;
|
||||
}
|
||||
static inline IData VL_CLOG2_Q(QData lhs) {
|
||||
// Perhaps can do better using fls GCC4 builtins
|
||||
int n=1;
|
||||
QData chk;
|
||||
if (!lhs) return 0;
|
||||
chk = lhs >> VL_ULL(32); if (chk) { n += 32; lhs = chk; }
|
||||
chk = lhs >> VL_ULL(16); if (chk) { n += 16; lhs = chk; }
|
||||
chk = lhs >> VL_ULL(8); if (chk) { n += 8; lhs = chk; }
|
||||
chk = lhs >> VL_ULL(4); if (chk) { n += 4; lhs = chk; }
|
||||
chk = lhs >> VL_ULL(2); if (chk) { n += 2; lhs = chk; }
|
||||
chk = lhs >> VL_ULL(1); if (chk) { n += 1; lhs = chk; }
|
||||
return n;
|
||||
}
|
||||
static inline IData VL_CLOG2_W(int words, WDataInP lwp) {
|
||||
for (int i=words-1; i>=0; i--) {
|
||||
if (lwp[i]) return VL_CLOG2_I(lwp[i])+i*VL_WORDSIZE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// EMIT_RULE: VL_COUNTONES_II: oclean = false; lhs clean
|
||||
static inline IData VL_COUNTONES_I(IData lhs) {
|
||||
// This is faster than __builtin_popcountl
|
||||
IData r = lhs - ((lhs >> 1) & 033333333333) - ((lhs >> 2) & 011111111111);
|
||||
r = (r + (r>>3)) & 030707070707;
|
||||
r = (r + (r>>6));
|
||||
@@ -829,7 +889,7 @@ static inline IData VL_POW_III(int, int, int rbits, IData lhs, IData rhs) {
|
||||
return out;
|
||||
}
|
||||
|
||||
#define VL_POW_QQI(obits,lbits,rbits,lhs,rhs) VL_POW_QQQ(obits,lbits,rbits,lhs,rhs)
|
||||
#define VL_POW_QQI(obits,lbits,rbits,lhs,rhs) VL_POW_QQQ(obits,lbits,rbits,lhs,rhs)
|
||||
|
||||
static inline QData VL_POW_QQQ(int, int, int rbits, QData lhs, QData rhs) {
|
||||
if (lhs==0) return 0;
|
||||
@@ -847,23 +907,23 @@ static inline QData VL_POW_QQQ(int, int, int rbits, QData lhs, QData rhs) {
|
||||
|
||||
// INTERNAL: Stuff LHS bit 0++ into OUTPUT at specified offset
|
||||
// ld may be "dirty", output is clean
|
||||
static inline void _VL_INSERT_II(int, CData& lhsr, IData ld, int hbit, int lbit) {
|
||||
static inline void _VL_INSERT_II(int, CData& lhsr, IData ld, int hbit, int lbit) {
|
||||
IData insmask = (VL_MASK_I(hbit-lbit+1))<<lbit;
|
||||
lhsr = (lhsr & ~insmask) | ((ld<<lbit) & insmask);
|
||||
}
|
||||
static inline void _VL_INSERT_II(int, SData& lhsr, IData ld, int hbit, int lbit) {
|
||||
static inline void _VL_INSERT_II(int, SData& lhsr, IData ld, int hbit, int lbit) {
|
||||
IData insmask = (VL_MASK_I(hbit-lbit+1))<<lbit;
|
||||
lhsr = (lhsr & ~insmask) | ((ld<<lbit) & insmask);
|
||||
}
|
||||
static inline void _VL_INSERT_II(int, IData& lhsr, IData ld, int hbit, int lbit) {
|
||||
static inline void _VL_INSERT_II(int, IData& lhsr, IData ld, int hbit, int lbit) {
|
||||
IData insmask = (VL_MASK_I(hbit-lbit+1))<<lbit;
|
||||
lhsr = (lhsr & ~insmask) | ((ld<<lbit) & insmask);
|
||||
}
|
||||
static inline void _VL_INSERT_QQ(int, QData& lhsr, QData ld, int hbit, int lbit) {
|
||||
static inline void _VL_INSERT_QQ(int, QData& lhsr, QData ld, int hbit, int lbit) {
|
||||
QData insmask = (VL_MASK_Q(hbit-lbit+1))<<lbit;
|
||||
lhsr = (lhsr & ~insmask) | ((ld<<lbit) & insmask);
|
||||
}
|
||||
static inline void _VL_INSERT_WI(int, WDataOutP owp, IData ld, int hbit, int lbit) {
|
||||
static inline void _VL_INSERT_WI(int, WDataOutP owp, IData ld, int hbit, int lbit) {
|
||||
int hoffset = VL_BITBIT_I(hbit);
|
||||
int loffset = VL_BITBIT_I(lbit);
|
||||
if (hoffset==VL_SIZEBITS_I && loffset==0) {
|
||||
@@ -888,7 +948,7 @@ static inline void _VL_INSERT_WI(int, WDataOutP owp, IData ld, int hbit, int lbi
|
||||
|
||||
// INTERNAL: Stuff large LHS bit 0++ into OUTPUT at specified offset
|
||||
// lwp may be "dirty"
|
||||
static inline void _VL_INSERT_WW(int, WDataOutP owp, WDataInP lwp, int hbit, int lbit) {
|
||||
static inline void _VL_INSERT_WW(int, WDataOutP owp, WDataInP lwp, int hbit, int lbit) {
|
||||
int hoffset = hbit & VL_SIZEBITS_I;
|
||||
int loffset = lbit & VL_SIZEBITS_I;
|
||||
int lword = VL_BITWORD_I(lbit);
|
||||
@@ -934,7 +994,7 @@ static inline void _VL_INSERT_WW(int, WDataOutP owp, WDataInP lwp, int hbit, int
|
||||
}
|
||||
}
|
||||
|
||||
static inline void _VL_INSERT_WQ(int obits, WDataOutP owp, QData ld, int hbit, int lbit) {
|
||||
static inline void _VL_INSERT_WQ(int obits, WDataOutP owp, QData ld, int hbit, int lbit) {
|
||||
WData lwp[2]; VL_SET_WQ(lwp,ld);
|
||||
_VL_INSERT_WW(obits,owp,lwp,hbit,lbit);
|
||||
}
|
||||
@@ -1214,7 +1274,7 @@ static inline QData VL_SEL_QWII(int, int lbits, int, int, WDataInP lwp, IData ls
|
||||
static inline WDataOutP VL_SEL_WWII(int obits,int lbits,int,int,WDataOutP owp,WDataInP lwp, IData lsb, IData width) {
|
||||
int msb = lsb+width-1;
|
||||
int word_shift = VL_BITWORD_I(lsb);
|
||||
if (msb>lbits) { // Outside bounds,
|
||||
if (msb>lbits) { // Outside bounds,
|
||||
for (int i=0; i<VL_WORDS_I(obits)-1; i++) owp[i] = ~0;
|
||||
owp[VL_WORDS_I(obits)-1] = VL_MASK_I(obits);
|
||||
} else if (VL_BITBIT_I(lsb)==0) {
|
||||
@@ -1311,32 +1371,32 @@ static inline WDataOutP VL_CONST_W_3X(int obits, WDataOutP o,
|
||||
o[0]=d0; o[1]=d1; o[2]=d2;
|
||||
_END(obits,3); }
|
||||
#define VL_HAVE_CONST_W_4X
|
||||
static inline WDataOutP VL_CONST_W_4X(int obits, WDataOutP o,
|
||||
static inline WDataOutP VL_CONST_W_4X(int obits, WDataOutP o,
|
||||
I d3,I d2,I d1,I d0) {
|
||||
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3;
|
||||
_END(obits,4); }
|
||||
#define VL_HAVE_CONST_W_5X
|
||||
static inline WDataOutP VL_CONST_W_5X(int obits, WDataOutP o,
|
||||
static inline WDataOutP VL_CONST_W_5X(int obits, WDataOutP o,
|
||||
I d4,I d3,I d2,I d1,I d0) {
|
||||
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4;
|
||||
_END(obits,5); }
|
||||
#define VL_HAVE_CONST_W_6X
|
||||
static inline WDataOutP VL_CONST_W_6X(int obits, WDataOutP o,
|
||||
static inline WDataOutP VL_CONST_W_6X(int obits, WDataOutP o,
|
||||
I d5,I d4,I d3,I d2,I d1,I d0) {
|
||||
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5;
|
||||
_END(obits,6); }
|
||||
#define VL_HAVE_CONST_W_7X
|
||||
static inline WDataOutP VL_CONST_W_7X(int obits, WDataOutP o,
|
||||
static inline WDataOutP VL_CONST_W_7X(int obits, WDataOutP o,
|
||||
I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
|
||||
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6;
|
||||
_END(obits,7); }
|
||||
#define VL_HAVE_CONST_W_8X
|
||||
static inline WDataOutP VL_CONST_W_8X(int obits, WDataOutP o,
|
||||
static inline WDataOutP VL_CONST_W_8X(int obits, WDataOutP o,
|
||||
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
|
||||
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
|
||||
_END(obits,8); }
|
||||
#define VL_HAVE_CONST_W_9X
|
||||
static inline WDataOutP VL_CONST_W_9X(int obits, WDataOutP o,
|
||||
static inline WDataOutP VL_CONST_W_9X(int obits, WDataOutP o,
|
||||
I d8,
|
||||
I d7,I d6,I d5,I d4,I d3,I d2,I d1,I d0) {
|
||||
o[0]=d0; o[1]=d1; o[2]=d2; o[3]=d3; o[4]=d4; o[5]=d5; o[6]=d6; o[7]=d7;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# $Id$ -*- Makefile -*-
|
||||
# -*- Makefile -*-
|
||||
######################################################################
|
||||
# DESCRIPTION: Makefile commands for all verilated target files
|
||||
#
|
||||
@@ -44,7 +44,7 @@ CPPFLAGS += -I. $(VK_CPPFLAGS_ALWAYS) $(VK_CPPFLAGS_WALL)
|
||||
VPATH += ..
|
||||
VPATH += $(VERILATOR_ROOT)/include
|
||||
|
||||
#OPT = -ggdb -DPRINTINITSTR -DDETECTCHANGE
|
||||
#OPT = -ggdb -DPRINTINITSTR -DDETECTCHANGE
|
||||
#OPT = -ggdb -DPRINTINITSTR
|
||||
CPPFLAGS += $(OPT)
|
||||
|
||||
@@ -59,11 +59,11 @@ LDFLAGS += $(USER_LDFLAGS)
|
||||
# See the benchmarking section of bin/verilator.
|
||||
# Support class optimizations. This includes the tracing and symbol table.
|
||||
# SystemC takes minutes to optimize, thus it is off by default.
|
||||
#OPT_SLOW =
|
||||
#OPT_SLOW =
|
||||
# Fast path optimizations. Most time is spent in these classes.
|
||||
#OPT_FAST = -O2 -fstrict-aliasing
|
||||
#OPT_FAST = -O
|
||||
#OPT_FAST =
|
||||
#OPT_FAST =
|
||||
|
||||
#######################################################################
|
||||
##### Aggregates
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
// $Id$ -*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
@@ -13,7 +13,7 @@
|
||||
// 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.
|
||||
//
|
||||
//
|
||||
//=========================================================================
|
||||
//
|
||||
// DESCRIPTION: Verilator: Include in verilog files to hide verilator defines
|
||||
@@ -25,7 +25,7 @@
|
||||
`ifdef verilator `else
|
||||
`define coverage_block_off
|
||||
`endif
|
||||
|
||||
|
||||
// Hide file descriptor difference
|
||||
`ifdef verilator
|
||||
`define verilator_file_descriptor reg [63:0]
|
||||
|
||||
+12
-8
@@ -1,4 +1,4 @@
|
||||
// $Id$ -*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2008 by Wilson Snyder. This program is free software; you can
|
||||
@@ -9,7 +9,7 @@
|
||||
// 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.
|
||||
//
|
||||
//
|
||||
//*************************************************************************
|
||||
///
|
||||
/// \file
|
||||
@@ -21,7 +21,7 @@
|
||||
/// config_build.h.in, code needed by Verilated code only goes into
|
||||
/// verilated.h, and code needed by both goes here (verilatedos.h).
|
||||
///
|
||||
/// Code available from: http://www.veripool.com/verilator
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
//*************************************************************************
|
||||
|
||||
@@ -84,7 +84,7 @@ typedef unsigned char vluint8_t; ///< 8-bit unsigned type
|
||||
typedef unsigned short int vluint16_t; ///< 16-bit unsigned type
|
||||
typedef long vlsint32_t; ///< 32-bit signed type
|
||||
typedef unsigned long vluint32_t; ///< 32-bit unsigned type
|
||||
typedef long long vlsint64_t; ///< 64-bit signed type
|
||||
typedef long long vlsint64_t; ///< 64-bit signed type
|
||||
typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
||||
#elif defined(_WIN32) && !defined(__MINGW32__)
|
||||
typedef unsigned char uint8_t; ///< 8-bit unsigned type (backward compatibility)
|
||||
@@ -92,28 +92,32 @@ typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward co
|
||||
typedef unsigned long uint32_t; ///< 32-bit unsigned type (backward compatibility)
|
||||
typedef unsigned char vluint8_t; ///< 8-bit unsigned type
|
||||
typedef unsigned short int vluint16_t; ///< 16-bit unsigned type
|
||||
typedef int vlsint32_t; ///< 32-bit signed type
|
||||
typedef int vlsint32_t; ///< 32-bit signed type
|
||||
typedef unsigned int vluint32_t; ///< 32-bit unsigned type
|
||||
typedef __int64 vlsint64_t; ///< 64-bit signed type
|
||||
typedef __int64 vlsint64_t; ///< 64-bit signed type
|
||||
typedef unsigned __int64 vluint64_t; ///< 64-bit unsigned type
|
||||
#else // Linux or compliant Unix flavors, -m64
|
||||
# include <stdint.h> // Linux and most flavors
|
||||
# include <inttypes.h> // Solaris
|
||||
typedef uint8_t vluint8_t; ///< 32-bit unsigned type
|
||||
typedef uint16_t vluint16_t; ///< 32-bit unsigned type
|
||||
typedef int vlsint32_t; ///< 32-bit signed type
|
||||
typedef int vlsint32_t; ///< 32-bit signed type
|
||||
typedef uint32_t vluint32_t; ///< 32-bit signed type
|
||||
typedef long long vlsint64_t; ///< 64-bit signed type
|
||||
typedef long long vlsint64_t; ///< 64-bit signed type
|
||||
typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
||||
#endif
|
||||
|
||||
//=========================================================================
|
||||
// Integer size macros
|
||||
|
||||
#define VL_BYTESIZE 8 ///< Bits in a byte
|
||||
#define VL_SHORTSIZE 16 ///< Bits in a short
|
||||
#define VL_WORDSIZE 32 ///< Bits in a word
|
||||
#define VL_QUADSIZE 64 ///< Bits in a quadword
|
||||
#define VL_WORDSIZE_LOG2 5 ///< log2(VL_WORDSIZE)
|
||||
|
||||
/// Bytes this number of bits needs (1 bit=1 byte)
|
||||
#define VL_BYTES_I(nbits) (((nbits)+(VL_BYTESIZE-1))/VL_BYTESIZE)
|
||||
/// Words this number of bits needs (1 bit=1 word)
|
||||
#define VL_WORDS_I(nbits) (((nbits)+(VL_WORDSIZE-1))/VL_WORDSIZE)
|
||||
|
||||
|
||||
+1
-1
@@ -115,7 +115,7 @@ fi
|
||||
if [ x"$dir_arg" != x ]; then
|
||||
dst=$src
|
||||
src=""
|
||||
|
||||
|
||||
if [ -d $dst ]; then
|
||||
instcmd=:
|
||||
else
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
# Created: 1993-05-16
|
||||
# Public domain
|
||||
|
||||
# $Id:$
|
||||
|
||||
errstatus=0
|
||||
|
||||
for file
|
||||
|
||||
+3
-4
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/perl -w
|
||||
#$Id$
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2007-2008 by Wilson Snyder.
|
||||
@@ -7,16 +6,16 @@
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of either the GNU General Public License or the
|
||||
# Perl Artistic License.
|
||||
#
|
||||
#
|
||||
# This program 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.
|
||||
#
|
||||
#
|
||||
# You should have received a copy of the Perl Artistic License
|
||||
# along with this module; see the file COPYING. If not, see
|
||||
# www.cpan.org
|
||||
#
|
||||
#
|
||||
######################################################################
|
||||
|
||||
# DESCRIPTION: Debugging of bison output
|
||||
|
||||
+1
-3
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/perl -w
|
||||
# $Id$
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2005-2008 by Wilson Snyder <[email protected]>. This
|
||||
@@ -50,7 +49,6 @@ cwrite ("graph_export.cpp");
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub usage {
|
||||
print '$Id$ ', "\n";
|
||||
pod2usage(-verbose=>2, -exitval => 2);
|
||||
exit (1);
|
||||
}
|
||||
@@ -120,7 +118,7 @@ sub cwrite {
|
||||
foreach my $edge (@Edges) {
|
||||
$fh->printf(" new V3GraphEdge(gp, %s, %s, %s, %s);\n",
|
||||
$edge->{from}, $edge->{to},
|
||||
$edge->{weight}, $edge->{cutable}?"true":"false");
|
||||
$edge->{weight}, $edge->{cutable}?"true":"false");
|
||||
}
|
||||
$fh->print("}\n");
|
||||
}
|
||||
|
||||
+1
-3
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/perl -w
|
||||
# $Id$
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2005-2008 by Wilson Snyder <[email protected]>. This
|
||||
@@ -55,7 +54,6 @@ dotwrite();
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub usage {
|
||||
print '$Id$ ', "\n";
|
||||
pod2usage(-verbose=>2, -exitval => 2);
|
||||
exit (1);
|
||||
}
|
||||
@@ -175,7 +173,7 @@ __END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
dot_pruner -
|
||||
dot_pruner -
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/perl -w
|
||||
# $Id$
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2007-2008 by Wilson Snyder <[email protected]>. This
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
export GLIBCPP_FORCE_NEW=1
|
||||
compile with -DVL_LEAK_CHECKS
|
||||
valgrind --tool=memcheck --leak-check=yes /home/wsnyder/src/verilator/v4/verilator/verilator_bin_dbg -MMD --bin /home/wsnyder/src/verilator/v4/verilator/verilator_bin_dbg --cc -f /home/wsnyder/src/verilator/v4/verilator/test_c/../test_v/input.vc top.v --no-skip-identical 2>&1 | tee ~/d/aa
|
||||
valgrind --tool=memcheck --leak-check=yes /home/wsnyder/src/verilator/v4/verilator/verilator_bin_dbg -MMD --bin /home/wsnyder/src/verilator/v4/verilator/verilator_bin_dbg --cc /home/wsnyder/src/verilator/v4/verilator/test_regress/t/t_case_huge.v --no-skip-identical -I/home/wsnyder/src/verilator/v4/verilator/test_regress/t 2>&1 | tee ~/d/aa
|
||||
@@ -1,5 +1,4 @@
|
||||
#!/usr/bin/perl -w
|
||||
# $Id$
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2005-2008 by Wilson Snyder <[email protected]>. This
|
||||
@@ -52,7 +51,6 @@ print '(query-replace-regexp "(\\([0-9a-z_]+\\))" "\\1" nil nil nil)',"\n";
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub usage {
|
||||
print '$Id$ ', "\n";
|
||||
pod2usage(-verbose=>2, -exitval => 2);
|
||||
exit (1);
|
||||
}
|
||||
@@ -292,7 +290,7 @@ sub p_var {
|
||||
}
|
||||
p "\t";
|
||||
{
|
||||
local $Avoid_Hex=1;
|
||||
local $Avoid_Hex=1;
|
||||
t1;
|
||||
}
|
||||
p "\t";
|
||||
@@ -322,7 +320,7 @@ __END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
vtree_importer -
|
||||
vtree_importer -
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
|
||||
+17
-12
@@ -1,6 +1,5 @@
|
||||
\input texinfo @c -*-texinfo-*-
|
||||
@c %**start of header
|
||||
$c $Id$
|
||||
@setfilename readme.info
|
||||
@settitle Verilator Installation
|
||||
@c %**end of header
|
||||
@@ -15,13 +14,13 @@ $c $Id$
|
||||
This is the Verilator Package.
|
||||
|
||||
@menu
|
||||
* Copyright::
|
||||
* Description::
|
||||
* Obtaining Distribution::
|
||||
* Directory Structure::
|
||||
* Supported Systems::
|
||||
* Installation::
|
||||
* Limitations::
|
||||
* Copyright::
|
||||
* Description::
|
||||
* Obtaining Distribution::
|
||||
* Directory Structure::
|
||||
* Supported Systems::
|
||||
* Installation::
|
||||
* Limitations::
|
||||
@end menu
|
||||
|
||||
@node Copyright, Description, Top, Top
|
||||
@@ -45,7 +44,7 @@ Verilator is invoked with parameters similar to GCC or Synopsys's VCS. It
|
||||
reads the specified Verilog code, lints it, and optionally adds coverage
|
||||
code. For C++ format, it outputs .cpp and .h files. For SystemC format,
|
||||
it outputs .sp files for the SystemPerl preprocessor available at
|
||||
http://veripool.com.
|
||||
http://www.veripool.org.
|
||||
|
||||
The resulting files are then compiled with C++. The user writes a little
|
||||
C++ wrapper file, which instantiates the top level module. This is
|
||||
@@ -56,11 +55,11 @@ The resulting executable will perform the actual simulation.
|
||||
@node Obtaining Distribution, Directory Structure, Description, Top
|
||||
@section Obtaining Distribution
|
||||
|
||||
The latest version is available at
|
||||
@uref{http://veripool.com/verilator.htm}
|
||||
The latest version is available at
|
||||
@uref{http://www.veripool.org/verilator}
|
||||
|
||||
Download the latest package from that site, and decompress.
|
||||
@samp{gunzip verilator_version.tar.gz ; tar xvf verilator_version.tar}
|
||||
@samp{tar xvzf verilator_version.tgz}
|
||||
|
||||
@node Directory Structure, Supported Systems, Obtaining Distribution, Top
|
||||
@section Directory Structure
|
||||
@@ -126,6 +125,12 @@ do a @code{make sc_patch}.
|
||||
@item
|
||||
Type @samp{./configure} to configure Verilator for your system.
|
||||
|
||||
If you are configuring Verilator to be part of a RPM or other
|
||||
distribution package system, you may want to use the --enable-defenv
|
||||
configure flag. This will take the current value of VERILATOR_ROOT,
|
||||
SYSTEMC, SYSTEMC_ARCH, and SYSTEMPERL and build them as defaults into
|
||||
the executable.
|
||||
|
||||
@item
|
||||
Type @samp{make} to compile Verilator.
|
||||
|
||||
|
||||
+9
-5
@@ -1,9 +1,9 @@
|
||||
# $Id$ */
|
||||
# -*- Makefile -*-
|
||||
#*****************************************************************************
|
||||
#
|
||||
# DESCRIPTION: Verilator: Makefile for verilog source
|
||||
#
|
||||
# Code available from: http://www.veripool.com/verilator
|
||||
# Code available from: http://www.veripool.org/verilator
|
||||
#
|
||||
#*****************************************************************************
|
||||
#
|
||||
@@ -40,12 +40,16 @@ export OBJCACHE_HOSTS := $(shell rschedule --no-allow-reserved --similar hostnam
|
||||
endif
|
||||
|
||||
ifeq ($(OBJCACHE_HOSTS),)
|
||||
export OBJCACHE :=
|
||||
export OBJCACHE :=
|
||||
else
|
||||
export OBJCACHE_JOBS := -j $(shell objcache --jobs "$(OBJCACHE_HOSTS)")
|
||||
export OBJCACHE := @objcache --read --write
|
||||
endif
|
||||
|
||||
UNDER_GIT = $(wildcard ../.git)
|
||||
|
||||
#*********************************************************************
|
||||
|
||||
obj_opt:
|
||||
mkdir $@
|
||||
obj_dbg:
|
||||
@@ -71,10 +75,10 @@ dbg: ../verilator_bin_dbg
|
||||
|
||||
prefiles::
|
||||
|
||||
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
|
||||
ifneq ($(UNDER_GIT),) # If local git tree... Else don't burden users
|
||||
prefiles:: config_rev.h
|
||||
# This output goes into srcdir, as we need to distribute it as part of the kit.
|
||||
config_rev.h: config_rev.pl .svn/entries
|
||||
config_rev.h: config_rev.pl ../.git/index
|
||||
$(PERL) config_rev.pl . >$@
|
||||
endif
|
||||
|
||||
|
||||
+41
-11
@@ -1,9 +1,9 @@
|
||||
# $Id$ -*- Makefile -*-
|
||||
# -*- Makefile -*-
|
||||
#*****************************************************************************
|
||||
#
|
||||
# DESCRIPTION: Verilator: Makefile for verilog source
|
||||
#
|
||||
# Code available from: http://www.veripool.com/verilator
|
||||
# Code available from: http://www.veripool.org/verilator
|
||||
#
|
||||
#*****************************************************************************
|
||||
#
|
||||
@@ -23,11 +23,28 @@
|
||||
srcdir = ..
|
||||
incdir = ../../include
|
||||
|
||||
PERL = @PERL@
|
||||
# Programs
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
LINK = @CXX@
|
||||
LEX = @LEX@
|
||||
LFLAGS = -d
|
||||
PERL = @PERL@
|
||||
YACC = @YACC@
|
||||
YFLAGS = -y -d -v
|
||||
|
||||
prefix = @prefix@
|
||||
|
||||
# Directory in which to install data across multiple architectures
|
||||
datarootdir = @datarootdir@
|
||||
|
||||
# Directory in which to install package specific files
|
||||
# Generally ${prefix}/share/verilator
|
||||
pkgdatadir = @pkgdatadir@
|
||||
|
||||
# Compile options
|
||||
CFG_WITH_DEFENV = @CFG_WITH_DEFENV@
|
||||
CPPFLAGSNOWALL += @CPPFLAGS@
|
||||
LDFLAGS += @LDFLAGS@
|
||||
|
||||
#### End of system configuration section. ####
|
||||
@@ -48,17 +65,12 @@ COPT = -ggdb -DVL_DEBUG
|
||||
endif
|
||||
#################
|
||||
|
||||
LEX = @LEX@
|
||||
LFLAGS = -d
|
||||
YACC = @YACC@
|
||||
YFLAGS = -y -d -v
|
||||
|
||||
#LIBS += -ldl
|
||||
#CCMALLOC = /usr/local/lib/ccmalloc-gcc.o -lccmalloc -ldl
|
||||
|
||||
LIBS = -lm -lfl
|
||||
|
||||
CPPFLAGSNOWALL = -MMD
|
||||
CPPFLAGSNOWALL += -MMD
|
||||
CPPFLAGSNOWALL += -I. -I$(srcdir) -I$(incdir)
|
||||
CPPFLAGSNOWALL += -DYYDEBUG # Required to get nice error messages
|
||||
#CPPFLAGSNOWALL += -DVL_LEAK_CHECKS # If running valgrind or other hunting tool
|
||||
@@ -70,6 +82,19 @@ CPPFLAGS += -W -Wall -Wno-unused-parameter -Wno-char-subscripts -Werror
|
||||
#CPPFLAGS += -pedantic-errors
|
||||
endif
|
||||
|
||||
# Allow RPM builds to specify hardcoded data directories
|
||||
# To do this:
|
||||
ifeq ($(CFG_WITH_DEFENV),yes)
|
||||
CPPFLAGS += -DDEFENV_SYSTEMC=\"$(SYSTEMC)\"
|
||||
CPPFLAGS += -DDEFENV_SYSTEMC_ARCH=\"$(SYSTEMC_ARCH)\"
|
||||
CPPFLAGS += -DDEFENV_SYSTEMPERL=\"$(SYSTEMPERL)\"
|
||||
ifeq ($(VERILATOR_ROOT),) # Use what we're given, or intuit
|
||||
CPPFLAGS += -DDEFENV_VERILATOR_ROOT=\"$(pkgdatadir)\"
|
||||
else
|
||||
CPPFLAGS += -DDEFENV_VERILATOR_ROOT=\"$(VERILATOR_ROOT)\"
|
||||
endif
|
||||
endif
|
||||
|
||||
HEADERS = $(wildcard V*.h v*.h)
|
||||
|
||||
ASTGEN = $(srcdir)/astgen
|
||||
@@ -221,14 +246,19 @@ V3PreProc.o: V3PreProc.cpp V3PreLex.yy.cpp
|
||||
#### Generated files
|
||||
|
||||
# Target rule called before parallel build to make generated files
|
||||
serial:: V3Ast__gen_classes.h
|
||||
serial:: V3Ast__gen_classes.h y.tab.c
|
||||
|
||||
V3Ast__gen_classes.h : $(ASTGEN) V3Ast.h V3AstNodes.h
|
||||
$(PERL) $(ASTGEN) -I$(srcdir) --classes
|
||||
|
||||
y.tab.c y.tab.h: verilog.y $(HEADERS)
|
||||
y.tab.h: y.tab.c
|
||||
|
||||
# Have only one output file in this rule to prevent parallel make issues
|
||||
y.tab.c: verilog.y $(HEADERS)
|
||||
@echo "If you get errors from verilog.y below, try upgrading bison to version 1.875 or newer."
|
||||
${YACC} ${YFLAGS} $<
|
||||
mv y.tab.c y_pregen.tab.c && $(PERL) $(srcdir)/bisonfix < y_pregen.tab.c > y.tab.c
|
||||
mv y.tab.h y_pregen.tab.h && $(PERL) $(srcdir)/bisonfix < y_pregen.tab.h > y.tab.h
|
||||
|
||||
V3Lexer_pregen.yy.cpp: verilog.l y.tab.h $(HEADERS)
|
||||
${LEX} ${LFLAGS} -o$@ $<
|
||||
|
||||
+4
-5
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Break always into sensitivity active domains
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -19,7 +18,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
// V3Active's Transformations:
|
||||
//
|
||||
//
|
||||
// Note this can be called multiple times.
|
||||
// Create a IACTIVE(initial), SACTIVE(combo)
|
||||
// ALWAYS: Remove any-edges from sense list
|
||||
@@ -33,8 +32,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Break always into sensitivity block domains
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+4
-5
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Break always into sensitivity active domains
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -19,7 +18,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
// V3Active's Transformations:
|
||||
//
|
||||
//
|
||||
// Note this can be called multiple times.
|
||||
// Across all ACTIVES
|
||||
// SenTrees are now under each ACTIVE statement, we want them global:
|
||||
@@ -30,8 +29,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Break always into sensitivity block domains
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+4
-5
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Collect and print statistics
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -21,8 +20,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <map>
|
||||
#include <iomanip>
|
||||
@@ -106,7 +105,7 @@ private:
|
||||
sentreep->unlinkFrBack();
|
||||
//
|
||||
AstNode* bodysp = NULL;
|
||||
bool selfDestruct = false;
|
||||
bool selfDestruct = false;
|
||||
if (AstPslCover* snodep = nodep->castPslCover()) {
|
||||
if (!v3Global.opt.coverageUser()) {
|
||||
selfDestruct = true;
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Assertion expansion
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+3
-4
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Collect and print statistics
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -24,8 +23,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <map>
|
||||
#include <iomanip>
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Assertion pre-expansion
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+31
-15
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Ast node structures
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -19,8 +18,8 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <memory>
|
||||
@@ -83,6 +82,20 @@ void AstNode::init() {
|
||||
m_user5Cnt = 0;
|
||||
}
|
||||
|
||||
string AstNode::encodeName(const string& namein) {
|
||||
string name2 = namein;
|
||||
string out;
|
||||
for (string::iterator pos = name2.begin(); pos != name2.end(); pos++) {
|
||||
if (pos[0]=='_' && pos[1]=='_') {
|
||||
out += "__ULUL_";
|
||||
pos++;
|
||||
} else {
|
||||
out += pos[0];
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
string AstNode::shortName() const {
|
||||
string pretty = name();
|
||||
string::size_type pos;
|
||||
@@ -114,6 +127,9 @@ string AstNode::prettyName(const string& namein) {
|
||||
while ((pos=pretty.find("__PVT__")) != string::npos) {
|
||||
pretty.replace(pos, 7, "");
|
||||
}
|
||||
while ((pos=pretty.find("__ULUL_")) != string::npos) {
|
||||
pretty.replace(pos, 7, "");
|
||||
}
|
||||
return AstNode::dedotName(pretty);
|
||||
}
|
||||
|
||||
@@ -238,8 +254,8 @@ void AstNode::addNextHere(AstNode* newp) {
|
||||
void AstNode::setOp1p(AstNode* newp) {
|
||||
UASSERT(newp,"Null item passed to setOp1p\n");
|
||||
UDEBUGONLY(if (m_op1p) this->v3fatalSrc("Adding to non-empty, non-list op1"););
|
||||
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
|
||||
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op1"););
|
||||
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
|
||||
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op1"););
|
||||
this->debugTreeChange("-setOp1pThs: ", __LINE__, false);
|
||||
newp->debugTreeChange("-setOp1pNew: ", __LINE__, true);
|
||||
m_op1p = newp;
|
||||
@@ -251,8 +267,8 @@ void AstNode::setOp1p(AstNode* newp) {
|
||||
void AstNode::setOp2p(AstNode* newp) {
|
||||
UASSERT(newp,"Null item passed to setOp2p\n");
|
||||
UDEBUGONLY(if (m_op2p) this->v3fatalSrc("Adding to non-empty, non-list op2"););
|
||||
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
|
||||
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op2"););
|
||||
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
|
||||
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op2"););
|
||||
this->debugTreeChange("-setOp2pThs: ", __LINE__, false);
|
||||
newp->debugTreeChange("-setOp2pNew: ", __LINE__, true);
|
||||
m_op2p = newp;
|
||||
@@ -264,8 +280,8 @@ void AstNode::setOp2p(AstNode* newp) {
|
||||
void AstNode::setOp3p(AstNode* newp) {
|
||||
UASSERT(newp,"Null item passed to setOp3p\n");
|
||||
UDEBUGONLY(if (m_op3p) this->v3fatalSrc("Adding to non-empty, non-list op3"););
|
||||
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
|
||||
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op3"););
|
||||
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
|
||||
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op3"););
|
||||
this->debugTreeChange("-setOp3pThs: ", __LINE__, false);
|
||||
newp->debugTreeChange("-setOp3pNew: ", __LINE__, true);
|
||||
m_op3p = newp;
|
||||
@@ -277,8 +293,8 @@ void AstNode::setOp3p(AstNode* newp) {
|
||||
void AstNode::setOp4p(AstNode* newp) {
|
||||
UASSERT(newp,"Null item passed to setOp4p\n");
|
||||
UDEBUGONLY(if (m_op4p) this->v3fatalSrc("Adding to non-empty, non-list op4"););
|
||||
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
|
||||
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op4"););
|
||||
UDEBUGONLY(if (newp->m_backp) newp->v3fatalSrc("Adding already linked node"););
|
||||
UDEBUGONLY(if (newp->m_nextp) newp->v3fatalSrc("Adding list to non-list op4"););
|
||||
this->debugTreeChange("-setOp4pThs: ", __LINE__, false);
|
||||
newp->debugTreeChange("-setOp4pNew: ", __LINE__, true);
|
||||
m_op4p = newp;
|
||||
@@ -627,7 +643,7 @@ void AstNode::iterateListBackwards(AstNVisitor& v, AstNUser* vup) {
|
||||
while (nodep->m_nextp) nodep=nodep->m_nextp;
|
||||
while (nodep) {
|
||||
// Edits not supported: nodep->m_iterpp = &nodep;
|
||||
nodep->accept(v, vup);
|
||||
nodep->accept(v, vup);
|
||||
if (nodep->backp()->m_nextp == nodep) nodep=nodep->backp();
|
||||
else nodep = NULL; // else: backp points up the tree.
|
||||
}
|
||||
@@ -648,7 +664,7 @@ void AstNode::iterateAndNext(AstNVisitor& v, AstNUser* vup) {
|
||||
for (AstNode* nodep=this; nodep;) {
|
||||
AstNode* niterp = nodep;
|
||||
niterp->m_iterpp = &niterp;
|
||||
niterp->accept(v, vup);
|
||||
niterp->accept(v, vup);
|
||||
// accept may do a replaceNode and change niterp on us...
|
||||
if (!niterp) return;
|
||||
niterp->m_iterpp = NULL;
|
||||
@@ -665,7 +681,7 @@ void AstNode::iterateAndNextIgnoreEdit(AstNVisitor& v, AstNUser* vup) {
|
||||
if (!this) return;
|
||||
for (AstNode* nodep=this; nodep; ) {
|
||||
AstNode* nnextp = nodep->m_nextp;
|
||||
nodep->accept(v, vup);
|
||||
nodep->accept(v, vup);
|
||||
nodep = nnextp;
|
||||
}
|
||||
}
|
||||
|
||||
+28
-8
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Ast node structure
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -197,7 +197,8 @@ public:
|
||||
TRIWIRE,
|
||||
BLOCKTEMP,
|
||||
MODULETEMP,
|
||||
STMTTEMP
|
||||
STMTTEMP,
|
||||
XTEMP
|
||||
};
|
||||
enum en m_e;
|
||||
inline AstVarType () {};
|
||||
@@ -209,7 +210,7 @@ public:
|
||||
"?","GPARAM","LPARAM","GENVAR",
|
||||
"INTEGER","INPUT","OUTPUT","INOUT",
|
||||
"SUPPLY0","SUPPLY1","WIRE","IMPLICIT","REG","TRIWIRE",
|
||||
"BLOCKTEMP","MODULETEMP","STMTTEMP"};
|
||||
"BLOCKTEMP","MODULETEMP","STMTTEMP","XTEMP"};
|
||||
return names[m_e];};
|
||||
};
|
||||
inline bool operator== (AstVarType lhs, AstVarType rhs) { return (lhs.m_e == rhs.m_e); }
|
||||
@@ -250,6 +251,25 @@ public:
|
||||
|
||||
//######################################################################
|
||||
|
||||
class AstCaseType {
|
||||
public:
|
||||
enum en {
|
||||
CASE,
|
||||
CASEX,
|
||||
CASEZ
|
||||
};
|
||||
enum en m_e;
|
||||
inline AstCaseType () {};
|
||||
inline AstCaseType (en _e) : m_e(_e) {};
|
||||
explicit inline AstCaseType (int _e) : m_e(static_cast<en>(_e)) {};
|
||||
operator en () const { return m_e; };
|
||||
};
|
||||
inline bool operator== (AstCaseType lhs, AstCaseType rhs) { return (lhs.m_e == rhs.m_e); }
|
||||
inline bool operator== (AstCaseType lhs, AstCaseType::en rhs) { return (lhs.m_e == rhs); }
|
||||
inline bool operator== (AstCaseType::en lhs, AstCaseType rhs) { return (lhs == rhs.m_e); }
|
||||
|
||||
//######################################################################
|
||||
|
||||
class AstDisplayType {
|
||||
public:
|
||||
enum en {
|
||||
@@ -558,6 +578,7 @@ public:
|
||||
string shortName() const; // Name with __PVT__ removed for concatenating scopes
|
||||
static string dedotName(const string& namein); // Name with dots removed
|
||||
static string prettyName(const string& namein); // Name for printing out to the user
|
||||
static string encodeName(const string& namein); // Encode user name into internal C representation
|
||||
string prettyName() const { return prettyName(name()); }
|
||||
FileLine* fileline() const { return m_fileline; }
|
||||
int width() const { return m_width; }
|
||||
@@ -650,7 +671,6 @@ public:
|
||||
virtual bool same(AstNode* otherp) const { return true; }
|
||||
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; }
|
||||
virtual bool emitWordForm() { return false; }
|
||||
|
||||
// INVOKERS
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) = 0;
|
||||
@@ -681,7 +701,7 @@ struct AstNodeMath : public AstNode {
|
||||
virtual ~AstNodeMath() {}
|
||||
// METHODS
|
||||
virtual string emitVerilog() = 0; /// Format string for verilog writing; see V3EmitV
|
||||
virtual string emitOperator() = 0;
|
||||
virtual string emitC() = 0;
|
||||
virtual string emitSimpleOperator() { return ""; }
|
||||
virtual bool cleanOut() = 0; // True if output has extra upper bits zero
|
||||
};
|
||||
@@ -783,7 +803,7 @@ struct AstNodeCond : public AstNodeTriop {
|
||||
AstNode* expr1p() const { return op2p()->castNode(); } // op2 = If true...
|
||||
AstNode* expr2p() const { return op3p()->castNode(); } // op3 = If false...
|
||||
virtual string emitVerilog() { return "%k(%l %k? %r %k: %t)"; }
|
||||
virtual string emitOperator() { return "VL_COND"; }
|
||||
virtual string emitC() { return "VL_COND_%nq%lq%rq%tq(%nw,%lw,%rw,%tw, %P, %li, %ri, %ti)"; }
|
||||
virtual bool cleanOut() { return false; } // clean if e1 & e2 clean
|
||||
virtual bool cleanLhs() { return true; }
|
||||
virtual bool cleanRhs() { return false; } virtual bool cleanThs() { return false; } // Propagates up
|
||||
@@ -1008,7 +1028,7 @@ public:
|
||||
AstNodeFTaskRef(FileLine* fl, AstNode* namep, AstNode* pinsp)
|
||||
:AstNode(fl)
|
||||
, m_taskp(NULL) {
|
||||
setOp1p(namep); addNOp2p(pinsp);
|
||||
setOp1p(namep); addNOp2p(pinsp);
|
||||
}
|
||||
virtual ~AstNodeFTaskRef() {}
|
||||
virtual bool broken() const { return m_taskp && !m_taskp->brokeExists(); }
|
||||
|
||||
+7
-4
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Ast node structures
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -21,8 +20,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include <vector>
|
||||
@@ -304,6 +303,10 @@ void AstCellInline::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" -> "<<origModName();
|
||||
}
|
||||
void AstDisplay::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
//str<<" "<<displayType().ascii();
|
||||
}
|
||||
void AstPin::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
if (modVarp()) { str<<" -> "; modVarp()->dump(str); }
|
||||
|
||||
+251
-118
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Ast node structure
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -53,7 +53,7 @@ public:
|
||||
uint32_t asInt() const { return num().asInt(); }
|
||||
vluint64_t asQuad() const { return num().asQuad(); }
|
||||
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
|
||||
virtual string emitOperator() { V3ERROR_NA; return ""; }
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
virtual bool cleanOut() { return true; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(num().asHash()); }
|
||||
virtual bool same(AstNode* samep) const {
|
||||
@@ -81,7 +81,7 @@ struct AstRange : public AstNode {
|
||||
int msbConst() const { AstConst* constp=msbp()->castConst(); return (constp?constp->asInt():0); }
|
||||
int lsbConst() const { AstConst* constp=lsbp()->castConst(); return (constp?constp->asInt():0); }
|
||||
int elementsConst() const { return msbConst()-lsbConst()+1; }
|
||||
virtual string emitOperator() { V3ERROR_NA; return ""; }
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(AstNode* samep) const { return true; }
|
||||
};
|
||||
@@ -100,7 +100,7 @@ struct AstArraySel : public AstNodeSel {
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) {
|
||||
V3ERROR_NA; /* How can from be a const? */ }
|
||||
virtual string emitVerilog() { return "%k(%l%k[%r])"; }
|
||||
virtual string emitOperator() { V3ERROR_NA; return ""; }
|
||||
virtual string emitC() { return "%li%k[%ri]"; }
|
||||
virtual bool cleanOut() { return true; }
|
||||
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -133,7 +133,7 @@ struct AstWordSel : public AstNodeSel {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& from, const V3Number& bit) { V3ERROR_NA; }
|
||||
virtual string emitVerilog() { return "%k(%l[%r])"; } // Not %k, as usually it's a small constant rhsp
|
||||
virtual string emitOperator() { V3ERROR_NA; return ""; }
|
||||
virtual string emitC() { return "%li[%ri]"; } // Not %k, as usually it's a small constant rhsp
|
||||
virtual bool cleanOut() { return true; }
|
||||
virtual bool cleanLhs() { return true; } virtual bool cleanRhs() { return true; }
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -206,7 +206,10 @@ struct AstSel : public AstNodeTriop {
|
||||
virtual void numberOperate(V3Number& out, const V3Number& from, const V3Number& bit, const V3Number& width) {
|
||||
out.opRange(from, bit.asInt()+width.asInt()-1, bit.asInt()); }
|
||||
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
|
||||
virtual string emitOperator() { V3ERROR_NA; return ""; }
|
||||
virtual string emitC() {
|
||||
return this->widthp()->isOne()
|
||||
? "VL_BITSEL_%nq%lq%rq%tq(%nw,%lw,%rw,%tw, %P, %li, %ri)"
|
||||
: "VL_SEL_%nq%lq%rq%tq(%nw,%lw,%rw,%tw, %P, %li, %ri, %ti)"; }
|
||||
virtual bool cleanOut() { return false; }
|
||||
virtual bool cleanLhs() { return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool cleanThs() {return true;}
|
||||
@@ -254,7 +257,7 @@ private:
|
||||
m_sc=false; m_scClocked=false; m_scSensitive=false;
|
||||
m_usedClock=false; m_usedParam=false;
|
||||
m_sigPublic=false; m_sigModPublic=false;
|
||||
m_funcLocal=false; m_funcReturn=false;
|
||||
m_funcLocal=false; m_funcReturn=false;
|
||||
m_attrClockEn=false; m_attrIsolateAssign=false;
|
||||
m_fileDescr=false; m_isConst=false; m_isStatic=false;
|
||||
m_trace=false;
|
||||
@@ -332,9 +335,10 @@ public:
|
||||
bool isSignal() const { return (varType()==AstVarType::WIRE || varType()==AstVarType::IMPLICIT
|
||||
|| varType()==AstVarType::REG || varType()==AstVarType::INTEGER); }
|
||||
bool isTemp() const { return (varType()==AstVarType::BLOCKTEMP || varType()==AstVarType::MODULETEMP
|
||||
|| varType()==AstVarType::STMTTEMP); }
|
||||
|| varType()==AstVarType::STMTTEMP || varType()==AstVarType::XTEMP); }
|
||||
bool isStatementTemp() const { return (varType()==AstVarType::STMTTEMP); }
|
||||
bool isMovableToBlock() const { return (varType()==AstVarType::BLOCKTEMP || isFuncLocal()); }
|
||||
bool isPure() const { return (varType()==AstVarType::XTEMP); }
|
||||
bool isParam() const { return (varType()==AstVarType::LPARAM || varType()==AstVarType::GPARAM); }
|
||||
bool isGParam() const { return (varType()==AstVarType::GPARAM); }
|
||||
bool isGenVar() const { return (varType()==AstVarType::GENVAR); }
|
||||
@@ -531,7 +535,7 @@ public:
|
||||
&& varp()->name()==samep->castVarRef()->varp()->name()); }
|
||||
virtual int instrCount() const { return widthInstrs()*(lvalue()?1:instrCountLd()); }
|
||||
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
|
||||
virtual string emitOperator() { V3ERROR_NA; return ""; }
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
virtual bool cleanOut() { return true; }
|
||||
};
|
||||
|
||||
@@ -554,12 +558,12 @@ public:
|
||||
virtual AstNode* clone() { return new AstVarXRef(*this);}
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void dump(ostream& str);
|
||||
string dotted() const { return m_dotted; }
|
||||
string dotted() const { return m_dotted; }
|
||||
string prettyDotted() const { return prettyName(dotted()); }
|
||||
string inlinedDots() const { return m_inlinedDots; }
|
||||
void inlinedDots(const string& flag) { m_inlinedDots = flag; }
|
||||
virtual string emitVerilog() { V3ERROR_NA; return ""; }
|
||||
virtual string emitOperator() { V3ERROR_NA; return ""; }
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
virtual bool cleanOut() { return true; }
|
||||
virtual int instrCount() const { return widthInstrs(); }
|
||||
virtual V3Hash sameHash() const { return V3Hash(V3Hash(varp()),V3Hash(dotted())); }
|
||||
@@ -755,7 +759,7 @@ public:
|
||||
AstNode* stmtsp() const { return op1p()->castNode(); } // op1 = List of statements
|
||||
void addStmtp(AstNode* nodep) { addOp1p(nodep); }
|
||||
};
|
||||
|
||||
|
||||
struct AstGenerate : public AstNode {
|
||||
// A Generate/end block
|
||||
// Parents: MODULE
|
||||
@@ -792,7 +796,7 @@ public:
|
||||
virtual V3Hash sameHash() const { return V3Hash(m_expect); }
|
||||
virtual bool same(AstNode* samep) const { return expect() == samep->castParseRef()->expect(); }
|
||||
virtual string emitVerilog() { V3ERROR_NA; return ""; }
|
||||
virtual string emitOperator() { V3ERROR_NA; return ""; }
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
AstParseRefExp expect() const { return m_expect; }
|
||||
// op1 = Components
|
||||
AstNode* lhsp() const { return op1p(); } // op1 = List of statements
|
||||
@@ -808,7 +812,7 @@ struct AstDot : public AstNode {
|
||||
virtual AstNode* clone() { return new AstDot(*this);}
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual string emitVerilog() { V3ERROR_NA; return ""; }
|
||||
virtual string emitOperator() { V3ERROR_NA; return ""; }
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
AstNode* lhsp() const { return op1p(); }
|
||||
AstNode* rhsp() const { return op2p(); }
|
||||
};
|
||||
@@ -1117,7 +1121,7 @@ private:
|
||||
public:
|
||||
AstCoverDecl(FileLine* fl, int column, const string& type, const string& comment)
|
||||
: AstNodeStmt(fl) {
|
||||
m_text = comment; m_typeText = type; m_column = column;
|
||||
m_text = comment; m_typeText = type; m_column = column;
|
||||
}
|
||||
virtual ~AstCoverDecl() {}
|
||||
virtual AstType type() const { return AstType::COVERDECL;}
|
||||
@@ -1191,11 +1195,11 @@ struct AstCase : public AstNodeCase {
|
||||
// exprp Children: MATHs
|
||||
// casesp Children: CASEITEMs
|
||||
private:
|
||||
bool m_casex; // True if casex instead of normal case.
|
||||
AstCaseType m_casex; // 0=case, 1=casex, 2=casez
|
||||
bool m_fullPragma; // Synthesis full_case
|
||||
bool m_parallelPragma; // Synthesis parallel_case
|
||||
public:
|
||||
AstCase(FileLine* fileline, bool casex, AstNode* exprp, AstNode* casesp)
|
||||
AstCase(FileLine* fileline, AstCaseType casex, AstNode* exprp, AstNode* casesp)
|
||||
: AstNodeCase(fileline, exprp, casesp) {
|
||||
m_casex=casex;
|
||||
m_fullPragma=false; m_parallelPragma=false;
|
||||
@@ -1204,11 +1208,14 @@ public:
|
||||
virtual AstType type() const { return AstType::CASE;}
|
||||
virtual AstNode* clone() { return new AstCase(*this); }
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual string verilogKwd() const { return casex()?"casex":"case"; }
|
||||
bool casex() const { return m_casex; }
|
||||
virtual string verilogKwd() const { return casez()?"casez":casex()?"casex":"case"; }
|
||||
virtual bool same(AstNode* samep) const {
|
||||
return m_casex==samep->castCase()->m_casex; }
|
||||
bool casex() const { return m_casex==AstCaseType::CASEX; }
|
||||
bool casez() const { return m_casex==AstCaseType::CASEZ; }
|
||||
bool fullPragma() const { return m_fullPragma; }
|
||||
bool parallelPragma() const { return m_parallelPragma; }
|
||||
void fullPragma(bool flag) { m_fullPragma=flag; }
|
||||
bool parallelPragma() const { return m_parallelPragma; }
|
||||
void parallelPragma(bool flag) { m_parallelPragma=flag; }
|
||||
};
|
||||
|
||||
@@ -1254,6 +1261,7 @@ public:
|
||||
virtual AstType type() const { return AstType::DISPLAY;}
|
||||
virtual AstNode* clone() { return new AstDisplay(*this); }
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void dump(ostream& str);
|
||||
virtual string verilogKwd() const { return (filep() ? (string)"$f"+(string)displayType().ascii()
|
||||
: (string)"$"+(string)displayType().ascii()); }
|
||||
virtual bool isGateOptimizable() const { return false; }
|
||||
@@ -1322,6 +1330,101 @@ struct AstFOpen : public AstNodeStmt {
|
||||
AstNode* modep() const { return op3p(); }
|
||||
};
|
||||
|
||||
struct AstFFlush : public AstNodeStmt {
|
||||
// Parents: stmtlist
|
||||
// Children: file which must be a varref
|
||||
AstFFlush(FileLine* fileline, AstNode* filep)
|
||||
: AstNodeStmt (fileline) {
|
||||
setNOp2p(filep);
|
||||
}
|
||||
virtual ~AstFFlush() {}
|
||||
virtual AstType type() const { return AstType::FFLUSH;}
|
||||
virtual AstNode* clone() { return new AstFFlush(*this); }
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual string verilogKwd() const { return "$fflush"; };
|
||||
virtual bool isGateOptimizable() const { return false; }
|
||||
virtual bool isPredictOptimizable() const { return false; }
|
||||
virtual bool isSplittable() const { return false; }
|
||||
virtual bool isOutputter() const { return true; }
|
||||
virtual bool isUnlikely() const { return true; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(AstNode* samep) const { return true; }
|
||||
AstNode* filep() const { return op2p(); }
|
||||
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
|
||||
};
|
||||
|
||||
struct AstFScanF : public AstNodeMath {
|
||||
// Parents: expr
|
||||
// Children: file which must be a varref
|
||||
// Children: varrefs to load
|
||||
private:
|
||||
string m_text;
|
||||
public:
|
||||
AstFScanF(FileLine* fileline, const string& text, AstNode* filep, AstNode* exprsp)
|
||||
: AstNodeMath (fileline), m_text(text) {
|
||||
addNOp1p(exprsp);
|
||||
setNOp2p(filep);
|
||||
}
|
||||
virtual ~AstFScanF() {}
|
||||
virtual AstType type() const { return AstType::FSCANF;}
|
||||
virtual AstNode* clone() { return new AstFScanF(*this); }
|
||||
virtual string name() const { return m_text; }
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual string verilogKwd() const { return "$fscanf"; }
|
||||
virtual string emitVerilog() { V3ERROR_NA; return ""; }
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
virtual bool isGateOptimizable() const { return false; }
|
||||
virtual bool isPredictOptimizable() const { return false; }
|
||||
virtual bool isSplittable() const { return false; } // SPECIAL: has 'visual' ordering
|
||||
virtual bool isOutputter() const { return true; } // SPECIAL: makes output
|
||||
virtual bool cleanOut() { return false; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(text()); }
|
||||
virtual bool same(AstNode* samep) const {
|
||||
return text()==samep->castFScanF()->text(); }
|
||||
AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Expressions to output
|
||||
void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output
|
||||
string text() const { return m_text; } // * = Text to display
|
||||
void text(const string& text) { m_text=text; }
|
||||
AstNode* filep() const { return op2p(); }
|
||||
void filep(AstNodeVarRef* nodep) { setNOp2p(nodep); }
|
||||
};
|
||||
|
||||
struct AstSScanF : public AstNodeMath {
|
||||
// Parents: expr
|
||||
// Children: file which must be a varref
|
||||
// Children: varrefs to load
|
||||
private:
|
||||
string m_text;
|
||||
public:
|
||||
AstSScanF(FileLine* fileline, const string& text, AstNode* fromp, AstNode* exprsp)
|
||||
: AstNodeMath (fileline), m_text(text) {
|
||||
addNOp1p(exprsp);
|
||||
setOp2p(fromp);
|
||||
}
|
||||
virtual ~AstSScanF() {}
|
||||
virtual AstType type() const { return AstType::SSCANF;}
|
||||
virtual AstNode* clone() { return new AstSScanF(*this); }
|
||||
virtual string name() const { return m_text; }
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual string verilogKwd() const { return "$sscanf"; }
|
||||
virtual string emitVerilog() { V3ERROR_NA; return ""; }
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
virtual bool isGateOptimizable() const { return false; }
|
||||
virtual bool isPredictOptimizable() const { return false; }
|
||||
virtual bool isSplittable() const { return false; } // SPECIAL: has 'visual' ordering
|
||||
virtual bool isOutputter() const { return true; } // SPECIAL: makes output
|
||||
virtual bool cleanOut() { return false; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(text()); }
|
||||
virtual bool same(AstNode* samep) const {
|
||||
return text()==samep->castSScanF()->text(); }
|
||||
AstNode* exprsp() const { return op1p()->castNode(); } // op1 = Expressions to output
|
||||
void exprsp(AstNode* nodep) { addOp1p(nodep); } // op1 = Expressions to output
|
||||
string text() const { return m_text; } // * = Text to display
|
||||
void text(const string& text) { m_text=text; }
|
||||
AstNode* fromp() const { return op2p(); }
|
||||
void fromp(AstNode* nodep) { setOp2p(nodep); }
|
||||
};
|
||||
|
||||
struct AstReadMem : public AstNodeStmt {
|
||||
private:
|
||||
bool m_isHex; // readmemh, not readmemb
|
||||
@@ -1450,9 +1553,8 @@ struct AstChangeXor : public AstNodeBiComAsv {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opChangeXor(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l ^ %r)"; }
|
||||
virtual string emitOperator() { return "VL_CHANGEXOR"; }
|
||||
virtual string emitC() { return "VL_CHANGEXOR_%li(%lw, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "^"; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual bool cleanOut() {return false;} // Lclean && Rclean
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -1744,14 +1846,21 @@ struct AstScopeName : public AstNode {
|
||||
|
||||
struct AstRand : public AstNodeTermop {
|
||||
// Return a random number, based upon width()
|
||||
AstRand(FileLine* fl, int wwidth) : AstNodeTermop(fl) {
|
||||
width(wwidth,wwidth); }
|
||||
private:
|
||||
bool m_reset; // Random reset, versus always random
|
||||
public:
|
||||
AstRand(FileLine* fl, int wwidth, bool reset) : AstNodeTermop(fl) {
|
||||
width(wwidth,wwidth); m_reset=reset; }
|
||||
AstRand(FileLine* fl) : AstNodeTermop(fl), m_reset(false) { }
|
||||
virtual ~AstRand() {}
|
||||
virtual AstType type() const { return AstType::RAND;}
|
||||
virtual AstNode* clone() { return new AstRand(*this); }
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual string emitVerilog() { return "$random"; }
|
||||
virtual string emitOperator() { return "VL_RAND_RESET"; }
|
||||
virtual string emitC() {
|
||||
return (m_reset ?
|
||||
"VL_RAND_RESET_%nq(%nw, %P)"
|
||||
:"VL_RANDOM_%nq(%nw, %P)"); }
|
||||
virtual bool cleanOut() { return true; }
|
||||
virtual bool isGateOptimizable() const { return false; }
|
||||
virtual bool isPredictOptimizable() const { return false; }
|
||||
@@ -1768,7 +1877,7 @@ struct AstTime : public AstNodeTermop {
|
||||
virtual AstNode* clone() { return new AstTime(*this); }
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual string emitVerilog() { return "$time"; }
|
||||
virtual string emitOperator() { return "VL_TIME"; }
|
||||
virtual string emitC() { return "VL_TIME_%nq()"; }
|
||||
virtual bool cleanOut() { return true; }
|
||||
virtual bool isGateOptimizable() const { return false; }
|
||||
virtual bool isPredictOptimizable() const { return false; }
|
||||
@@ -1790,7 +1899,7 @@ public:
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual bool cleanOut() { return false; }
|
||||
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
|
||||
virtual string emitOperator() { V3ERROR_NA; return ""; }
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
AstNode* bodysp() const { return op1p()->castNode(); } // op1= expressions to print
|
||||
virtual bool isSplittable() const { return false; } // SPECIAL: User may order w/other sigs
|
||||
virtual bool isOutputter() const { return true; }
|
||||
@@ -1814,8 +1923,7 @@ struct AstUnaryMin : public AstNodeUniop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opUnaryMin(lhs); }
|
||||
virtual string emitVerilog() { return "%k(- %l)"; }
|
||||
virtual string emitOperator() { return "VL_UNARYMIN"; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual string emitC() { return "VL_UNARYMIN_%lq(%lW, %P, %li)"; }
|
||||
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;}
|
||||
virtual bool sizeMattersLhs() {return true;}
|
||||
};
|
||||
@@ -1828,7 +1936,7 @@ struct AstRedAnd : public AstNodeUniop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedAnd(lhs); }
|
||||
virtual string emitVerilog() { return "%k(& %l)"; }
|
||||
virtual string emitOperator() { return "VL_REDAND"; }
|
||||
virtual string emitC() { return "VL_REDAND_%nq%lq(%nw,%lw, %P, %li)"; }
|
||||
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;}
|
||||
};
|
||||
@@ -1841,8 +1949,7 @@ struct AstRedOr : public AstNodeUniop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedOr(lhs); }
|
||||
virtual string emitVerilog() { return "%k(| %l)"; }
|
||||
virtual string emitOperator() { return "VL_REDOR"; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual string emitC() { return "VL_REDOR_%lq(%lW, %P, %li)"; }
|
||||
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;}
|
||||
};
|
||||
@@ -1855,8 +1962,7 @@ struct AstRedXor : public AstNodeUniop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedXor(lhs); }
|
||||
virtual string emitVerilog() { return "%k(^ %l)"; }
|
||||
virtual string emitOperator() { return "VL_REDXOR"; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual string emitC() { return "VL_REDXOR_%lq(%lW, %P, %li)"; }
|
||||
virtual bool cleanOut() {return false;}
|
||||
virtual bool cleanLhs() {return (lhsp()->width()!=1 && lhsp()->width()!=2 && lhsp()->width()!=4
|
||||
&& lhsp()->width()!=8 && lhsp()->width()!=16);}
|
||||
@@ -1873,8 +1979,7 @@ struct AstRedXnor : public AstNodeUniop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opRedXnor(lhs); }
|
||||
virtual string emitVerilog() { return "%k(~^ %l)"; }
|
||||
virtual string emitOperator() { v3fatalSrc("REDXNOR should have became REDXOR"); return ""; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual string emitC() { v3fatalSrc("REDXNOR should have became REDXOR"); return ""; }
|
||||
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;}
|
||||
virtual int instrCount() const { return 1+V3Number::log2b(width()); }
|
||||
@@ -1889,7 +1994,7 @@ struct AstLogNot : public AstNodeUniop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opLogNot(lhs); }
|
||||
virtual string emitVerilog() { return "%k(! %l)"; }
|
||||
virtual string emitOperator() { return "VL_LOGNOT"; }
|
||||
virtual string emitC() { return "VL_LOGNOT_%nq%lq(%nw,%lw, %P, %li)"; }
|
||||
virtual string emitSimpleOperator() { return "!"; }
|
||||
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;}
|
||||
@@ -1903,9 +2008,8 @@ struct AstNot : public AstNodeUniop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opNot(lhs); }
|
||||
virtual string emitVerilog() { return "%k(~ %l)"; }
|
||||
virtual string emitOperator() { return "VL_NOT"; }
|
||||
virtual string emitC() { return "VL_NOT_%lq(%lW, %P, %li)"; }
|
||||
virtual string emitSimpleOperator() { return "~"; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;}
|
||||
virtual bool sizeMattersLhs() {return true;}
|
||||
};
|
||||
@@ -1918,7 +2022,7 @@ struct AstExtend : public AstNodeUniop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); }
|
||||
virtual string emitVerilog() { return "%l"; }
|
||||
virtual string emitOperator() { return "VL_EXTEND"; }
|
||||
virtual string emitC() { return "VL_EXTEND_%nq%lq(%nw,%lw, %P, %li)"; }
|
||||
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} // Because the EXTEND operator self-casts
|
||||
virtual int instrCount() const { return 0; }
|
||||
@@ -1932,7 +2036,7 @@ struct AstExtendS : public AstNodeUniop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opExtendS(lhs); }
|
||||
virtual string emitVerilog() { return "%l"; }
|
||||
virtual string emitOperator() { return "VL_EXTENDS"; }
|
||||
virtual string emitC() { return "VL_EXTENDS_%nq%lq(%nw,%lw, %P, %li)"; }
|
||||
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} // Because the EXTEND operator self-casts
|
||||
virtual int instrCount() const { return 0; }
|
||||
@@ -1949,7 +2053,7 @@ struct AstSigned : public AstNodeUniop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); out.isSigned(false); }
|
||||
virtual string emitVerilog() { return "%k$signed(%l)"; }
|
||||
virtual string emitOperator() { V3ERROR_NA; return ""; }
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters
|
||||
virtual bool sizeMattersLhs() {return true;} // Eliminated before matters
|
||||
virtual int instrCount() const { return 0; }
|
||||
@@ -1965,11 +2069,24 @@ struct AstUnsigned : public AstNodeUniop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); out.isSigned(false); }
|
||||
virtual string emitVerilog() { return "%k$unsigned(%l)"; }
|
||||
virtual string emitOperator() { V3ERROR_NA; return ""; }
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;} // Eliminated before matters
|
||||
virtual bool sizeMattersLhs() {return true;} // Eliminated before matters
|
||||
virtual int instrCount() const { return 0; }
|
||||
};
|
||||
struct AstCLog2 : public AstNodeUniop {
|
||||
AstCLog2(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {}
|
||||
virtual ~AstCLog2() {}
|
||||
virtual AstType type() const { return AstType::CLOG2;}
|
||||
virtual AstNode* clone() { return new AstCLog2(*this); }
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opCLog2(lhs); }
|
||||
virtual string emitVerilog() { return "%k$clog2(%l)"; }
|
||||
virtual string emitC() { return "VL_CLOG2_%lq(%lW, %P, %li)"; }
|
||||
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;}
|
||||
virtual int instrCount() const { return widthInstrs()*16; }
|
||||
};
|
||||
struct AstCountOnes : public AstNodeUniop {
|
||||
// Number of bits set in vector
|
||||
AstCountOnes(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {}
|
||||
@@ -1979,8 +2096,7 @@ struct AstCountOnes : public AstNodeUniop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opCountOnes(lhs); }
|
||||
virtual string emitVerilog() { return "%k$countones(%l)"; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual string emitOperator() { return "VL_COUNTONES"; }
|
||||
virtual string emitC() { return "VL_COUNTONES_%lq(%lW, %P, %li)"; }
|
||||
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;}
|
||||
virtual int instrCount() const { return widthInstrs()*16; }
|
||||
@@ -1995,7 +2111,7 @@ struct AstIsUnknown : public AstNodeUniop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opIsUnknown(lhs); }
|
||||
virtual string emitVerilog() { return "%k$isunknown(%l)"; }
|
||||
virtual string emitOperator() { V3ERROR_NA; return ""; }
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return false;}
|
||||
virtual bool sizeMattersLhs() {return false;}
|
||||
};
|
||||
@@ -2009,8 +2125,7 @@ struct AstOneHot : public AstNodeUniop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opOneHot(lhs); }
|
||||
virtual string emitVerilog() { return "%k$onehot(%l)"; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual string emitOperator() { return "VL_ONEHOT"; }
|
||||
virtual string emitC() { return "VL_ONEHOT_%lq(%lW, %P, %li)"; }
|
||||
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;}
|
||||
virtual int instrCount() const { return widthInstrs()*4; }
|
||||
@@ -2025,8 +2140,7 @@ struct AstOneHot0 : public AstNodeUniop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opOneHot0(lhs); }
|
||||
virtual string emitVerilog() { return "%k$onehot0(%l)"; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual string emitOperator() { return "VL_ONEHOT0"; }
|
||||
virtual string emitC() { return "VL_ONEHOT0_%lq(%lW, %P, %li)"; }
|
||||
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;}
|
||||
virtual int instrCount() const { return widthInstrs()*3; }
|
||||
@@ -2051,7 +2165,7 @@ public:
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { out.opAssign(lhs); }
|
||||
virtual string emitVerilog() { return "%k$_CAST(%l)"; }
|
||||
virtual string emitOperator() { return "VL_CAST"; }
|
||||
virtual string emitC() { return "VL_CAST_%nq%lq(%nw,%lw, %P, %li)"; }
|
||||
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} // Special cased in V3Cast
|
||||
virtual V3Hash sameHash() const { return V3Hash(size()); }
|
||||
@@ -2061,6 +2175,37 @@ public:
|
||||
int size() const { return m_size; }
|
||||
};
|
||||
|
||||
struct AstFEof : public AstNodeUniop {
|
||||
AstFEof(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {}
|
||||
virtual ~AstFEof() {}
|
||||
virtual AstType type() const { return AstType::FEOF;}
|
||||
virtual AstNode* clone() { return new AstFEof(*this); }
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { V3ERROR_NA; }
|
||||
virtual string emitVerilog() { return "%k$feof(%l)"; }
|
||||
virtual string emitC() { return "(%li ? feof(VL_CVT_Q_FP(%li)) : true)"; }
|
||||
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;}
|
||||
virtual int instrCount() const { return widthInstrs()*16; }
|
||||
AstNode* filep() const { return lhsp(); }
|
||||
};
|
||||
|
||||
struct AstFGetC : public AstNodeUniop {
|
||||
AstFGetC(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {}
|
||||
virtual ~AstFGetC() {}
|
||||
virtual AstType type() const { return AstType::FEOF;}
|
||||
virtual AstNode* clone() { return new AstFGetC(*this); }
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs) { V3ERROR_NA; }
|
||||
virtual string emitVerilog() { return "%k$fgetc(%l)"; }
|
||||
// Non-existant filehandle returns EOF
|
||||
virtual string emitC() { return "(%li ? fgetc(VL_CVT_Q_FP(%li)) : -1)"; }
|
||||
virtual bool cleanOut() {return false;} virtual bool cleanLhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;}
|
||||
virtual int instrCount() const { return widthInstrs()*64; }
|
||||
AstNode* filep() const { return lhsp(); }
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
// Binary ops
|
||||
|
||||
@@ -2073,7 +2218,7 @@ struct AstLogOr : public AstNodeBiComAsv {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogOr(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k|| %r)"; }
|
||||
virtual string emitOperator() { return "VL_LOGOR"; }
|
||||
virtual string emitC() { return "VL_LOGOR_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "||"; }
|
||||
virtual bool cleanOut() {return true;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
@@ -2089,7 +2234,7 @@ struct AstLogAnd : public AstNodeBiComAsv {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLogAnd(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k&& %r)"; }
|
||||
virtual string emitOperator() { return "VL_LOGAND"; }
|
||||
virtual string emitC() { return "VL_LOGAND_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "&&"; }
|
||||
virtual bool cleanOut() {return true;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
@@ -2105,7 +2250,7 @@ struct AstLogIf : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; }
|
||||
virtual string emitVerilog() { return "%k(%l %k-> %r)"; }
|
||||
virtual string emitOperator() { return "VL_LOGIF"; }
|
||||
virtual string emitC() { return "VL_LOGIF_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "->"; }
|
||||
virtual bool cleanOut() {return true;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
@@ -2121,7 +2266,7 @@ struct AstLogIff : public AstNodeBiCom {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; }
|
||||
virtual string emitVerilog() { return "%k(%l %k<-> %r)"; }
|
||||
virtual string emitOperator() { return "VL_LOGIFF"; }
|
||||
virtual string emitC() { return "VL_LOGIFF_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "<->"; }
|
||||
virtual bool cleanOut() {return true;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
@@ -2137,9 +2282,8 @@ struct AstOr : public AstNodeBiComAsv {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opOr(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k| %r)"; }
|
||||
virtual string emitOperator() { return "VL_OR"; }
|
||||
virtual string emitC() { return "VL_OR_%lq(%lW, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "|"; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual bool cleanOut() {V3ERROR_NA; return false;} // Lclean && Rclean
|
||||
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2153,9 +2297,8 @@ struct AstAnd : public AstNodeBiComAsv {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAnd(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k& %r)"; }
|
||||
virtual string emitOperator() { return "VL_AND"; }
|
||||
virtual string emitC() { return "VL_AND_%lq(%lW, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "&"; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual bool cleanOut() {V3ERROR_NA; return false;} // Lclean || Rclean
|
||||
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2169,9 +2312,8 @@ struct AstXor : public AstNodeBiComAsv {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opXor(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k^ %r)"; }
|
||||
virtual string emitOperator() { return "VL_XOR"; }
|
||||
virtual string emitC() { return "VL_XOR_%lq(%lW, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "^"; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual bool cleanOut() {return false;} // Lclean && Rclean
|
||||
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2185,9 +2327,8 @@ struct AstXnor : public AstNodeBiComAsv {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opXnor(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k^ ~ %r)"; }
|
||||
virtual string emitOperator() { return "VL_XNOR"; }
|
||||
virtual string emitC() { return "VL_XNOR_%lq(%lW, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "^ ~"; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual bool cleanOut() {return false;}
|
||||
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
|
||||
@@ -2201,9 +2342,8 @@ struct AstEq : public AstNodeBiCom {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opEq(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k== %r)"; }
|
||||
virtual string emitOperator() { return "VL_EQ"; }
|
||||
virtual string emitC() { return "VL_EQ_%lq(%lW, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "=="; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual bool cleanOut() {return true;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2217,9 +2357,8 @@ struct AstNeq : public AstNodeBiCom {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opNeq(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k!= %r)"; }
|
||||
virtual string emitOperator() { return "VL_NEQ"; }
|
||||
virtual string emitC() { return "VL_NEQ_%lq(%lW, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "!="; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual bool cleanOut() {return true;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2233,9 +2372,8 @@ struct AstLt : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLt(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k< %r)"; }
|
||||
virtual string emitOperator() { return "VL_LT"; }
|
||||
virtual string emitC() { return "VL_LT_%lq(%lW, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "<"; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual bool cleanOut() {return true;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2249,9 +2387,8 @@ struct AstLtS : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLtS(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k< %r)"; }
|
||||
virtual string emitOperator() { return "VL_LTS"; }
|
||||
virtual string emitC() { return "VL_LTS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return ""; }
|
||||
virtual bool emitWordForm() { return false; }
|
||||
virtual bool cleanOut() {return true;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2266,9 +2403,8 @@ struct AstGt : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGt(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k> %r)"; }
|
||||
virtual string emitOperator() { return "VL_GT"; }
|
||||
virtual string emitC() { return "VL_GT_%lq(%lW, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return ">"; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual bool cleanOut() {return true;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2282,9 +2418,8 @@ struct AstGtS : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGtS(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k> %r)"; }
|
||||
virtual string emitOperator() { return "VL_GTS"; }
|
||||
virtual string emitC() { return "VL_GTS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return ""; }
|
||||
virtual bool emitWordForm() { return false; }
|
||||
virtual bool cleanOut() {return true;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2299,9 +2434,8 @@ struct AstGte : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGte(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k>= %r)"; }
|
||||
virtual string emitOperator() { return "VL_GTE"; }
|
||||
virtual string emitC() { return "VL_GTE_%lq(%lW, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return ">="; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual bool cleanOut() {return true;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2315,9 +2449,8 @@ struct AstGteS : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGteS(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k>= %r)"; }
|
||||
virtual string emitOperator() { return "VL_GTES"; }
|
||||
virtual string emitC() { return "VL_GTES_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return ""; }
|
||||
virtual bool emitWordForm() { return false; }
|
||||
virtual bool cleanOut() {return true;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2332,9 +2465,8 @@ struct AstLte : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLte(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k<= %r)"; }
|
||||
virtual string emitOperator() { return "VL_LTE"; }
|
||||
virtual string emitC() { return "VL_LTE_%lq(%lW, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "<="; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual bool cleanOut() {return true;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2348,9 +2480,8 @@ struct AstLteS : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLteS(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k<= %r)"; }
|
||||
virtual string emitOperator() { return "VL_LTES"; }
|
||||
virtual string emitC() { return "VL_LTES_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return ""; }
|
||||
virtual bool emitWordForm() { return false; }
|
||||
virtual bool cleanOut() {return true;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2367,7 +2498,7 @@ struct AstShiftL : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftL(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k<< %r)"; }
|
||||
virtual string emitOperator() { return "VL_SHIFTL"; }
|
||||
virtual string emitC() { return "VL_SHIFTL_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "<<"; }
|
||||
virtual bool cleanOut() {return false;}
|
||||
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return true;}
|
||||
@@ -2384,7 +2515,7 @@ struct AstShiftR : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftR(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k>> %r)"; }
|
||||
virtual string emitOperator() { return "VL_SHIFTR"; }
|
||||
virtual string emitC() { return "VL_SHIFTR_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return ">>"; }
|
||||
virtual bool cleanOut() {return false;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
@@ -2401,7 +2532,7 @@ struct AstShiftRS : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opShiftRS(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k>>> %r)"; }
|
||||
virtual string emitOperator() { return "VL_SHIFTRS"; }
|
||||
virtual string emitC() { return "VL_SHIFTRS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return ""; }
|
||||
virtual bool cleanOut() {return false;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
@@ -2417,9 +2548,8 @@ struct AstAdd : public AstNodeBiComAsv {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opAdd(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k+ %r)"; }
|
||||
virtual string emitOperator() { return "VL_ADD"; }
|
||||
virtual string emitC() { return "VL_ADD_%lq(%lW, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "+"; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual bool cleanOut() {return false;}
|
||||
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
|
||||
@@ -2433,9 +2563,8 @@ struct AstSub : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opSub(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k- %r)"; }
|
||||
virtual string emitOperator() { return "VL_SUB"; }
|
||||
virtual string emitC() { return "VL_SUB_%lq(%lW, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "-"; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual bool cleanOut() {return false;}
|
||||
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
|
||||
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
|
||||
@@ -2449,9 +2578,8 @@ struct AstMul : public AstNodeBiComAsv {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opMul(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k* %r)"; }
|
||||
virtual string emitOperator() { return "VL_MUL"; }
|
||||
virtual string emitC() { return "VL_MUL_%lq(%lW, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "*"; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual bool cleanOut() {return false;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
|
||||
@@ -2466,9 +2594,8 @@ struct AstMulS : public AstNodeBiComAsv {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opMulS(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k* %r)"; }
|
||||
virtual string emitOperator() { return "VL_MULS"; }
|
||||
virtual string emitC() { return "VL_MULS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return ""; }
|
||||
virtual bool emitWordForm() { return false; }
|
||||
virtual bool cleanOut() {return false;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
|
||||
@@ -2484,8 +2611,7 @@ struct AstDiv : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opDiv(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k/ %r)"; }
|
||||
virtual string emitOperator() { return "VL_DIV"; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual string emitC() { return "VL_DIV_%lq(%lW, %P, %li, %ri)"; }
|
||||
virtual bool cleanOut() {return false;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
|
||||
@@ -2500,8 +2626,7 @@ struct AstDivS : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opDivS(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k/ %r)"; }
|
||||
virtual string emitOperator() { return "VL_DIVS"; }
|
||||
virtual bool emitWordForm() { return false; }
|
||||
virtual string emitC() { return "VL_DIVS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual bool cleanOut() {return false;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
|
||||
@@ -2517,8 +2642,7 @@ struct AstModDiv : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opModDiv(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k%% %r)"; }
|
||||
virtual string emitOperator() { return "VL_MODDIV"; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual string emitC() { return "VL_MODDIV_%lq(%lW, %P, %li, %ri)"; }
|
||||
virtual bool cleanOut() {return false;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
|
||||
@@ -2533,8 +2657,7 @@ struct AstModDivS : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opModDivS(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k%% %r)"; }
|
||||
virtual string emitOperator() { return "VL_MODDIVS"; }
|
||||
virtual bool emitWordForm() { return false; }
|
||||
virtual string emitC() { return "VL_MODDIVS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual bool cleanOut() {return false;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return true;}
|
||||
@@ -2550,8 +2673,7 @@ struct AstPow : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPow(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k** %r)"; }
|
||||
virtual string emitOperator() { return "VL_POW"; }
|
||||
virtual bool emitWordForm() { return false; }
|
||||
virtual string emitC() { return "VL_POW_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual bool cleanOut() {return false;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2566,8 +2688,7 @@ struct AstPowS : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opPowS(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k** %r)"; }
|
||||
virtual string emitOperator() { return "VL_POWS"; }
|
||||
virtual bool emitWordForm() { return false; }
|
||||
virtual string emitC() { return "VL_POWS_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual bool cleanOut() {return false;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return true;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2583,9 +2704,8 @@ struct AstEqCase : public AstNodeBiCom {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opCaseEq(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k=== %r)"; }
|
||||
virtual string emitOperator() { return "VL_EQ"; } // Until have 4 state anyways
|
||||
virtual string emitC() { return "VL_EQ_%lq(%lW, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "=="; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual bool cleanOut() {return true;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2599,9 +2719,8 @@ struct AstNeqCase : public AstNodeBiCom {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opCaseNeq(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k!== %r)"; }
|
||||
virtual string emitOperator() { return "VL_NEQ"; } // Until have 4 state anyways
|
||||
virtual string emitC() { return "VL_NEQ_%lq(%lW, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "!="; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual bool cleanOut() {return true;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2616,9 +2735,8 @@ struct AstEqWild : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildEq(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k==? %r)"; }
|
||||
virtual string emitOperator() { return "VL_EQ"; } // Until have 4 state anyways
|
||||
virtual string emitC() { return "VL_EQ_%lq(%lW, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "=="; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual bool cleanOut() {return true;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2632,9 +2750,8 @@ struct AstNeqWild : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opWildNeq(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k(%l %k!=? %r)"; }
|
||||
virtual string emitOperator() { return "VL_NEQ"; } // Until have 4 state anyways
|
||||
virtual string emitC() { return "VL_NEQ_%lq(%lW, %P, %li, %ri)"; }
|
||||
virtual string emitSimpleOperator() { return "!="; }
|
||||
virtual bool emitWordForm() { return true; }
|
||||
virtual bool cleanOut() {return true;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2650,7 +2767,7 @@ struct AstConcat : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual string emitVerilog() { return "%k{%l, %k%r}"; }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opConcat(lhs,rhs); }
|
||||
virtual string emitOperator() { return "VL_CONCAT"; }
|
||||
virtual string emitC() { return "VL_CONCAT_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual bool cleanOut() {return true;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
@@ -2666,12 +2783,28 @@ struct AstReplicate : public AstNodeBiop {
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opRepl(lhs,rhs); }
|
||||
virtual string emitVerilog() { return "%k{%l{%k%r}}"; }
|
||||
virtual string emitOperator() { return "VL_REPLICATE"; }
|
||||
virtual string emitC() { return "VL_REPLICATE_%nq%lq%rq(%nw,%lw,%rw, %P, %li, %ri)"; }
|
||||
virtual bool cleanOut() {return false;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
virtual int instrCount() const { return widthInstrs()*2; }
|
||||
};
|
||||
struct AstFGetS : public AstNodeBiop {
|
||||
AstFGetS(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {}
|
||||
virtual ~AstFGetS() {}
|
||||
virtual AstType type() const { return AstType::FEOF;}
|
||||
virtual AstNode* clone() { return new AstFGetS(*this); }
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { V3ERROR_NA; }
|
||||
virtual string emitVerilog() { return "%k$fgets(%l,%r)"; }
|
||||
virtual string emitC() { return "VL_FGETS_%nqX%rq(%lw, %P, &(%li), %ri)"; }
|
||||
virtual bool cleanOut() {return false;}
|
||||
virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
|
||||
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
|
||||
virtual int instrCount() const { return widthInstrs()*64; }
|
||||
AstNode* strgp() const { return lhsp(); }
|
||||
AstNode* filep() const { return rhsp(); }
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
// SysVerilog assertions
|
||||
@@ -3140,7 +3273,7 @@ struct AstCMath : public AstNodeMath {
|
||||
virtual bool isPredictOptimizable() const { return false; }
|
||||
virtual bool cleanOut() { return true; }
|
||||
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
|
||||
virtual string emitOperator() { V3ERROR_NA; return ""; }
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(AstNode* samep) const { return true; }
|
||||
};
|
||||
|
||||
+5
-5
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Removal of named begin blocks
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -19,7 +18,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
// V3Begin's Transformations:
|
||||
//
|
||||
//
|
||||
// Each module:
|
||||
// Look for BEGINs
|
||||
// BEGIN(VAR...) -> VAR ... {renamed}
|
||||
@@ -29,9 +28,10 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <cstring>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Removal of named begin blocks
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+3
-4
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Branch prediction
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -27,8 +26,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <map>
|
||||
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Branch prediction
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+4
-5
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Find broken links in tree
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -19,7 +18,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
// V3Broken's Transformations:
|
||||
//
|
||||
//
|
||||
// Entire netlist
|
||||
// Mark all nodes
|
||||
// Check all links point to marked nodes
|
||||
@@ -28,8 +27,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Find broken links in tree
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+54
-26
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Break case statements up and add Unknown assigns
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -19,7 +18,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
// V3Case's Transformations:
|
||||
//
|
||||
//
|
||||
// Each module:
|
||||
// TBD: Eliminate tristates by adding __in, __inen, __en wires in parallel
|
||||
// Need __en in changed list if a signal is on the LHS of a assign
|
||||
@@ -40,8 +39,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -74,7 +73,7 @@ private:
|
||||
}
|
||||
|
||||
// Check for X/Z in non-casex statements
|
||||
if (!nodep->castCase() || !nodep->castCase()->casex()) {
|
||||
{
|
||||
m_caseExprp = nodep;
|
||||
nodep->exprp()->accept(*this);
|
||||
for (AstCaseItem* itemp = nodep->itemsp(); itemp; itemp=itemp->nextp()->castCaseItem()) {
|
||||
@@ -84,11 +83,18 @@ private:
|
||||
}
|
||||
}
|
||||
virtual void visit(AstConst* nodep, AstNUser*) {
|
||||
// See also neverItem
|
||||
if (m_caseExprp && nodep->num().isFourState()) {
|
||||
if (m_caseExprp->castGenCase()) {
|
||||
nodep->v3error("Use of x/? constant in generate case statement, (no such thing as 'generate casez')");
|
||||
} else if (m_caseExprp->castCase() && m_caseExprp->castCase()->casex()) {
|
||||
// Don't sweat it, we already complained about casex in general
|
||||
} else if (m_caseExprp->castCase() && m_caseExprp->castCase()->casez()) {
|
||||
if (nodep->num().isUnknown()) {
|
||||
nodep->v3warn(CASEWITHX, "Use of x constant in casez statement, (perhaps intended ?/z in constant)");
|
||||
}
|
||||
} else {
|
||||
nodep->v3error("Use of x/? constant in case statement, (perhaps intended casex/casez)");
|
||||
nodep->v3warn(CASEWITHX, "Use of x/? constant in case statement, (perhaps intended casex/casez)");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,20 +159,24 @@ private:
|
||||
//if (debug()>=9) icondp->dumpTree(cout," caseitem: ");
|
||||
AstConst* iconstp = icondp->castConst();
|
||||
if (!iconstp) nodep->v3fatalSrc("above 'can't parse' should have caught this\n");
|
||||
V3Number nummask (itemp->fileline(), iconstp->width());
|
||||
nummask.opBitsNonX(iconstp->num());
|
||||
uint32_t mask = nummask.asInt();
|
||||
V3Number numval (itemp->fileline(), iconstp->width());
|
||||
numval.opBitsOne(iconstp->num());
|
||||
uint32_t val = numval.asInt();
|
||||
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
|
||||
if ((i & mask) == val) {
|
||||
if (!m_valueItem[i]) {
|
||||
m_valueItem[i] = itemp;
|
||||
} else if (!itemp->ignoreOverlap() && !bitched) {
|
||||
itemp->v3warn(CASEOVERLAP,"Case values overlap (example pattern 0x"<<hex<<i<<")");
|
||||
bitched = true;
|
||||
m_caseNoOverlapsAllCovered = false;
|
||||
if (neverItem(nodep, iconstp)) {
|
||||
// X in casez can't ever be executed
|
||||
} else {
|
||||
V3Number nummask (itemp->fileline(), iconstp->width());
|
||||
nummask.opBitsNonX(iconstp->num());
|
||||
uint32_t mask = nummask.asInt();
|
||||
V3Number numval (itemp->fileline(), iconstp->width());
|
||||
numval.opBitsOne(iconstp->num());
|
||||
uint32_t val = numval.asInt();
|
||||
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
|
||||
if ((i & mask) == val) {
|
||||
if (!m_valueItem[i]) {
|
||||
m_valueItem[i] = itemp;
|
||||
} else if (!itemp->ignoreOverlap() && !bitched) {
|
||||
itemp->v3warn(CASEOVERLAP,"Case values overlap (example pattern 0x"<<hex<<i<<")");
|
||||
bitched = true;
|
||||
m_caseNoOverlapsAllCovered = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,7 +245,7 @@ private:
|
||||
// new AstConst(cexprp->fileline(), nummask));
|
||||
AstNode* and1p = new AstSel(cexprp->fileline(), cexprp->cloneTree(false),
|
||||
msb, 1);
|
||||
AstNode* eqp = new AstNeq(cexprp->fileline(),
|
||||
AstNode* eqp = new AstNeq(cexprp->fileline(),
|
||||
new AstConst(cexprp->fileline(), 0),
|
||||
and1p);
|
||||
AstIf* ifp = new AstIf(cexprp->fileline(), eqp, tree1p, tree0p);
|
||||
@@ -293,19 +303,26 @@ private:
|
||||
for (AstNode* icondp = itemp->condsp(); icondp!=NULL; icondp=icondNextp) {
|
||||
icondNextp = icondp->nextp();
|
||||
icondp->unlinkFrBack();
|
||||
|
||||
|
||||
AstNode* and1p;
|
||||
AstNode* and2p;
|
||||
AstConst* iconstp = icondp->castConst();
|
||||
if (iconstp && iconstp->num().isFourState()
|
||||
&& nodep->casex()) {
|
||||
if (iconstp && neverItem(nodep, iconstp)) {
|
||||
// X in casez can't ever be executed
|
||||
icondp->deleteTree(); icondp=NULL; iconstp=NULL;
|
||||
// For simplicity, make expression that is not equal, and let later
|
||||
// optimizations remove it
|
||||
and1p = new AstConst(itemp->fileline(), V3Number(itemp->fileline(),1,0));
|
||||
and2p = new AstConst(itemp->fileline(), V3Number(itemp->fileline(),1,1));
|
||||
} else if (iconstp && iconstp->num().isFourState()
|
||||
&& (nodep->casex() || nodep->casez())) {
|
||||
V3Number nummask (itemp->fileline(), iconstp->width());
|
||||
nummask.opBitsNonX(iconstp->num());
|
||||
V3Number numval (itemp->fileline(), iconstp->width());
|
||||
numval.opBitsOne(iconstp->num());
|
||||
and1p = new AstAnd(itemp->fileline(), cexprp->cloneTree(false),
|
||||
new AstConst(itemp->fileline(), nummask));
|
||||
and2p = new AstAnd(itemp->fileline(),
|
||||
and2p = new AstAnd(itemp->fileline(),
|
||||
new AstConst(itemp->fileline(), numval),
|
||||
new AstConst(itemp->fileline(), nummask));
|
||||
icondp->deleteTree(); icondp=NULL; iconstp=NULL;
|
||||
@@ -395,6 +412,17 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
bool neverItem(AstCase* casep, AstConst* itemp) {
|
||||
// Xs in case or casez are impossible due to two state simulations
|
||||
if (casep->casex()) {
|
||||
} else if (casep->casez()) {
|
||||
if (itemp->num().isUnknown()) return true;
|
||||
} else {
|
||||
if (itemp->num().isFourState()) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstCase* nodep, AstNUser*) {
|
||||
V3Case::caseLint(nodep);
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Break case statements up and add Unknown assigns
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+5
-6
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Add C++ casts across expression size changes
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -19,7 +18,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
// V3Cast's Transformations:
|
||||
//
|
||||
//
|
||||
// Each module:
|
||||
// For each math operator, if above operator requires 32 bits,
|
||||
// and this isn't, cast to 32 bits.
|
||||
@@ -44,8 +43,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -148,7 +147,7 @@ private:
|
||||
&& nodep->backp()->width()
|
||||
&& castSize(nodep) != castSize(nodep->varp())) {
|
||||
// Cast vars to IData first, else below has upper bits wrongly set
|
||||
// CData x=3; out = (QData)(x<<30);
|
||||
// CData x=3; out = (QData)(x<<30);
|
||||
insertCast (nodep, castSize(nodep));
|
||||
}
|
||||
nodep->user(1);
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Add C++ casts across expression size changes
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+4
-5
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Add temporaries, such as for changed nodes
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -19,7 +18,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
// V3Changed's Transformations:
|
||||
//
|
||||
//
|
||||
// Each module:
|
||||
// Each combo block
|
||||
// For each variable that comes from combo block and is generated AFTER a usage
|
||||
@@ -33,8 +32,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
#include <set>
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Pre C-Emit stage changes
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+5
-6
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Add temporaries, such as for clean nodes
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -19,7 +18,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
// V3Clean's Transformations:
|
||||
//
|
||||
//
|
||||
// Each module:
|
||||
// For each math operator, if it requires a clean operand,
|
||||
// and the operand is dirty, insert a CLEAN node.
|
||||
@@ -30,8 +29,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -55,7 +54,7 @@ private:
|
||||
|
||||
// ENUMS
|
||||
enum CleanState { UNKNOWN, CLEAN, DIRTY };
|
||||
|
||||
|
||||
// METHODS
|
||||
// Width resetting
|
||||
int cppWidth(AstNode* nodep) {
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Pre C-Emit stage changes
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+7
-8
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Clocking POS/NEGEDGE insertion
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -19,7 +18,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
// V3Clock's Transformations:
|
||||
//
|
||||
//
|
||||
// Top Scope:
|
||||
// Check created ACTIVEs
|
||||
// Compress adjacent ACTIVEs with same sensitivity list
|
||||
@@ -34,8 +33,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -245,12 +244,12 @@ private:
|
||||
//UINFO(4," MOD "<<nodep<<endl);
|
||||
m_modp = nodep;
|
||||
m_stableNum = 0;
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
virtual void visit(AstScope* nodep, AstNUser*) {
|
||||
//UINFO(4," SCOPE "<<nodep<<endl);
|
||||
m_scopep = nodep;
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->iterateChildren(*this);
|
||||
if (AstNode* movep = nodep->finalClksp()) {
|
||||
if (!m_topScopep) nodep->v3fatalSrc("Final clocks under non-top scope");
|
||||
movep->unlinkFrBackWithNext();
|
||||
@@ -416,7 +415,7 @@ private:
|
||||
new AstConst(fl, 1)));
|
||||
preUntilp->addNext(new AstAssign(fl, new AstVarRef(fl, countVarp, true),
|
||||
new AstConst(fl, 0)));
|
||||
|
||||
|
||||
// Add stable variables & preinits
|
||||
AstNode* setChglastp = NULL;
|
||||
for (AstVarRef* varrefp = nodep->stablesp(); varrefp; varrefp=varrefp->nextp()->castVarRef()) {
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Clocking POS/NEGEDGE insertion
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+6
-7
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Combine common code into functions
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -19,7 +18,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
// V3Combine's Transformations:
|
||||
//
|
||||
//
|
||||
// For every function that we spit out
|
||||
// Examine code to find largest common blocks
|
||||
// Hash each node depth first
|
||||
@@ -32,13 +31,13 @@
|
||||
// Make new function
|
||||
// Move common block to function
|
||||
// Replace each common block ref with funccall
|
||||
//
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
@@ -392,7 +391,7 @@ private:
|
||||
m_hashed.clear();
|
||||
// Compute hash of all statement trees in the function
|
||||
m_state = STATE_HASH;
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->iterateChildren(*this);
|
||||
m_state = STATE_IDLE;
|
||||
// Walk the hashes removing empty functions
|
||||
if (emptyFunctionDeletion()) {
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Combine common code into functions
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+8
-9
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Constant folding
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -27,8 +26,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <map>
|
||||
|
||||
@@ -102,7 +101,7 @@ private:
|
||||
bool m_wremove; // Inside scope, no assignw removal
|
||||
bool m_warn; // Output warnings
|
||||
bool m_cpp; // C++ conversions only
|
||||
AstModule* m_modp; // Current module
|
||||
AstModule* m_modp; // Current module
|
||||
AstNode* m_scopep; // Current scope
|
||||
//int debug() { return 9; }
|
||||
|
||||
@@ -143,7 +142,7 @@ private:
|
||||
}
|
||||
bool operandIsTwo(AstNode* nodep) {
|
||||
return (nodep->castConst()
|
||||
&& nodep->width() <= VL_QUADSIZE
|
||||
&& nodep->width() <= VL_QUADSIZE
|
||||
&& nodep->castConst()->asQuad()==2);
|
||||
}
|
||||
bool operandIsTwostate(AstNode* nodep) {
|
||||
@@ -745,7 +744,7 @@ private:
|
||||
// Recurse rather then calling node->iterate to prevent 2^n recursion!
|
||||
if (operandConcatMove(abConcp)) moveConcat(abConcp);
|
||||
bcConcp->deleteTree(); bcConcp=NULL;
|
||||
} else {
|
||||
} else {
|
||||
AstConcat* abConcp = nodep->lhsp()->castConcat(); abConcp->unlinkFrBack();
|
||||
AstNode* ap = abConcp->lhsp()->unlinkFrBack();
|
||||
AstNode* bp = abConcp->rhsp()->unlinkFrBack();
|
||||
@@ -1017,7 +1016,7 @@ private:
|
||||
&& nodep->ifsp() && nodep->elsesp()) {
|
||||
UINFO(4,"IF(NOT {x}) => IF(x) swapped if/else"<<nodep<<endl);
|
||||
AstNode* condp = nodep->condp()->castNot()->lhsp()->unlinkFrBackWithNext();
|
||||
AstNode* ifsp = nodep->ifsp()->unlinkFrBackWithNext();
|
||||
AstNode* ifsp = nodep->ifsp()->unlinkFrBackWithNext();
|
||||
AstNode* elsesp = nodep->elsesp()->unlinkFrBackWithNext();
|
||||
AstIf* ifp = new AstIf(nodep->fileline(), condp, elsesp, ifsp);
|
||||
ifp->branchPred(nodep->branchPred().invert());
|
||||
@@ -1038,7 +1037,7 @@ private:
|
||||
nodep->deleteTree(); nodep=NULL;
|
||||
}
|
||||
else if (0 // Disabled, as vpm assertions are faster without due to short-circuiting
|
||||
&& operandIfIf(nodep)) {
|
||||
&& operandIfIf(nodep)) {
|
||||
UINFO(0,"IF({a}) IF({b}) => IF({a} && {b})"<<endl);
|
||||
AstNodeIf* lowerIfp = nodep->ifsp()->castNodeIf();
|
||||
AstNode* condp = nodep->condp()->unlinkFrBack();
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Propagate constants across AST
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+5
-6
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Netlist (top level) functions
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -31,8 +30,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <map>
|
||||
|
||||
@@ -53,7 +52,7 @@ private:
|
||||
bool m_checkBlock; // Should this block get covered?
|
||||
AstModule* m_modp; // Current module to add statement to
|
||||
FileMap m_fileps; // Column counts for each fileline
|
||||
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
@@ -66,7 +65,7 @@ private:
|
||||
column = (it->second)++;
|
||||
}
|
||||
|
||||
AstCoverDecl* declp = new AstCoverDecl(fl, column, type, comment);
|
||||
AstCoverDecl* declp = new AstCoverDecl(fl, column, type, comment);
|
||||
m_modp->addStmtp(declp);
|
||||
|
||||
return new AstCoverInc(fl, declp);
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Coverage modules/signals together
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+4
-5
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Dead code elimination
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -21,13 +20,13 @@
|
||||
// DEAD TRANSFORMATIONS:
|
||||
// Remove any unreferenced modules
|
||||
// Remove any unreferenced variables
|
||||
//
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Dead branch elimination
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+9
-10
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Add temporaries, such as for delayed nodes
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -19,9 +18,9 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
// V3Delayed's Transformations:
|
||||
//
|
||||
//
|
||||
// Each module:
|
||||
// Replace ASSIGNDLY var, exp
|
||||
// Replace ASSIGNDLY var, exp
|
||||
// With ASSIGNDLY newvar, exp
|
||||
// At top of block: VAR newvar
|
||||
// At bottom of block: ASSIGNW var newvar
|
||||
@@ -54,8 +53,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
@@ -269,7 +268,7 @@ private:
|
||||
AstAlwaysPost* finalp = varrefp->varScopep()->user4p()->castNode()->castAlwaysPost();
|
||||
if (!finalp) {
|
||||
finalp = new AstAlwaysPost(nodep->fileline(), NULL/*sens*/, NULL/*body*/);
|
||||
UINFO(9," Created "<<finalp<<endl);
|
||||
UINFO(9," Created "<<finalp<<endl);
|
||||
m_activep->addStmtsp(finalp);
|
||||
varrefp->varScopep()->user4p(finalp);
|
||||
}
|
||||
@@ -284,7 +283,7 @@ private:
|
||||
new AstVarRef(nodep->fileline(), setvscp, false),
|
||||
NULL,
|
||||
NULL);
|
||||
UINFO(9," Created "<<postLogicp<<endl);
|
||||
UINFO(9," Created "<<postLogicp<<endl);
|
||||
finalp->addBodysp(postLogicp);
|
||||
finalp->user5p(setvscp); // Remember IF's vset variable
|
||||
finalp->user4p(postLogicp); // and the associated IF, as we may be able to reuse it
|
||||
@@ -347,7 +346,7 @@ private:
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
if (!nodep->user2()) { // Not done yet
|
||||
nodep->user2(true);
|
||||
|
||||
|
||||
if (m_inDly && nodep->lvalue()) {
|
||||
UINFO(4,"AssignDlyVar: "<<nodep<<endl);
|
||||
markVarUsage(nodep->varp(), VU_DLY);
|
||||
@@ -401,7 +400,7 @@ private:
|
||||
m_activep->sensesp());
|
||||
newactp->addStmtsp(prep); // Add to FRONT of statements
|
||||
newactp->addStmtsp(postp);
|
||||
m_activep->addNext(newactp);
|
||||
m_activep->addNext(newactp);
|
||||
dlyvscp->user2p(newactp);
|
||||
}
|
||||
AstVarRef* newrefp = new AstVarRef(nodep->fileline(), dlyvscp, true);
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Pre C-Emit stage changes
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+5
-6
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Prevent very deep expressions
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -19,7 +18,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
// V3Depth's Transformations:
|
||||
//
|
||||
//
|
||||
// Each module:
|
||||
// For each wide OP, assign a temporary variable.
|
||||
// For each deep expression, assign expression to temporary.
|
||||
@@ -30,8 +29,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -111,7 +110,7 @@ private:
|
||||
// We have some operator defines that use 2 parens, so += 2.
|
||||
m_depth += 2;
|
||||
if (m_depth>m_maxdepth) m_maxdepth=m_depth;
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->iterateChildren(*this);
|
||||
m_depth -= 2;
|
||||
|
||||
if (m_stmtp
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Prevent very deep expressions
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Prevent very deep expressions
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -19,7 +18,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
// V3DepthBlock's Transformations:
|
||||
//
|
||||
//
|
||||
// Each module:
|
||||
// For each deep block, create cfunc including that block.
|
||||
//
|
||||
@@ -27,8 +26,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Prevent very deep expressions
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+4
-5
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Rename scope references to module-local references
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -24,13 +23,13 @@
|
||||
// Change varref name() to be relative to current module
|
||||
// Remove varScopep()
|
||||
// This allows for better V3Combine'ing.
|
||||
//
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <map>
|
||||
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Rename scope references to module-local references
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+267
-213
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit C++ for tree
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -21,10 +20,10 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
@@ -79,10 +78,10 @@ public:
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
void displayEmit(AstDisplay* nodep);
|
||||
string displayFormat(AstNode* widthNode, string in,
|
||||
char fmtLetter, bool padZero, bool reallyString);
|
||||
void displayArg(AstDisplay* dispp, AstNode** elistp, string fmt, char fmtLetter);
|
||||
void displayNode(AstNode* nodep, const string& vformat, AstNode* exprsp, bool isScan);
|
||||
void displayEmit(AstNode* nodep, bool isScan);
|
||||
void displayArg(AstNode* dispp, AstNode** elistp, bool isScan,
|
||||
string vfmt, char fmtLetter);
|
||||
|
||||
void emitVarDecl(AstVar* nodep, const string& prefixIfImp);
|
||||
typedef enum {EVL_IO, EVL_SIG, EVL_TEMP, EVL_STATIC, EVL_ALL} EisWhich;
|
||||
@@ -92,7 +91,8 @@ public:
|
||||
void emitIQW(AstNode* nodep) {
|
||||
puts (nodep->isWide()?"W":(nodep->isQuad()?"Q":"I"));
|
||||
}
|
||||
void emitOpName(AstNode* nodep, const string& name);
|
||||
void emitOpName(AstNode* nodep, const string& format,
|
||||
AstNode* lhsp, AstNode* rhsp, AstNode* thsp);
|
||||
|
||||
string cFuncArgs(AstCFunc* nodep) {
|
||||
// Return argument list for given C function
|
||||
@@ -212,7 +212,7 @@ public:
|
||||
}
|
||||
virtual void visit(AstCoverDecl* nodep, AstNUser*) {
|
||||
puts("__vlCoverInsert("); // As Declared in emitCoverageDecl
|
||||
puts("&__Vcoverage[");
|
||||
puts("&__Vcoverage[");
|
||||
puts(cvtToStr(m_coverIds.remap(nodep))); puts("]");
|
||||
puts(", \""); puts(nodep->fileline()->filebasename()); puts("\"");
|
||||
puts(", "); puts(cvtToStr(nodep->fileline()->lineno()));
|
||||
@@ -231,7 +231,23 @@ public:
|
||||
nodep->lhsp()->iterateAndNext(*this);
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstDisplay* nodep, AstNUser*); // BELOW
|
||||
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
||||
string text = nodep->text();
|
||||
if (nodep->addNewline()) text += "\\n";
|
||||
displayNode(nodep, text, nodep->exprsp(), false);
|
||||
}
|
||||
virtual void visit(AstFScanF* nodep, AstNUser*) {
|
||||
displayNode(nodep, nodep->text(), nodep->exprsp(), true);
|
||||
}
|
||||
virtual void visit(AstSScanF* nodep, AstNUser*) {
|
||||
displayNode(nodep, nodep->text(), nodep->exprsp(), true);
|
||||
}
|
||||
|
||||
void checkMaxWords(AstNode* nodep) {
|
||||
if (nodep->widthWords() > VL_TO_STRING_MAX_WORDS) {
|
||||
nodep->v3error("String of "<<nodep->width()<<" bits exceeds hardcoded limit VL_TO_STRING_MAX_WORDS in verilatedos.h\n");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstFOpen* nodep, AstNUser*) {
|
||||
nodep->filep()->iterateAndNext(*this);
|
||||
puts(" = VL_FOPEN_");
|
||||
@@ -243,9 +259,7 @@ public:
|
||||
puts(cvtToStr(nodep->filenamep()->widthWords()));
|
||||
putbs(", ");
|
||||
}
|
||||
if (nodep->filenamep()->widthWords() > VL_TO_STRING_MAX_WORDS) {
|
||||
nodep->v3error("String of "<<nodep->filenamep()->width()<<" bits exceeds hardcoded limit VL_TO_STRING_MAX_WORDS in verilatedos.h\n");
|
||||
}
|
||||
checkMaxWords(nodep->filenamep());
|
||||
nodep->filenamep()->iterateAndNext(*this);
|
||||
putbs(", ");
|
||||
nodep->modep()->iterateAndNext(*this);
|
||||
@@ -272,9 +286,7 @@ public:
|
||||
puts(cvtToStr(array_lsb));
|
||||
putbs(",");
|
||||
puts(cvtToStr(nodep->filenamep()->widthWords()));
|
||||
if (nodep->filenamep()->widthWords() > VL_TO_STRING_MAX_WORDS) {
|
||||
nodep->v3error("String of "<<nodep->filenamep()->width()<<" bits exceeds hardcoded limit VL_TO_STRING_MAX_WORDS in verilatedos.h\n");
|
||||
}
|
||||
checkMaxWords(nodep->filenamep());
|
||||
putbs(", ");
|
||||
nodep->filenamep()->iterateAndNext(*this);
|
||||
putbs(", ");
|
||||
@@ -293,6 +305,17 @@ public:
|
||||
nodep->filep()->iterateAndNext(*this); // For saftey, so user doesn't later WRITE with it.
|
||||
puts("=0; }\n");
|
||||
}
|
||||
virtual void visit(AstFFlush* nodep, AstNUser*) {
|
||||
if (!nodep->filep()) {
|
||||
puts("fflush (stdout);\n");
|
||||
} else {
|
||||
puts("if (");
|
||||
nodep->filep()->iterateAndNext(*this);
|
||||
puts(") { fflush (VL_CVT_Q_FP(");
|
||||
nodep->filep()->iterateAndNext(*this);
|
||||
puts(")); }\n");
|
||||
}
|
||||
}
|
||||
virtual void visit(AstWhile* nodep, AstNUser*) {
|
||||
nodep->precondsp()->iterateAndNext(*this);
|
||||
puts("while (");
|
||||
@@ -354,26 +377,24 @@ public:
|
||||
|
||||
// Operators
|
||||
virtual void visit(AstNodeTermop* nodep, AstNUser*) {
|
||||
emitOpName(nodep,nodep->emitOperator());
|
||||
puts(")");
|
||||
emitOpName(nodep, nodep->emitC(), NULL, NULL, NULL);
|
||||
}
|
||||
virtual void visit(AstNodeUniop* nodep, AstNUser*) {
|
||||
if (emitSimpleOk(nodep)) {
|
||||
putbs("("); puts(nodep->emitSimpleOperator()); puts(" ");
|
||||
nodep->lhsp()->iterateAndNext(*this); puts(")");
|
||||
} else {
|
||||
emitOpName(nodep,nodep->emitOperator());
|
||||
emitOpName(nodep, nodep->emitC(), nodep->lhsp(), NULL, NULL);
|
||||
}
|
||||
nodep->lhsp()->iterateAndNext(*this); puts(")");
|
||||
}
|
||||
virtual void visit(AstNodeBiop* nodep, AstNUser*) {
|
||||
if (emitSimpleOk(nodep)) {
|
||||
putbs("("); nodep->lhsp()->iterateAndNext(*this);
|
||||
puts(" "); putbs(nodep->emitSimpleOperator()); puts(" ");
|
||||
nodep->rhsp()->iterateAndNext(*this); puts(")");
|
||||
} else {
|
||||
emitOpName(nodep,nodep->emitOperator());
|
||||
nodep->lhsp()->iterateAndNext(*this); puts(", ");
|
||||
emitOpName(nodep, nodep->emitC(), nodep->lhsp(), nodep->rhsp(), NULL);
|
||||
}
|
||||
nodep->rhsp()->iterateAndNext(*this); puts(")");
|
||||
}
|
||||
virtual void visit(AstRedXor* nodep, AstNUser* vup) {
|
||||
if (nodep->lhsp()->isWide()) {
|
||||
@@ -405,10 +426,7 @@ public:
|
||||
virtual void visit(AstNodeCond* nodep, AstNUser*) {
|
||||
// Widths match up already, so we'll just use C++'s operator w/o any temps.
|
||||
if (nodep->expr1p()->isWide()) {
|
||||
emitOpName(nodep,nodep->emitOperator());
|
||||
nodep->condp()->iterateAndNext(*this); puts(", ");
|
||||
nodep->expr1p()->iterateAndNext(*this); puts(", ");
|
||||
nodep->expr2p()->iterateAndNext(*this); puts(")");
|
||||
emitOpName(nodep, nodep->emitC(), nodep->condp(), nodep->expr1p(), nodep->expr2p());
|
||||
} else {
|
||||
putbs("(");
|
||||
nodep->condp()->iterateAndNext(*this); putbs(" ? ");
|
||||
@@ -418,16 +436,7 @@ public:
|
||||
}
|
||||
virtual void visit(AstSel* nodep, AstNUser*) {
|
||||
// Note ASSIGN checks for this on a LHS
|
||||
if (nodep->widthp()->isOne()) {
|
||||
emitOpName(nodep,"VL_BITSEL");
|
||||
nodep->fromp()->iterateAndNext(*this); puts(", ");
|
||||
nodep->lsbp()->iterateAndNext(*this); puts(")");
|
||||
} else {
|
||||
emitOpName(nodep,"VL_SEL");
|
||||
nodep->fromp()->iterateAndNext(*this); puts(", ");
|
||||
nodep->lsbp()->iterateAndNext(*this); puts(", ");
|
||||
nodep->widthp()->iterateAndNext(*this); puts(")");
|
||||
}
|
||||
emitOpName(nodep, nodep->emitC(), nodep->fromp(), nodep->lsbp(), nodep->thsp());
|
||||
}
|
||||
virtual void visit(AstReplicate* nodep, AstNUser*) {
|
||||
if (nodep->lhsp()->widthMin() == 1 && !nodep->isWide()) {
|
||||
@@ -441,24 +450,16 @@ public:
|
||||
if (nodep->lhsp()) { puts(","+cvtToStr(nodep->lhsp()->widthMin())); }
|
||||
if (nodep->rhsp()) { puts(","+cvtToStr(nodep->rhsp()->widthMin())); }
|
||||
puts(",");
|
||||
nodep->lhsp()->iterateAndNext(*this); puts(", ");
|
||||
nodep->rhsp()->iterateAndNext(*this); puts(")");
|
||||
} else {
|
||||
emitOpName(nodep,nodep->emitOperator());
|
||||
emitOpName(nodep, nodep->emitC(), nodep->lhsp(), nodep->rhsp(), NULL);
|
||||
}
|
||||
nodep->lhsp()->iterateAndNext(*this); puts(", ");
|
||||
nodep->rhsp()->iterateAndNext(*this); puts(")");
|
||||
}
|
||||
virtual void visit(AstArraySel* nodep, AstNUser*) {
|
||||
nodep->fromp()->iterateAndNext(*this); putbs("[");
|
||||
nodep->bitp()->iterateAndNext(*this); puts("]");
|
||||
}
|
||||
virtual void visit(AstWordSel* nodep, AstNUser*) {
|
||||
nodep->fromp()->iterateAndNext(*this); puts("["); // Not putbs, as usually it's a small constant next
|
||||
nodep->bitp()->iterateAndNext(*this); puts("]");
|
||||
}
|
||||
// Terminals
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
puts(nodep->hiername());
|
||||
puts(nodep->varp()->name());
|
||||
puts(nodep->varp()->name());
|
||||
}
|
||||
void emitConstant(AstConst* nodep, AstVarRef* assigntop, const string& assignString) {
|
||||
// Put out constant set to the specified variable, or given variable in a string
|
||||
@@ -639,7 +640,7 @@ class EmitCImp : EmitCStmts {
|
||||
puts(modClassName(m_modp)+"::"+nodep->name()
|
||||
+"("+cFuncArgs(nodep)+") {\n");
|
||||
|
||||
puts("VL_DEBUG_IF(cout<<\" ");
|
||||
puts("VL_DEBUG_IF(cout<<\" ");
|
||||
for (int i=0;i<m_modp->level();i++) { puts(" "); }
|
||||
puts(modClassName(m_modp)+"::"+nodep->name()
|
||||
+"\"<<endl; );\n");
|
||||
@@ -853,33 +854,95 @@ bool EmitCStmts::emitSimpleOk(AstNodeMath* nodep) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void EmitCStmts::emitOpName(AstNode* nodep, const string& opname) {
|
||||
putbs(opname+"_");
|
||||
if (nodep->emitWordForm()) {
|
||||
emitIQW(nodep->op1p());
|
||||
puts("(");
|
||||
if (nodep->op1p()->isWide()) {
|
||||
puts(cvtToStr(nodep->op1p()->widthWords()));
|
||||
puts(", ");
|
||||
void EmitCStmts::emitOpName(AstNode* nodep, const string& format,
|
||||
AstNode* lhsp, AstNode* rhsp, AstNode* thsp) {
|
||||
// Look at emitOperator() format for term/uni/dual/triops,
|
||||
// and write out appropriate text.
|
||||
// %n* node
|
||||
// %nq emitIQW on the [node]
|
||||
// %nw width in bits
|
||||
// %nW width in words
|
||||
// %ni iterate
|
||||
// %l* lhsp - if appropriate, then second char as above
|
||||
// %r* rhsp - if appropriate, then second char as above
|
||||
// %t* thsp - if appropriate, then second char as above
|
||||
// %k Potential line break
|
||||
// %P Wide temporary name
|
||||
// , Commas suppressed if the previous field is suppressed
|
||||
string nextComma;
|
||||
bool needComma = false;
|
||||
#define COMMA { if (nextComma!="") { puts(nextComma); nextComma=""; } }
|
||||
|
||||
putbs("");
|
||||
for (string::const_iterator pos = format.begin(); pos != format.end(); ++pos) {
|
||||
if (pos[0]==',') {
|
||||
// Remember we need to add one, but don't do yet to avoid ",)"
|
||||
if (needComma) {
|
||||
if (pos[1]==' ') { nextComma=", "; }
|
||||
else nextComma = ",";
|
||||
needComma = false;
|
||||
}
|
||||
if (pos[1]==' ') { ++pos; } // Must do even if no nextComma
|
||||
}
|
||||
else if (pos[0]=='%') {
|
||||
++pos;
|
||||
bool detail = false;
|
||||
AstNode* detailp = NULL;
|
||||
switch (pos[0]) {
|
||||
case '%': puts("%"); break;
|
||||
case 'k': putbs(""); break;
|
||||
case 'n': detail = true; detailp = nodep; break;
|
||||
case 'l': detail = true; detailp = lhsp; break;
|
||||
case 'r': detail = true; detailp = rhsp; break;
|
||||
case 't': detail = true; detailp = thsp; break;
|
||||
case 'P':
|
||||
if (nodep->isWide()) {
|
||||
if (!m_wideTempRefp) nodep->v3fatalSrc("Wide Op w/ no temp, perhaps missing op in V3EmitC?");
|
||||
COMMA;
|
||||
puts(m_wideTempRefp->hiername());
|
||||
puts(m_wideTempRefp->varp()->name());
|
||||
m_wideTempRefp = NULL;
|
||||
needComma = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
nodep->v3fatalSrc("Unknown emitOperator format code: %"<<pos[0]);
|
||||
break;
|
||||
}
|
||||
if (detail) {
|
||||
// Get next letter of %[nlrt]
|
||||
++pos;
|
||||
switch (pos[0]) {
|
||||
case 'q': emitIQW(detailp); break;
|
||||
case 'w':
|
||||
COMMA;
|
||||
puts(cvtToStr(detailp->widthMin()));
|
||||
needComma = true;
|
||||
break;
|
||||
case 'W':
|
||||
if (lhsp->isWide()) {
|
||||
COMMA;
|
||||
puts(cvtToStr(lhsp->widthWords()));
|
||||
needComma = true;
|
||||
}
|
||||
break;
|
||||
case 'i':
|
||||
COMMA;
|
||||
if (!detailp) { nodep->v3fatalSrc("emitOperator() references undef node"); }
|
||||
else detailp->iterateAndNext(*this);
|
||||
needComma = true;
|
||||
break;
|
||||
default:
|
||||
nodep->v3fatalSrc("Unknown emitOperator format code: %[nlrt]"<<pos[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Normal text
|
||||
if (pos[0] == ')') nextComma="";
|
||||
COMMA;
|
||||
string s; s+=pos[0]; puts(s);
|
||||
}
|
||||
} else {
|
||||
emitIQW(nodep);
|
||||
if (nodep->op1p()) { emitIQW(nodep->op1p()); }
|
||||
if (nodep->op2p()) { emitIQW(nodep->op2p()); }
|
||||
if (nodep->op3p()) { emitIQW(nodep->op3p()); }
|
||||
puts("(");
|
||||
puts(cvtToStr(nodep->widthMin()));
|
||||
if (nodep->op1p()) { puts(","+cvtToStr(nodep->op1p()->widthMin())); }
|
||||
if (nodep->op2p()) { puts(","+cvtToStr(nodep->op2p()->widthMin())); }
|
||||
if (nodep->op3p()) { puts(","+cvtToStr(nodep->op3p()->widthMin())); }
|
||||
if (nodep->op1p() || nodep->isWide()) puts(", ");
|
||||
}
|
||||
if (nodep->isWide()) {
|
||||
if (!m_wideTempRefp) nodep->v3fatalSrc("Wide Op w/ no temp, perhaps missing op in V3EmitC?");
|
||||
puts(m_wideTempRefp->hiername());
|
||||
puts(m_wideTempRefp->varp()->name());
|
||||
m_wideTempRefp = NULL;
|
||||
if (nodep->op1p()) puts(", ");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -889,13 +952,11 @@ void EmitCStmts::emitOpName(AstNode* nodep, const string& opname) {
|
||||
// We only do one display at once, so can just use static state
|
||||
|
||||
struct EmitDispState {
|
||||
bool m_wide; // Put out a wide func that needs string buffer
|
||||
string m_format; // "%s" and text from user
|
||||
vector<AstNode*> m_argsp; // Each argument to be printed
|
||||
vector<string> m_argsFunc; // Function before each argument to be printed
|
||||
EmitDispState() { clear(); }
|
||||
void clear() {
|
||||
m_wide = false;
|
||||
m_format = "";
|
||||
m_argsp.clear();
|
||||
m_argsFunc.clear();
|
||||
@@ -907,18 +968,40 @@ struct EmitDispState {
|
||||
}
|
||||
} emitDispState;
|
||||
|
||||
void EmitCStmts::displayEmit(AstDisplay* nodep) {
|
||||
if (emitDispState.m_format != "") {
|
||||
void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) {
|
||||
if (emitDispState.m_format == ""
|
||||
&& nodep->castDisplay()) { // not fscanf etc, as they need to return value
|
||||
// NOP
|
||||
} else {
|
||||
// Format
|
||||
if (nodep->filep()) {
|
||||
puts("if (");
|
||||
nodep->filep()->iterate(*this); // Check if closed, to avoid core dump
|
||||
puts(") fprintf(VL_CVT_Q_FP(");
|
||||
nodep->filep()->iterate(*this);
|
||||
puts("),\"");
|
||||
bool isStmt;
|
||||
if (AstFScanF* dispp = nodep->castFScanF()) {
|
||||
isStmt = false;
|
||||
puts("VL_FSCANF_IX(");
|
||||
dispp->filep()->iterate(*this);
|
||||
puts(",");
|
||||
} else if (AstSScanF* dispp = nodep->castSScanF()) {
|
||||
isStmt = false;
|
||||
checkMaxWords(dispp->fromp());
|
||||
puts("VL_SSCANF_I"); emitIQW(dispp->fromp()); puts("X(");
|
||||
puts(cvtToStr(dispp->fromp()->widthMin()));
|
||||
puts(",");
|
||||
dispp->fromp()->iterate(*this);
|
||||
puts(",");
|
||||
} else if (AstDisplay* dispp = nodep->castDisplay()) {
|
||||
isStmt = true;
|
||||
if (dispp->filep()) {
|
||||
puts("VL_FWRITEF(");
|
||||
dispp->filep()->iterate(*this);
|
||||
puts(",");
|
||||
} else {
|
||||
puts("VL_WRITEF(");
|
||||
}
|
||||
} else {
|
||||
puts("VL_PRINTF(\"");
|
||||
isStmt = true;
|
||||
nodep->v3fatalSrc("Unknown displayEmit node type");
|
||||
}
|
||||
puts("\"");
|
||||
ofp()->putsNoTracking(emitDispState.m_format);
|
||||
puts("\"");
|
||||
// Arguments
|
||||
@@ -929,162 +1012,133 @@ void EmitCStmts::displayEmit(AstDisplay* nodep) {
|
||||
ofp()->indentInc();
|
||||
ofp()->putbs("");
|
||||
if (func!="") puts(func);
|
||||
if (argp) argp->iterate(*this);
|
||||
if (func!="") puts(")");
|
||||
if (argp) {
|
||||
if (isScan) puts("&(");
|
||||
argp->iterate(*this);
|
||||
if (isScan) puts(")");
|
||||
}
|
||||
ofp()->indentDec();
|
||||
}
|
||||
// End
|
||||
puts(");\n");
|
||||
puts(")");
|
||||
if (isStmt) puts(";\n");
|
||||
else puts(" ");
|
||||
// Prep for next
|
||||
emitDispState.clear();
|
||||
}
|
||||
}
|
||||
|
||||
string EmitCStmts::displayFormat(AstNode* widthNodep, string in,
|
||||
char fmtLetter, bool padZero, bool reallyString) {
|
||||
if (fmtLetter=='s') padZero = false;
|
||||
if (widthNodep && widthNodep->isWide()
|
||||
&& (fmtLetter=='d'||fmtLetter=='u')) {
|
||||
widthNodep->v3error("Unsupported: $display of dec format of > 64 bit results (use hex format instead)");
|
||||
}
|
||||
if (widthNodep && widthNodep->widthMin()>8 && fmtLetter=='c') {
|
||||
widthNodep->v3error("$display of char format of > 8 bit result");
|
||||
}
|
||||
string fmt;
|
||||
if (in == "") {
|
||||
// Size naturally
|
||||
if (widthNodep == NULL) fmt=""; // Out of args, will get error
|
||||
if (fmtLetter=='u' || fmtLetter=='d') { // Decimal. Spec says leading spaces, not zeros
|
||||
double mantissabits = widthNodep->widthMin() - ((fmtLetter=='d')?1:0);
|
||||
double maxval = pow(2.0, mantissabits);
|
||||
double dchars = log10(maxval)+1.0;
|
||||
if (fmtLetter=='d') dchars++; // space for sign
|
||||
int nchars = int(dchars);
|
||||
fmt=cvtToStr(nchars);
|
||||
} else if (fmtLetter!='s' && fmtLetter!='c') { // Strings/chars don't get padding
|
||||
int bitsPerChar = (fmtLetter=='b'?1 : fmtLetter=='o'?3 : 4);
|
||||
int nchars = (widthNodep->widthMin() + bitsPerChar-1)/bitsPerChar;
|
||||
if (padZero) fmt=(string)("0")+cvtToStr(nchars);
|
||||
else fmt=cvtToStr(nchars);
|
||||
}
|
||||
} else if (in == "0") {
|
||||
fmt=""; // No width
|
||||
} else {
|
||||
fmt=in;
|
||||
}
|
||||
return fmt;
|
||||
}
|
||||
|
||||
void EmitCStmts::displayArg(AstDisplay* dispp, AstNode** elistp, string fmt, char fmtLetter) {
|
||||
void EmitCStmts::displayArg(AstNode* dispp, AstNode** elistp, bool isScan,
|
||||
string vfmt, char fmtLetter) {
|
||||
// Print display argument, edits elistp
|
||||
if (!*elistp) {
|
||||
dispp->v3error("Missing arguments for $display format");
|
||||
AstNode* argp = *elistp;
|
||||
if (!argp) {
|
||||
// expectDisplay() checks this first, so internal error if found here
|
||||
dispp->v3error("Internal: Missing arguments for $display format");
|
||||
return;
|
||||
}
|
||||
if ((*elistp)->widthMin() > VL_VALUE_STRING_MAX_WIDTH) {
|
||||
if (argp->widthMin() > VL_VALUE_STRING_MAX_WIDTH) {
|
||||
dispp->v3error("Exceeded limit of 1024 bits for any display arguments");
|
||||
}
|
||||
|
||||
if ((*elistp)->isWide() // Have to use our own function for wide,
|
||||
|| fmtLetter=='s' // ... Verilog strings
|
||||
|| fmtLetter=='b' // ... binary, no printf %b in C
|
||||
|| fmtLetter=='d') { // ... Signed decimal
|
||||
// We use a single static string, so must only have one call per VL_PRINT
|
||||
if (emitDispState.m_wide) { displayEmit(dispp); }
|
||||
emitDispState.m_wide = true;
|
||||
string nfmt = displayFormat(*elistp, fmt, fmtLetter, false, true);
|
||||
string pfmt = "%"+nfmt+"s";
|
||||
string func = "VL_VALUE_FORMATTED_";
|
||||
func += ((*elistp)->isWide()) ? "W(" : ((*elistp)->isQuad()) ? "Q(" : "I(";
|
||||
func += (cvtToStr((*elistp)->widthMin())
|
||||
+",'"+fmtLetter+"'"
|
||||
+","+(fmt=="0"?"true":"false")+",");
|
||||
emitDispState.pushFormat(pfmt);
|
||||
emitDispState.pushArg(*elistp,func);
|
||||
} else {
|
||||
string func;
|
||||
string nfmt = displayFormat(*elistp, fmt, fmtLetter, true, false);
|
||||
// We don't need to check for fmtLetter=='d', as it is above.
|
||||
if ((*elistp)->isQuad() && (fmtLetter=='u'||fmtLetter=='o'||fmtLetter=='x')) {
|
||||
nfmt+="ll";
|
||||
func="(unsigned long long)("; // Must match %ull to avoid warnings
|
||||
}
|
||||
string pfmt = "%"+nfmt+fmtLetter;
|
||||
|
||||
emitDispState.pushFormat(pfmt);
|
||||
emitDispState.pushArg(*elistp,func);
|
||||
if (argp && argp->isWide()
|
||||
&& (fmtLetter=='d'||fmtLetter=='u')) {
|
||||
argp->v3error("Unsupported: "<<dispp->verilogKwd()<<" of dec format of > 64 bit results (use hex format instead)");
|
||||
}
|
||||
if (argp && argp->widthMin()>8 && fmtLetter=='c') {
|
||||
// Technically legal, but surely not what the user intended.
|
||||
argp->v3error(dispp->verilogKwd()<<" of char format of > 8 bit result");
|
||||
}
|
||||
|
||||
//string pfmt = "%"+displayFormat(argp, vfmt, fmtLetter)+fmtLetter;
|
||||
string pfmt;
|
||||
if ((fmtLetter=='u' || fmtLetter=='d')
|
||||
&& !isScan
|
||||
&& vfmt == "") { // Size decimal output. Spec says leading spaces, not zeros
|
||||
double mantissabits = argp->widthMin() - ((fmtLetter=='d')?1:0);
|
||||
double maxval = pow(2.0, mantissabits);
|
||||
double dchars = log10(maxval)+1.0;
|
||||
if (fmtLetter=='d') dchars++; // space for sign
|
||||
int nchars = int(dchars);
|
||||
pfmt = string("%") + cvtToStr(nchars) + fmtLetter;
|
||||
} else {
|
||||
pfmt = string("%") + vfmt + fmtLetter;
|
||||
}
|
||||
emitDispState.pushFormat(pfmt);
|
||||
emitDispState.pushArg(NULL,cvtToStr(argp->widthMin()));
|
||||
emitDispState.pushArg(argp,"");
|
||||
|
||||
// Next parameter
|
||||
*elistp = (*elistp)->nextp();
|
||||
}
|
||||
|
||||
void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) {
|
||||
string vformat = nodep->text();
|
||||
AstNode* elistp = nodep->exprsp();
|
||||
void EmitCStmts::displayNode(AstNode* nodep, const string& vformat, AstNode* exprsp,
|
||||
bool isScan) {
|
||||
AstNode* elistp = exprsp;
|
||||
|
||||
// Convert Verilog display to C printf formats
|
||||
// "%0t" becomes "%d"
|
||||
emitDispState.clear();
|
||||
string fmt = "";
|
||||
string::iterator pos = vformat.begin();
|
||||
if (*pos == '"') pos++;
|
||||
string vfmt = "";
|
||||
string::const_iterator pos = vformat.begin();
|
||||
bool inPct = false;
|
||||
for (; pos != vformat.end(); ++pos) {
|
||||
if (pos[0]=='"' && (pos+1)==vformat.end()) break;
|
||||
if (inPct && pos[0]=='%') {
|
||||
emitDispState.pushFormat("%%"); // We're printf'ing it, so need to quote the %
|
||||
inPct = false;
|
||||
} else if (pos[0]=='%') {
|
||||
//UINFO(1,"Parse '"<<*pos<<"' IP"<<inPct<<" List "<<(void*)(elistp)<<endl);
|
||||
if (!inPct && pos[0]=='%') {
|
||||
inPct = true;
|
||||
fmt = "";
|
||||
vfmt = "";
|
||||
} else if (!inPct) { // Normal text
|
||||
//char text[2]; text[0]=*pos; text[1]='\0';
|
||||
emitDispState.pushFormat(*pos);
|
||||
} else { // Format character
|
||||
if (isdigit(pos[0])) {
|
||||
inPct = false;
|
||||
switch (tolower(pos[0])) {
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
// Digits, like %5d, etc.
|
||||
fmt += pos[0];
|
||||
} else {
|
||||
inPct = false;
|
||||
switch (tolower(pos[0])) {
|
||||
// Special codes
|
||||
case '~': displayArg(nodep,&elistp,fmt,'d'); break; // Signed decimal
|
||||
// Spec: h d o b c l
|
||||
case 'b': displayArg(nodep,&elistp,fmt,'b'); break;
|
||||
case 'c': displayArg(nodep,&elistp,fmt,'c'); break;
|
||||
case 't':
|
||||
case 'd': displayArg(nodep,&elistp,fmt,'u'); break; // Unsigned decimal
|
||||
case 'o': displayArg(nodep,&elistp,fmt,'o'); break;
|
||||
case 'h':
|
||||
case 'x': displayArg(nodep,&elistp,fmt,'x'); break;
|
||||
case 's': displayArg(nodep,&elistp,fmt,'s'); break;
|
||||
case 'm': {
|
||||
emitDispState.pushFormat("%s");
|
||||
emitDispState.pushArg(NULL, "vlSymsp->name(");
|
||||
if (!nodep->scopeNamep()) nodep->v3fatalSrc("Display with %m but no AstScopeName");
|
||||
for (AstText* textp=nodep->scopeNamep()->scopeAttrp(); textp; textp=textp->nextp()->castText()) {
|
||||
emitDispState.pushFormat(textp->text());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'u':
|
||||
case 'z':
|
||||
case 'l':
|
||||
case 'v':
|
||||
nodep->v3error("Unsupported: $display format code: %"<<pos[0]);
|
||||
break;
|
||||
default:
|
||||
nodep->v3error("Unknown $display format code: %"<<pos[0]);
|
||||
break;
|
||||
vfmt += pos[0];
|
||||
inPct = true; // Get more digits
|
||||
break;
|
||||
case '%':
|
||||
emitDispState.pushFormat("%%"); // We're printf'ing it, so need to quote the %
|
||||
break;
|
||||
// Special codes
|
||||
case '~': displayArg(nodep,&elistp,isScan, vfmt,'d'); break; // Signed decimal
|
||||
// Spec: h d o b c l
|
||||
case 'b': displayArg(nodep,&elistp,isScan, vfmt,'b'); break;
|
||||
case 'c': displayArg(nodep,&elistp,isScan, vfmt,'c'); break;
|
||||
case 't':
|
||||
case 'd': displayArg(nodep,&elistp,isScan, vfmt,'u'); break; // Unsigned decimal
|
||||
case 'o': displayArg(nodep,&elistp,isScan, vfmt,'o'); break;
|
||||
case 'h':
|
||||
case 'x': displayArg(nodep,&elistp,isScan, vfmt,'x'); break;
|
||||
case 's': displayArg(nodep,&elistp,isScan, vfmt,'s'); break;
|
||||
case 'm': {
|
||||
emitDispState.pushFormat("%S");
|
||||
emitDispState.pushArg(NULL, "vlSymsp->name()");
|
||||
if (!nodep->castDisplay()) nodep->v3fatalSrc("Non-Display with %m");
|
||||
AstScopeName* scopenamep = nodep->castDisplay()->scopeNamep();
|
||||
if (!scopenamep) nodep->v3fatalSrc("Display with %m but no AstScopeName");
|
||||
for (AstText* textp=scopenamep->scopeAttrp(); textp; textp=textp->nextp()->castText()) {
|
||||
emitDispState.pushFormat(textp->text());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'u':
|
||||
case 'z':
|
||||
case 'l':
|
||||
case 'v':
|
||||
nodep->v3error("Unsupported: $display format code: %"<<pos[0]);
|
||||
break;
|
||||
default:
|
||||
nodep->v3error("Unknown $display format code: %"<<pos[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (elistp != NULL) {
|
||||
nodep->v3error("Extra arguments for $display format\n");
|
||||
// expectFormat also checks this, and should have found it first, so internal
|
||||
elistp->v3error("Internal: Extra arguments for $display format\n");
|
||||
}
|
||||
if (nodep->addNewline()) emitDispState.pushFormat("\\n");
|
||||
displayEmit(nodep);
|
||||
displayEmit(nodep, isScan);
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
@@ -1680,7 +1734,7 @@ void EmitCImp::main(AstModule* modp, bool slow, bool fast) {
|
||||
}
|
||||
|
||||
emitImp (modp);
|
||||
|
||||
|
||||
for (AstNode* nodep=modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (AstCFunc* funcp = nodep->castCFunc()) {
|
||||
if (v3Global.opt.outputSplit() > 1 && splitSize()
|
||||
@@ -1741,7 +1795,7 @@ class EmitCTrace : EmitCStmts {
|
||||
puts("if (!Verilated::calcUnusedSigs()) vl_fatal(__FILE__,__LINE__,__FILE__,\"Turning on wave traces requires Verilated::traceEverOn(true) call before time 0.\");\n");
|
||||
puts("t->traceInitThis (vlSymsp, vcdp, code);\n");
|
||||
puts("}\n");
|
||||
|
||||
|
||||
puts("void "+topClassName()+"::traceFull(SpTraceVcd* vcdp, void* userthis, uint32_t code) {\n");
|
||||
puts("// Callback from vcd->dump()\n");
|
||||
puts(topClassName()+"* t=("+topClassName()+"*)userthis;\n");
|
||||
@@ -1911,7 +1965,7 @@ class EmitCTrace : EmitCStmts {
|
||||
}
|
||||
virtual void visit(AstCoverInc* nodep, AstNUser*) {
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
EmitCTrace(bool slow) {
|
||||
m_funcp = NULL;
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit C++ code for module tree
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
// $Id$ -*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit C++ for tree
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -24,10 +24,10 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
|
||||
#include "V3Global.h"
|
||||
#include "V3File.h"
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit C++ for tree
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -21,10 +20,10 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
|
||||
+5
-6
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit C++ for tree
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -21,10 +20,10 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
@@ -68,7 +67,7 @@ class EmitCSyms : EmitCBaseVisitor {
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
// Collect list of scopes
|
||||
nodep->iterateChildren(*this);
|
||||
|
||||
|
||||
// Sort m_scopes by scope name
|
||||
sort(m_scopes.begin(), m_scopes.end(), CmpName());
|
||||
// Output
|
||||
|
||||
+8
-9
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit Makefile
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -21,10 +20,10 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
@@ -79,16 +78,16 @@ public:
|
||||
of.puts("default: "+v3Global.opt.prefix()+"__ALL.a\n");
|
||||
}
|
||||
of.puts("\n# Constants...\n");
|
||||
of.puts("PERL = "+V3Options::getenvStr("PERL","perl")+"\n");
|
||||
of.puts("VERILATOR_ROOT = "+V3Options::getenvStr("VERILATOR_ROOT","")+"\n");
|
||||
of.puts("SYSTEMPERL = "+V3Options::getenvStr("SYSTEMPERL","")+"\n");
|
||||
of.puts("PERL = "+V3Options::getenvPERL()+"\n");
|
||||
of.puts("VERILATOR_ROOT = "+V3Options::getenvVERILATOR_ROOT()+"\n");
|
||||
of.puts("SYSTEMPERL = "+V3Options::getenvSYSTEMPERL()+"\n");
|
||||
|
||||
of.puts("\n# Switches...\n");
|
||||
of.puts(string("VM_SP = ")+(v3Global.opt.systemPerl()?"1":"0")+"\n");
|
||||
of.puts(string("VM_SC = ")+((v3Global.opt.systemC()&&!v3Global.opt.systemPerl())?"1":"0")+"\n");
|
||||
of.puts(string("VM_SP_OR_SC = ")+(v3Global.opt.systemC()?"1":"0")+"\n");
|
||||
of.puts(string("VM_PCLI = ")+(v3Global.opt.systemC()?"0":"1")+"\n");
|
||||
of.puts(string("VM_SC_TARGET_ARCH = ")+V3Options::getenvStr("SYSTEMC_ARCH","")+"\n");
|
||||
of.puts(string("VM_SC_TARGET_ARCH = ")+V3Options::getenvSYSTEMC_ARCH()+"\n");
|
||||
|
||||
of.puts("\n# Vars...\n");
|
||||
of.puts(string("VM_PREFIX = ")+v3Global.opt.prefix()+"\n");
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit Makefile
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+27
-11
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit Verilog from tree
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -21,10 +20,10 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <cmath>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
@@ -164,19 +163,30 @@ public:
|
||||
virtual void visit(AstCoverInc*, AstNUser*) {
|
||||
// N/A
|
||||
}
|
||||
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
||||
|
||||
void visitNodeDisplay(AstNode* nodep, AstNode* filep, const string& text, AstNode* exprsp) {
|
||||
putbs(nodep->verilogKwd());
|
||||
putbs(" (");
|
||||
if (nodep->filep()) { nodep->filep()->iterateAndNext(*this); putbs(","); }
|
||||
if (filep) { filep->iterateAndNext(*this); putbs(","); }
|
||||
puts("\"");
|
||||
ofp()->putsNoTracking(nodep->text());
|
||||
ofp()->putsNoTracking(text);
|
||||
puts("\"");
|
||||
for (AstNode* expp=nodep->exprsp(); expp; expp = expp->nextp()) {
|
||||
for (AstNode* expp=exprsp; expp; expp = expp->nextp()) {
|
||||
puts(",");
|
||||
expp->iterateAndNext(*this);
|
||||
}
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstDisplay* nodep, AstNUser*) {
|
||||
visitNodeDisplay(nodep, nodep->filep(), nodep->text(), nodep->exprsp());
|
||||
}
|
||||
virtual void visit(AstFScanF* nodep, AstNUser*) {
|
||||
visitNodeDisplay(nodep, nodep->filep(), nodep->text(), nodep->exprsp());
|
||||
}
|
||||
virtual void visit(AstSScanF* nodep, AstNUser*) {
|
||||
visitNodeDisplay(nodep, nodep->fromp(), nodep->text(), nodep->exprsp());
|
||||
}
|
||||
|
||||
virtual void visit(AstFOpen* nodep, AstNUser*) {
|
||||
putbs(nodep->verilogKwd());
|
||||
putbs(" (");
|
||||
@@ -193,6 +203,12 @@ public:
|
||||
if (nodep->filep()) nodep->filep()->iterateChildren(*this);
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstFFlush* nodep, AstNUser*) {
|
||||
putbs(nodep->verilogKwd());
|
||||
putbs(" (");
|
||||
if (nodep->filep()) nodep->filep()->iterateChildren(*this);
|
||||
puts(");\n");
|
||||
}
|
||||
virtual void visit(AstReadMem* nodep, AstNUser*) {
|
||||
putbs(nodep->verilogKwd());
|
||||
putbs(" (");
|
||||
@@ -368,12 +384,12 @@ public:
|
||||
// Terminals
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
puts(nodep->hiername());
|
||||
puts(nodep->varp()->name());
|
||||
puts(nodep->varp()->name());
|
||||
}
|
||||
virtual void visit(AstVarXRef* nodep, AstNUser*) {
|
||||
puts(nodep->dotted());
|
||||
puts(".");
|
||||
puts(nodep->varp()->name());
|
||||
puts(nodep->varp()->name());
|
||||
}
|
||||
virtual void visit(AstConst* nodep, AstNUser*) {
|
||||
puts(nodep->num().ascii(true,true));
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
//-*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Emit Verilog code for module tree
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+12
-10
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Error handling
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -19,9 +18,9 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <cstring>
|
||||
#include <set>
|
||||
#include "V3Error.h"
|
||||
#ifndef _V3ERROR_NO_GLOBAL_
|
||||
@@ -47,7 +46,7 @@ bool V3Error::s_pretendError[V3ErrorCode::MAX];
|
||||
struct v3errorIniter {
|
||||
v3errorIniter() { V3Error::init(); };
|
||||
};
|
||||
v3errorIniter v3errorInit;
|
||||
v3errorIniter v3errorInit;
|
||||
|
||||
//######################################################################
|
||||
// ErrorCode class functions
|
||||
@@ -203,7 +202,7 @@ void FileLine::deleteAllRemaining() {
|
||||
while (1) {
|
||||
FileLineCheckSet::iterator it=fileLineLeakChecks.begin();
|
||||
if (it==fileLineLeakChecks.end()) break;
|
||||
delete *it;
|
||||
delete *it;
|
||||
// Operator delete will remove the iterated object from the list.
|
||||
// Eventually the list will be empty and terminate the loop.
|
||||
}
|
||||
@@ -243,8 +242,8 @@ void V3Error::incWarnings() {
|
||||
|
||||
void V3Error::incErrors() {
|
||||
s_errCount++;
|
||||
if (errorCount() == MAX_ERRORS) { // Not >= as would otherwise recurse
|
||||
v3fatal ("Exiting due to too many errors encountered\n");
|
||||
if (errorCount() == v3Global.opt.errorLimit()) { // Not >= as would otherwise recurse
|
||||
v3fatal ("Exiting due to too many errors encountered; --error-limit="<<errorCount()<<endl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,6 +261,7 @@ void V3Error::abortIfWarnings() {
|
||||
|
||||
bool V3Error::isError(V3ErrorCode code) {
|
||||
if (code==V3ErrorCode::SUPPRESS) return false;
|
||||
else if (code==V3ErrorCode::INFO) return false;
|
||||
else if (code==V3ErrorCode::FATAL) return true;
|
||||
else if (code==V3ErrorCode::ERROR) return true;
|
||||
else if (code<V3ErrorCode::FIRST_WARN
|
||||
@@ -271,6 +271,7 @@ bool V3Error::isError(V3ErrorCode code) {
|
||||
|
||||
string V3Error::msgPrefix(V3ErrorCode code) {
|
||||
if (code==V3ErrorCode::SUPPRESS) return "-arning-suppressed: ";
|
||||
else if (code==V3ErrorCode::INFO) return "-Info: ";
|
||||
else if (code==V3ErrorCode::FATAL) return "%Error: ";
|
||||
else if (code==V3ErrorCode::ERROR) return "%Error: ";
|
||||
else if (isError(code)) return "%Error-"+(string)code.ascii()+": ";
|
||||
@@ -312,7 +313,8 @@ void V3Error::v3errorEnd (ostringstream& sstr) {
|
||||
if (sstr.str()[sstr.str().length()-1] != '\n') {
|
||||
cerr<<endl;
|
||||
}
|
||||
if (s_errorCode!=V3ErrorCode::SUPPRESS) {
|
||||
if (s_errorCode!=V3ErrorCode::SUPPRESS
|
||||
&& s_errorCode!=V3ErrorCode::INFO) {
|
||||
if (!s_describedEachWarn[s_errorCode]
|
||||
&& !s_pretendError[s_errorCode]) {
|
||||
s_describedEachWarn[s_errorCode] = true;
|
||||
|
||||
+13
-7
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Error handling
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -34,6 +34,7 @@ class V3ErrorCode {
|
||||
public:
|
||||
enum en {
|
||||
SUPPRESS, // Warning suppressed by user
|
||||
INFO, // General information out
|
||||
FATAL, // Kill the program
|
||||
ERROR, // General error out, can't suppress
|
||||
// Error codes:
|
||||
@@ -45,6 +46,7 @@ public:
|
||||
BLKANDNBLK, // Blocked and non-blocking assignments to same variable
|
||||
CASEINCOMPLETE, // Case statement has missing values
|
||||
CASEOVERLAP, // Case statements overlap
|
||||
CASEWITHX, // Case with X values
|
||||
CASEX, // Casex
|
||||
CMPCONST, // Comparison is constant due to limited range
|
||||
COMBDLY, // Combinatorial delayed assignment
|
||||
@@ -53,6 +55,7 @@ public:
|
||||
IMPLICIT, // Implicit wire
|
||||
IMPURE, // Impure function not being inlined
|
||||
MULTIDRIVEN, // Driven from multiple blocks
|
||||
REDEFMACRO, // Redefining existing define macro
|
||||
UNDRIVEN, // No drivers
|
||||
UNOPT, // Unoptimizable block
|
||||
UNOPTFLAT, // Unoptimizable block after flattening
|
||||
@@ -60,6 +63,7 @@ public:
|
||||
UNUSED, // No receivers
|
||||
VARHIDDEN, // Hiding variable
|
||||
WIDTH, // Width mismatch
|
||||
WIDTHCONCAT, // Unsized numbers/parameters in concatenations
|
||||
MAX
|
||||
// ***Add new elements below also***
|
||||
};
|
||||
@@ -72,15 +76,15 @@ public:
|
||||
const char* ascii() const {
|
||||
const char* names[] = {
|
||||
// Leading spaces indicate it can't be disabled.
|
||||
" SUPPRESS", " FATAL", " ERROR",
|
||||
" SUPPRESS", " INFO", " FATAL", " ERROR",
|
||||
"MULTITOP", "TASKNSVAR",
|
||||
" FIRST_WARN",
|
||||
"BLKANDNBLK",
|
||||
"CASEINCOMPLETE", "CASEOVERLAP", "CASEX", "CMPCONST",
|
||||
"CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CMPCONST",
|
||||
"COMBDLY", "STMTDLY", "GENCLK", "IMPLICIT", "IMPURE",
|
||||
"MULTIDRIVEN",
|
||||
"MULTIDRIVEN", "REDEFMACRO",
|
||||
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED",
|
||||
"VARHIDDEN", "WIDTH",
|
||||
"VARHIDDEN", "WIDTH", "WIDTHCONCAT",
|
||||
" MAX"
|
||||
};
|
||||
return names[m_e];
|
||||
@@ -92,7 +96,8 @@ public:
|
||||
bool pretendError() const { return ( m_e==BLKANDNBLK || m_e==IMPURE); };
|
||||
// Warnings that are lint only
|
||||
bool lintError() const { return ( m_e==CASEINCOMPLETE || m_e==CASEOVERLAP
|
||||
|| m_e==CASEX || m_e==CMPCONST
|
||||
|| m_e==CASEWITHX || m_e==CASEX
|
||||
|| m_e==CMPCONST
|
||||
|| m_e==IMPLICIT
|
||||
|| m_e==UNDRIVEN || m_e==UNSIGNED
|
||||
|| m_e==UNUSED || m_e==VARHIDDEN
|
||||
@@ -157,6 +162,7 @@ inline void v3errorEnd(ostringstream& sstr) { V3Error::v3errorEnd(sstr); }
|
||||
|
||||
// These allow errors using << operators: v3error("foo"<<"bar");
|
||||
// Careful, you can't put () around msg, as you would in most macro definitions
|
||||
#define v3info(msg) v3errorEnd(((V3Error::v3errorPrep(V3ErrorCode::INFO)<<msg),V3Error::v3errorStr()));
|
||||
#define v3fatal(msg) v3errorEnd(((V3Error::v3errorPrep(V3ErrorCode::FATAL)<<msg),V3Error::v3errorStr()));
|
||||
#define v3error(msg) v3errorEnd(((V3Error::v3errorPrep(V3ErrorCode::ERROR)<<msg),V3Error::v3errorStr()));
|
||||
#define v3warn(code,msg) v3errorEnd(((V3Error::v3errorPrep(V3ErrorCode::code)<<msg),V3Error::v3errorStr()));
|
||||
|
||||
+19
-20
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Add temporaries, such as for expand nodes
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -19,7 +18,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
// V3Expand's Transformations:
|
||||
//
|
||||
//
|
||||
// Each module:
|
||||
// Expand verilated.h macros into internal micro optimizations (RTL)
|
||||
// this will enable later optimizations.
|
||||
@@ -32,8 +31,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
|
||||
@@ -168,7 +167,7 @@ private:
|
||||
}
|
||||
return newp;
|
||||
}
|
||||
|
||||
|
||||
AstNode* newSelBitWord(AstNode* lsbp, int wordAdder) {
|
||||
// Return equation to get the VL_BITWORD of a constant or non-constant
|
||||
if (lsbp->castConst()) {
|
||||
@@ -355,7 +354,7 @@ private:
|
||||
AstNode* lowwordp = new AstWordSel (nodep->fromp()->fileline(),
|
||||
nodep->fromp()->cloneTree(true),
|
||||
newSelBitWord(nodep->lsbp(), 0));
|
||||
if (nodep->isQuad() && !lowwordp->isQuad()) lowwordp = new AstCast(nodep->fileline(), lowwordp, nodep);
|
||||
if (nodep->isQuad() && !lowwordp->isQuad()) lowwordp = new AstCast(nodep->fileline(), lowwordp, nodep);
|
||||
AstNode* lowp = new AstShiftR (nodep->fileline(),
|
||||
lowwordp,
|
||||
newSelBitBit(nodep->lsbp()),
|
||||
@@ -368,7 +367,7 @@ private:
|
||||
new AstWordSel (nodep->fromp()->fileline(),
|
||||
nodep->fromp()->cloneTree(true),
|
||||
newSelBitWord(nodep->lsbp(), 1));
|
||||
if (nodep->isQuad() && !midwordp->isQuad()) midwordp = new AstCast(nodep->fileline(), midwordp, nodep);
|
||||
if (nodep->isQuad() && !midwordp->isQuad()) midwordp = new AstCast(nodep->fileline(), midwordp, nodep);
|
||||
// If we're selecting bit zero, then all 32 bits in word 1 get shifted << by 32 bits
|
||||
// else we need to form the lower word, so we << by 31 or less
|
||||
// nbitsfromlow <= (lsb==0) ? 64-bitbit(lsb) : 32-bitbit(lsb)
|
||||
@@ -406,7 +405,7 @@ private:
|
||||
new AstWordSel (nodep->fromp()->fileline(),
|
||||
nodep->fromp()->cloneTree(true),
|
||||
newSelBitWord(nodep->lsbp(), 2));
|
||||
if (nodep->isQuad() && !hiwordp->isQuad()) hiwordp = new AstCast(nodep->fileline(), hiwordp, nodep);
|
||||
if (nodep->isQuad() && !hiwordp->isQuad()) hiwordp = new AstCast(nodep->fileline(), hiwordp, nodep);
|
||||
AstNode* himayp =
|
||||
new AstShiftL (nodep->fileline(),
|
||||
hiwordp,
|
||||
@@ -434,7 +433,7 @@ private:
|
||||
UINFO(8," SEL->SHIFT "<<nodep<<endl);
|
||||
AstNode* fromp = nodep->fromp()->unlinkFrBack();
|
||||
AstNode* lsbp = nodep->lsbp()->unlinkFrBack();
|
||||
if (nodep->isQuad() && !fromp->isQuad()) fromp = new AstCast(nodep->fileline(), fromp, nodep);
|
||||
if (nodep->isQuad() && !fromp->isQuad()) fromp = new AstCast(nodep->fileline(), fromp, nodep);
|
||||
AstNode* newp = new AstShiftR (nodep->fileline(),
|
||||
fromp,
|
||||
dropCondBound(lsbp),
|
||||
@@ -504,7 +503,7 @@ private:
|
||||
bool destwide = lhsp->fromp()->isWide();
|
||||
bool ones = nodep->rhsp()->isAllOnesV();
|
||||
if (lhsp->lsbp()->castConst()) {
|
||||
// The code should work without this constant test, but it won't
|
||||
// The code should work without this constant test, but it won't
|
||||
// constify as nicely as we'd like.
|
||||
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNode* destp = lhsp->fromp()->unlinkFrBack();
|
||||
@@ -592,7 +591,7 @@ private:
|
||||
// For wide destp, we can either form a equation for every destination word,
|
||||
// with the appropriate long equation of if it's being written or not.
|
||||
// Or, we can use a LHS variable arraysel with non-constant index to set the vector.
|
||||
// Doing the variable arraysel is better for globals and large arrays,
|
||||
// Doing the variable arraysel is better for globals and large arrays,
|
||||
// doing every word is better for temporaries and if we're setting most words
|
||||
// since it may result in better substitution optimizations later.
|
||||
// This results in so much code, we're better off leaving a function call.
|
||||
@@ -630,7 +629,7 @@ private:
|
||||
//newp->dumpTree(cout,"- new: ");
|
||||
insertBefore(nodep,newp);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -641,10 +640,10 @@ private:
|
||||
} else {
|
||||
UINFO(8," CONCAT "<<nodep<<endl);
|
||||
AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
|
||||
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
|
||||
AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
|
||||
int rhsshift = rhsp->widthMin();
|
||||
if (nodep->isQuad() && !lhsp->isQuad()) lhsp = new AstCast(nodep->fileline(), lhsp, nodep);
|
||||
if (nodep->isQuad() && !rhsp->isQuad()) rhsp = new AstCast(nodep->fileline(), rhsp, nodep);
|
||||
if (nodep->isQuad() && !lhsp->isQuad()) lhsp = new AstCast(nodep->fileline(), lhsp, nodep);
|
||||
if (nodep->isQuad() && !rhsp->isQuad()) rhsp = new AstCast(nodep->fileline(), rhsp, nodep);
|
||||
AstNode* newp = new AstOr (nodep->fileline(),
|
||||
new AstShiftL (nodep->fileline(),
|
||||
lhsp,
|
||||
@@ -657,7 +656,7 @@ private:
|
||||
}
|
||||
bool expandWide (AstNodeAssign* nodep, AstConcat* rhsp) {
|
||||
UINFO(8," Wordize ASSIGN(CONCAT) "<<nodep<<endl);
|
||||
// Lhs or Rhs may be word, long, or quad.
|
||||
// Lhs or Rhs may be word, long, or quad.
|
||||
// newAstWordSelClone nicely abstracts the difference.
|
||||
int rhsshift = rhsp->rhsp()->widthMin();
|
||||
// Sometimes doing the words backwards is preferrable.
|
||||
@@ -670,7 +669,7 @@ private:
|
||||
rhsp->lhsp(), rhsshift),
|
||||
newAstWordSelClone (rhsp->rhsp(), w)));
|
||||
}
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void visit(AstReplicate* nodep, AstNUser*) {
|
||||
@@ -690,7 +689,7 @@ private:
|
||||
AstConst* constp = nodep->rhsp()->castConst();
|
||||
if (!constp) nodep->v3fatalSrc("Replication value isn't a constant. Checked earlier!");
|
||||
uint32_t times = constp->asInt();
|
||||
if (nodep->isQuad() && !lhsp->isQuad()) lhsp = new AstCast(nodep->fileline(), lhsp, nodep);
|
||||
if (nodep->isQuad() && !lhsp->isQuad()) lhsp = new AstCast(nodep->fileline(), lhsp, nodep);
|
||||
newp = lhsp->cloneTree(true);
|
||||
for (unsigned repnum=1; repnum<times; repnum++) {
|
||||
int rhsshift = repnum*lhswidth;
|
||||
@@ -731,7 +730,7 @@ private:
|
||||
}
|
||||
addWordAssign(nodep, w, newp);
|
||||
}
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void visit(AstChangeXor* nodep, AstNUser*) {
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Expansion of wide operator macros to C operators
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+5
-5
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: File stream wrapper that understands indentation
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -21,7 +20,7 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdarg.h>
|
||||
#include <cstdarg>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
@@ -245,8 +244,9 @@ void V3File::createMakeDir() {
|
||||
// V3OutFile: A class for printing to a file, with automatic indentation of C++ code.
|
||||
|
||||
V3OutFile::V3OutFile(const string& filename)
|
||||
: m_lineno(1), m_column(0), m_nobreak(false), m_prependIndent(true), m_indentLevel(0)
|
||||
, m_declSAlign(0), m_declNSAlign(0), m_declPadNum(0) {
|
||||
: m_filename(filename), m_lineno(1), m_column(0)
|
||||
, m_nobreak(false), m_prependIndent(true), m_indentLevel(0)
|
||||
, m_declSAlign(0), m_declNSAlign(0), m_declPadNum(0) {
|
||||
if ((m_fp = V3File::new_fopen_w(filename.c_str())) == NULL) {
|
||||
v3fatal("Cannot write "<<filename);
|
||||
}
|
||||
|
||||
+7
-5
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: File stream wrapper that understands indentation
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -24,7 +24,7 @@
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include "V3Error.h"
|
||||
#include <stdio.h>
|
||||
#include <cstdio>
|
||||
#include <stack>
|
||||
#include <set>
|
||||
#include <fstream>
|
||||
@@ -87,6 +87,7 @@ public:
|
||||
private:
|
||||
// MEMBERS
|
||||
FILE* m_fp;
|
||||
string m_filename;
|
||||
int m_lineno;
|
||||
int m_column;
|
||||
int m_nobreak; // Basic operator or begin paren, don't break next
|
||||
@@ -120,8 +121,9 @@ public:
|
||||
bool tokenStart(const char* cp, const char* cmp);
|
||||
bool tokenEnd(const char* cp);
|
||||
void indentInc() { m_indentLevel += INDBLK; };
|
||||
void indentDec() { m_indentLevel -= INDBLK;
|
||||
UASSERT(m_indentLevel>=0,"Underflow of indentation\n");
|
||||
void indentDec() {
|
||||
m_indentLevel -= INDBLK;
|
||||
UASSERT(m_indentLevel>=0, ": "<<m_filename<<": Underflow of indentation\n");
|
||||
}
|
||||
void blockInc() { m_parenVec.push(m_indentLevel + INDBLK); }
|
||||
void blockDec() { if (!m_parenVec.empty()) m_parenVec.pop(); }
|
||||
|
||||
+7
-8
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Gate optimizations, such as wire elimination
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -19,7 +18,7 @@
|
||||
//
|
||||
//*************************************************************************
|
||||
// V3Gate's Transformations:
|
||||
//
|
||||
//
|
||||
// Extract a graph of the *entire* netlist with cells expanded
|
||||
// Perform constant optimization across the graph
|
||||
// Create VARSCOPEs for any variables we can rip out
|
||||
@@ -28,8 +27,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
#include <iomanip>
|
||||
@@ -170,7 +169,7 @@ private:
|
||||
// V3Const cleans up any NOTs by flipping the edges for us
|
||||
if (m_buffersOnly
|
||||
&& !(nodep->rhsp()->castVarRef()
|
||||
// Until NEW_ORDERING, avoid making non-clocked logic into clocked,
|
||||
// Until NEW_ORDERING, avoid making non-clocked logic into clocked,
|
||||
// as it slows down the verilator_sim_benchmark
|
||||
|| (nodep->rhsp()->castNot()
|
||||
&& nodep->rhsp()->castNot()->lhsp()->castVarRef()
|
||||
@@ -343,7 +342,7 @@ private:
|
||||
UINFO(5," VARREF to "<<varscp<<endl);
|
||||
// We use weight of one; if we ref the var more than once, when we simplify,
|
||||
// the weight will increase
|
||||
if (nodep->lvalue()) {
|
||||
if (nodep->lvalue()) {
|
||||
new V3GraphEdge(&m_graph, m_logicVertexp, varvertexp, 1);
|
||||
} else {
|
||||
new V3GraphEdge(&m_graph, varvertexp, m_logicVertexp, 1);
|
||||
@@ -490,7 +489,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
|
||||
if (debug()>=5) substp->dumpTree(cout,"\t subst: ");
|
||||
m_statSigs++;
|
||||
while (V3GraphEdge* edgep = vvertexp->outBeginp()) {
|
||||
GateLogicVertex* consumeVertexp = dynamic_cast<GateLogicVertex*>(edgep->top());
|
||||
GateLogicVertex* consumeVertexp = dynamic_cast<GateLogicVertex*>(edgep->top());
|
||||
AstNode* consumerp = consumeVertexp->nodep();
|
||||
optimizeElimVar(vvertexp->varScp(), substp, consumerp);
|
||||
// If the new replacement referred to a signal,
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Break always into sensitivity block domains
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+6
-7
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Generated Clock repairs
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -21,13 +20,13 @@
|
||||
// GENCLK TRANSFORMATIONS:
|
||||
// Follow control-flow graph with assignments and var usages
|
||||
// ASSIGNDLY to variable later used as clock requires change detect
|
||||
//
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "V3Global.h"
|
||||
@@ -93,7 +92,7 @@ private:
|
||||
}
|
||||
//----
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
// Consumption/generation of a variable,
|
||||
// Consumption/generation of a variable,
|
||||
AstVarScope* vscp = nodep->varScopep();
|
||||
if (!vscp) nodep->v3fatalSrc("Scope not assigned");
|
||||
if (m_activep && !nodep->user3()) {
|
||||
@@ -172,7 +171,7 @@ private:
|
||||
//----
|
||||
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
// Consumption/generation of a variable,
|
||||
// Consumption/generation of a variable,
|
||||
AstVarScope* vscp = nodep->varScopep();
|
||||
if (!vscp) nodep->v3fatalSrc("Scope not assigned");
|
||||
if (m_activep) {
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
//-*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Generated Clock Repairs
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Common headers
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
// $Id$
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Graph optimizations
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -21,8 +21,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
@@ -106,7 +106,7 @@ ostream& operator<<(ostream& os, V3GraphVertex* vertexp) {
|
||||
//######################################################################
|
||||
// Edges
|
||||
|
||||
V3GraphEdge::V3GraphEdge(V3Graph* graphp,
|
||||
V3GraphEdge::V3GraphEdge(V3Graph* graphp,
|
||||
V3GraphVertex* fromp, V3GraphVertex* top, int weight,
|
||||
bool cutable) {
|
||||
UASSERT(fromp, "Null from pointer\n");
|
||||
|
||||
+3
-3
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
//-*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Graph optimizations
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
virtual ~V3Graph();
|
||||
static void debug(int level) { s_debug = level; }
|
||||
virtual string dotRankDir() { return "TB"; } // rankdir for dot plotting
|
||||
|
||||
|
||||
// METHODS
|
||||
void clear(); // Empty it of all vertices/edges, as if making a new object
|
||||
|
||||
|
||||
+3
-4
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Graph acyclic algorithm
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -21,8 +20,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
+4
-5
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Graph optimizations
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -21,8 +20,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
@@ -345,7 +344,7 @@ private:
|
||||
if (m_done) return;
|
||||
|
||||
m_callTrace.reserve(currentRank+10); // Leave slop for speed
|
||||
m_callTrace[currentRank++] = vertexp;
|
||||
m_callTrace[currentRank++] = vertexp;
|
||||
|
||||
if (vertexp->user() == 1) {
|
||||
for (unsigned i=0; i<currentRank; i++) {
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Graph algorithm base class
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
|
||||
+104
-11
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Graph optimizations
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -21,8 +20,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <stack>
|
||||
#include <map>
|
||||
@@ -224,7 +223,7 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void main() {
|
||||
UINFO(5,"Dfa to Nfa conversion...\n");
|
||||
// Vertex::color() begin: 1 indicates vertex on DFA graph, 0=NFA graph
|
||||
@@ -236,7 +235,7 @@ private:
|
||||
|
||||
// Find NFA start
|
||||
DfaVertex* nfaStartp = graphp()->findStart();
|
||||
|
||||
|
||||
// Create new DFA State (start state) from the NFA states
|
||||
DfaVertex* dfaStartp = newDfaVertex(nfaStartp);
|
||||
|
||||
@@ -267,7 +266,7 @@ private:
|
||||
}
|
||||
}
|
||||
if (debug()>=6) m_graphp->dumpDotFilePrefixed("dfa_start");
|
||||
insertDfaOrigins(dfaStartp);
|
||||
insertDfaOrigins(dfaStartp);
|
||||
|
||||
int i=0;
|
||||
UINFO(5,"Main state conversion...\n");
|
||||
@@ -293,7 +292,7 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Foreach input state (NFA inputs of this DFA state)
|
||||
for (set<DfaInput>::const_iterator inIt=inputs.begin(); inIt!=inputs.end(); ++inIt) {
|
||||
DfaInput input = *inIt;
|
||||
@@ -303,7 +302,7 @@ private:
|
||||
// Find all states reachable for given input
|
||||
DfaStates nfasWithInput;
|
||||
findNfasWithInput(dfaStatep, input, nfasWithInput/*ref*/);
|
||||
|
||||
|
||||
// nfasWithInput now maps to the DFA we want a transition to.
|
||||
// Does a DFA already exist with this, and only this subset of NFA's?
|
||||
DfaVertex* toDfaStatep = findDfaOrigins(nfasWithInput);
|
||||
@@ -317,7 +316,7 @@ private:
|
||||
new DfaEdge (graphp(), toDfaStatep, *nfaIt, DfaEdge::NA());
|
||||
if ((*nfaIt)->accepting()) toDfaStatep->accepting(true);
|
||||
}
|
||||
insertDfaOrigins(toDfaStatep);
|
||||
insertDfaOrigins(toDfaStatep);
|
||||
}
|
||||
// Add input transition
|
||||
new DfaEdge (graphp(), dfaStatep, toDfaStatep, input);
|
||||
@@ -375,7 +374,7 @@ private:
|
||||
}
|
||||
|
||||
void optimize_accepting_out() {
|
||||
// Delete outbound edges from accepting states
|
||||
// Delete outbound edges from accepting states
|
||||
// (As once we've accepted, we no longer care about anything else.)
|
||||
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
|
||||
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
|
||||
@@ -480,3 +479,97 @@ public:
|
||||
void DfaGraph::dfaReduce() {
|
||||
DfaGraphReduce (this, &V3GraphEdge::followAlwaysTrue);
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
//######################################################################
|
||||
// Algorithms - complement a DFA
|
||||
//
|
||||
// The traditional algorithm is to make a rejecting state, add edges to
|
||||
// reject from all missing values, then swap accept and reject. Rather
|
||||
// than swap at the end, it's faster if we swap up front, then do the edge
|
||||
// changes.
|
||||
//
|
||||
// 1. Since we didn't log rejecting states, make a temp state (this will be
|
||||
// the old accept, and new reject).
|
||||
//
|
||||
// 2. All vertexes except start/accept get edges to NEW accept for any
|
||||
// non-existing case. Weedely we don't have a nice way of representing
|
||||
// this so we just create a edge for each case and mark it "complemented."
|
||||
//
|
||||
// 3. Delete temp vertex (old accept/new reject) and related edges.
|
||||
// The user's old accept is now the new accept. This is imporant as
|
||||
// we want the virtual type of it to be intact.
|
||||
|
||||
class DfaGraphComplement : GraphAlg {
|
||||
private:
|
||||
// MEMBERS
|
||||
DfaVertex* m_tempNewerReject;
|
||||
|
||||
// METHODS
|
||||
int debug() { return 9; }
|
||||
DfaGraph* graphp() { return static_cast<DfaGraph*>(m_graphp); }
|
||||
|
||||
void add_complement_edges() {
|
||||
// Find accepting vertex
|
||||
DfaVertex* acceptp = NULL;
|
||||
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
|
||||
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
|
||||
if (vvertexp->accepting()) {
|
||||
acceptp = vvertexp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!acceptp) v3fatalSrc("No accepting vertex in DFA\n");
|
||||
|
||||
// Remap edges
|
||||
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
|
||||
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
|
||||
//UINFO(9, " on vertex "<<vvertexp->name()<<endl);
|
||||
if (!vvertexp->accepting() && vvertexp != m_tempNewerReject) {
|
||||
for (V3GraphEdge* nextp, *edgep = vertexp->outBeginp(); edgep; edgep=nextp) {
|
||||
nextp = edgep->outNextp();
|
||||
if (!edgep->user()) { // Not processed
|
||||
// Old edges to accept now go to new reject
|
||||
DfaEdge* vedgep = static_cast<DfaEdge*>(edgep);
|
||||
DfaVertex* tovertexp = static_cast<DfaVertex*>(edgep->top());
|
||||
if (tovertexp->accepting()) {
|
||||
new DfaEdge(graphp(), vvertexp, m_tempNewerReject, vedgep);
|
||||
edgep->unlinkDelete(); edgep=NULL;
|
||||
}
|
||||
|
||||
// NOT of all values goes to accept
|
||||
// We make a edge for each value to OR, IE
|
||||
// edge(complemented,a) edge(complemented,b) means !(a | b)
|
||||
if (!tovertexp->accepting()) { // Note we must include edges moved above to reject
|
||||
DfaEdge* newp = new DfaEdge (graphp(), vvertexp, acceptp, vedgep);
|
||||
newp->complement(!newp->complement());
|
||||
newp->user(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
DfaGraphComplement(V3Graph* dfagraphp, V3EdgeFuncP edgeFuncp)
|
||||
: GraphAlg(dfagraphp, edgeFuncp) {
|
||||
if (debug()>=6) m_graphp->dumpDotFilePrefixed("comp_in");
|
||||
|
||||
// Vertex::m_user begin: 1 indicates new edge, no more processing
|
||||
m_graphp->userClearEdges();
|
||||
|
||||
m_tempNewerReject = new DfaVertex(graphp());
|
||||
add_complement_edges();
|
||||
if (debug()>=6) m_graphp->dumpDotFilePrefixed("comp_preswap");
|
||||
|
||||
m_tempNewerReject->unlinkDelete(graphp()); m_tempNewerReject=NULL;
|
||||
if (debug()>=6) m_graphp->dumpDotFilePrefixed("comp_out");
|
||||
}
|
||||
~DfaGraphComplement() {}
|
||||
};
|
||||
|
||||
void DfaGraph::dfaComplement() {
|
||||
DfaGraphComplement (this, &V3GraphEdge::followAlwaysTrue);
|
||||
}
|
||||
|
||||
+29
-11
@@ -1,8 +1,8 @@
|
||||
// $Id$ //-*- C++ -*-
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Graph automata base class
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -43,16 +43,18 @@ class DfaEdge;
|
||||
/// or epsilon, represented as a empty list of inputs.
|
||||
///
|
||||
/// We're only looking for matches, so the only accepting states are
|
||||
/// at the end of the transformations.
|
||||
///
|
||||
/// at the end of the transformations. (If we want the complement, we
|
||||
/// call complement and the algorithm makes a REJECT state, then flips
|
||||
/// accept and reject for you.)
|
||||
///
|
||||
/// Common transforms:
|
||||
///
|
||||
/// "*": DfaVertex(START) --> [epsilon] -->DfaVertex(ACCEPT)
|
||||
///
|
||||
/// "L": ...->[ON_L]-->DfaVtx-->[epsilon]-->DfaVtx(ACCEPT)
|
||||
///
|
||||
/// "LR": ...->[ON_L]-->DfaVtx-->[epsilon]-->DfaVtx()
|
||||
/// ->[ON_R]-->DfaVtx-->[epsilon]-->DfaVtx(ACCEPT)
|
||||
/// "LR": ...->[ON_L]-->DfaVtx-->[epsilon]-->DfaVtx(ACCEPT)
|
||||
/// ->[ON_R]-->DfaVtx-->[epsilon]-/
|
||||
///
|
||||
/// "L|R": ...->DfaVtx-->[epsilon]-->DfaVtx-->[ON_L]-->DfaVtx()->[epsilon]-->DfaVtx(ACCEPT)
|
||||
/// \->[epsilon]-->DfaVtx-->[ON_R]-->DfaVtx()->[epsilon]-/
|
||||
@@ -76,13 +78,16 @@ public:
|
||||
|
||||
/// Simplify a DFA automata
|
||||
void dfaReduce();
|
||||
|
||||
/// Complement result (must already be dfa)
|
||||
void dfaComplement();
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// Vertex
|
||||
|
||||
class DfaVertex : public V3GraphVertex {
|
||||
// Each DFA state is captured in this vertex.
|
||||
// Each DFA state is captured in this vertex.
|
||||
// Start and accepting are members, rather than the more intuitive
|
||||
// subclasses, as subclassing them would make it harder to inherit from here.
|
||||
bool m_start; // Start state
|
||||
@@ -93,7 +98,7 @@ public:
|
||||
: V3GraphVertex(graphp)
|
||||
, m_start(start), m_accepting(accepting) {}
|
||||
virtual DfaVertex* clone(DfaGraph* graphp) {
|
||||
return new DfaVertex(graphp, start(), accepting()); }
|
||||
return new DfaVertex(graphp, start(), accepting()); }
|
||||
virtual ~DfaVertex() {}
|
||||
// ACCESSORS
|
||||
virtual string dotShape() const { return (accepting()?"doublecircle":""); }
|
||||
@@ -113,20 +118,33 @@ typedef AstNUser* DfaInput;
|
||||
|
||||
class DfaEdge : public V3GraphEdge {
|
||||
DfaInput m_input;
|
||||
bool m_complement; // Invert value when doing compare
|
||||
public:
|
||||
static DfaInput EPSILON() { return NULL; }
|
||||
static DfaInput NA() { return AstNUser::fromInt(1); } // as in not-applicable
|
||||
// CONSTRUCTORS
|
||||
DfaEdge(DfaGraph* graphp, DfaVertex* fromp, DfaVertex* top, DfaInput input)
|
||||
: V3GraphEdge(graphp, fromp, top, 1)
|
||||
, m_input(input) {}
|
||||
, m_input(input), m_complement(false) {}
|
||||
DfaEdge(DfaGraph* graphp, DfaVertex* fromp, DfaVertex* top, const DfaEdge* copyfrom)
|
||||
: V3GraphEdge(graphp, fromp, top, copyfrom->weight())
|
||||
, m_input(copyfrom->input()), m_complement(copyfrom->complement()) {}
|
||||
virtual ~DfaEdge() {}
|
||||
// METHODS
|
||||
virtual string dotColor() const { return na()?"yellow":epsilon()?"green":"black"; }
|
||||
virtual string dotLabel() const { return na()?"":epsilon()?"e":cvtToStr((void*)(input())); }
|
||||
virtual string dotColor() const {
|
||||
return (na() ? "yellow"
|
||||
: epsilon() ? "green"
|
||||
: "black"); }
|
||||
virtual string dotLabel() const {
|
||||
return (na() ? ""
|
||||
: epsilon() ? "e"
|
||||
: complement() ? ("not "+cvtToStr((void*)(input())))
|
||||
: cvtToStr((void*)(input()))); }
|
||||
virtual string dotStyle() const { return (na()||cutable())?"dashed":""; }
|
||||
bool epsilon() const { return input()==EPSILON(); }
|
||||
bool na() const { return input()==NA(); }
|
||||
bool complement() const { return m_complement; }
|
||||
void complement(bool value) { m_complement=value; }
|
||||
DfaInput input() const { return m_input; }
|
||||
};
|
||||
|
||||
|
||||
+27
-22
@@ -1,8 +1,7 @@
|
||||
// $Id$
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Graph tests
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
// AUTHORS: Wilson Snyder with Paul Wasson, Duane Gabli
|
||||
//
|
||||
@@ -21,8 +20,8 @@
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "V3Global.h"
|
||||
@@ -112,7 +111,7 @@ public:
|
||||
new V3GraphEdge(gp, g1, q, 2, true);
|
||||
new V3GraphEdge(gp, g2, q, 2, true);
|
||||
new V3GraphEdge(gp, g3, q, 2, true);
|
||||
|
||||
|
||||
gp->stronglyConnected(&V3GraphEdge::followAlwaysTrue);
|
||||
dump();
|
||||
|
||||
@@ -143,7 +142,7 @@ public:
|
||||
new V3GraphEdge(gp, g1, a, 2, true);
|
||||
new V3GraphEdge(gp, g2, a, 2, true);
|
||||
new V3GraphEdge(gp, g3, a, 2, true);
|
||||
|
||||
|
||||
gp->acyclic(&V3GraphEdge::followAlwaysTrue);
|
||||
gp->order();
|
||||
dump();
|
||||
@@ -157,7 +156,7 @@ public:
|
||||
V3Graph* gp = &m_graph;
|
||||
|
||||
V3GraphTestVertex* clk = new V3GraphTestVarVertex(gp,"$clk");
|
||||
|
||||
|
||||
V3GraphTestVertex* a = new V3GraphTestVarVertex(gp,"$a");
|
||||
V3GraphTestVertex* a_dly = new V3GraphTestVarVertex(gp,"$a_dly");
|
||||
V3GraphTestVertex* a_dlyblk= new V3GraphTestVarVertex(gp,"$a_dlyblk");
|
||||
@@ -166,13 +165,13 @@ public:
|
||||
V3GraphTestVertex* b_dlyblk= new V3GraphTestVarVertex(gp,"$b_dlyblk");
|
||||
V3GraphTestVertex* c = new V3GraphTestVarVertex(gp,"$c");
|
||||
V3GraphTestVertex* i = new V3GraphTestVarVertex(gp,"$i");
|
||||
|
||||
|
||||
V3GraphTestVertex* ap = new V3GraphTestVarVertex(gp,"$a_pre");
|
||||
V3GraphTestVertex* bp = new V3GraphTestVarVertex(gp,"$b_pre");
|
||||
V3GraphTestVertex* cp = new V3GraphTestVarVertex(gp,"$c_pre");
|
||||
|
||||
|
||||
V3GraphTestVertex* n;
|
||||
|
||||
|
||||
// Logical order between clk, and posedge blocks
|
||||
// implemented by special CLK prod/cons?
|
||||
// Required order between first x_DLY<=x_pre and final x<=x_DLY
|
||||
@@ -183,23 +182,23 @@ public:
|
||||
// implemented by producer/consumer on a_dly signals
|
||||
// Desired order between different _DLY blocks so we can elim temporaries
|
||||
// implemented by cutable "pre" signal dependencies
|
||||
|
||||
|
||||
|
||||
|
||||
n = new V3GraphTestVertex(gp,"*INPUTS*"); {
|
||||
new V3GraphEdge(gp, n, clk, 2);
|
||||
new V3GraphEdge(gp, n, i, 2);
|
||||
}
|
||||
|
||||
|
||||
V3GraphTestVertex* posedge = n = new V3GraphTestVertex(gp,"*posedge clk*"); {
|
||||
new V3GraphEdge(gp, clk, n, 2);
|
||||
}
|
||||
|
||||
|
||||
// AssignPre's VarRefs on LHS: generate special BLK
|
||||
// normal: VarRefs on LHS: generate normal
|
||||
// underSBlock: VarRefs on RHS: consume 'pre' (required to save cutable tests)
|
||||
n = new V3GraphTestVertex(gp,"a_dly<PRE=a"); {
|
||||
new V3GraphEdge(gp, n, a_dlyblk, 2); // Block ordering
|
||||
new V3GraphEdge(gp, n, a_dly, 2);
|
||||
new V3GraphEdge(gp, n, a_dly, 2);
|
||||
new V3GraphEdge(gp, ap, n, 2, true); // DESIRED delayed ordering (inp is required)
|
||||
new V3GraphEdge(gp, posedge, n, 2);
|
||||
}
|
||||
@@ -209,7 +208,7 @@ public:
|
||||
new V3GraphEdge(gp, bp, n, 2, true); // DESIRED delayed ordering
|
||||
new V3GraphEdge(gp, posedge, n, 2);
|
||||
}
|
||||
|
||||
|
||||
// AssignDly's VarRefs on LHS: consume special BLK
|
||||
// normal: VarRefs on LHS: generate normal
|
||||
// underSBlock: VarRefs on RHS: generate 'pre' signals (cutable)
|
||||
@@ -228,7 +227,7 @@ public:
|
||||
new V3GraphEdge(gp, n, ap, 2); // DESIRED delayed usage
|
||||
new V3GraphEdge(gp, posedge, n, 2);
|
||||
}
|
||||
|
||||
|
||||
// AssignPost's
|
||||
// normal: VarRefs on LHS: generate normal
|
||||
// underSBlock: VarRefs on RHS: consume normal
|
||||
@@ -242,11 +241,11 @@ public:
|
||||
new V3GraphEdge(gp, b_dly, n, 3);
|
||||
new V3GraphEdge(gp, posedge, n, 2);
|
||||
}
|
||||
|
||||
|
||||
// COMBO
|
||||
// Inbound edges are always uncutable, because we must put combo logic after sequential
|
||||
// Outbound are cutable, as we may need to evaluate multiple times
|
||||
|
||||
|
||||
{
|
||||
V3GraphTestVertex* n = new V3GraphTestVertex(gp,"c=a|b|i");
|
||||
new V3GraphEdge(gp, n, c, 1, true);
|
||||
@@ -254,7 +253,7 @@ public:
|
||||
new V3GraphEdge(gp, b, n, 1, false);
|
||||
new V3GraphEdge(gp, i, n, 1, false);
|
||||
}
|
||||
|
||||
|
||||
gp->acyclic(&V3GraphEdge::followAlwaysTrue);
|
||||
gp->order();
|
||||
|
||||
@@ -288,7 +287,7 @@ public:
|
||||
DfaTestVertex* sr = new DfaTestVertex(gp,"sR");
|
||||
DfaTestVertex* sz = new DfaTestVertex(gp,"sZ");
|
||||
DfaTestVertex* sac = new DfaTestVertex(gp,"*ACCEPT*"); sac->accepting(true);
|
||||
|
||||
|
||||
AstNUser* L = AstNUser::fromInt(0xaa);
|
||||
AstNUser* R = AstNUser::fromInt(0xbb);
|
||||
AstNUser* Z = AstNUser::fromInt(0xcc);
|
||||
@@ -309,6 +308,12 @@ public:
|
||||
gp->nfaToDfa();
|
||||
dump();
|
||||
gp->dfaReduce();
|
||||
dump();
|
||||
|
||||
gp->dfaComplement();
|
||||
dump();
|
||||
gp->dfaReduce();
|
||||
dump();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -334,7 +339,7 @@ public:
|
||||
|
||||
#if 0
|
||||
# include "graph_export.cpp"
|
||||
#else
|
||||
#else
|
||||
void V3GraphTestImport::dotImport() {
|
||||
}
|
||||
#endif
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user