Compare commits

...
57 Commits
Author SHA1 Message Date
Wilson Snyder 4100f20a69 Version bump 2011-11-27 10:37:23 -05:00
Wilson Snyder bedf946fb2 Support V-AMS wreal 2011-11-27 10:31:06 -05:00
Wilson Snyder b9e67157c6 With "--language VAMS" support a touch of Verilog AMS. 2011-11-25 00:49:38 -05:00
Wilson Snyder b30b2a183b Support . 2011-11-20 02:01:48 -05:00
Wilson Snyder 9ab3bcdde3 Support with %g. 2011-11-20 01:01:02 -05:00
Wilson Snyder 5df3bbe188 Fix $display with %d following %g. 2011-11-20 00:45:59 -05:00
Wilson Snyder 8cf12416c0 Commentary 2011-11-18 13:33:31 -05:00
Wilson Snyder b7c2c83c88 Fix bad result with if-else-return optimization, bug420. 2011-11-12 08:07:30 -05:00
Wilson Snyder 3b6da93331 Reuse goto labels inside functions, bug420a 2011-11-10 19:13:32 -05:00
Wilson Snyder b4642d3fd4 Show examples with timestamps as 64 bits 2011-11-06 11:54:17 -05:00
Wilson Snyder 88a2b0b911 Support constants in sensitivity lists, bug412. 2011-11-02 18:34:17 -04:00
Wilson Snyder 954e127f1d Commentary: Report children node types 2011-11-01 19:33:11 -04:00
Wilson Snyder 7654add5e5 Indicate 'exiting due to errors' if errors, not warnings. 2011-10-31 21:39:15 -04:00
Wilson Snyder 85a37ea53f Search for user -y paths before default current directory. 2011-10-28 18:57:40 -04:00
Wilson Snyder b337acebcc When multiple tops, show example 2011-10-28 18:19:04 -04:00
Wilson Snyder fb9ca54c95 Fix reporting not found modules if generate-off, bug403. 2011-10-27 20:56:38 -04:00
Wilson Snyder 1a15d41523 Support jumps in program modules 2011-10-27 19:13:24 -04:00
Wilson Snyder e378cc5791 Add sc_bv attribute to force bit vectors, bug402. 2011-10-26 08:57:27 -04:00
Wilson Snyder 748c189c79 Devel version 2011-10-25 19:11:45 -04:00
Wilson Snyder b89be6c4b9 Version bump 2011-10-25 18:59:40 -04:00
Wilson Snyder df207807b6 Add ASSIGNIN as suppressable error. 2011-10-25 18:57:49 -04:00
Wilson Snyder 1f2b40cff1 Fix 3.823 constructor core dump on Debian, bug401. 2011-10-25 18:41:04 -04:00
Wilson Snyder 734400fd37 Fix version number mistake 2011-10-25 18:11:06 -04:00
Wilson Snyder f19979d928 Fix "always @ (* )", bug403, bug404. 2011-10-25 18:08:24 -04:00
Wilson Snyder 19be7a53da List unsupported on delays 2011-10-21 07:13:38 -04:00
Wilson Snyder e56af34fb0 Post release 2011-10-20 21:18:16 -04:00
Wilson Snyder 7737aa20e8 Version bump 2011-10-20 21:13:42 -04:00
Wilson Snyder ead046201c Fix make info tex warning 2011-10-20 21:13:33 -04:00
Wilson Snyder 0aa7c3f659 Add -Wall reporting ASSIGNDLY on assignment delays. 2011-10-20 20:50:42 -04:00
Wilson Snyder 4aa7222022 tests: use verilator_flags and skip more widely 2011-10-12 23:03:53 -04:00
Wilson Snyder 86e3c78776 configure: Test for compiler flags, and remove old config checks 2011-10-12 19:04:57 -04:00
Wilson Snyder 40076287ea Internals: In .tree files show filename as letter 2011-10-11 07:17:39 -04:00
Wilson Snyder ca81db8edf Remove dead node types; make report of node usage. No functional change 2011-10-10 18:13:42 -04:00
Wilson Snyder ae68a80e98 Fix fflush 2011-10-10 18:13:17 -04:00
Wilson Snyder beb7c58375 Fix DPI import false BLKSEQ warnings. 2011-10-07 20:04:15 -04:00
Wilson Snyder e080b9d565 Fix DPI import output of 64 bits, bug398. 2011-10-07 19:47:10 -04:00
Wilson Snyder ca2db37039 Fix UNDRIVEN warnings inside DPI import functions. 2011-10-07 08:29:34 -04:00
Wilson Snyder 194825f78e Add configure options for cc warnings and extended tests. 2011-10-07 06:48:40 -04:00
Wilson Snyder 55bd765ea0 Find config_rev when under git in remote config dir 2011-10-05 18:36:44 -04:00
Wilson Snyder b03d61e2cf Use EXEEXT to fix make warning 2011-10-05 17:07:10 -04:00
Wilson Snyder 6fc0e5167b Commentary 2011-10-05 17:06:08 -04:00
Wilson Snyder 0065be011f Fix errors when building from git outside of kit directory 2011-10-05 10:47:05 -04:00
Wilson Snyder 3f7cbce58c Move version to configure.ac 2011-10-05 09:50:14 -04:00
Wilson Snyder 246b62e322 Tests: Add runtime 2011-10-05 09:50:00 -04:00
Wilson Snyder 7c2fdd1ee9 Fix --help output to go to stderr, not stdout, bug397. 2011-10-04 10:08:16 -04:00
Wilson Snyder f77aa2623c Fix autoconf suggestions 2011-10-04 10:07:46 -04:00
Wilson Snyder 20847a3ff5 Fix autoconf warnings, bug396. 2011-10-04 08:48:37 -04:00
Wilson Snyder eb6d42acf9 Support $ceil, $floor, etc. 2011-09-28 21:35:26 -04:00
Wilson Snyder 094d676a8b Fix MSVC compile warning with trunc/round, bug394. 2011-09-21 09:08:05 -04:00
Wilson Snyder 71306ceb1d Devel version 2011-09-14 21:44:54 -04:00
Wilson Snyder 8bbfc7fc22 Version bump 2011-09-14 21:12:40 -04:00
Wilson Snyder 19baba12b1 Commentary 2011-09-14 21:11:14 -04:00
Wilson Snyder 15b8819136 Avoid warning on older flex/gcc systems (lion) 2011-09-12 20:26:34 -04:00
Wilson Snyder 3fae8ade05 Fix PowerPC runtime error, bug288 2011-08-22 21:02:09 -04:00
Wilson Snyder f9bbf31d65 Fix internal error on integer casts, bug374. 2011-08-09 19:56:22 -04:00
Wilson Snyder df1da3dda9 Internals: Fix cppcheck warnings; no functional change intended 2011-08-04 21:58:45 -04:00
Wilson Snyder c83f2a4abd Internals: Fix preincrements to reduce cppcheck warnings 2011-08-04 21:15:24 -04:00
240 changed files with 2710 additions and 805 deletions
+208
View File
File diff suppressed because it is too large Load Diff
+2
View File
@@ -24,6 +24,8 @@ src/Makefile_obj$
include/verilated.mk$
config.cache$
config.status$
verilator.log
verilator.tex
verilator_bin.*
.vcsmx_rebuild$
autom4te\.cache/
+36 -20
View File
@@ -88,7 +88,10 @@ pkgdatadir = @pkgdatadir@
datarootdir = @datarootdir@
# Compile options
CFG_WITH_CCWARN = @CFG_WITH_CCWARN@
CFG_WITH_DEFENV = @CFG_WITH_DEFENV@
CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@
PACKAGE_VERSION = @PACKAGE_VERSION@
#### End of system configuration section. ####
######################################################################
@@ -101,8 +104,6 @@ INFOS = README internals.txt verilator.txt verilator.html verilator.1 verilator.
# Files that can be generated, but should be up to date for a distribution.
DISTDEP = info Makefile
# Files to distribute.
DISTBIN = $(wildcard bin/verilator-*)
DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
*.in *.ac \
@@ -129,7 +130,6 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
test_regress/t/*.pl \
test_regress/t/*.pf \
test_regress/t/*.v* \
verilator.* \
INST_PROJ_FILES = \
bin/verilator \
@@ -171,7 +171,7 @@ msg_test:
@echo
.PHONY:test
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
ifeq ($(CFG_WITH_LONGTESTS),yes) # Local... Else don't burden users
test: test_vcs test_c test_sc test_sp test_verilated test_regress
else
test: test_c test_sc test_sp
@@ -203,17 +203,18 @@ test_regress: all_nomsg
info: $(INFOS)
# Use --no-split to avoid creating filenames > 14 chars.
verilator.1: bin/verilator
verilator.1: ${srcdir}/bin/verilator
pod2man $< $@
verilator.txt: bin/verilator
verilator.txt: ${srcdir}/bin/verilator
$(POD2TEXT) $< $@
verilator.html: bin/verilator
verilator.html: ${srcdir}/bin/verilator
pod2html $< >$@
verilator.pdf: bin/verilator $(DISTCONFIG)
pod2latex --full --out verilator.tex bin/verilator
# PDF needs DIST variables; but having configure.ac as dependency isn't detected
verilator.pdf: ${srcdir}/bin/verilator Makefile
pod2latex --full --out verilator.tex ${srcdir}/bin/verilator
cat < verilator.tex \
| sed 's/\\begin{document}/\\usepackage[left=1.7in,right=1.7in,top=1.3in,bottom=1.3in]{geometry}\n\\begin{document}/' \
| sed 's/\\begin{document}/\\usepackage[pdftex,bookmarks=true,bookmarksnumbered=true,hypertexnames=false,breaklinks=true,linkbordercolor={0 0 1}]{hyperref}\n\\begin{document}/' \
@@ -257,7 +258,7 @@ VL_INST_DATA_SRCDIR_FILES = \
test_v/*.[chv]* \
test_c/*.[chv]* test_c/Makefile test_c/Makefile_obj \
test_sc/*.[chv]* test_sc/Makefile test_sc/Makefile_obj \
test_sp/*.[chv]* test_sp/Makefile test_sp/Makefile_obj \
test_sp/Makefile test_sp/Makefile_obj \
installbin:
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(bindir)
@@ -268,9 +269,11 @@ installbin:
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/bin
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_includer $(DESTDIR)$(pkgdatadir)/bin/verilator_includer )
# Man files can either be part of the original kit, or built in current directory
# So important we use $< so VPATH is searched
installman: $(VL_INST_MAN_FILES)
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(mandir)/man1
for p in $(VL_INST_MAN_FILES) ; do \
for p in $< ; do \
$(INSTALL_DATA) $$p $(DESTDIR)$(mandir)/man1/$$p; \
done
@@ -315,6 +318,8 @@ install: all_nomsg installbin installman installdata install-msg
install-here: installman ftp
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
DISTNAMEREV = $(shell sed -e '/DTVERSION/!d' -e 's/.*verilator_\([^"]*\).*/\1/' -e q ${srcdir}/src/config_rev.h)
DIRPROJECT := $(shell project_dir --project)
VERILATOR_CAD_DIR = $(CAD_DIR)/verilator/$(DISTNAMEREV)/$(DIRPROJECT_ARCH)
INST_PROJ_CVS = cp_if_cvs_diff
@@ -323,7 +328,7 @@ install-project: dist
@echo "Install-project to $(DIRPROJECT)"
strip verilator_bin*
$(MAKE) install-project-quick
for p in verilator.1 ; do \
for p in $(VL_INST_MAN_FILES) ; do \
$(INSTALL_DATA) $$p $(DIRPROJECT_PREFIX)/man/man1/$$p; \
done
$(INST_PROJ_CVS) $(DISTNAME).tgz $(DIRPROJECT)/hw/utils/verilator/verilator.tgz
@@ -347,7 +352,7 @@ install-cadtools: dist
strip verilator_bin*
$(MAKE) install-cadtools-quick
$(SHELL) ${srcdir}/mkinstalldirs $(VERILATOR_CAD_DIR)/man/man1
for p in verilator.1 ; do \
for p in $(VL_INST_MAN_FILES) ; do \
$(INSTALL_DATA) $$p $(VERILATOR_CAD_DIR)/man/man1/$$p; \
done
$(INST_PROJ_CVS) $(DISTNAME).tgz $(VERILATOR_CAD_DIR)/verilator.tgz
@@ -371,6 +376,15 @@ endif
# VERILATOR_AUTHOR_SITE
endif
CPPCHECK = cppcheck
CPPCHECK_FLAGS = --enable=all --inline-suppr --suppress=unusedScopedObject
CPPCHECK_CPP = $(wildcard $(srcdir)/include/*.cpp $(srcdir)/src/*.cpp)
CPPCHECK_DEP = $(subst .cpp,.cppcheck,$(CPPCHECK_CPP))
cppcheck: $(CPPCHECK_DEP)
%.cppcheck: %.cpp
$(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -I$(srcdir)/include -I$(srcdir)/src $<
ftp: info
install-msg:
@@ -391,8 +405,13 @@ Makefile: Makefile.in config.status $(IN_WILD)
src/Makefile: src/Makefile.in Makefile
config.status: configure
./config.status --recheck
configure: configure.ac
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
autoconf --warnings=all
else
autoconf
endif
maintainer-clean::
@echo "This command is intended for maintainers to use;"
@@ -433,15 +452,12 @@ dist-file-list:
######################################################################
# Distributions
DISTCONFIG = ${srcdir}/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/.*\([1-2][0-9][0-9][0-9].[0-9]*[0-9].[0-9]*[0-9]\).*/\1/' -e q $(DISTCONFIG))
DISTNAMEREV := $(shell sed -e '/DTVERSION/!d' -e 's/.*verilator_\([^"]*\).*/\1/' -e q src/config_rev.h)
DISTTITLE := Verilator $(word 1,$(PACKAGE_VERSION))
DISTNAME := verilator-$(word 1,$(PACKAGE_VERSION))
DISTDATEPRE := $(word 2,$(PACKAGE_VERSION))
DISTDATE := $(subst /,-,$(DISTDATEPRE))
DISTTAGNAME := $(subst .,_,$(subst -,_,$(DISTNAME)))
DISTDATE := $(subst /,-,$(DISTDATEPRE))
tag:
svnorcvs tag $(DISTTAGNAME)
+95 -37
View File
@@ -70,7 +70,7 @@ if (! GetOptions (
# "version!" => \&version, # Also passthru'ed
# Switches
"gdb=s" => \$opt_gdb, # Undocumented debugging
"gdbbt!" => \$opt_gdbbt, # Undocumented debugging
"gdbbt!" => \$opt_gdbbt,
# Additional parameters
"<>" => sub {}, # Ignored
)) {
@@ -99,7 +99,7 @@ if ($opt_gdbbt && !$opt_gdb && $Debug) {
#----------------------------------------------------------------------
sub usage {
pod2usage(-exitstatus=>2, -verbose=>2);
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
}
sub debug {
@@ -125,7 +125,14 @@ sub verilator_bin {
$bin = "$dir/$basename"; # From pointing to kit directory
}
} else {
$bin = $basename;
if (-x "$RealBin/$basename") {
$bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed
} else {
$bin = $basename; # Find in PATH
}
# Note we don't look under bin/$basename which would be right if running
# in the kit dir. Running that would likely break, since
# VERILATOR_ROOT wouldn't be set and Verilator won't find internal files.
}
return $bin;
}
@@ -196,8 +203,9 @@ Verilator - Convert Verilog code to C++/SystemC
=head1 DESCRIPTION
Verilator converts synthesizable (not behavioral) Verilog code, plus some
Synthesis, SystemVerilog and Sugar/PSL assertions, into C++, SystemC or
SystemPerl code. It is not a complete simulator, just a compiler.
Synthesis, SystemVerilog and a small subset of Verilog AMS and Sugar/PSL
assertions, into C++, SystemC or SystemPerl code. It is not a complete
simulator, just a compiler.
Verilator is invoked with parameters similar to GCC, Cadence
Verilog-XL/NC-Verilog, or Synopsys's VCS. It reads the specified Verilog
@@ -292,8 +300,8 @@ descriptions in the next sections for more information.
--top-module <topname> Name of top level input module
--trace Enable waveform creation
--trace-depth <levels> Depth of tracing
--trace-max-array <bits> Maximum bit width for tracing
--trace-max-width <depth> Maximum array depth for tracing
--trace-max-array <depth> Maximum bit width for tracing
--trace-max-width <width> Maximum array depth for tracing
--trace-underscore Enable tracing of _signals
-U<var> Undefine preprocessor define
--unroll-count <loops> Tune maximum loop iterations
@@ -562,10 +570,7 @@ Displays this message and program version and exits.
=item -II<dir>
Add the directory to the list of directories that should be searched for
include directories or libraries. Same as +incdir and -y; +incdir and -y
are fairly standard across Verilog tools while -I is an alias for GCC
compatibility.
See -y.
=item --if-depth I<value>
@@ -574,10 +579,7 @@ defaults to 0 which disables this warning.
=item +incdir+I<dir>
Add the directory to the list of directories that should be searched for
include directories or libraries. Same as -I and -y; +incdir and -y
are fairly standard across Verilog tools while -I is an alias for GCC
compatibility.
See -y.
=item --inhibit-sim
@@ -609,9 +611,13 @@ in the Make variable LDLIBS, not LDFLAGS.)
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.
"1364-2005", "1800-2005", "VAMS-2.3". Verilator also allows the
non-standard "1800+VAMS" to allow both the full SystemVerilog and
Verilog-AMS keywords.
The --language flag is only recommended for legacy code, as the preferable
option is to edit the code to repair new keywords, or add appropriate
`begin_keywords.
=item +libext+I<ext>+I<ext>...
@@ -715,7 +721,8 @@ Backward compatible alias for "--pins-bv 65". Note that's a 65, not a 64.
Specifies SystemC inputs/outputs of greater than or equal to I<width> bits
wide should use sc_bv's instead of uint32/vluint64_t's. The default is
"--pins-bv 65". Versions before Verilator 3.671 defaulted to "--pins-bv
33". The more sc_bv is used, the worse for performance.
33". The more sc_bv is used, the worse for performance. Use the
"/*verilator sc_bv*/" attribute to select specific ports to be sc_bv.
=item --pins-uint8
@@ -823,13 +830,13 @@ Specify the number of levels deep to enable tracing, for example
entire model. Using a small number will decrease visibility, but greatly
improve runtime and trace file size.
=item --trace-max-array I<bits>
=item --trace-max-array I<depth>
Rarely needed. Specify the maximum array depth of a signal that may be
traced. Defaults to 32, as tracing large arrays may greatly slow traced
simulations.
=item --trace-max-width I<depth>
=item --trace-max-width I<width>
Rarely needed. Specify the maximum bit width of a signal that may be
traced. Defaults to 256, as tracing large vectors may greatly slow traced
@@ -936,8 +943,8 @@ enabled), but do not affect style messages. This is equivalent to
=item -Wwarn-style
Enable all code style related warning messages. This is equivalent to
"-Wwarn-DECLFILENAME -Wwarn-DEFPARAM -Wwarn-INCABSPATH -Wwarn-SYNCASYNCNET
-Wwarn-UNDRIVEN -Wwarn-UNUSED -Wwarn-VARHIDDEN".
"-Wwarn ASSIGNDLY -Wwarn-DECLFILENAME -Wwarn-DEFPARAM -Wwarn-INCABSPATH
-Wwarn-SYNCASYNCNET -Wwarn-UNDRIVEN -Wwarn-UNUSED -Wwarn-VARHIDDEN".
=item -x-assign 0
@@ -965,9 +972,14 @@ enable rerunning with that same seed so you can reproduce bugs.
=item -y I<dir>
Add the directory to the list of directories that should be searched for
include directories or libraries. Same as +incdir and -I; +incdir and +y
are fairly standard across Verilog tools while -I is an alias for GCC
compatibility.
include files or libraries. The three flags -y, +incdir and -I have
similar effect; +incdir and +y are fairly standard across Verilog tools while -I
is an alias for GCC compatibility.
Verilator defaults to the current directory ("-y .") and any specified
--Mdir, though these default paths are used after any user specified
directories. This allows '-y "$(pwd)"' to be used if absolute filenames
are desired for error messages instead of relative filenames.
=back
@@ -1226,11 +1238,6 @@ all runs of the C++ Compiler. For example, "objcache --read --write", or
"ccache". If using distcc, it would generally be run under either objcache
or ccache; see the documentation for those programs.
=item OBJCACHE_JOBS
Optionally lists Make flags that specifies parallel make jobs. For example
a 4 CPU system may use "-j 6" to request 6 parallel compiles when making.
=item SYSTEMC
Required for SystemC output mode. If set, specifies the directory
@@ -1306,10 +1313,13 @@ example:
Vtop *top; // Instantiation of module
unsigned int main_time = 0; // Current simulation time
vluint64_t main_time = 0; // Current simulation time
// This is a 64-bit integer to reduce wrap over issues and
// allow modulus. You can also use a double, if you wish.
double sc_time_stamp () { // Called by $time in Verilog
return main_time;
return main_time; // converts to double, to match
// what SystemC does
}
int main(int argc, char** argv) {
@@ -1680,6 +1690,18 @@ Verilator currently has some support for SystemVerilog 2009 synthesis
constructs. As SystemVerilog features enter common usage they are added;
please file a bug if a feature you need is missing.
=head2 Verilog AMS Support
Verilator implements a very small subset of Verilog AMS (Verilog Analog and
Mixed-Signal Extensions) with the subset corresponding to those VMS
keywords with near equivelents in the Verilog 2005 or SystemVerilog 2009
languages.
AMS parsing is enabled with "--language VAMS" or "--language 1800+VAMS".
At present Verilator implements ceil, exp, floor, ln, log, pow, sqrt,
string, and wreal.
=head2 Sugar/PSL Support
Most future work is being directed towards improving SystemVerilog
@@ -2028,6 +2050,15 @@ should be declared in SystemC as a sc_clock instead of a bool. This was
needed in SystemC 1.1 and 1.2 only; versions 2.0 and later do not require
clock pins to be sc_clocks and this is no longer needed.
=item /*verilator sc_bv*/
Used after a port declaration. It sets the port to be of sc_bv<I<width>>
type, instead of bool, vluint32_t or vluint64_t. This may be useful if
the port width is parametrized and different of such modules interface
a templated module (such as a transactor) or for other reasons. In general
you should avoid using this attribute when not necessary as with increasing
usage of sc_bv the performance increases significantly.
=item /*verilator sformat*/
Attached to the final input of a function or task "input string" to
@@ -2375,6 +2406,29 @@ List of all warnings:
=over 4
=item ASSIGNIN
Error that an assignment is being made to an input signal. This is almost
certainly a mistake, though technically legal.
input a;
assign a = 1'b1;
Ignoring this warning will only suppress the lint check, it will simulate
correctly.
=item ASSIGNDLY
Warns that you have an assignment statement with a delayed time in front of
it, for example:
a <= #100 b;
assign #100 a = b;
Ignoring this warning may make Verilator simulations differ from other
simulators, however at one point this was a common style so disabled by
default as a code style warning.
=item BLKANDNBLK
BLKANDNBLK is an error that a variable comes from a mix of blocked and
@@ -2948,6 +3002,11 @@ One limit is that you cannot under either license release a commercial
Verilog simulation product incorporating Verilator without making the
source code available.
As is standard with Open Source, contributions back to Verilator will be
placed under the Verilator copyright and LGPL/Artistic license. Small test
cases will be released into the public domain so they can be used anywhere,
large tests under the LGPL/Artistic, unless requested otherwise.
=item Why is Verilation so slow?
Verilator needs more memory than the resulting simulator will require, as
@@ -3145,10 +3204,9 @@ Between GCC 3.0 to 3.3, each compiled progressively slower, thus if you can
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.org/>. Make::Cache will skip GCC runs between
identical source builds, even across different users. You can use the
OBJCACHE environment variable to use these CC wrappers.
packages. ccache will skip GCC runs between identical source builds, even
across different users. You can use the OBJCACHE environment variable to
use these CC wrappers.
=item Why do so many files need to recompile when I add a signal?
+2 -2
View File
@@ -99,7 +99,7 @@ sub filter {
next if $line =~ / This=/;
$line =~ s/0x[a-f0-9]+/0x/g;
$line =~ s/<e[0-9]+\#?>/<e>/g;
$line =~ s/{\d+}/{}/g if !$Opt_Lineno;
$line =~ s/{[a-z]*\d+}/{}/g if !$Opt_Lineno;
print $f2 $line;
}
$f1->close;
@@ -109,7 +109,7 @@ sub filter {
#----------------------------------------------------------------------
sub usage {
pod2usage(-verbose=>2, -exitval => 2);
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
exit (1);
}
+1 -1
View File
@@ -39,7 +39,7 @@ profcfunc($Opt_File);
#----------------------------------------------------------------------
sub usage {
pod2usage(-verbose=>2, -exitval => 2);
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
exit (1);
}
+100 -31
View File
@@ -1,35 +1,83 @@
dnl DESCRIPTION: Process this file with autoconf to produce a configure script.
dnl
dnl Copyright 2003-2011 by Wilson Snyder. Verilator is free software; you can
dnl redistribute it and/or modify it under the terms of either the GNU Lesser
dnl General Public License Version 3 or the Perl Artistic License Version 2.0.
# DESCRIPTION: Process this file with autoconf to produce a configure script.
#
# Copyright 2003-2011 by Wilson Snyder. Verilator is free software; you can
# redistribute it and/or modify it under the terms of either the GNU Lesser
# General Public License Version 3 or the Perl Artistic License Version 2.0.
AC_INIT(src/Verilator.cpp)
AC_INIT([Verilator],[3.830])
AC_CONFIG_HEADER(src/config_build.h)
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk)
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_MSG_RESULT([configuring for $PACKAGE_STRING])
# Special Substitutions - CFG_WITH_DEFENV
AC_MSG_CHECKING(whether to disable hardcoded paths)
AC_ARG_ENABLE([defenv],
[AS_HELP_STRING([--disable-defenv],
[disable using some hardcoded data paths extracted from some default environment variables (the default is to use hardcoded paths)])],
[case "${enableval}" in
yes) CFG_WITH_DEFENV=yes ;;
no) CFG_WITH_DEFENV=no ;;
*) AC_MSG_ERROR([bad value ${enableval} for --disable-defenv]) ;;
esac],
CFG_WITH_DEFENV=yes)
AC_SUBST(CFG_WITH_DEFENV)
AC_MSG_RESULT($CFG_WITH_DEFENV)
dnl Compiler flags
# Special Substitutions - CFG_WITH_CCWARN
AC_MSG_CHECKING(whether to show and stop on compilation warnings)
AC_ARG_ENABLE([ccwarn],
[AS_HELP_STRING([--enable-ccwarn],
[enable showing and stopping on compilation warnings])],
[case "${enableval}" in
yes) CFG_WITH_CCWARN=yes ;;
no) CFG_WITH_CCWARN=no ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-ccwarn]) ;;
esac],
[case "x${VERILATOR_AUTHOR_SITE}" in
x) CFG_WITH_CCWARN=no ;;
*) CFG_WITH_CCWARN=yes ;;
esac]
)
AC_SUBST(CFG_WITH_CCWARN)
AC_MSG_RESULT($CFG_WITH_CCWARN)
# Special Substitutions - CFG_WITH_LONGTESTS
AC_MSG_CHECKING(whether to run long tests)
AC_ARG_ENABLE([longtests],
[AS_HELP_STRING([--enable-longtests],
[enable running long developer tests])],
[case "${enableval}" in
yes) CFG_WITH_LONGTESTS=yes ;;
no) CFG_WITH_LONGTESTS=no ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-longtests]) ;;
esac],
[case "x${VERILATOR_AUTHOR_SITE}" in
x) CFG_WITH_LONGTESTS=no ;;
*) CFG_WITH_LONGTESTS=yes ;;
esac]
)
AC_SUBST(CFG_WITH_LONGTESTS)
AC_MSG_RESULT($CFG_WITH_LONGTESTS)
# Compiler flags
CFLAGS=-I${includedir}
CPPFLAGS=-I${includedir}
CXXFLAGS=-I${includedir}
LDFLAGS=-L${libdir}
dnl Checks for programs.
# Checks for programs.
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_RUN_IFELSE(
[AC_LANG_SOURCE([int main() { return 0; }])],
AC_MSG_RESULT(yes),
AC_MSG_RESULT(no);AC_MSG_ERROR([a working C++ compiler is required]))
AC_MSG_RESULT(no);AC_MSG_ERROR([a working C++ compiler is required]),
AC_MSG_RESULT(yes))
AC_PATH_PROG(PERL,perl)
if test "x$PERL" = "x" ; then
@@ -44,33 +92,54 @@ if test "x$YACC" = "x" ; then
AC_MSG_ERROR([Cannot find "bison" in your PATH, please install it])
fi
dnl Checks for libraries.
# Checks for libraries.
dnl Checks for header files.
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS(fcntl.h unistd.h inttypes.h sys/file.h sys/time.h sys/un.h math.h stdint.h mingw/stdint.h)
dnl Checks for typedefs, structures
# Checks for typedefs, structures
AC_CHECK_TYPE(size_t,unsigned int)
AC_CHECK_TYPE(uint_t,unsigned int)
AC_CHECK_TYPE(ulong_t,unsigned long)
AC_TYPE_SIZE_T
AC_STRUCT_TM
dnl Checks for compiler characteristics.
# Checks for compiler characteristics.
AC_C_INLINE
dnl Checks for library functions.
AC_DEFUN([_MY_CXX_CHECK_OPT],
[# _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options
ACO_SAVE_CXXFLAGS="$CXXFLAGS"
# -Werror needed otherwise unknown -Wno-div-by-zero won't report problems
CXXFLAGS="$CXXFLAGS $1 -Werror"
AC_MSG_CHECKING([whether $CXX accepts $1])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([],[])],
[_my_result=yes],
[_my_result=no])
AC_MSG_RESULT($_my_result)
if test "$_my_result" = "yes" ; then
CFG_CXXFLAGS_NO_UNUSED="$CFG_CXXFLAGS_NO_UNUSED $1"
fi
CXXFLAGS="$ACO_SAVE_CXXFLAGS"
])# _MY_CXX_CHECK_OPT
dnl Checks for system services
# For example, -Wno-div-by-zero isn't in 4.1.2
_MY_CXX_CHECK_OPT(-Wno-char-subscripts)
# Random code often does / 0. Unfortunately VL_DIV_I(0,0) will warn
# without this flag, even though there's a conditional to prevent the divide.
# We still don't add no-div-by-zero as it throws message to stdout, though doesn't die.
#_MY_CXX_CHECK_OPT(-Wno-div-by-zero)
_MY_CXX_CHECK_OPT(-Wno-sign-compare)
_MY_CXX_CHECK_OPT(-Wno-uninitialized)
_MY_CXX_CHECK_OPT(-Wno-unused-parameter)
_MY_CXX_CHECK_OPT(-Wno-unused-variable)
AC_SUBST(CFG_CXXFLAGS_NO_UNUSED)
dnl Other install directories
# Checks for library functions.
# Checks for system services
# Other install directories
pkgdatadir=${datadir}/verilator
AC_SUBST(pkgdatadir)
AC_OUTPUT(Makefile src/Makefile src/Makefile_obj include/verilated.mk)
AC_OUTPUT
AC_MSG_RESULT([])
AC_MSG_RESULT([Now type 'gmake'])
AC_MSG_RESULT([Now type 'make' (or sometimes 'gmake') to build Verilator.])
AC_MSG_RESULT([])
+25
View File
@@ -333,7 +333,9 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
case 'e':
case 'f':
case 'g': {
const int lbits = va_arg(ap, int);
double d = va_arg(ap, double);
if (lbits) {} // UNUSED - always 64
strncpy(tmpf, pctp, pos-pctp+1);
tmpf[pos-pctp+1] = '\0';
sprintf(tmp, tmpf, d);
@@ -596,6 +598,17 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
VL_SET_WQ(owp,ld);
break;
}
case 'f':
case 'e':
case 'g': { // Real number
_vl_vsss_skipspace(fp,floc,fromp);
_vl_vsss_read(fp,floc,fromp, tmp, "+-.0123456789eE");
if (!tmp[0]) goto done;
union { double r; vlsint64_t ld; } u;
u.r = strtod(tmp, NULL);
VL_SET_WQ(owp,u.ld);
break;
}
case 't': // FALLTHRU // Time
case 'u': { // Unsigned decimal
_vl_vsss_skipspace(fp,floc,fromp);
@@ -924,6 +937,17 @@ void VL_READMEM_W(bool hex, int width, int depth, int array_lsb, int fnwords,
}
}
IData VL_SYSTEM_IQ(QData lhs) {
IData lhsw[2]; VL_SET_WQ(lhsw, lhs);
return VL_SYSTEM_IW(2, lhsw);
}
IData VL_SYSTEM_IW(int lhswords, WDataInP filenamep) {
char filenamez[VL_TO_STRING_MAX_WORDS*VL_WORDSIZE+1];
_VL_VINT_TO_STRING(lhswords*VL_WORDSIZE, filenamez, filenamep);
int code = system(filenamez);
return code >> 8; // Want exit status
}
IData VL_TESTPLUSARGS_I(const char* formatp) {
string match = VerilatedImp::argPlusMatch(formatp);
if (match == "") return 0;
@@ -1079,6 +1103,7 @@ VerilatedScope::VerilatedScope() {
m_callbacksp = NULL;
m_namep = NULL;
m_funcnumMax = 0;
m_symsp = NULL;
m_varsp = NULL;
}
+6 -2
View File
@@ -349,6 +349,10 @@ extern IData VL_SSCANF_IWX(int lbits, WDataInP lwp, const char* formatp, ...);
extern void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...);
extern IData VL_SYSTEM_IW(int lhsnwords, WDataInP lhs);
extern IData VL_SYSTEM_IQ(QData lhs);
inline IData VL_SYSTEM_II(IData lhs) { return VL_SYSTEM_IQ(lhs); }
extern IData VL_TESTPLUSARGS_I(const char* formatp);
extern IData VL_VALUEPLUSARGS_IW(int rbits, const char* prefixp, char fmt, WDataOutP rwp);
extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish
@@ -383,9 +387,9 @@ static inline QData VL_CVT_Q_D(double lhs) { union { double d; QData q; } u; u.
/// Return double from QData (numeric)
static inline double VL_ITOR_D_I(IData lhs) { return ((double)((vlsint32_t)(lhs))); }
/// Return QData from double (numeric)
static inline IData VL_RTOI_I_D(double lhs) { return ((vlsint32_t)(trunc(lhs))); }
static inline IData VL_RTOI_I_D(double lhs) { return ((vlsint32_t)(VL_TRUNC(lhs))); }
/// Return QData from double (numeric)
static inline IData VL_RTOIROUND_I_D(double lhs) { return ((vlsint32_t)(round(lhs))); }
static inline IData VL_RTOIROUND_I_D(double lhs) { return ((vlsint32_t)(VL_ROUND(lhs))); }
// Sign extend such that if MSB set, we get ffff_ffff, else 0s
// (Requires clean input)
+8 -6
View File
@@ -13,6 +13,12 @@ LINK = @CXX@
AR = ar
RANLIB = ranlib
CFG_WITH_CCWARN = @CFG_WITH_CCWARN@
CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@
# Compiler flags to use to turn off unused and generated code warnings, such as -Wno-div-by-zero
CFG_CXXFLAGS_NO_UNUSED = @CFG_CXXFLAGS_NO_UNUSED@
######################################################################
# Programs
@@ -38,13 +44,9 @@ VK_CPPFLAGS_ALWAYS += \
-DVM_TRACE=$(VM_TRACE) \
-DVM_COVERAGE=$(VM_COVERAGE) \
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
VK_CPPFLAGS_WALL += -Wall \
-Wno-char-subscripts \
-Wno-sign-compare \
-Wno-unused-parameter \
-Wno-unused-variable \
-Wno-uninitialized \
$(CFG_CXXFLAGS_NO_UNUSED) \
-Werror
endif
+6 -3
View File
@@ -86,8 +86,8 @@ private:
NameMap* m_namemapp; ///< List of names for the header
static vector<VerilatedVcd*> s_vcdVecp; ///< List of all created traces
inline size_t bufferSize() { return 256*1024; } // See below for slack calculation
inline size_t bufferInsertSize() { return 16*1024; }
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
inline static size_t bufferInsertSize() { return 16*1024; }
void bufferFlush();
void bufferCheck() {
// Flush the write buffer if there's not enough space left for new information
@@ -110,6 +110,7 @@ private:
void dumpHeader();
void dumpPrep (vluint64_t timeui);
void dumpFull (vluint64_t timeui);
// cppcheck-suppress functionConst
void dumpDone ();
inline void printCode (vluint32_t code) {
if (code>=(94*94*94)) *m_writep++ = ((char)((code/94/94/94)%94+33));
@@ -117,7 +118,7 @@ private:
if (code>=(94)) *m_writep++ = ((char)((code/94)%94+33));
*m_writep++ = ((char)((code)%94+33));
}
string stringCode (vluint32_t code) {
static string stringCode (vluint32_t code) {
string out;
if (code>=(94*94*94)) out += ((char)((code/94/94/94)%94+33));
if (code>=(94*94)) out += ((char)((code/94/94)%94+33));
@@ -141,6 +142,8 @@ public:
m_evcd = false;
m_scopeEscape = '.'; // Backward compatibility
m_wroteBytes = 0;
m_fd = 0;
m_fullDump = true;
}
~VerilatedVcd();
+3 -1
View File
@@ -98,7 +98,9 @@ class VerilatedVpioCb : public VerilatedVpio {
s_vpi_value m_value;
QData m_time;
public:
VerilatedVpioCb(const t_cb_data* cbDatap, QData time) : m_cbData(*cbDatap), m_time(time) {
// cppcheck-suppress uninitVar // m_value
VerilatedVpioCb(const t_cb_data* cbDatap, QData time)
: m_cbData(*cbDatap), m_time(time) {
m_cbData.value = &m_value;
}
virtual ~VerilatedVpioCb() {}
+12
View File
@@ -221,6 +221,18 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
#define VL_BITBIT_I(bit) ((bit)&VL_SIZEBITS_I) ///< Bit number for a bit in a long
#define VL_BITBIT_Q(bit) ((bit)&VL_SIZEBITS_Q) ///< Bit number for a bit in a quad
//=========================================================================
// Floating point
// #defines, to avoid requiring math.h on all compile runs
#ifdef _MSC_VER
# define VL_TRUNC(n) (((n)<0) ? ceil((n)) : floor((n)))
# define VL_ROUND(n) (((n)<0) ? ceil((n)-0.5) : floor((n)+0.5))
#else
# define VL_TRUNC(n) trunc(n)
# define VL_ROUND(n) round(n)
#endif
//=========================================================================
#endif /*guard*/
+6 -5
View File
@@ -207,10 +207,10 @@ viewers let us know; ZGRViewer isn't great for large graphs.
Tree files are dumps of the AST Tree and are produced between every major
algorithmic stage. An example:
NETLIST 0x90fb00 <e1> {0} w0
1: MODULE 0x912b20 <e8822> {8} w0 top L2 [P]
*1:2: VAR 0x91a780 <e74#> {22} w70 out_wide [O] WIRE
1:2:1: BASICDTYPE 0x91a3c0 <e73> {22} w70 [logic]
NETLIST 0x90fb00 <e1> {a0} w0
1: MODULE 0x912b20 <e8822> {a8} w0 top L2 [P]
*1:2: VAR 0x91a780 <e74#> {a22} w70 out_wide [O] WIRE
1:2:1: BASICDTYPE 0x91a3c0 <e73> {a22} w70 [logic]
=over 4
@@ -224,7 +224,8 @@ algorithmic stage. An example:
this node. A trailing # indicates this node changed since the last tree
dump was made. You can gdb break on this edit; see below.
"{22}" indicates this node is related to line 22 in the source.
"{a22}" indicates this node is related to line 22 in the source filename
"a", where "a" is the first file read, "z" the 36th, and "aa" the 37th.
"w70" indicates the width is 70 bits. sw70 would be signed 70 bits.
+1 -1
View File
@@ -38,7 +38,7 @@ cwrite ("graph_export.cpp");
#----------------------------------------------------------------------
sub usage {
pod2usage(-verbose=>2, -exitval => 2);
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
exit (1);
}
+1 -1
View File
@@ -43,7 +43,7 @@ dotwrite();
#----------------------------------------------------------------------
sub usage {
pod2usage(-verbose=>2, -exitval => 2);
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
exit (1);
}
+55 -11
View File
@@ -12,12 +12,15 @@ use vars qw ($Debug);
#======================================================================
# main
our $Opt_Stage = 0;
autoflush STDOUT 1;
autoflush STDERR 1;
Getopt::Long::config ("no_auto_abbrev");
if (! GetOptions (
"debug" => sub { $Debug = 1; },
"<>" => sub { die "%Error: Unknown parameter: $_[0]\n"; },
"stage=i" => \$Opt_Stage,
)) {
die "%Error: Bad usage, try 'install_test --help'\n";
}
@@ -37,8 +40,10 @@ sub test {
my $srcdir = getcwd();
my $blddir = $srcdir."/test_regress/obj_dir/install_test_bld";
my $prefix = $srcdir."/test_regress/obj_dir/install_test_prefix";
my $testdir = $srcdir."/test_regress/obj_dir/install_test_test";
if (1) {
my $testdirp= $srcdir."/test_regress/obj_dir/install_test_testp";
my $testdirn= $srcdir."/test_regress/obj_dir/install_test_testn";
if ($Opt_Stage <= 0) {
run("/bin/rm -rf $blddir");
run("/bin/mkdir -p $blddir");
run("cd $blddir && $srcdir/configure --prefix $prefix");
@@ -46,24 +51,63 @@ sub test {
}
# Install it under the prefix
if (1) {
if ($Opt_Stage <= 1) {
run("/bin/rm -rf $prefix");
run("/bin/mkdir -p $prefix");
run("cd $blddir && make install");
run("test -e $prefix/share/man/man1/verilator.1");
run("test -e $prefix/share/verilator/examples/test_c/Makefile");
run("test -e $prefix/share/verilator/include/verilated.h");
run("test -e $prefix/bin/verilator");
run("test -e $prefix/bin/verilator_bin");
run("test -e $prefix/bin/verilator_bin_dbg");
run("test -e $prefix/bin/verilator_profcfunc");
}
# Run a test using just the path
if (1) {
run("/bin/rm -rf $testdir");
run("/bin/mkdir -p $testdir");
if ($Opt_Stage <= 2) {
my $dir = $testdirp;
run("/bin/rm -rf $dir");
run("/bin/mkdir -p $dir");
my $bin1 = $prefix."/bin";
my $bin2 = $prefix."/share/bin";
IO::File->new(">$testdir/foo.v")->print('module t; initial begin $display("HELLO WORLD"); end endmodule'."\n");
run("cd $testdir && PATH=$bin1:$bin2:\$PATH verilator --cc foo.v");
run("cd $testdir/obj_dir && PATH=$bin1:$bin2:\$PATH make -f Vfoo.mk");
#Need .c file, and --exe for this to work
#run("cd $testdir && PATH=$bin1:$bin2:\$PATH obj_dir/Vfoo");
write_verilog($dir);
run("cd $dir && PATH=$bin1:$bin2:\$PATH verilator --cc foo.v --exe foo.cpp");
run("cd $dir/obj_dir && PATH=$bin1:$bin2:\$PATH make -f Vfoo.mk");
run("cd $dir && PATH=$bin1:$bin2:\$PATH obj_dir/Vfoo");
}
# Run a test using exact path to binary
if ($Opt_Stage <= 3) {
my $dir = $testdirn;
run("/bin/rm -rf $dir");
run("/bin/mkdir -p $dir");
write_verilog($dir);
my $bin1 = $prefix."/bin";
my $bin2 = $prefix."/share/bin";
run("cd $dir && $bin1/verilator --cc foo.v --exe foo.cpp");
run("cd $dir/obj_dir && make -f Vfoo.mk");
run("cd $dir/obj_dir && ./Vfoo");
}
}
sub write_verilog {
my $dir = shift;
IO::File->new(">$dir/foo.v")->print('module t; initial begin $display("HELLO WORLD"); $finish; end endmodule'."\n");
my $fh = IO::File->new(">$dir/foo.cpp");
$fh->print('#include "Vfoo.h"' ,"\n");
$fh->print('unsigned int main_time = 0;' ,"\n");
$fh->print('double sc_time_stamp () {' ,"\n");
$fh->print(' return main_time;' ,"\n");
$fh->print('}' ,"\n");
$fh->print('int main() {' ,"\n");
$fh->print(' Vfoo *top = new Vfoo;' ,"\n");
$fh->print(' while (!Verilated::gotFinish()) {',"\n");
$fh->print(' top->eval();' ,"\n");
$fh->print(' main_time++;' ,"\n");
$fh->print(' }' ,"\n");
$fh->print(' top->final();' ,"\n");
$fh->print('}' ,"\n");
}
sub cleanenv {
+1 -1
View File
@@ -40,7 +40,7 @@ print '(query-replace-regexp "(\\([0-9a-z_]+\\))" "\\1" nil nil nil)',"\n";
#----------------------------------------------------------------------
sub usage {
pod2usage(-verbose=>2, -exitval => 2);
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
exit (1);
}
+7
View File
@@ -91,6 +91,10 @@ headers.
=item
You will need the C<flex> and C<bison> packages installed.
=item
C<cd> to the Verilator directory containing this README.
=item
@@ -147,6 +151,9 @@ most GNU tools support:
unsetenv VERILATOR_ROOT # if your shell is csh
./configure --prefix /opt/verilator-VERSION
Then after installing you will need to add /opt/verilator-VERSION/bin to
PATH.
=back
=item
+13 -24
View File
@@ -24,6 +24,7 @@
srcdir = @srcdir@
VPATH = @srcdir@
PERL = @PERL@
EXEEXT = @EXEEXT@
#### End of system configuration section. ####
@@ -32,25 +33,11 @@ default: dbg opt
debug: dbg
optimize: opt
ifeq ($(OBJCACHE_HOSTS),)
ifneq ($(SLCHOOSED_HOST),)
ifeq ($(VERILATOR_AUTHOR_SITE),1)
export OBJCACHE_HOSTS := $(shell rschedule --no-allow-reserved --similar hostnames)
endif
endif
endif
ifeq ($(OBJCACHE_JOBS),)
ifneq ($(OBJCACHE_HOSTS),)
export OBJCACHE_JOBS := -j $(shell objcache --jobs "$(OBJCACHE_HOSTS)")
endif
endif
ifneq ($(words $(CURDIR)),1)
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
endif
UNDER_GIT = $(wildcard ../.git/logs/HEAD)
UNDER_GIT = $(wildcard ${srcdir}/../.git/logs/HEAD)
#*********************************************************************
@@ -65,26 +52,25 @@ opt: ../verilator_bin
ifeq ($(VERILATOR_NO_OPT_BUILD),1) # Faster laptop development... One build
../verilator_bin: ../verilator_bin_dbg
-rm -rf $@ $@.exe
-cp -p $< $@
-cp -p $<.exe $@.exe
-cp -p $<$(EXEEXT) $@$(EXEEXT)
else
../verilator_bin: obj_opt prefiles
cd obj_opt && $(MAKE) -j 1 TGT=../$@ -f ../Makefile_obj serial
cd obj_opt && $(MAKE) $(OBJCACHE_JOBS) TGT=../$@ -f ../Makefile_obj
cd obj_opt && $(MAKE) -j 1 TGT=../$@ -f ../Makefile_obj serial
cd obj_opt && $(MAKE) TGT=../$@ -f ../Makefile_obj
endif
dbg: ../verilator_bin_dbg
../verilator_bin_dbg: obj_dbg prefiles
cd obj_dbg && $(MAKE) -j 1 TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj serial
cd obj_dbg && $(MAKE) $(OBJCACHE_JOBS) TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj
cd obj_dbg && $(MAKE) -j 1 TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj serial
cd obj_dbg && $(MAKE) TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj
prefiles::
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 ../.git/logs/HEAD
$(PERL) config_rev.pl . >$@
# This output goes into srcdir if locally configured, as we need to distribute it as part of the kit.
config_rev.h: ${srcdir}/config_rev.pl ${srcdir}/../.git/logs/HEAD
$(PERL) ${srcdir}/config_rev.pl ${srcdir} >$@
endif
maintainer-copy::
@@ -96,3 +82,6 @@ clean mostlyclean distclean maintainer-clean::
distclean maintainer-clean::
-rm -f Makefile Makefile_obj config_build.h
maintainer-clean::
-rm -f config_rev.h
+14 -13
View File
@@ -57,9 +57,11 @@ datarootdir = @datarootdir@
pkgdatadir = @pkgdatadir@
# Compile options
CFG_WITH_CCWARN = @CFG_WITH_CCWARN@
CFG_WITH_DEFENV = @CFG_WITH_DEFENV@
CPPFLAGSNOWALL += @CPPFLAGS@
CPPFLAGS += @CPPFLAGS@
LDFLAGS += @LDFLAGS@
EXEEXT = @EXEEXT@
#### End of system configuration section. ####
@@ -85,17 +87,18 @@ endif
# -lfl not needed as Flex invoked with %nowrap option
LIBS = -lm
CPPFLAGSNOWALL += -MMD
CPPFLAGSNOWALL += -I. -I$(bldsrc) -I$(srcdir) -I$(incdir)
CPPFLAGSNOWALL += -DYYDEBUG # Required to get nice error messages
#CPPFLAGSNOWALL += -DVL_LEAK_CHECKS # If running valgrind or other hunting tool
CPPFLAGSNOWALL += $(COPT)
CPPFLAGS = $(CPPFLAGSNOWALL)
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
CPPFLAGSNOWALL += -MP # Only works on recent GCC versions
CPPFLAGS += -MMD
CPPFLAGS += -I. -I$(bldsrc) -I$(srcdir) -I$(incdir)
CPPFLAGS += -DYYDEBUG # Required to get nice error messages
#CPPFLAGS += -DVL_LEAK_CHECKS # If running valgrind or other hunting tool
CPPFLAGS += $(COPT)
CPPFLAGS += -MP # Only works on recent GCC versions
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
CPPFLAGS += -W -Wall -Wno-unused-parameter -Wno-char-subscripts -Werror
#CPPFLAGS += -pedantic-errors
endif
CPPFLAGSWALL = $(CPPFLAGS)
CPPFLAGSNOWALL = $(CPPFLAGS) -Wno-unused
ifneq ($(SYSTEMPERL),) # Intuit SYSTEMPERL_INCLUDE as it's new
SYSTEMPERL_INCLUDE ?= $(SYSTEMPERL)/src
@@ -250,8 +253,6 @@ $(TGT): V3Ast__gen_classes.h $(OBJS)
@echo " Linking $@..."
-rm -rf $@ [email protected]
${LINK} ${LDFLAGS} -o $@ $(OBJS) $(CCMALLOC) ${LIBS}
@-(cp [email protected] $@ || true)
# ok if cp failes on linux, it's there to insure executable works on NT
V3Number_test: V3Number_test.o
${LINK} ${LDFLAGS} -o $@ $^ ${LIBS}
@@ -262,9 +263,9 @@ V3Number_test: V3Number_test.o
$(PERL) $(ASTGEN) -I$(srcdir) $*.cpp
%.o: %.cpp
$(OBJCACHE) ${CXX} ${CPPFLAGS} -c $<
$(OBJCACHE) ${CXX} ${CPPFLAGSWALL} -c $<
%.o: %.c
$(OBJCACHE) ${CC} ${CPPFLAGS} -c $<
$(OBJCACHE) ${CC} ${CPPFLAGSWALL} -c $<
V3ParseLex.o: V3ParseLex.cpp V3Lexer.yy.cpp V3ParseBison.c
$(OBJCACHE) ${CXX} ${CPPFLAGSNOWALL} -c $<
+5 -1
View File
@@ -148,7 +148,11 @@ public:
}
public:
// CONSTUCTORS
ActiveNamer() {}
ActiveNamer() {
m_scopep = NULL;
m_iActivep = NULL;
m_cActivep = NULL;
}
virtual ~ActiveNamer() {}
void main(AstScope* nodep) {
nodep->accept(*this);
+5 -5
View File
@@ -184,7 +184,7 @@ private:
}
if (nodep->fullPragma() || nodep->priorityPragma()) {
// Simply need to add a default if there isn't one already
m_statAsFull++;
++m_statAsFull;
if (!has_default) {
nodep->addItemsp(new AstCaseItem(nodep->fileline(), NULL/*DEFAULT*/,
newFireAssert(nodep, "synthesis full_case, but non-match found")));
@@ -193,7 +193,7 @@ private:
if (nodep->parallelPragma() || nodep->uniquePragma() || nodep->unique0Pragma()) {
// Need to check that one, and only one of the case items match at any moment
// If there's a default, we allow none to match, else exactly one must match
m_statAsFull++;
++m_statAsFull;
if (!has_default && !nodep->itemsp()) {
// Not parallel, but harmlessly so.
} else {
@@ -241,18 +241,18 @@ private:
if (m_beginp && nodep->name() == "") nodep->name(m_beginp->name());
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(),
nodep->stmtsp(), nodep->name()); nodep=NULL;
m_statAsCover++;
++m_statAsCover;
}
virtual void visit(AstPslAssert* nodep, AstNUser*) {
nodep->iterateChildren(*this);
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(),
NULL, nodep->name()); nodep=NULL;
m_statAsPsl++;
++m_statAsPsl;
}
virtual void visit(AstVAssert* nodep, AstNUser*) {
nodep->iterateChildren(*this);
newVAssertion(nodep, nodep->propp()); nodep=NULL;
m_statAsSV++;
++m_statAsSV;
}
virtual void visit(AstNodeModule* nodep, AstNUser*) {
+2 -2
View File
@@ -430,7 +430,7 @@ void AstNode::replaceWith(AstNode* newp) {
repHandle.relink(newp);
}
void AstNRelinker::dump(ostream& str) {
void AstNRelinker::dump(ostream& str) const {
str<<" BK="<<(uint32_t*)m_backp;
str<<" ITER="<<(uint32_t*)m_iterpp;
str<<" CHG="<<(m_chg==RELINK_NEXT?"[NEXT] ":"");
@@ -947,7 +947,7 @@ void AstNode::checkTree() {
}
}
void AstNode::dumpPtrs(ostream& os) {
void AstNode::dumpPtrs(ostream& os) const {
os<<"This="<<typeName()<<" "<<(void*)this;
os<<" back="<<(void*)backp();
if (nextp()) os<<" next="<<(void*)nextp();
+24 -13
View File
@@ -27,6 +27,7 @@
#include "V3Error.h"
#include "V3Number.h"
#include <vector>
#include <cmath>
#include "V3Ast__gen_classes.h" // From ./astgen
// Things like:
@@ -71,7 +72,7 @@ public:
};
return names[m_e];
};
inline AstNumeric () {}
inline AstNumeric () : m_e(UNSIGNED) {}
inline AstNumeric (en _e) : m_e(_e) {}
explicit inline AstNumeric (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -89,6 +90,7 @@ public:
class AstPragmaType {
public:
enum en {
ILLEGAL,
COVERAGE_BLOCK_OFF,
INLINE_MODULE,
NO_INLINE_MODULE,
@@ -97,7 +99,7 @@ public:
PUBLIC_TASK
};
enum en m_e;
inline AstPragmaType () {}
inline AstPragmaType () : m_e(ILLEGAL) {}
inline AstPragmaType (en _e) : m_e(_e) {}
explicit inline AstPragmaType (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -120,7 +122,7 @@ public:
TRACE_CHANGE_SUB
};
enum en m_e;
inline AstCFuncType () {}
inline AstCFuncType () : m_e(FT_NORMAL) {}
inline AstCFuncType (en _e) : m_e(_e) {}
explicit inline AstCFuncType (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -188,7 +190,7 @@ public:
};
return names[m_e];
};
inline AstEdgeType () {}
inline AstEdgeType () : m_e(ET_ILLEGAL) {}
inline AstEdgeType (en _e) : m_e(_e) {}
explicit inline AstEdgeType (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -202,6 +204,7 @@ public:
class AstAttrType {
public:
enum en {
ILLEGAL,
EXPR_BITS, // V3Const converts to constant
//
VAR_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes
@@ -212,19 +215,20 @@ public:
VAR_PUBLIC_FLAT_RD, // V3LinkParse moves to AstVar::sigPublic
VAR_PUBLIC_FLAT_RW, // V3LinkParse moves to AstVar::sigPublic
VAR_ISOLATE_ASSIGNMENTS, // V3LinkParse moves to AstVar::attrIsolateAssign
VAR_SC_BV, // V3LinkParse moves to AstVar::attrScBv
VAR_SFORMAT // V3LinkParse moves to AstVar::attrSFormat
};
enum en m_e;
const char* ascii() const {
static const char* names[] = {
"EXPR_BITS", "VAR_BASE",
"%E-AT", "EXPR_BITS", "VAR_BASE",
"VAR_CLOCK", "VAR_CLOCK_ENABLE", "VAR_PUBLIC",
"VAR_PUBLIC_FLAT", "VAR_PUBLIC_FLAT_RD","VAR_PUBLIC_FLAT_RW",
"VAR_ISOLATE_ASSIGNMENTS", "VAR_SFORMAT"
"VAR_ISOLATE_ASSIGNMENTS", "VAR_SC_BV", "VAR_SFORMAT"
};
return names[m_e];
};
inline AstAttrType () {}
inline AstAttrType () : m_e(ILLEGAL) {}
inline AstAttrType (en _e) : m_e(_e) {}
explicit inline AstAttrType (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -238,6 +242,7 @@ public:
class AstBasicDTypeKwd {
public:
enum en {
UNKNOWN,
BIT, BYTE, CHANDLE, INT, INTEGER, LOGIC, LONGINT,
DOUBLE, SHORTINT, FLOAT, TIME,
// Closer to a class type, but limited usage
@@ -250,6 +255,7 @@ public:
enum en m_e;
const char* ascii() const {
static const char* names[] = {
"%E-unk",
"bit", "byte", "chandle", "int", "integer", "logic", "longint",
"real", "shortint", "shortreal", "time",
"string",
@@ -260,6 +266,7 @@ public:
};
const char* dpiType() const {
static const char* names[] = {
"%E-unk",
"unsigned char", "char", "void*", "int", "int", "svLogic", "long long",
"double", "short int", "float", "long long",
"const char*",
@@ -268,7 +275,7 @@ public:
};
return names[m_e];
};
inline AstBasicDTypeKwd () {}
inline AstBasicDTypeKwd () : m_e(UNKNOWN) {}
inline AstBasicDTypeKwd (en _e) : m_e(_e) {}
explicit inline AstBasicDTypeKwd (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -351,7 +358,7 @@ public:
XTEMP
};
enum en m_e;
inline AstVarType () {}
inline AstVarType () : m_e(UNKNOWN) {}
inline AstVarType (en _e) : m_e(_e) {}
explicit inline AstVarType (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -409,7 +416,7 @@ public:
CT_CASEZ
};
enum en m_e;
inline AstCaseType () {}
inline AstCaseType () : m_e(CT_CASE) {}
inline AstCaseType (en _e) : m_e(_e) {}
explicit inline AstCaseType (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -431,7 +438,7 @@ public:
DT_FATAL
};
enum en m_e;
inline AstDisplayType () {}
inline AstDisplayType () : m_e(DT_DISPLAY) {}
inline AstDisplayType (en _e) : m_e(_e) {}
explicit inline AstDisplayType (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
@@ -641,7 +648,7 @@ public:
AstNRelinker() { m_backp=NULL; m_chg=RELINK_BAD; m_iterpp=NULL;}
void relink(AstNode* newp);
AstNode* oldp() const { return m_oldp; }
void dump(ostream& str=cout);
void dump(ostream& str=cout) const;
};
inline ostream& operator<<(ostream& os, AstNRelinker& rhs) { rhs.dump(os); return os;}
@@ -754,6 +761,7 @@ class AstNode {
void deleteTreeIter();
void deleteNode();
static void relinkOneLink(AstNode*& pointpr, AstNode* newp);
// cppcheck-suppress functionConst
void debugTreeChange(const char* prefix, int lineno, bool next);
protected:
@@ -819,6 +827,7 @@ public:
static int instrCountPli() { return 20; } ///< Instruction cycles to call pli routines
static int instrCountDouble() { return 8; } ///< Instruction cycles to convert or do floats
static int instrCountDoubleDiv() { return 40; } ///< Instruction cycles to divide floats
static int instrCountDoubleTrig() { return 200; } ///< Instruction cycles to do triganomics
static int instrCountCall() { return instrCountBranch()+10; } ///< Instruction cycles to call subroutine
static int instrCountTime() { return instrCountCall()+5; } ///< Instruction cycles to determine simulation time
@@ -945,7 +954,7 @@ public:
bool sameTree(AstNode* node2p); // Does tree of this == node2p?
void deleteTree(); // Always deletes the next link
void checkTree(); // User Interface version
void dumpPtrs(ostream& str=cout);
void dumpPtrs(ostream& str=cout) const;
void dumpTree(ostream& str=cout, const string& indent=" ", int maxDepth=0);
void dumpTreeAndNext(ostream& str=cout, const string& indent=" ", int maxDepth=0);
void dumpTreeFile(const string& filename, bool append=false);
@@ -1012,6 +1021,7 @@ struct AstNodeTermop : public AstNodeMath {
ASTNODE_BASE_FUNCS(NodeTermop)
// Know no children, and hot function, so skip iterator for speed
// See checkTreeIter also that asserts no children
// cppcheck-suppress functionConst
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { }
};
@@ -1274,6 +1284,7 @@ public:
void packagep(AstPackage* nodep) { m_packagep=nodep; }
// Know no children, and hot function, so skip iterator for speed
// See checkTreeIter also that asserts no children
// cppcheck-suppress functionConst
void iterateChildren(AstNVisitor& v, AstNUser* vup=NULL) { }
};
+2 -2
View File
@@ -70,7 +70,7 @@ bool AstVar::isScQuad() const {
}
bool AstVar::isScBv() const {
return (isSc() && width() >= v3Global.opt.pinsBv());
return ((isSc() && width() >= v3Global.opt.pinsBv()) || m_attrScBv);
}
void AstVar::combineType(AstVarType type) {
@@ -501,7 +501,7 @@ void AstNode::dump(ostream& os) {
//<<" "<<(void*)this->m_backp
<<" <e"<<dec<<editCount()
<<((editCount()>=editCountLast())?"#>":">")
<<" {"<<dec<<fileline()->lineno()<<"}"
<<" {"<<fileline()->filenameLetters()<<dec<<fileline()->lineno()<<"}"
<<" "<<(isSigned()?"s":"")
<<(isDouble()?"d":"")
<<"w"<<(widthSized()?"":"u")<<width();
+138 -32
View File
@@ -461,10 +461,10 @@ public:
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return true; }
virtual int instrCount() const { return widthInstrs(); }
unsigned length() { return m_length; }
unsigned length() const { return m_length; }
void length(unsigned length) { m_length = length; }
void start(unsigned start) { m_start = start; }
unsigned start() { return m_start; }
unsigned start() const { return m_start; }
// Special operators
static int dimension(AstNode* nodep); ///< How many dimensions is this reference from the base variable?
static AstNode* baseFromp(AstNode* nodep); ///< What is the base variable (or const) this dereferences?
@@ -587,6 +587,7 @@ private:
bool m_funcLocal:1; // Local variable for a function
bool m_funcReturn:1; // Return variable for a function
bool m_attrClockEn:1;// User clock enable attribute
bool m_attrScBv:1; // User force bit vector attribute
bool m_attrIsolateAssign:1;// User isolate_assignments attribute
bool m_attrSFormat:1;// User sformat attribute
bool m_fileDescr:1; // File descriptor
@@ -601,7 +602,7 @@ private:
m_usedClock=false; m_usedParam=false; m_usedLoopIdx=false;
m_sigPublic=false; m_sigModPublic=false; m_sigUserRdPublic=false; m_sigUserRWPublic=false;
m_funcLocal=false; m_funcReturn=false;
m_attrClockEn=false; m_attrIsolateAssign=false; m_attrSFormat=false;
m_attrClockEn=false; m_attrScBv=false; m_attrIsolateAssign=false; m_attrSFormat=false;
m_fileDescr=false; m_isConst=false; m_isStatic=false;
m_trace=false;
}
@@ -664,6 +665,7 @@ public:
void attrClockEn(bool flag) { m_attrClockEn = flag; }
void attrFileDescr(bool flag) { m_fileDescr = flag; }
void attrScClocked(bool flag) { m_scClocked = flag; }
void attrScBv(bool flag) { m_attrScBv = flag; }
void attrIsolateAssign(bool flag) { m_attrIsolateAssign = flag; }
void attrSFormat(bool flag) { m_attrSFormat = flag; }
void usedClock(bool flag) { m_usedClock = flag; }
@@ -724,6 +726,7 @@ public:
bool isFuncLocal() const { return m_funcLocal; }
bool isFuncReturn() const { return m_funcReturn; }
bool attrClockEn() const { return m_attrClockEn; }
bool attrScBv() const { return m_attrScBv; }
bool attrFileDescr() const { return m_fileDescr; }
bool attrScClocked() const { return m_scClocked; }
bool attrSFormat() const { return m_attrSFormat; }
@@ -970,6 +973,14 @@ struct AstModule : public AstNodeModule {
virtual string verilogKwd() const { return "module"; }
};
struct AstNotFoundModule : public AstNodeModule {
// A missing module declaration
AstNotFoundModule(FileLine* fl, const string& name)
: AstNodeModule (fl,name) {}
ASTNODE_NODE_FUNCS(NotFoundModule, NOTFOUNDMODULE)
virtual string verilogKwd() const { return "/*not-found-*/ module"; }
};
struct AstPackage : public AstNodeModule {
// A package declaration
AstPackage(FileLine* fl, const string& name)
@@ -1457,15 +1468,6 @@ struct AstCondBound : public AstNodeCond {
ASTNODE_NODE_FUNCS(CondBound, CONDBOUND)
};
struct AstCondD : public AstNodeCond {
// Conditional ?: statement, double rhs/lhs/out
// Parents: MATH
// Children: MATH
AstCondD(FileLine* fl, AstNode* condp, AstNode* expr1p, AstNode* expr2p)
: AstNodeCond(fl, condp, expr1p, expr2p) { numeric(AstNumeric::DOUBLE); }
ASTNODE_NODE_FUNCS(CondD, CONDD)
};
struct AstCoverDecl : public AstNodeStmt {
// Coverage analysis point declaration
// Parents: {statement list}
@@ -1893,6 +1895,45 @@ public:
AstNode* msbp() const { return op4p()->castNode(); }
};
struct AstSystemT : public AstNodeStmt {
// $system used as task
AstSystemT(FileLine* fileline, AstNode* lhsp)
: AstNodeStmt (fileline) {
setOp1p(lhsp);
}
ASTNODE_NODE_FUNCS(SystemT, SYSTEMT)
virtual string verilogKwd() const { return "$system"; }
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* lhsp() const { return op1p(); }
};
struct AstSystemF : public AstNodeMath {
// $system used as function
AstSystemF(FileLine* fileline, AstNode* lhsp)
: AstNodeMath (fileline) {
setOp1p(lhsp);
}
ASTNODE_NODE_FUNCS(SystemF, SYSTEMF)
virtual string verilogKwd() const { return "$system"; }
virtual string emitVerilog() { return verilogKwd(); }
virtual string emitC() { return "VL_SYSTEM_%nq(%lw, %P)"; }
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 bool cleanOut() { return true; }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode* samep) const { return true; }
AstNode* lhsp() const { return op1p(); }
};
struct AstValuePlusArgs : public AstNodeMath {
// Parents: expr
// Child: variable to set. If NULL then this is a $test$plusargs instead of $value$plusargs
@@ -2832,6 +2873,90 @@ struct AstFGetC : public AstNodeUniop {
AstNode* filep() const { return lhsp(); }
};
struct AstCeilD : public AstNodeUniop {
AstCeilD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
numeric(AstNumeric::DOUBLE); }
ASTNODE_NODE_FUNCS(CeilD, CEILD)
virtual void numberOperate(V3Number& out, const V3Number& lhs) {
out.setDouble(ceil(lhs.toDouble())); }
virtual string emitVerilog() { return "%f$ceil(%l)"; }
virtual string emitC() { return "ceil(%li)"; }
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;}
virtual bool sizeMattersLhs() {return false;}
virtual int instrCount() const { return instrCountDoubleTrig(); }
virtual bool doubleFlavor() const { return true; }
};
struct AstExpD : public AstNodeUniop {
AstExpD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
numeric(AstNumeric::DOUBLE); }
ASTNODE_NODE_FUNCS(ExpD, EXPD)
virtual void numberOperate(V3Number& out, const V3Number& lhs) {
out.setDouble(exp(lhs.toDouble())); }
virtual string emitVerilog() { return "%f$exp(%l)"; }
virtual string emitC() { return "exp(%li)"; }
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;}
virtual bool sizeMattersLhs() {return false;}
virtual int instrCount() const { return instrCountDoubleTrig(); }
virtual bool doubleFlavor() const { return true; }
};
struct AstFloorD : public AstNodeUniop {
AstFloorD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
numeric(AstNumeric::DOUBLE); }
ASTNODE_NODE_FUNCS(FloorD, FLOORD)
virtual void numberOperate(V3Number& out, const V3Number& lhs) {
out.setDouble(floor(lhs.toDouble())); }
virtual string emitVerilog() { return "%f$floor(%l)"; }
virtual string emitC() { return "floor(%li)"; }
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;}
virtual bool sizeMattersLhs() {return false;}
virtual int instrCount() const { return instrCountDoubleTrig(); }
virtual bool doubleFlavor() const { return true; }
};
struct AstLogD : public AstNodeUniop {
AstLogD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
numeric(AstNumeric::DOUBLE); }
ASTNODE_NODE_FUNCS(LogD, LOGD)
virtual void numberOperate(V3Number& out, const V3Number& lhs) {
out.setDouble(log(lhs.toDouble())); }
virtual string emitVerilog() { return "%f$ln(%l)"; }
virtual string emitC() { return "log(%li)"; }
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;}
virtual bool sizeMattersLhs() {return false;}
virtual int instrCount() const { return instrCountDoubleTrig(); }
virtual bool doubleFlavor() const { return true; }
};
struct AstLog10D : public AstNodeUniop {
AstLog10D(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
numeric(AstNumeric::DOUBLE); }
ASTNODE_NODE_FUNCS(Log10D, LOG10D)
virtual void numberOperate(V3Number& out, const V3Number& lhs) {
out.setDouble(log10(lhs.toDouble())); }
virtual string emitVerilog() { return "%f$log10(%l)"; }
virtual string emitC() { return "log10(%li)"; }
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;}
virtual bool sizeMattersLhs() {return false;}
virtual int instrCount() const { return instrCountDoubleTrig(); }
virtual bool doubleFlavor() const { return true; }
};
struct AstSqrtD : public AstNodeUniop {
AstSqrtD(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
numeric(AstNumeric::DOUBLE); }
ASTNODE_NODE_FUNCS(SqrtD, SQRTD)
virtual void numberOperate(V3Number& out, const V3Number& lhs) {
out.setDouble(sqrt(lhs.toDouble())); }
virtual string emitVerilog() { return "%f$sqrt(%l)"; }
virtual string emitC() { return "sqrt(%li)"; }
virtual bool cleanOut() {return true;} virtual bool cleanLhs() {return false;}
virtual bool sizeMattersLhs() {return false;}
virtual int instrCount() const { return instrCountDoubleTrig(); }
virtual bool doubleFlavor() const { return true; }
};
//======================================================================
// Binary ops
@@ -3465,7 +3590,7 @@ struct AstBufIf1 : public AstNodeBiop {
virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opBufIf1(lhs,rhs); }
virtual string emitVerilog() { return "bufif(%r,%l)"; }
virtual string emitC() { V3ERROR_NA; return "";} // Lclean || Rclean
virtual string emitSimpleOperator() { V3ERROR_NA; return false;} // Lclean || Rclean
virtual string emitSimpleOperator() { V3ERROR_NA; return "";} // Lclean || Rclean
virtual bool cleanOut() {V3ERROR_NA; return "";} // Lclean || Rclean
virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
@@ -3904,25 +4029,6 @@ struct AstCReturn : public AstNodeStmt {
AstNode* lhsp() const { return op1p(); }
};
struct AstCInclude : public AstNode {
// C++ use of another class
// Parents: MODULE
// Children: None
private:
AstNodeModule* m_modp;
public:
AstCInclude(FileLine* fl, AstNodeModule* modp)
: AstNode(fl) {
m_modp = modp;
}
ASTNODE_NODE_FUNCS(CInclude, CINCLUDE)
virtual bool broken() const { return (m_modp && !m_modp->brokeExists()); }
virtual void cloneRelink() { if (m_modp && m_modp->clonep()) {
m_modp = m_modp->clonep()->castNodeModule();
}}
AstNodeModule* modp() const { return m_modp; }
};
struct AstCMath : public AstNodeMath {
private:
bool m_cleanOut;
+2 -2
View File
@@ -452,10 +452,10 @@ private:
if (isCaseTreeFast(nodep) && v3Global.opt.oCase()) {
// It's a simple priority encoder or complete statement
// we can make a tree of statements to avoid extra comparisons
m_statCaseFast++;
++m_statCaseFast;
replaceCaseFast(nodep); nodep=NULL;
} else {
m_statCaseSlow++;
++m_statCaseSlow;
replaceCaseComplicated(nodep); nodep=NULL;
}
}
+2 -1
View File
@@ -315,6 +315,7 @@ public:
m_exprp = exprp;
m_original = original;
m_state = STATE_UNKNOWN;
m_cloning = false;
if (debug()>=9) nodep->dumpTree(cout," GateBodyIn: ");
nodep->bodysp()->iterateAndNext(*this);
if (debug()>=9) nodep->dumpTree(cout," GateBodyOut: ");
@@ -696,7 +697,7 @@ class GaterVisitor : public GaterBaseVisitor {
// Blow old statements from new body
GaterBodyVisitor(alwp,exprp,false);
m_statGaters++;
++m_statGaters;
if (debug()>=9) alwp->dumpTree(cout," new: ");
}
+6 -4
View File
@@ -70,8 +70,8 @@ protected:
virtual ~CombBaseVisitor() {}
//***** optimization levels
bool emptyFunctionDeletion() { return true; }
bool duplicateFunctionCombine() { return true; }
static bool emptyFunctionDeletion() { return true; }
static bool duplicateFunctionCombine() { return true; }
// Note this is disabled, it still needed work
// Also repair it for DPI functions; when make __common need to insure proper
// flags get inherited from the old to new AstCFunc, and that AstText doesn't
@@ -146,7 +146,9 @@ private:
}
public:
// CONSTRUCTORS
CombCallVisitor() {}
CombCallVisitor() {
m_find = false;
}
virtual ~CombCallVisitor() {}
void main(AstNetlist* nodep) {
nodep->accept(*this);
@@ -257,7 +259,7 @@ private:
UINFO(5," DupFunc "<<hex<<V3Hash(newfuncp->user4p())<<" "<<newfuncp<<endl);
UINFO(5," and "<<hex<<V3Hash(oldfuncp->user4p())<<" "<<oldfuncp<<endl);
// Mark user3p on entire old tree, so we don't process it more
m_statCombs++;
++m_statCombs;
CombMarkVisitor visitor(oldfuncp);
m_call.replaceFunc(oldfuncp, newfuncp);
oldfuncp->unlinkFrBack();
+8 -2
View File
@@ -821,7 +821,9 @@ private:
AstNodeAssign* asn2ap=nodep->cloneType(lc2p, sel2p)->castNodeAssign();
asn1ap->width(msb1-lsb1+1,msb1-lsb1+1);
asn2ap->width(msb2-lsb2+1,msb2-lsb2+1);
// cppcheck-suppress nullPointer // addNext deals with it
newp = newp->addNext(asn1ap);
// cppcheck-suppress nullPointer // addNext deals with it
newp = newp->addNext(asn2ap);
} else {
if (!m_modp) nodep->v3fatalSrc("Not under module");
@@ -852,12 +854,16 @@ private:
asn2ap->width(msb2-lsb2+1,msb2-lsb2+1);
asn2bp->width(msb2-lsb2+1,msb2-lsb2+1);
// This order matters
// cppcheck-suppress nullPointer // addNext deals with it
newp = newp->addNext(asn1ap);
// cppcheck-suppress nullPointer // addNext deals with it
newp = newp->addNext(asn2ap);
// cppcheck-suppress nullPointer // addNext deals with it
newp = newp->addNext(asn1bp);
// cppcheck-suppress nullPointer // addNext deals with it
newp = newp->addNext(asn2bp);
}
if (debug()>=9) newp->dumpTreeAndNext(cout," _new: ");
if (debug()>=9 && newp) newp->dumpTreeAndNext(cout," _new: ");
nodep->addNextHere(newp);
// Cleanup
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
@@ -1534,7 +1540,7 @@ private:
UINFO(9," DispConst: "<<fmt<<" -> "<<out<<" for "<<argp<<endl);
{ // fmt = out w/ replace % with %% as it must be literal.
fmt = "";
for (string::iterator pos = out.begin(); pos != out.end(); pos++) {
for (string::iterator pos = out.begin(); pos != out.end(); ++pos) {
if (*pos == '%') fmt += '%';
fmt += *pos;
}
+1 -1
View File
@@ -97,7 +97,7 @@ private:
removep->unlinkFrBack(); pushDeletep(removep); removep=NULL;
// Remove node from comparison so don't hit it again
hashed.erase(dupit);
m_statToggleJoins++;
++m_statToggleJoins;
}
}
}
+1 -3
View File
@@ -224,7 +224,6 @@ private:
}
//
//=== Setting/not setting boolean: __Vdlyvset__
bool sharedVset = false;
AstVarScope* setvscp;
if (nodep->user3p()) {
@@ -232,9 +231,8 @@ private:
// then we told this nodep->user3 we can use its Vdlyvset rather than making a new one.
// This is good for code like:
// for (i=0; i<5; i++) vector[i] <= something;
sharedVset = true;
setvscp = nodep->user3p()->castNode()->castVarScope();
m_statSharedSet++;
++m_statSharedSet;
} else { // Create new one
string setvarname = (string("__Vdlyvset__")+oldvarp->shortName()+"__v"+cvtToStr(modVecNum));
setvscp = createVarSc(varrefp->varScopep(), setvarname, 1);
+30 -3
View File
@@ -55,9 +55,9 @@ public:
}
// ACCESSORS
int splitFilenum() { return m_splitFilenum; }
int splitFilenum() const { return m_splitFilenum; }
int splitFilenumInc() { m_splitSize = 0; return ++m_splitFilenum; }
int splitSize() { return m_splitSize; }
int splitSize() const { return m_splitSize; }
void splitSizeInc(AstNode* nodep) { m_splitSize += EmitCBaseCounterVisitor(nodep).count(); }
bool splitNeeded() { return (splitSize() && v3Global.opt.outputSplit() > 1
&& v3Global.opt.outputSplit() < splitSize()); }
@@ -361,6 +361,30 @@ public:
puts(")); }\n");
}
}
virtual void visit(AstSystemT* nodep, AstNUser*) {
puts("(void)VL_SYSTEM_I");
emitIQW(nodep->lhsp());
puts("(");
if (nodep->lhsp()->isWide()) {
puts(cvtToStr(nodep->lhsp()->widthWords()));
putbs(", ");
}
checkMaxWords(nodep->lhsp());
nodep->lhsp()->iterateAndNext(*this);
puts(");\n");
}
virtual void visit(AstSystemF* nodep, AstNUser*) {
puts("VL_SYSTEM_I");
emitIQW(nodep->lhsp());
puts("(");
if (nodep->lhsp()->isWide()) {
puts(cvtToStr(nodep->lhsp()->widthWords()));
putbs(", ");
}
checkMaxWords(nodep->lhsp());
nodep->lhsp()->iterateAndNext(*this);
puts(")");
}
virtual void visit(AstJumpGo* nodep, AstNUser*) {
puts("goto __Vlabel"+cvtToStr(nodep->labelp()->labelNum())+";\n");
}
@@ -546,7 +570,7 @@ public:
}
ofp()->printf(",0x%08" VL_PRI64 "x)", (vluint64_t)(nodep->num().dataWord(0)));
} else if (nodep->isDouble()) {
ofp()->printf("%g", nodep->num().toDouble());
ofp()->printf("%.17g", nodep->num().toDouble());
} else if (nodep->isQuad()) {
vluint64_t num = nodep->toUQuad();
if (num<10) ofp()->printf("VL_ULL(%" VL_PRI64 "d)", num);
@@ -830,6 +854,8 @@ class EmitCImp : EmitCStmts {
public:
EmitCImp() {
m_modp = NULL;
m_slow = false;
m_fast = false;
}
virtual ~EmitCImp() {}
void main(AstNodeModule* modp, bool slow, bool fast);
@@ -1424,6 +1450,7 @@ void EmitCImp::emitStaticDecl(AstNodeModule* modp) {
// Need implementation here. Be careful of alignment code; needs to be uniquified
// with module name to avoid multiple symbols.
//emitVarList(modp->stmtsp(), EVL_ALL, modp->name());
puts(""); // NOP for cppcheck, otherwise const function
}
void EmitCImp::emitTextSection(AstType type) {
+2 -2
View File
@@ -526,8 +526,8 @@ void EmitCSyms::emitDpiHdr() {
puts("#endif\n");
puts("\n");
bool firstExp = false;
bool firstImp = false;
int firstExp = 0;
int firstImp = 0;
for (vector<AstCFunc*>::iterator it = m_dpis.begin(); it != m_dpis.end(); ++it) {
AstCFunc* nodep = *it;
if (nodep->dpiExportWrapper()) {
+40 -7
View File
@@ -34,8 +34,6 @@
//======================================================================
// Statics
FileLine FileLine::s_defaultFileLine = FileLine(EmptySecret());
int V3Error::s_errCount = 0;
int V3Error::s_warnCount = 0;
int V3Error::s_debugDefault = 0;
@@ -66,12 +64,28 @@ V3ErrorCode::V3ErrorCode(const char* msgp) {
m_e = V3ErrorCode::EC_ERROR;
}
//######################################################################
// FileLineSingleton class functions
int FileLineSingleton::nameToNumber(const string& filename) {
// Convert filenames to a filenameno
// This lets us assign a nice small identifier for debug messages, but more
// importantly lets us use a 4 byte int instead of 8 byte pointer in every FileLine.
map<string,int>::const_iterator iter = m_namemap.find(filename);
if (VL_LIKELY(iter != m_namemap.end())) return iter->second;
int num = m_names.size();
m_names.push_back(filename);
m_namemap.insert(make_pair(filename,num));
return num;
}
//######################################################################
// FileLine class functions
FileLine::FileLine(FileLine::EmptySecret) {
// Sort of a singleton
m_lineno=0;
m_filename="COMMAND_LINE";
m_filenameno=singleton().nameToNumber("AstRoot");
m_warnOn=0;
for (int codei=V3ErrorCode::EC_MIN; codei<V3ErrorCode::_ENUM_MAX; codei++) {
@@ -80,6 +94,19 @@ FileLine::FileLine(FileLine::EmptySecret) {
}
}
const string FileLine::filenameLetters() const {
const int size = 1 + (64 / 4); // Each letter retires more than 4 bits of a > 64 bit number
char out[size];
char* op = out+size-1;
*--op = '\0'; // We build backwards
int num = m_filenameno;
do {
*--op = 'a'+num%26;
num /= 26;
} while (num);
return op;
}
string FileLine::lineDirectiveStrg(int enterExit) const {
char numbuf[20]; sprintf(numbuf, "%d", lineno());
char levelbuf[20]; sprintf(levelbuf, "%d", enterExit);
@@ -262,6 +289,7 @@ void FileLine::deleteAllRemaining() {
// Eventually the list will be empty and terminate the loop.
}
fileLineLeakChecks.clear();
FileLineSingleton::clear();
#endif
}
@@ -304,13 +332,18 @@ void V3Error::incErrors() {
void V3Error::abortIfErrors() {
if (errorCount()) {
v3fatal ("Exiting due to "<<dec<<errorOrWarnCount()<<" warning(s)\n");
abortIfWarnings();
}
}
void V3Error::abortIfWarnings() {
if (v3Global.opt.warnFatal() ? errorOrWarnCount() : errorCount()) {
v3fatal ("Exiting due to "<<dec<<errorOrWarnCount()<<" warning(s)\n");
bool exwarn = v3Global.opt.warnFatal() && warnCount();
if (errorCount() && exwarn) {
v3fatal ("Exiting due to "<<dec<<errorCount()<<" error(s), "<<warnCount()<<" warning(s)\n");
} else if (errorCount()) {
v3fatal ("Exiting due to "<<dec<<errorCount()<<" error(s)\n");
} else if (exwarn) {
v3fatal ("Exiting due to "<<dec<<warnCount()<<" warning(s)\n");
}
}
@@ -370,7 +403,7 @@ void V3Error::suppressThisWarning() {
}
void V3Error::v3errorEnd (ostringstream& sstr) {
#ifdef __COVERITY__
#if defined(__COVERITY__) || defined(__cppcheck__)
if (s_errorCode==V3ErrorCode::EC_FATAL) __coverity_panic__(x);
#endif
if (!s_errorSuppressed
+59 -18
View File
@@ -28,6 +28,8 @@
#include <iostream>
#include <sstream>
#include <bitset>
#include <map>
#include <deque>
//######################################################################
@@ -46,13 +48,15 @@ public:
I_LINT, // All lint messages
I_DEF_NETTYPE_WIRE, // `default_nettype is WIRE (false=NONE)
// Error codes:
E_BLKLOOPINIT, // Error: Delayed assignment to array inside for loops
E_MULTITOP, // Error: Multiple top level modules
E_TASKNSVAR, // Error: Task I/O not simple
E_BLKLOOPINIT, // Error: Delayed assignment to array inside for loops
//
// Warning codes:
EC_FIRST_WARN, // Just a code so the program knows where to start warnings
//
ASSIGNDLY, // Assignment delays
ASSIGNIN, // Assigning to input
BLKANDNBLK, // Blocked and non-blocking assignments to same variable
BLKSEQ, // Blocking assignments in sequential block
CASEINCOMPLETE, // Case statement has missing values
@@ -90,7 +94,7 @@ public:
// ***Add new elements below also***
};
enum en m_e;
inline V3ErrorCode () {}
inline V3ErrorCode () : m_e(EC_MIN) {}
inline V3ErrorCode (en _e) : m_e(_e) {}
V3ErrorCode (const char* msgp); // Matching code or ERROR
explicit inline V3ErrorCode (int _e) : m_e(static_cast<en>(_e)) {}
@@ -102,9 +106,10 @@ public:
// Boolean
" I_COVERAGE", " I_TRACING", " I_LINT", " I_DEF_NETTYPE_WIRE",
// Errors
"MULTITOP", "TASKNSVAR", "BLKLOOPINIT",
"BLKLOOPINIT", "MULTITOP", "TASKNSVAR",
// Warnings
" EC_FIRST_WARN",
"ASSIGNDLY", "ASSIGNIN",
"BLKANDNBLK", "BLKSEQ",
"CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CDCRSTLOGIC", "CMPCONST",
"COMBDLY", "DEFPARAM", "DECLFILENAME",
@@ -126,7 +131,8 @@ public:
bool dangerous() const { return ( m_e==COMBDLY ); }
// Warnings we'll present to the user as errors
// Later -Werror- options may make more of these.
bool pretendError() const { return ( m_e==BLKANDNBLK || m_e==IMPURE || m_e==MODDUP || m_e==SYMRSVDWORD); }
bool pretendError() const { return ( m_e==ASSIGNIN || m_e==BLKANDNBLK
|| m_e==IMPURE || m_e==MODDUP || m_e==SYMRSVDWORD); }
// Warnings to mention manual
bool mentionManual() const { return ( m_e==EC_FATALSRC || pretendError() ); }
@@ -140,7 +146,8 @@ public:
|| m_e==UNSIGNED
|| m_e==WIDTH); }
// Warnings that are style only
bool styleError() const { return ( m_e==BLKSEQ
bool styleError() const { return ( m_e==ASSIGNDLY // More than style, but for backward compatibility
|| m_e==BLKSEQ
|| m_e==DEFPARAM
|| m_e==DECLFILENAME
|| m_e==INCABSPATH
@@ -244,29 +251,58 @@ inline uint32_t cvtToHash(void* vp) {
//######################################################################
class FileLine;
class FileLineSingleton {
map<string,int> m_namemap; // filenameno for each filename
deque<string> m_names; // filename text for each filenameno
// COSNTRUCTORS
FileLineSingleton() { }
~FileLineSingleton() { }
protected:
friend class FileLine;
// METHODS
int nameToNumber(const string& filename);
string numberToName(int filenameno) { return m_names[filenameno]; }
void clear() { m_namemap.clear(); m_names.clear(); }
};
class FileLine {
// File and line number of an object, mostly for error reporting
int m_lineno;
string m_filename;
int m_filenameno;
bitset<V3ErrorCode::_ENUM_MAX> m_warnOn;
// Consider moving opt.language() into here, so can know language per-node
static FileLine s_defaultFileLine;
private:
struct EmptySecret {};
inline static FileLineSingleton& singleton() {
static FileLineSingleton s;
return s;
}
inline static FileLine& defaultFileLine() {
static FileLine* defFilelinep = new FileLine(FileLine::EmptySecret());
return *defFilelinep;
}
protected:
// User routines should never need to change line numbers
// We are storing pointers, so we CAN'T change them after initial reading.
friend class FileLineSingleton;
friend class V3ParseImp;
friend class V3PreLex;
friend class V3PreProcImp;
void lineno(int num) { m_lineno = num; }
void filename(const string& name) { m_filename = name; }
void filename(const string& name) { m_filenameno = singleton().nameToNumber(name); }
void lineDirective(const char* textp, int& enterExitRef);
void linenoInc() { m_lineno++; }
void linenoIncInPlace() { m_lineno++; }
FileLine* copyOrSameFileLine();
public:
FileLine (const string& filename, int lineno) { m_lineno=lineno; m_filename = filename; m_warnOn=s_defaultFileLine.m_warnOn; }
FileLine (FileLine* fromp) { m_lineno=fromp->lineno(); m_filename = fromp->filename(); m_warnOn=fromp->m_warnOn; }
FileLine (const string& filename, int lineno) {
m_lineno=lineno; m_filenameno = singleton().nameToNumber(filename);
m_warnOn=defaultFileLine().m_warnOn; }
FileLine (FileLine* fromp) {
m_lineno=fromp->m_lineno; m_filenameno = fromp->m_filenameno; m_warnOn=fromp->m_warnOn; }
FileLine (EmptySecret);
~FileLine() { }
FileLine* create(const string& filename, int lineno) { return new FileLine(filename,lineno); }
@@ -279,7 +315,8 @@ public:
int lineno () const { return m_lineno; }
string ascii() const;
const string filename () const { return m_filename; }
const string filename () const { return singleton().numberToName(m_filenameno); }
const string filenameLetters() const;
const string filebasename () const;
const string filebasenameNoExt () const;
const string profileFuncname() const;
@@ -291,7 +328,7 @@ public:
void warnLintOff(bool flag);
void warnStyleOff(bool flag);
void warnStateFrom(const FileLine& from) { m_warnOn=from.m_warnOn; }
void warnResetDefault() { warnStateFrom(s_defaultFileLine); }
void warnResetDefault() { warnStateFrom(defaultFileLine()); }
// Specific flag ACCESSORS/METHODS
bool coverageOn() const { return m_warnOn.test(V3ErrorCode::I_COVERAGE); }
@@ -300,10 +337,14 @@ public:
void tracingOn(bool flag) { warnOn(V3ErrorCode::I_TRACING,flag); }
// METHODS - Global
static void globalWarnLintOff(bool flag) { s_defaultFileLine.warnLintOff(flag); }
static void globalWarnStyleOff(bool flag) { s_defaultFileLine.warnStyleOff(flag); }
static void globalWarnOff(V3ErrorCode code, bool flag) { s_defaultFileLine.warnOff(code, flag); }
static bool globalWarnOff(const string& code, bool flag) { return s_defaultFileLine.warnOff(code, flag); }
static void globalWarnLintOff(bool flag) {
defaultFileLine().warnLintOff(flag); }
static void globalWarnStyleOff(bool flag) {
defaultFileLine().warnStyleOff(flag); }
static void globalWarnOff(V3ErrorCode code, bool flag) {
defaultFileLine().warnOff(code, flag); }
static bool globalWarnOff(const string& code, bool flag) {
return defaultFileLine().warnOff(code, flag); }
// METHODS - Called from netlist
// Merge warning disables from another fileline
@@ -315,8 +356,8 @@ public:
// OPERATORS
void v3errorEnd(ostringstream& str);
inline bool operator==(FileLine rhs) {
return (m_lineno==rhs.m_lineno && m_filename==rhs.m_filename && m_warnOn==rhs.m_warnOn);
inline bool operator==(FileLine rhs) const {
return (m_lineno==rhs.m_lineno && m_filenameno==rhs.m_filenameno && m_warnOn==rhs.m_warnOn);
}
};
ostream& operator<<(ostream& os, FileLine* fileline);
+3
View File
@@ -327,6 +327,7 @@ private:
#endif
}
// cppcheck-suppress functionConst
void checkFilter(bool hang) {
#ifdef INFILTER_PIPE
if (!m_pidExited && waitpid(m_pid, &m_pidStatus, hang?0:WNOHANG)) {
@@ -355,6 +356,7 @@ private:
|| errno == EWOULDBLOCK
#endif
) {
// cppcheck-suppress obsoleteFunctionsusleep
checkFilter(false); usleep(1000); continue;
} else { m_readEof = true; break; }
}
@@ -390,6 +392,7 @@ private:
|| errno == EWOULDBLOCK
#endif
) {
// cppcheck-suppress obsoleteFunctionsusleep
checkFilter(false); usleep(1000); continue;
}
else break;
+2 -2
View File
@@ -535,7 +535,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
AstNode* substp = okVisitor.substTree();
if (debug()>=5) logicp->dumpTree(cout,"\telimVar: ");
if (debug()>=5) substp->dumpTree(cout,"\t subst: ");
m_statSigs++;
++m_statSigs;
while (V3GraphEdge* edgep = vvertexp->outBeginp()) {
GateLogicVertex* consumeVertexp = dynamic_cast<GateLogicVertex*>(edgep->top());
AstNode* consumerp = consumeVertexp->nodep();
@@ -557,7 +557,7 @@ void GateVisitor::optimizeSignals(bool allowMultiIn) {
}
// Remove the edge
edgep->unlinkDelete(); edgep=NULL;
m_statRefs++;
++m_statRefs;
}
// Remove input links
while (V3GraphEdge* edgep = vvertexp->inBeginp()) {
+4 -4
View File
@@ -70,7 +70,7 @@ private:
// MEMBERS
uint32_t m_step; // Processing step, so we can avoid clearUser all the time
HashMap m_hashMap; // Dfa Vertex for each set of NFA vertexes
int debug() { return 0; }
static int debug() { return 0; }
// METHODS
DfaGraph* graphp() { return static_cast<DfaGraph*>(m_graphp); }
@@ -94,7 +94,7 @@ private:
}
// Hashing
uint32_t hashVertex(V3GraphVertex* vertexp) {
static uint32_t hashVertex(V3GraphVertex* vertexp) {
union { void* up; struct {uint32_t upper; uint32_t lower;} l;} u;
u.l.upper=0; u.l.lower=0; u.up=vertexp;
return u.l.upper ^ u.l.lower;
@@ -362,7 +362,7 @@ void DfaGraph::nfaToDfa() {
class DfaGraphReduce : GraphAlg {
private:
// METHODS
int debug() { return 0; }
static int debug() { return 0; }
DfaGraph* graphp() { return static_cast<DfaGraph*>(m_graphp); }
bool isDead(DfaVertex* vertexp) {
@@ -507,7 +507,7 @@ private:
DfaVertex* m_tempNewerReject;
// METHODS
int debug() { return 9; }
static int debug() { return 9; }
DfaGraph* graphp() { return static_cast<DfaGraph*>(m_graphp); }
void add_complement_edges() {
+1
View File
@@ -326,6 +326,7 @@ public:
class V3GraphTestImport : public V3GraphTest {
// cppcheck-suppress functionConst
void dotImport();
public:
+1 -1
View File
@@ -106,7 +106,7 @@ private:
if (m_cellp) nodep->v3error("Cloning should have already been done bottom-up");
UINFO(5," Inline CELL "<<nodep<<endl);
UINFO(5," To MOD "<<m_modp<<endl);
m_statCells++;
++m_statCells;
// Before cloning simplify pin assignments
// Better off before, as if module has multiple instantiations
+3
View File
@@ -293,6 +293,7 @@ private:
// LIFE MAP
// For each basic block, we'll make a new map of what variables that if/else is changing
typedef std::map<AstVarScope*, LifeVarEntry> LifeMap;
// cppcheck-suppress memleak // cppcheck bug - it is deleted
LifeBlock* m_lifep; // Current active lifetime map for current scope
// METHODS
@@ -455,6 +456,8 @@ public:
m_sideEffect = false;
m_noopt = false;
{
// Cpp check bug, it is deleted
// cppcheck-suppress leak
m_lifep = new LifeBlock (NULL, m_statep);
nodep->accept(*this);
delete m_lifep; m_lifep=NULL;
+1 -1
View File
@@ -157,7 +157,7 @@ private:
// Mark so LifePostElimVisitor will get it
rhsp->varScopep()->user4p(lhsp->varScopep());
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
m_statAssnDel++;
++m_statAssnDel;
}
}
}
+6 -1
View File
@@ -563,8 +563,13 @@ private:
nodep->v3fatalSrc("Cell has unlinked module"); // V3LinkCell should have errored out
}
else {
if (nodep->modp()->castNotFoundModule()) {
// Prevent warnings about missing pin connects
if (nodep->pinsp()) nodep->pinsp()->unlinkFrBackWithNext()->deleteTree();
if (nodep->paramsp()) nodep->paramsp()->unlinkFrBackWithNext()->deleteTree();
}
// Need to pass the module info to this cell, so we can link up the pin names
if (m_idState==ID_RESOLVE) {
else if (m_idState==ID_RESOLVE) {
m_cellVarsp = nodep->modp()->user4p()->castSymTable();
UINFO(4,"(Backto) Link Cell: "<<nodep<<endl);
//if (debug()) { nodep->dumpTree(cout,"linkcell:"); }
+12 -2
View File
@@ -135,7 +135,15 @@ private:
AstNodeModule* modp = vvertexp->modp();
modp->level(vvertexp->rank()+1);
if (vvertexp == m_topVertexp && modp->level() != 2) {
v3error("Specified --top-module '"<<v3Global.opt.topModule()<<"' isn't at the top level, it's under another cell.");
AstNodeModule* abovep = NULL;
if (V3GraphEdge* edgep = vvertexp->inBeginp()) {
if (LinkCellsVertex* eFromVertexp = dynamic_cast<LinkCellsVertex*>(edgep->fromp())) {
abovep = eFromVertexp->modp();
}
}
v3error("Specified --top-module '"<<v3Global.opt.topModule()
<<"' isn't at the top level, it's under another cell '"
<<(abovep ? abovep->prettyName() : "UNKNOWN")<<"'");
}
}
}
@@ -176,8 +184,10 @@ private:
AstNodeModule* modp = m_mods.findIdUpward(nodep->modName())->castNodeModule();
if (!modp) {
// Read-subfile
// If file not found, make AstNotFoundModule, rather than error out.
// We'll throw the error when we know the module will really be needed.
V3Parse parser (v3Global.rootp(), m_filterp);
parser.parseFile(nodep->fileline(), nodep->modName(), false);
parser.parseFile(nodep->fileline(), nodep->modName(), false, "");
V3Error::abortIfErrors();
// We've read new modules, grab new pointers to their names
readModNames();
+7 -2
View File
@@ -47,7 +47,7 @@ private:
typedef vector<AstBegin*> BeginStack;
// STATE
AstModule* m_modp; // Current module
AstNodeModule* m_modp; // Current module
AstNodeFTask* m_ftaskp; // Current function/task
AstWhile* m_loopp; // Current loop
bool m_loopInc; // In loop increment
@@ -82,6 +82,11 @@ private:
nodep->v3fatalSrc("Unknown jump point for break/disable/continue");
return NULL;
}
// Skip over variables as we'll just move them in a momement
// Also this would otherwise prevent us from using a label twice
// see t_func_return test.
while (underp && underp->castVar()) underp = underp->nextp();
if (underp) UINFO(5," Underpoint is "<<underp<<endl);
if (!underp) {
nodep->v3fatalSrc("Break/disable/continue not under expected statement");
@@ -109,7 +114,7 @@ private:
}
// VISITORS
virtual void visit(AstModule* nodep, AstNUser*) {
virtual void visit(AstNodeModule* nodep, AstNUser*) {
m_modp = nodep;
m_repeatNum = 0;
nodep->iterateChildren(*this);
+1 -1
View File
@@ -65,7 +65,7 @@ private:
if (nodep->varp()) {
if (nodep->lvalue() && nodep->varp()->isInOnly()) {
if (!m_ftaskp) {
nodep->v3error("Assigning to input variable: "<<nodep->prettyName());
nodep->v3warn(ASSIGNIN,"Assigning to input variable: "<<nodep->prettyName());
}
}
if (nodep->lvalue() && nodep->varp()->isConst()
+5
View File
@@ -326,6 +326,11 @@ private:
m_varp->attrSFormat(true);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
}
else if (nodep->attrType() == AstAttrType::VAR_SC_BV) {
if (!m_varp) nodep->v3fatalSrc("Attribute not attached to variable");
m_varp->attrScBv(true);
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
}
}
virtual void visit(AstAlwaysPublic* nodep, AstNUser*) {
+7 -4
View File
@@ -60,7 +60,7 @@ private:
T m_nextp; // Pointer to next element, NULL=end
T m_prevp; // Pointer to previous element, NULL=beginning
friend class V3List<T>;
static V3ListEnt* baseToListEnt(void* newbasep, uint32_t offset) {
static V3ListEnt* baseToListEnt(void* newbasep, size_t offset) {
// "this" must be a element inside of *basep
// Use that to determine a structure offset, then apply to the new base
// to get our new pointer information
@@ -80,7 +80,8 @@ public:
// METHODS
void pushBack (V3List<T>& listr, T newp) {
// "this" must be a element inside of *newp
uint32_t offset = (vluint8_t*)(this) - (vluint8_t*)(newp);
// cppcheck-suppress thisSubtraction
size_t offset = (vluint8_t*)(this) - (vluint8_t*)(newp);
m_nextp = NULL;
if (!listr.m_headp) listr.m_headp = newp;
m_prevp = listr.m_tailp;
@@ -89,7 +90,8 @@ public:
}
void pushFront (V3List<T>& listr, T newp) {
// "this" must be a element inside of *newp
uint32_t offset = (vluint8_t*)(this) - (vluint8_t*)(newp);
// cppcheck-suppress thisSubtraction
size_t offset = (vluint8_t*)(this) - (vluint8_t*)(newp);
m_nextp = listr.m_headp;
if (m_nextp) baseToListEnt(m_nextp,offset)->m_prevp = newp;
listr.m_headp = newp;
@@ -99,7 +101,8 @@ public:
// Unlink from side
void unlink (V3List<T>& listr, T oldp) {
// "this" must be a element inside of *oldp
uint32_t offset = (vluint8_t*)(this) - (vluint8_t*)(oldp);
// cppcheck-suppress thisSubtraction
size_t offset = (vluint8_t*)(this) - (vluint8_t*)(oldp);
if (m_nextp) baseToListEnt(m_nextp,offset)->m_prevp = m_prevp;
else listr.m_tailp = m_prevp;
if (m_prevp) baseToListEnt(m_prevp,offset)->m_nextp = m_nextp;
+1 -1
View File
@@ -141,7 +141,7 @@ private:
&& nodep->user1p()) { // Single cfunc
// We don't need to test for tracing; it would be in the tracefunc if it was needed
UINFO(4," ModVar->BlkVar "<<nodep<<endl);
m_statLocVars++;
++m_statLocVars;
AstCFunc* newfuncp = nodep->user1p()->castNode()->castCFunc();
nodep->unlinkFrBack();
newfuncp->addInitsp(nodep);
+8 -24
View File
@@ -25,6 +25,7 @@
#include <cstdio>
#include <cstdarg>
#include <algorithm>
#include <iomanip>
#include "V3Number.h"
#define MAX_SPRINTF_DOUBLE_SIZE 100 // Maximum characters with a sprintf %e/%f/%g (probably < 30)
@@ -33,28 +34,10 @@
// Read class functions
// CREATION
void V3Number::width(int width, bool sized) {
// Set width. Only set m_width here, as we need to tweak vector size
if (width) { m_sized = sized; m_width=width; }
else { m_sized = false; m_width=1; }
if (m_value.size() < (unsigned)(words()+1)) {
m_value.resize(words()+1);
m_valueX.resize(words()+1);
}
}
void V3Number::init (FileLine* fileline, int swidth) {
m_fileline = fileline;
m_signed = false;
m_double = false;
m_autoExtend = false;
m_fromString = false;
width(swidth);
for (int i=0; i<words(); i++) m_value[i]=m_valueX[i] = 0;
}
V3Number::V3Number(VerilogString, FileLine* fileline, const string& str) {
// Create a number using a verilog string as the value, thus 8 bits per character.
// cppcheck bug - doesn't see init() resets these
// cppcheck: Member variable 'm_sized/m_width' is not initialized in the constructor
init(fileline, str.length()*8);
m_fromString = true;
for (unsigned pos=0; pos<str.length(); ++pos) {
@@ -355,6 +338,7 @@ string V3Number::ascii(bool prefixed, bool cleanVerilog) const {
ostringstream out;
if (isDouble()) {
out.precision(17);
out<<toDouble();
return out.str();
}
@@ -416,9 +400,9 @@ bool V3Number::displayedFmtLegal(char format) {
string V3Number::displayed(const string& vformat) const {
string::const_iterator pos = vformat.begin();
UASSERT(pos != vformat.end() && pos[0]=='%', "display with non format argument "<<*this);
pos++;
++pos;
string fmtsize;
for (; pos != vformat.end() && (isdigit(pos[0]) || pos[0]=='.'); pos++) {
for (; pos != vformat.end() && (isdigit(pos[0]) || pos[0]=='.'); ++pos) {
fmtsize += pos[0];
}
string str;
@@ -1493,12 +1477,12 @@ V3Number& V3Number::opIToRD (const V3Number& lhs) {
return setDouble(lhs.toSInt());
}
V3Number& V3Number::opRToIS (const V3Number& lhs) {
double v = trunc(lhs.toDouble());
double v = VL_TRUNC(lhs.toDouble());
vlsint32_t i = (vlsint32_t)v; // C converts from double to vlsint32
return setLongS(i);
}
V3Number& V3Number::opRToIRoundS (const V3Number& lhs) {
double v = round(lhs.toDouble());
double v = VL_ROUND(lhs.toDouble());
vlsint32_t i = (vlsint32_t)v; // C converts from double to vlsint32
return setLongS(i);
}
+21 -2
View File
@@ -42,7 +42,6 @@ class V3Number {
vector<uint32_t> m_value; // The Value, with bit 0 being in bit 0 of this vector (unless X/Z)
vector<uint32_t> m_valueX; // Each bit is true if it's X or Z, 10=z, 11=x
// METHODS
void init(FileLine* fileline, int width);
V3Number& setSingleBits(char value);
void opCleanThis();
public:
@@ -118,6 +117,27 @@ public:
V3Number(FileLine* fileline, const char* source); // Create from a verilog 32'hxxxx number.
V3Number(VerilogString, FileLine* fileline, const string& vvalue);
private:
void init(FileLine* fileline, int swidth) {
m_fileline = fileline;
m_signed = false;
m_double = false;
m_autoExtend = false;
m_fromString = false;
width(swidth);
for (int i=0; i<words(); i++) m_value[i]=m_valueX[i] = 0;
}
public:
void width(int width, bool sized=true) {
// Set width. Only set m_width here, as we need to tweak vector size
if (width) { m_sized = sized; m_width=width; }
else { m_sized = false; m_width=1; }
if (VL_UNLIKELY(m_value.size() < (unsigned)(words()+1))) {
m_value.resize(words()+1);
m_valueX.resize(words()+1);
}
}
// SETTERS
V3Number& setAllBitsX();
V3Number& setAllBitsZ();
@@ -147,7 +167,6 @@ public:
bool isEqAllOnes(int optwidth=0) const;
bool isCaseEq(const V3Number& rhsp) const; // operator==
bool isLt(const V3Number& rhsp) const; // operator<
void width(int width, bool sized=true);
void isSigned(bool ssigned) { m_signed=ssigned; }
bool isUnknown() const;
uint32_t toUInt() const;
+93 -46
View File
@@ -51,17 +51,29 @@ struct V3OptionsImp {
// STATE
list<string> m_allArgs; // List of every argument encountered
list<string> m_incDirs; // Include directories (ordered)
set<string> m_incDirSet; // Include directories (for removing duplicates)
list<string> m_incDirUsers; // Include directories (ordered)
set<string> m_incDirUserSet; // Include directories (for removing duplicates)
list<string> m_incDirFallbacks; // Include directories (ordered)
set<string> m_incDirFallbackSet; // Include directories (for removing duplicates)
list<string> m_libExts; // Library extensions (ordered)
set<string> m_libExtSet; // Library extensions (for removing duplicates)
DirMap m_dirMap; // Directory listing
// ACCESSOR METHODS
void addIncDir(const string& incdir) {
if (m_incDirSet.find(incdir) == m_incDirSet.end()) {
m_incDirSet.insert(incdir);
m_incDirs.push_back(incdir);
void addIncDirUser(const string& incdir) {
if (m_incDirUserSet.find(incdir) == m_incDirUserSet.end()) {
m_incDirUserSet.insert(incdir);
m_incDirUsers.push_back(incdir);
m_incDirFallbacks.remove(incdir); // User has priority over Fallback
m_incDirFallbackSet.erase(incdir); // User has priority over Fallback
}
}
void addIncDirFallback(const string& incdir) {
if (m_incDirUserSet.find(incdir) == m_incDirUserSet.end()) { // User has priority over Fallback
if (m_incDirFallbackSet.find(incdir) == m_incDirFallbackSet.end()) {
m_incDirFallbackSet.insert(incdir);
m_incDirFallbacks.push_back(incdir);
}
}
}
void addLibExt(const string& libext) {
@@ -73,8 +85,11 @@ struct V3OptionsImp {
V3OptionsImp() {}
};
void V3Options::addIncDir(const string& incdir) {
m_impp->addIncDir(incdir);
void V3Options::addIncDirUser(const string& incdir) {
m_impp->addIncDirUser(incdir);
}
void V3Options::addIncDirFallback(const string& incdir) {
m_impp->addIncDirFallback(incdir);
}
void V3Options::addLibExt(const string& libext) {
m_impp->addLibExt(libext);
@@ -288,42 +303,68 @@ string V3Options::fileExists (const string& filename) {
return filenameOut;
}
string V3Options::filePath (FileLine* fl, const string& modname, const string& errmsg) {
// Find a filename to read the specified module name,
// using the incdir and libext's.
// Return "" if not found.
for (list<string>::iterator dirIter=m_impp->m_incDirs.begin(); dirIter!=m_impp->m_incDirs.end(); ++dirIter) {
for (list<string>::iterator extIter=m_impp->m_libExts.begin(); extIter!=m_impp->m_libExts.end(); ++extIter) {
string fn = filenameFromDirBase(*dirIter,modname+*extIter);
string exists = fileExists(fn);
if (exists!="") {
// Strip ./, it just looks ugly
if (exists.substr(0,2)=="./") exists.erase(0,2);
return exists;
}
}
}
// Warn and return not found
fl->v3error(errmsg+modname);
static bool shown_notfound_msg = false;
if (!shown_notfound_msg) {
shown_notfound_msg = true;
if (m_impp->m_incDirs.empty()) {
fl->v3error("This may be because there's no search path specified with -I<dir>."<<endl);
} else {
fl->v3error("Looked in:"<<endl);
for (list<string>::iterator dirIter=m_impp->m_incDirs.begin(); dirIter!=m_impp->m_incDirs.end(); ++dirIter) {
for (list<string>::iterator extIter=m_impp->m_libExts.begin(); extIter!=m_impp->m_libExts.end(); ++extIter) {
string fn = filenameFromDirBase(*dirIter,modname+*extIter);
fl->v3error(" "<<fn<<endl);
}
}
string V3Options::filePathCheckOneDir(const string& modname, const string& dirname) {
for (list<string>::iterator extIter=m_impp->m_libExts.begin(); extIter!=m_impp->m_libExts.end(); ++extIter) {
string fn = filenameFromDirBase(dirname, modname+*extIter);
string exists = fileExists(fn);
if (exists!="") {
// Strip ./, it just looks ugly
if (exists.substr(0,2)=="./") exists.erase(0,2);
return exists;
}
}
return "";
}
string V3Options::filePath (FileLine* fl, const string& modname,
const string& errmsg) { // Error prefix or "" to suppress error
// Find a filename to read the specified module name,
// using the incdir and libext's.
// Return "" if not found.
for (list<string>::iterator dirIter=m_impp->m_incDirUsers.begin();
dirIter!=m_impp->m_incDirUsers.end(); ++dirIter) {
string exists = filePathCheckOneDir(modname, *dirIter);
if (exists!="") return exists;
}
for (list<string>::iterator dirIter=m_impp->m_incDirFallbacks.begin();
dirIter!=m_impp->m_incDirFallbacks.end(); ++dirIter) {
string exists = filePathCheckOneDir(modname, *dirIter);
if (exists!="") return exists;
}
// Warn and return not found
if (errmsg != "") {
fl->v3error(errmsg+modname);
filePathLookedMsg(fl, modname);
}
return "";
}
void V3Options::filePathLookedMsg(FileLine* fl, const string& modname) {
static bool shown_notfound_msg = false;
if (!shown_notfound_msg) {
shown_notfound_msg = true;
if (m_impp->m_incDirUsers.empty()) {
fl->v3error("This may be because there's no search path specified with -I<dir>."<<endl);
}
fl->v3error("Looked in:"<<endl);
for (list<string>::iterator dirIter=m_impp->m_incDirUsers.begin();
dirIter!=m_impp->m_incDirUsers.end(); ++dirIter) {
for (list<string>::iterator extIter=m_impp->m_libExts.begin(); extIter!=m_impp->m_libExts.end(); ++extIter) {
string fn = filenameFromDirBase(*dirIter,modname+*extIter);
fl->v3error(" "<<fn<<endl);
}
}
for (list<string>::iterator dirIter=m_impp->m_incDirFallbacks.begin();
dirIter!=m_impp->m_incDirFallbacks.end(); ++dirIter) {
for (list<string>::iterator extIter=m_impp->m_libExts.begin(); extIter!=m_impp->m_libExts.end(); ++extIter) {
string fn = filenameFromDirBase(*dirIter,modname+*extIter);
fl->v3error(" "<<fn<<endl);
}
}
}
}
void V3Options::unlinkRegexp(const string& dir, const string& regexp) {
if (DIR* dirp = opendir(dir.c_str())) {
while (struct dirent* direntp = readdir(dirp)) {
@@ -528,6 +569,11 @@ string V3Options::version() {
return ver;
}
void V3Options::throwSigsegv() {
// cppcheck-suppress nullPointer
char* zp=NULL; *zp=0;
}
//######################################################################
// V3 Options utilities
@@ -561,7 +607,7 @@ void V3Options::parseOpts (FileLine* fl, int argc, char** argv) {
if (modPrefix()=="") m_modPrefix = prefix();
// Find files in makedir
addIncDir(makeDir());
addIncDirFallback(makeDir());
}
//======================================================================
@@ -599,7 +645,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
addDefine (string (sw+strlen("+define+")));
}
else if ( !strncmp (sw, "+incdir+", 8)) {
addIncDir (parseFileArg(optdir, string (sw+strlen("+incdir+"))));
addIncDirUser (parseFileArg(optdir, string (sw+strlen("+incdir+"))));
}
else if ( !strncmp (sw, "+libext+", 8)) {
string exts = string(sw+strlen("+libext+"));
@@ -643,7 +689,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
else if ( onoff (sw, "-covsp", flag/*ref*/) ) { } // TBD
else if ( !strcmp (sw, "-debug-abort") ) { abort(); } // Undocumented, see also --debug-sigsegv
else if ( onoff (sw, "-debug-check", flag/*ref*/) ){ m_debugCheck = flag; }
else if ( !strcmp (sw, "-debug-sigsegv") ) { char* zp=NULL; *zp=0; } // Undocumented, see also --debug-abort
else if ( !strcmp (sw, "-debug-sigsegv") ) { throwSigsegv(); } // Undocumented, see also --debug-abort
else if ( !strcmp (sw, "-debug-fatalsrc") ) { v3fatalSrc("--debug-fatal-src"); } // Undocumented, see also --debug-abort
else if ( onoff (sw, "-dump-tree", flag/*ref*/) ) { m_dumpTree = flag; }
else if ( onoff (sw, "-exe", flag/*ref*/) ) { m_exe = flag; }
@@ -722,7 +768,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
m_errorLimit = atoi(argv[i]);
}
else if ( !strncmp (sw, "-I", 2)) {
addIncDir (parseFileArg(optdir, string (sw+strlen("-I"))));
addIncDirUser (parseFileArg(optdir, string (sw+strlen("-I"))));
}
else if ( !strcmp (sw, "-if-depth") && (i+1)<argc ) {
shift;
@@ -747,7 +793,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
}
else if ( !strcmp (sw, "-Mdir") && (i+1)<argc ) {
shift; m_makeDir = argv[i];
addIncDir (string (m_makeDir)); // Need to find generated files there too
addIncDirFallback (string (m_makeDir)); // Need to find generated files there too
}
else if ( !strcmp (sw, "-o") && (i+1)<argc ) {
shift; m_exeName = argv[i];
@@ -913,7 +959,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
}
}
else if ( !strcmp (sw, "-y") && (i+1)<argc ) {
shift; addIncDir (parseFileArg(optdir,string (argv[i])));
shift; addIncDirUser (parseFileArg(optdir,string (argv[i])));
}
else {
fl->v3fatal ("Invalid Option: "<<argv[i]);
@@ -973,6 +1019,7 @@ void V3Options::parseOptsFile(FileLine* fl, const string& filename, bool rel) {
break; // Ignore to EOL
} else if (*pos=='/' && *(pos+1)=='*') {
inCmt = true;
// cppcheck-suppress StlMissingComparison
++pos;
} else {
oline += *pos;
@@ -1127,7 +1174,7 @@ V3Options::V3Options() {
addLibExt(".v");
addLibExt(".sv");
// Default -I
addIncDir("."); // Looks better than {long_cwd_path}/...
addIncDirFallback("."); // Looks better than {long_cwd_path}/...
}
V3Options::~V3Options() {
+8 -2
View File
@@ -178,10 +178,11 @@ class V3Options {
private:
// METHODS
void addArg(const string& incdir);
void addArg(const string& flag);
void addDefine(const string& defline);
void addFuture(const string& flag);
void addIncDir(const string& incdir);
void addIncDirUser(const string& incdir); // User requested
void addIncDirFallback(const string& incdir); // Low priority if not found otherwise
void addLibExt(const string& libext);
void optimize(int level);
void showVersion(bool verbose);
@@ -189,6 +190,7 @@ class V3Options {
bool onoff(const char* sw, const char* arg, bool& flag);
bool suffixed(const char* sw, const char* arg);
string parseFileArg(const string& optdir, const string& relfilename);
string filePathCheckOneDir(const string& modname, const string& dirname);
static bool wildmatchi(const char* s, const char* p);
static string getenvStr(const string& envvar, const string& defaultValue);
@@ -345,8 +347,12 @@ class V3Options {
// METHODS (file utilities using these options)
string fileExists (const string& filename);
string filePath (FileLine* fl, const string& modname, const string& errmsg);
void filePathLookedMsg(FileLine* fl, const string& modname);
static bool fileStatDir (const string& filename);
static bool fileStatNormal (const string& filename);
// METHODS (other OS)
static void throwSigsegv();
};
//######################################################################
+6 -3
View File
@@ -148,7 +148,7 @@ private:
public:
OrderMoveDomScope(OrderLoopId inLoop, AstSenTree* domainp, AstScope* scopep)
: m_onReadyList(false), m_domainp(domainp), m_inLoop(inLoop) {}
: m_onReadyList(false), m_domainp(domainp), m_scopep(scopep), m_inLoop(inLoop) {}
OrderMoveDomScope* readyDomScopeNextp() const { return m_readyDomScopeE.nextp(); }
OrderLoopId inLoop() const { return m_inLoop; }
AstSenTree* domainp() const { return m_domainp; }
@@ -391,8 +391,8 @@ private:
void nodeMarkCircular(OrderVarVertex* vertexp, OrderEdge* edgep) {
AstVarScope* nodep = vertexp->varScp();
nodep->circular(true);
m_statCut[vertexp->type()]++;
if (edgep) m_statCut[edgep->type()]++;
++m_statCut[vertexp->type()];
if (edgep) ++m_statCut[edgep->type()];
if (vertexp->isClock()) {
// Seems obvious; no warning yet
//nodep->v3warn(GENCLK,"Signal unoptimizable: Generated clock: "<<nodep->prettyName());
@@ -715,6 +715,9 @@ public:
m_settleDomainp = NULL;
m_settleVxp = NULL;
m_inputsVxp = NULL;
m_activeSenVxp = NULL;
m_logicVxp = NULL;
m_pomNewFuncp = NULL;
m_loopIdMax = LOOPID_FIRST;
m_pomNewStmts = 0;
if (debug()) m_graph.debug(5); // 3 is default if global debug; we want acyc debugging
+1 -1
View File
@@ -105,7 +105,7 @@ struct OrderVEdgeType {
return names[m_e];
}
enum en m_e;
inline OrderVEdgeType () {}
inline OrderVEdgeType () : m_e(VERTEX_UNKNOWN) {}
inline OrderVEdgeType (en _e) : m_e(_e) {}
explicit inline OrderVEdgeType (int _e) : m_e(static_cast<en>(_e)) {}
operator en () const { return m_e; }
+2 -1
View File
@@ -45,7 +45,8 @@ public:
// METHODS
// Preprocess and read the Verilog file specified into the netlist database
void parseFile(FileLine* fileline, const string& modname, bool inLibrary);
void parseFile(FileLine* fileline, const string& modname, bool inLibrary,
const string& errmsg);
// Push preprocessed text to the lexer
static void ppPushText(V3ParseImp* impp, const string& text);
+13 -4
View File
@@ -89,7 +89,8 @@ size_t V3ParseImp::ppInputToLex(char* buf, size_t max_size) {
return got;
}
void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool inLibrary) {
void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool inLibrary,
const string& errmsg) { // "" for no error, make fake node
string modname = V3Options::filenameNonExt(modfilename);
UINFO(2,__FUNCTION__<<": "<<modname<<(inLibrary?" [LIB]":"")<<endl);
@@ -104,7 +105,14 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
}
// Preprocess into m_ppBuffer
V3PreShell::preproc(fileline, modfilename, m_filterp, this);
bool ok = V3PreShell::preproc(fileline, modfilename, m_filterp, this, errmsg);
if (!ok) {
if (errmsg != "") return; // Threw error already
// Create fake node for later error reporting
AstNodeModule* nodep = new AstNotFoundModule(fileline, modname);
v3Global.rootp()->addModulep(nodep);
return;
}
if (v3Global.opt.preprocOnly() || v3Global.opt.keepTempFiles()) {
// Create output file with all the preprocessor output we buffered up
@@ -157,8 +165,9 @@ V3Parse::V3Parse(AstNetlist* rootp, V3InFilter* filterp) {
V3Parse::~V3Parse() {
delete m_impp; m_impp = NULL;
}
void V3Parse::parseFile(FileLine* fileline, const string& modname, bool inLibrary) {
m_impp->parseFile(fileline, modname, inLibrary);
void V3Parse::parseFile(FileLine* fileline, const string& modname, bool inLibrary,
const string& errmsg) {
m_impp->parseFile(fileline, modname, inLibrary, errmsg);
}
void V3Parse::ppPushText(V3ParseImp* impp, const string& text) {
impp->ppPushText(text);
+11 -9
View File
@@ -257,7 +257,7 @@ public:
double parseDouble(const char* text, size_t length);
void pushBeginKeywords(int state) { m_inBeginKwd++; m_lastVerilogState=state; }
bool popBeginKeywords() { if (m_inBeginKwd) { m_inBeginKwd--; return true; } else return false; }
int lastVerilogState() { return m_lastVerilogState; }
int lastVerilogState() const { return m_lastVerilogState; }
static const char* tokenName(int tok);
void ppPushText(const string& text) { m_ppBuffers.push_back(text); }
@@ -291,12 +291,12 @@ public:
}
// Return next token, for bison, since bison isn't class based, use a global THIS
FileLine* fileline() { return m_fileline; }
AstNetlist* rootp() { return m_rootp; }
FileLine* fileline() const { return m_fileline; }
AstNetlist* rootp() const { return m_rootp; }
FileLine* copyOrSameFileLine() { return fileline()->copyOrSameFileLine(); }
bool inCellDefine() { return m_inCellDefine; }
bool inCellDefine() const { return m_inCellDefine; }
void inCellDefine(bool flag) { m_inCellDefine = flag; }
bool inLibrary() { return m_inLibrary; }
bool inLibrary() const { return m_inLibrary; }
// Interactions with parser
int bisonParse();
@@ -306,8 +306,8 @@ public:
void lexDestroy();
void stateExitPsl(); // Parser -> lexer communication
void statePushVlg(); // Parser -> lexer communication
void statePop(); // Parser -> lexer communication
int stateVerilogRecent(); // Parser -> lexer communication
void statePop(); // Parser -> lexer communication
static int stateVerilogRecent(); // Parser -> lexer communication
size_t flexPpInputToLex(char* buf, size_t max_size) { return ppInputToLex(buf,max_size); }
//==== Symbol tables
@@ -316,7 +316,8 @@ public:
public:
// CREATORS
V3ParseImp(AstNetlist* rootp, V3InFilter* filterp)
: m_sym(rootp), m_filterp(filterp) {
: m_filterp(filterp), m_sym(rootp) {
m_fileline = NULL;
m_rootp = rootp; m_lexerp = NULL;
m_inCellDefine = false;
m_inLibrary = false;
@@ -332,7 +333,8 @@ public:
// Preprocess and read the Verilog file specified into the netlist database
int lexToBison(); // Pass token to bison
void parseFile(FileLine* fileline, const string& modfilename, bool inLibrary);
void parseFile(FileLine* fileline, const string& modfilename, bool inLibrary,
const string& errmsg);
private:
void lexFile(const string& modname);
+1 -1
View File
@@ -62,7 +62,7 @@ public:
void V3ParseImp::stateExitPsl() { parsep()->m_lexerp->stateExitPsl(); }
void V3ParseImp::statePushVlg() { parsep()->m_lexerp->stateExitPsl(); }
void V3ParseImp::statePop() { parsep()->m_lexerp->statePop(); }
int V3ParseImp::yylexThis() { parsep()->m_lexerp->yylex(); }
int V3ParseImp::yylexThis() { return parsep()->m_lexerp->yylex(); }
//######################################################################
// Read class functions
+1 -1
View File
@@ -203,7 +203,7 @@ class V3PreLex {
/// Called by V3PreProc.cpp to get data from lexer
YY_BUFFER_STATE currentBuffer();
int lex();
int currentStartState();
int currentStartState() const;
void dumpSummary();
void dumpStack();
void unused();
+2 -1
View File
@@ -488,7 +488,7 @@ YY_BUFFER_STATE V3PreLex::currentBuffer() {
return YY_CURRENT_BUFFER;
}
int V3PreLex::currentStartState() {
int V3PreLex::currentStartState() const {
return YY_START;
}
@@ -538,6 +538,7 @@ void V3PreLex::unused() {
if (0) {
// Prevent unused warnings
yy_top_state();
yyerror((char*)"");
}
}
+5 -1
View File
@@ -127,7 +127,7 @@ struct V3PreProcImp : public V3PreProc {
ps_DEFNAME_IFDEF, ps_DEFNAME_IFNDEF, ps_DEFNAME_ELSIF,
ps_DEFFORM, ps_DEFVALUE, ps_DEFPAREN, ps_DEFARG,
ps_INCNAME, ps_ERRORNAME, ps_JOIN, ps_STRIFY };
const char* procStateName(ProcState s) {
static const char* procStateName(ProcState s) {
static const char* states[]
= {"ps_TOP",
"ps_DEFNAME_UNDEF", "ps_DEFNAME_DEFINE",
@@ -251,6 +251,10 @@ public:
m_finAtBol = true;
m_defDepth = 0;
m_defPutJoin = false;
m_finToken = 0;
m_finFilelinep = NULL;
m_lexp = NULL;
m_preprocp = NULL;
}
void configure(FileLine* filelinep) {
// configure() separate from constructor to avoid calling abstract functions
+4 -4
View File
@@ -67,10 +67,10 @@ public:
// CONTROL METHODS
// These options control how the parsing proceeds
int keepComments() { return 2; } // Return comments, 0=no, 1=yes, 2=callback
bool keepWhitespace() { return false; }
bool lineDirectives() { return true; } // Insert `line directives
bool pedantic() { return false; } // Obey standard; Don't substitute `error
static int keepComments() { return 2; } // Return comments, 0=no, 1=yes, 2=callback
static bool keepWhitespace() { return false; }
static bool lineDirectives() { return true; } // Insert `line directives
static bool pedantic() { return false; } // Obey standard; Don't substitute `error
static bool optPsl();
// CALLBACK METHODS
+14 -6
View File
@@ -74,7 +74,8 @@ protected:
}
}
void preproc (FileLine* fl, const string& modname, V3InFilter* filterp, V3ParseImp* parsep) {
bool preproc (FileLine* fl, const string& modname, V3InFilter* filterp, V3ParseImp* parsep,
const string& errmsg) { // "" for no error
debug(true); // Recheck if debug on - first check was before command line passed
// Preprocess the given module, putting output in vppFilename
@@ -82,11 +83,14 @@ protected:
// Preprocess
s_filterp = filterp;
preprocOpen(fl, s_filterp, modname, "Cannot find file containing module: ");
bool ok = preprocOpen(fl, s_filterp, modname, errmsg);
if (!ok) return false;
while (!s_preprocp->isEof()) {
string line = s_preprocp->getline();
V3Parse::ppPushText(parsep, line);
}
return true;
}
void preprocInclude (FileLine* fl, const string& modname) {
@@ -96,17 +100,20 @@ protected:
preprocOpen(fl, s_filterp, modname, "Cannot find include file: ");
}
void preprocOpen (FileLine* fl, V3InFilter* filterp, const string& modname, const string& errmsg) {
bool preprocOpen (FileLine* fl, V3InFilter* filterp, const string& modname,
const string& errmsg) { // Error message or "" to suppress
// Returns true if successful
// Allow user to put `defined names on the command line instead of filenames,
// then convert them properly.
string ppmodname = s_preprocp->removeDefines (modname);
// Open include or master file
string filename = v3Global.opt.filePath (fl, ppmodname, errmsg);
if (filename=="") return; // Not found
if (filename=="") return false; // Not found
UINFO(2," Reading "<<filename<<endl);
s_preprocp->openFile(fl, filterp, filename);
return true;
}
// CONSTRUCTORS
@@ -124,8 +131,9 @@ V3InFilter* V3PreShellImp::s_filterp = NULL;
void V3PreShell::boot(char** env) {
V3PreShellImp::s_preImp.boot(env);
}
void V3PreShell::preproc(FileLine* fl, const string& modname, V3InFilter* filterp, V3ParseImp* parsep) {
V3PreShellImp::s_preImp.preproc(fl, modname, filterp, parsep);
bool V3PreShell::preproc(FileLine* fl, const string& modname, V3InFilter* filterp,
V3ParseImp* parsep, const string& errmsg) {
return V3PreShellImp::s_preImp.preproc(fl, modname, filterp, parsep, errmsg);
}
void V3PreShell::preprocInclude(FileLine* fl, const string& modname) {
V3PreShellImp::s_preImp.preprocInclude(fl, modname);
+2 -1
View File
@@ -36,7 +36,8 @@ class V3PreShell {
// Static class for calling preprocessor
public:
static void boot(char** env);
static void preproc(FileLine* fileline, const string& module, V3InFilter* filterp, V3ParseImp* parsep);
static bool preproc(FileLine* fileline, const string& module, V3InFilter* filterp,
V3ParseImp* parsep, const string& errmsg);
static void preprocInclude(FileLine* fileline, const string& module);
static string dependFiles() { return ""; } // Perl only
static void defineCmdLine(const string& name, const string& value);
+25 -9
View File
@@ -229,6 +229,7 @@ private:
// STATE
bool m_reorder; // Reorder statements vs. just splitting
string m_noReorderWhy; // Reason we can't reorder
VStack m_stmtStackps; // Current statements being tracked
SplitPliVertex* m_pliVertexp; // Element specifying PLI ordering
V3Graph m_graph; // Scoreboard of var usages/dependencies
@@ -249,6 +250,7 @@ private:
m_graph.clear();
m_stmtStackps.clear();
m_pliVertexp = NULL;
m_noReorderWhy = "";
AstNode::user1ClearTree();
AstNode::user2ClearTree();
AstNode::user3ClearTree();
@@ -336,6 +338,7 @@ private:
}
// Weak coloring to determine what needs to remain in order
// This follows all step-relevant edges excluding PostEdges, which are done later
m_graph.weaklyConnected(&SplitEdge::followScoreboard);
// Add hard orderings between all nodes of same color, in the order they appeared
@@ -413,7 +416,7 @@ private:
newListp = newListp->addNext(nextp);
}
if (splitAlwaysp) {
m_statSplits++;
++m_statSplits;
AstAlways* alwaysp = new AstAlways(newListp->fileline(), NULL, NULL);
addAfterp->addNextHere(alwaysp); addAfterp=alwaysp;
alwaysp->addStmtp(newListp);
@@ -445,14 +448,18 @@ private:
UINFO(9," processBlock "<<nodep<<endl);
// Process block and followers
scanBlock(nodep);
// Reorder statements in this block
cleanupBlockGraph(nodep);
reorderBlock(nodep);
// Delete old vertexes and edges only applying to this block
while (firstp->backp()->nextp()==firstp) firstp = firstp->backp(); // Walk back to first in list
for (AstNode* nextp=firstp; nextp; nextp=nextp->nextp()) {
SplitLogicVertex* vvertexp = (SplitLogicVertex*)nextp->user3p();
vvertexp->unlinkDelete(&m_graph);
if (m_noReorderWhy != "") { // Jump or something nasty
UINFO(9," NoReorderBlock because "<<m_noReorderWhy<<endl);
} else {
// Reorder statements in this block
cleanupBlockGraph(nodep);
reorderBlock(nodep);
// Delete old vertexes and edges only applying to this block
while (firstp->backp()->nextp()==firstp) firstp = firstp->backp(); // Walk back to first in list
for (AstNode* nextp=firstp; nextp; nextp=nextp->nextp()) {
SplitLogicVertex* vvertexp = (SplitLogicVertex*)nextp->user3p();
vvertexp->unlinkDelete(&m_graph);
}
}
}
// Again, nodep may no longer be first.
@@ -534,6 +541,15 @@ private:
}
}
}
virtual void visit(AstJumpGo* nodep, AstNUser*) {
// Jumps will disable reordering at all levels
// This is overly pessimistic; we could treat jumps as barriers, and
// reorder everything between jumps/labels, however jumps are rare
// in always, so the performance gain probably isn't worth the work.
UINFO(9," NoReordering "<<nodep<<endl);
m_noReorderWhy = "JumpGo";
nodep->iterateChildren(*this);
}
//--------------------
// Default
+1 -1
View File
@@ -185,7 +185,7 @@ private:
// Now isolate the always
if (m_splitVscp) {
splitAlways(nodep);
m_statSplits++;
++m_statSplits;
} else {
nodep->user1(true);
}
+1 -1
View File
@@ -309,7 +309,7 @@ private:
if (debug()>5) newp->dumpTree(cout," w_new: ");
nodep->replaceWith(newp);
pushDeletep(nodep); nodep=NULL;
m_statSubsts++;
++m_statSubsts;
}
virtual void visit(AstWordSel* nodep, AstNUser*) {
nodep->rhsp()->accept(*this);
+2 -2
View File
@@ -176,8 +176,8 @@ public:
private:
void createTable(AstAlways* nodep) {
// We've determined this table of nodes is optimizable, do it.
m_modTables++;
m_statTablesCre++;
++m_modTables;
++m_statTablesCre;
// Index into our table
AstVar* indexVarp = new AstVar (nodep->fileline(), AstVarType::BLOCKTEMP,
+8
View File
@@ -408,6 +408,7 @@ private:
AstAssign* assp = new AstAssign (pinp->fileline(),
pinp,
new AstVarRef(outvscp->fileline(), outvscp, false));
assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); // Ok if in <= block
// Put assignment BEHIND of all other statements
beginp->addNext(assp);
}
@@ -418,6 +419,7 @@ private:
AstAssign* assp = new AstAssign (pinp->fileline(),
new AstVarRef(inVscp->fileline(), inVscp, true),
pinp);
assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); // Ok if in <= block
// Put assignment in FRONT of all other statements
if (AstNode* afterp = beginp->nextp()) {
afterp->unlinkFrBackWithNext();
@@ -507,6 +509,7 @@ private:
AstAssign* assp = new AstAssign (pinp->fileline(),
pinp,
new AstVarRef(outvscp->fileline(), outvscp, false));
assp->fileline()->modifyWarnOff(V3ErrorCode::BLKSEQ, true); // Ok if in <= block
// Put assignment BEHIND of all other statements
beginp->addNext(assp);
}
@@ -618,6 +621,11 @@ private:
stmt += "VL_CVT_VP_Q(";
ket += ")";
}
else if (portp->basicp() && portp->basicp()->isBitLogic() && portp->widthMin() != 1 && portp->isQuad()) {
// SV is vector, Verilator isn't
stmt += "VL_SET_QW(";
ket += ")";
}
if (!cvt
&& portp->basicp() && portp->basicp()->isBitLogic() && portp->widthMin() != 1 && !portp->isWide())
stmt += "*"; // it's a svBitVecVal, which other code won't think is arrayed (as WData aren't), but really is
+8 -8
View File
@@ -71,19 +71,19 @@ class TraceActivityVertex : public V3GraphVertex {
bool m_activityCodeValid;
bool m_slow; // If always slow, we can use the same code
public:
enum { ACTIVITY_NEVER =((1UL<<31) - 1) };
enum { ACTIVITY_ALWAYS=((1UL<<31) - 2) };
enum { ACTIVITY_SLOW=0 };
TraceActivityVertex(V3Graph* graphp, AstNode* nodep, bool slow)
: V3GraphVertex(graphp), m_insertp(nodep) {
m_activityCode = 0;
m_activityCodeValid = false;
m_slow = slow;
}
enum { ACTIVITY_NEVER =((1UL<<31) - 1) };
enum { ACTIVITY_ALWAYS=((1UL<<31) - 2) };
enum { ACTIVITY_SLOW=0 };
class ActivityAlways {};
TraceActivityVertex(V3Graph* graphp, vlsint32_t code)
: V3GraphVertex(graphp) {
activityCode(code);
: V3GraphVertex(graphp), m_insertp(NULL) {
m_activityCode = code;
m_activityCodeValid = true;
m_slow = false;
}
virtual ~TraceActivityVertex() {}
@@ -484,7 +484,7 @@ private:
nodep->code(m_code);
m_code += nodep->codeInc();
m_statUniqCodes += nodep->codeInc();
m_statUniqSigs++;
++m_statUniqSigs;
}
return nodep->code();
}
@@ -517,7 +517,7 @@ private:
if (!codePreassigned) {
// Add to trace cfuncs
if (needChg) {
m_statChgSigs++;
++m_statChgSigs;
incAddp = nodep->cloneTree(true);
}
+3 -2
View File
@@ -103,6 +103,7 @@ private:
} else {
basep->v3fatalSrc("Strange base function type");
}
// cppcheck-suppress nullPointer // above fatal prevents it
AstCCall* callp = new AstCCall(funcp->fileline(), funcp);
callp->argTypes("vlSymsp, vcdp, code");
basep->addStmtsp(callp);
@@ -137,12 +138,12 @@ private:
if (showname.substr(0,4) == "TOP ") showname.replace(0,4,"");
if (!m_initSubFuncp) nodep->v3fatalSrc("NULL");
if (varIgnoreTrace(varp)) {
m_statIgnSigs++;
++m_statIgnSigs;
m_initSubFuncp->addStmtsp(
new AstComment(nodep->fileline(),
"Tracing: "+showname+" // Ignored: "+varIgnoreTrace(varp)));
} else {
m_statSigs++;
++m_statSigs;
AstNode* valuep = NULL;
if (nodep->valuep()) valuep=nodep->valuep()->cloneTree(true);
else valuep = new AstVarRef(nodep->fileline(), nodep, false);
+15 -4
View File
@@ -76,8 +76,8 @@ public:
private:
// METHODS
inline bool bitNumOk(int bit) const { return (bit*FLAGS_PER_BIT < (int)m_flags.size()); }
inline bool usedFlag(int bit) { return m_usedWhole || m_flags[bit*FLAGS_PER_BIT + FLAG_USED]; }
inline bool drivenFlag(int bit) { return m_drivenWhole || m_flags[bit*FLAGS_PER_BIT + FLAG_DRIVEN]; }
inline bool usedFlag(int bit) const { return m_usedWhole || m_flags[bit*FLAGS_PER_BIT + FLAG_USED]; }
inline bool drivenFlag(int bit) const { return m_drivenWhole || m_flags[bit*FLAGS_PER_BIT + FLAG_DRIVEN]; }
enum BitNamesWhich { BN_UNUSED, BN_UNDRIVEN, BN_BOTH };
string bitNames(BitNamesWhich which) {
string bits="";
@@ -217,6 +217,7 @@ private:
// STATE
vector<UndrivenVarEntry*> m_entryps; // Nodes to delete when we are finished
bool m_markBoth; // Mark as driven+used
AstNodeFTask* m_taskp; // Current task
// METHODS
static int debug() {
@@ -241,12 +242,14 @@ private:
virtual void visit(AstVar* nodep, AstNUser*) {
UndrivenVarEntry* entryp = getEntryp (nodep);
if (nodep->isInput()
|| nodep->isSigPublic() || nodep->isSigUserRWPublic()) {
|| nodep->isSigPublic() || nodep->isSigUserRWPublic()
|| (m_taskp && (m_taskp->dpiImport() || m_taskp->dpiExport()))) {
entryp->drivenWhole();
}
if (nodep->isOutput()
|| nodep->isSigPublic() || nodep->isSigUserRWPublic()
|| nodep->isSigUserRdPublic()) {
|| nodep->isSigUserRdPublic()
|| (m_taskp && (m_taskp->dpiImport() || m_taskp->dpiExport()))) {
entryp->usedWhole();
}
// Discover variables used in bit definitions, etc
@@ -284,6 +287,13 @@ private:
m_markBoth = prevMark;
}
virtual void visit(AstNodeFTask* nodep, AstNUser*) {
AstNodeFTask* prevTaskp = m_taskp;
m_taskp = nodep;
nodep->iterateChildren(*this);
m_taskp = prevTaskp;
}
// Until we support tables, primitives will have undriven and unused I/Os
virtual void visit(AstPrimitive* nodep, AstNUser*) {}
@@ -303,6 +313,7 @@ public:
// CONSTUCTORS
UndrivenVisitor(AstNetlist* nodep) {
m_markBoth = false;
m_taskp = NULL;
nodep->accept(*this);
}
virtual ~UndrivenVisitor() {
+1 -1
View File
@@ -289,7 +289,7 @@ private:
AstVar* newvarp
= new AstVar (nodep->fileline(), AstVarType::XTEMP, newvarname,
AstLogicPacked(), nodep->width());
m_statUnkVars++;
++m_statUnkVars;
AstNRelinker replaceHandle;
nodep->unlinkFrBack(&replaceHandle);
AstNodeVarRef* newref1p = new AstVarRef(nodep->fileline(), newvarp, false);
+5 -2
View File
@@ -241,14 +241,17 @@ private:
}
if (precondsp) {
precondsp->unlinkFrBackWithNext();
// cppcheck-suppress nullPointer // addNextNull deals with it
stmtsp = stmtsp->addNextNull(precondsp);
}
if (bodysp) {
bodysp->unlinkFrBackWithNext();
// cppcheck-suppress nullPointer // addNextNull deals with it
stmtsp = stmtsp->addNextNull(bodysp); // Maybe null if no body
}
if (incp && !nodep->castGenFor()) { // Generates don't need to increment loop index
incp->unlinkFrBackWithNext();
// cppcheck-suppress nullPointer // addNextNull deals with it
stmtsp = stmtsp->addNextNull(incp); // Maybe null if no body
}
// Mark variable to disable some later warnings
@@ -259,7 +262,7 @@ private:
loopValue.opAssign(numInit);
AstNode* newbodysp = NULL;
m_statLoops++;
++m_statLoops;
if (stmtsp) {
int times = 0;
while (1) {
@@ -287,7 +290,7 @@ private:
if (newbodysp) newbodysp->addNext(oneloopp);
else newbodysp = oneloopp;
m_statIters++;
++m_statIters;
if (++times > unrollCount()*3) {
nodep->v3error("Loop unrolling took too long; probably this is an infinite loop, or set --unroll-count above "<<unrollCount());
break;
+42 -17
View File
@@ -208,6 +208,13 @@ private:
virtual void visit(AstPowD* nodep, AstNUser* vup) { visit_math_Or_LRr(nodep,vup); }
// Signed/Real: Output real or signed iff LHS signed/real
virtual void visit(AstNegateD* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); }
// Real: Output real
virtual void visit(AstCeilD* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); }
virtual void visit(AstExpD* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); }
virtual void visit(AstFloorD* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); }
virtual void visit(AstLogD* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); }
virtual void visit(AstLog10D* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); }
virtual void visit(AstSqrtD* nodep, AstNUser* vup) { visit_math_Or_Lr(nodep,vup); }
// Widths: out signed/unsigned width = lhs width, input un|signed
virtual void visit(AstSigned* nodep, AstNUser* vup) { visit_Ous_Lus_Wforce(nodep,vup,AstNumeric::SIGNED); }
@@ -642,10 +649,11 @@ private:
V3Width::widthParamsEdit(nodep->dtypep()); // MAY CHANGE dtypep()
AstBasicDType* basicp = nodep->dtypep()->basicp(); if (!basicp) nodep->v3fatalSrc("Unimplemented: Casting non-simple data type");
nodep->widthSignedFrom(basicp);
AstNode* newp = nodep->lhsp()->unlinkFrBack();
if (!basicp->isDouble() && !newp->isDouble()) {
widthCheck(nodep,"Cast",newp,nodep->width(),nodep->width(),true);
if (!basicp->isDouble() && !nodep->lhsp()->isDouble()) {
// Note widthCheck might modify nodep->lhsp()
widthCheck(nodep,"Cast",nodep->lhsp(),nodep->width(),nodep->width(),true);
}
AstNode* newp = nodep->lhsp()->unlinkFrBack();
if (basicp->numeric() == newp->numeric()) {
newp = newp; // Can just remove cast
} else if (basicp->isDouble() && !newp->isDouble()) {
@@ -687,7 +695,7 @@ private:
bool implicitParam = nodep->isParam() && bdtypep && bdtypep->implicit();
if (implicitParam) {
AstNumeric rs = AstNumeric::UNSIGNED;
int width=0; int mwidth=0;
int width=0;
if (nodep->valuep()) {
nodep->valuep()->iterateAndNext(*this,WidthVP(width,0,PRELIM).p());
// Although nodep will get a different width for parameters just below,
@@ -697,11 +705,10 @@ private:
rs = nodep->numeric();
if (!rs.isDouble()) {
if (nodep->valuep()->widthSized()) {
width = mwidth = nodep->valuep()->width();
width = nodep->valuep()->width();
} else {
if (nodep->valuep()->width()>32) nodep->valuep()->v3warn(WIDTH,"Assigning >32 bit to unranged parameter (defaults to 32 bits)");
width = 32;
mwidth = nodep->valuep()->widthMin();
}
}
}
@@ -1034,6 +1041,14 @@ private:
virtual void visit(AstSysIgnore* nodep, AstNUser* vup) {
nodep->exprsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
}
virtual void visit(AstSystemF* nodep, AstNUser*) {
nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
nodep->numeric(AstNumeric::UNSIGNED);
nodep->width(32,32);
}
virtual void visit(AstSystemT* nodep, AstNUser*) {
nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
}
virtual void visit(AstReadMem* nodep, AstNUser*) {
nodep->filenamep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
nodep->memp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
@@ -1130,6 +1145,13 @@ private:
}
virtual void visit(AstCell* nodep, AstNUser*) {
if (!m_paramsOnly) {
if (nodep->modp()->castNotFoundModule()) {
// We've resolved parameters and hit a module that we couldn't resolve. It's
// finally time to report it.
// Note only here in V3Width as this is first visitor after V3Dead.
nodep->v3error("Cannot find file containing module: "<<nodep->modName());
v3Global.opt.filePathLookedMsg(nodep->fileline(), nodep->modName());
}
if (nodep->rangep()) {
m_cellRangep = nodep->rangep();
nodep->rangep()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
@@ -1188,14 +1210,14 @@ private:
nodep->taskp()->iterate(*this);
//
// And do the arguments to the task/function too
for (int accept_mode=1; accept_mode>=0; accept_mode--) { // Avoid duplicate code; just do inner stuff twice
for (int accept_mode=0; accept_mode<3; accept_mode++) { // Avoid duplicate code; just do inner stuff several times
reloop:
V3TaskConnects tconnects = V3Task::taskConnects(nodep, nodep->taskp()->stmtsp());
bool lastloop = false;
for (V3TaskConnects::iterator it=tconnects.begin(); !lastloop && it!=tconnects.end(); ++it) {
for (V3TaskConnects::iterator it=tconnects.begin(); it!=tconnects.end(); ++it) {
AstVar* portp = it->first;
AstNode* pinp = it->second;
if (pinp!=NULL) { // Else argument error we'll find later
if (accept_mode) {
if (accept_mode==0) {
// Prelim may cause the node to get replaced; we've lost our
// pointer, so need to iterate separately later
if (portp->attrSFormat()
@@ -1214,7 +1236,7 @@ private:
}
handle.relink(newp);
// Connection list is now incorrect (has extra args in it).
lastloop = true; // so exit early; next loop will correct it
goto reloop; // so exit early; next loop will correct it
}
else if (portp->basicp() && portp->basicp()->keyword()==AstBasicDTypeKwd::STRING
&& !pinp->castCvtPackString()
@@ -1228,7 +1250,12 @@ private:
pinp = newp;
}
pinp->accept(*this,WidthVP(portp->width(),portp->widthMin(),PRELIM).p()); pinp=NULL;
} else {
} else if (accept_mode==1) {
// Change data types based on above accept completion
if (portp->isDouble()) {
spliceCvtD(pinp); pinp=NULL;
}
} else if (accept_mode==2) {
// Do PRELIM again, because above accept may have exited early due to node replacement
pinp->accept(*this,WidthVP(portp->width(),portp->widthMin(),BOTH).p());
if ((portp->isOutput() || portp->isInout())
@@ -1585,20 +1612,18 @@ private:
}
void visit_math_Or_LRr(AstNodeBiop* nodep, AstNUser* vup) {
if (vup->c()->prelim()) { // First stage evaluation
nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
nodep->rhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
checkCvtD(nodep->lhsp());
checkCvtD(nodep->rhsp());
nodep->numeric(AstNumeric::DOUBLE);
// Determine expression widths only relying on what's in the subops
nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
nodep->rhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
}
}
void visit_math_Or_Lr(AstNodeUniop* nodep, AstNUser* vup) {
if (vup->c()->prelim()) { // First stage evaluation
nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
checkCvtD(nodep->lhsp());
nodep->numeric(AstNumeric::DOUBLE);
// Determine expression widths only relying on what's in the subops
nodep->lhsp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
}
}
+4 -2
View File
@@ -106,7 +106,8 @@ void V3Global::readFiles() {
for (V3StringList::const_iterator it = v3Global.opt.vFiles().begin();
it != v3Global.opt.vFiles().end(); ++it) {
string filename = *it;
parser.parseFile(new FileLine("CommandLine",0), filename, false);
parser.parseFile(new FileLine("COMMAND_LINE",0), filename, false,
"Cannot find file containing module: ");
}
// Read libraries
@@ -115,7 +116,8 @@ void V3Global::readFiles() {
for (V3StringSet::const_iterator it = v3Global.opt.libraryFiles().begin();
it != v3Global.opt.libraryFiles().end(); ++it) {
string filename = *it;
parser.parseFile(new FileLine("CommandLine",0), filename, true);
parser.parseFile(new FileLine("COMMAND_LINE",0), filename, true,
"Cannot find file containing library module: ");
}
//v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("parse.tree"));
V3Error::abortIfErrors();
+118 -9
View File
@@ -7,28 +7,36 @@ use Getopt::Long;
use IO::File;
use Pod::Usage;
use strict;
use vars qw ($Debug @Types %Classes);
use vars qw ($Debug @Types %Classes %Children %ClassRefs %Stages);
#======================================================================
# main
$Debug = 0;
my $opt_classes;
my $opt_report;
my @Opt_Cpt;
my @Opt_I;
Getopt::Long::config ("pass_through", "no_auto_abbrev");
if (! GetOptions (
"help" => \&usage,
"debug" => \&debug,
"classes!" => \$opt_classes,
"<>" => \&parameter,
)) {
"help" => \&report,
"debug" => \&debug,
"classes!" => \$opt_classes,
"report!" => \$opt_report,
"<>" => \&parameter,
)) {
usage();
}
read_types("$Opt_I[0]/V3Ast.h");
read_types("$Opt_I[0]/V3AstNodes.h");
read_stages("$Opt_I[0]/Verilator.cpp");
read_refs(glob("$Opt_I[0]/*.y"), glob("$Opt_I[0]/*.h"), glob("$Opt_I[0]/*.cpp"));
if ($opt_report) {
write_report(undef);
}
if ($opt_classes) {
write_report("V3Ast__gen_report.txt");
write_classes("V3Ast__gen_classes.h");
write_visitor("V3Ast__gen_visitor.h");
write_intf("V3Ast__gen_interface.h");
@@ -42,7 +50,7 @@ foreach my $cpt (@Opt_Cpt) {
#----------------------------------------------------------------------
sub usage {
pod2usage(-verbose=>2, -exitval => 2);
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
exit (1);
}
@@ -80,11 +88,50 @@ sub read_types {
$class =~ s/^Ast//;
$inh =~ s/^Ast//;
$Classes{$class} = $inh;
$Children{$inh}{$class} = 1;
}
}
}
}
sub read_stages {
my $filename = shift;
my $fh = IO::File->new($filename) or die "%Error: $! $filename,";
my $n = 0;
while (defined (my $line = $fh->getline())) {
$line =~ s/\/\/.*$//;
next if $line =~ /^\s*$/;
if ($line =~ /^\s*([A-Za-z0-9]+)::/) {
my $stage = $1.".cpp";
if (!defined ($Stages{$stage})) {
$Stages{$stage} = $n++;
}
}
}
}
sub read_refs {
my @filenames = @_;
foreach my $filename (@filenames) {
(my $basename = $filename) =~ s!.*/!!;
my $fh = IO::File->new($filename) or die "%Error: $! $filename,";
while (defined (my $line = $fh->getline())) {
$line =~ s/\/\/.*$//;
while ($line =~ /\bnew\s*(Ast[A-Za-z0-9_]+)/g) {
$ClassRefs{$1}{newed}{$basename} = 1;
}
while ($line =~ /\b(Ast[A-Za-z0-9_]+)/g) {
$ClassRefs{$1}{used}{$basename} = 1;
}
}
}
#use Data::Dumper;print Dumper(\%ClassRefs);
}
#----------------------------------------------------------------------
sub open_file {
my $filename = shift;
my $fh = IO::File->new($filename,"w") or die "%Error: $! $filename,";
@@ -106,8 +153,66 @@ sub subclasses_of {
return (reverse @cllist);
}
sub children_of {
my $type = shift;
my @cllist;
my @todo;
push @todo, $type;
while (my $subclass = shift @todo) {
foreach my $child (sort keys %{$::Children{$subclass}}) {
push @todo, $child;
push @cllist, $child;
}
}
return (@cllist);
}
#----------------------------------------------------------------------
sub write_report {
my $filename = shift;
my $fh = defined($filename) ? open_file($filename) : \*STDOUT;
$fh->print("Processing stages (approximate, based on order in Verilator.cpp):\n");
foreach my $class (sort {$Stages{$a} <=> $Stages{$b}} keys %Stages) {
$fh->print("\t$class\n");
}
$fh->print("\nProcessing stages (approximate, based on order in Verilator.cpp):\n");
foreach my $type (sort (keys %Classes)) {
printf $fh " class %-20s\n", "Ast${type}";
$fh->print("\tparent:\t");
foreach my $subclass (subclasses_of($type)) {
next if $subclass eq 'Node';
printf $fh "Ast%-12s ",$subclass;
}
printf $fh "\n";
$fh->print("\tchilds:\t");
foreach my $subclass (children_of($type)) {
next if $subclass eq 'Node';
printf $fh "Ast%-12s ",$subclass;
}
printf $fh "\n";
if (my $refs = $ClassRefs{"Ast${type}"}) {
$fh->print("\tnewed:\t");
foreach my $stage (sort {($Stages{$a}||-1) <=> ($Stages{$b}||-1)}
keys %{$refs->{newed}}) {
$fh->print($stage." ");
}
$fh->print("\n");
$fh->print("\tused:\t");
foreach my $stage (sort {($Stages{$a}||-1) <=> ($Stages{$b}||-1)}
keys %{$refs->{used}}) {
$fh->print($stage." ");
}
$fh->print("\n");
}
$fh->print("\n");
}
}
sub write_classes {
my $fh = open_file(@_);
foreach my $type (sort (keys %Classes)) {
@@ -501,7 +606,11 @@ Displays this message and program version and exits.
=item --classes
Makes class declaration files
Makes class declaration files.
=item --report
Makes a report report.
=back
@@ -526,5 +635,5 @@ Wilson Snyder <[email protected]>
######################################################################
### Local Variables:
### compile-command: "./astgen "
### compile-command: "./astgen -I. --report"
### End:
+1 -1
View File
@@ -56,7 +56,7 @@ process();
sub usage {
print "Version $VERSION\n";
pod2usage(-verbose=>2, -exitval => 2);
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
exit (1);
}
+4 -28
View File
@@ -25,41 +25,17 @@
//**********************************************************************
//**** Version and host name
#define DTVERSION "Verilator 3.820 2011/07/28"
// Autoconf substitutes this with the strings from AC_INIT.
#define PACKAGE_STRING ""
#define DTVERSION PACKAGE_STRING
//**********************************************************************
//**** Functions
// Set define if we have function: strdup (string)
#define HAVE_STRDUP 0
//**********************************************************************
//**** Headers
// Set define if we have header: <fcntl.h>
#define HAVE_FCNTL_H 0
// Set define if we have header: <math.h>
#define HAVE_MATH_H 1
// Set define if we have header: <unistd.h>
#define HAVE_UNISTD_H 0
// Set define if we have header: <sys/time.h>
#define HAVE_SYS_TIME_H 0
// Set define if we have header: <sys/un.h>
#define HAVE_SYS_UN_H 0
// Set define if we have header: <stdint.h>
#define HAVE_STDINT_H 0
// Set define if we have header: <mingw/stdint.h>
#define HAVE_MINGW_STDINT_H 0
// Set define if we have header: <inttypes.h>
#define HAVE_INTTYPES_H 0
//**********************************************************************
//**** Default environment
+124 -18
View File
@@ -134,7 +134,7 @@ void yyerrorf(const char* format, ...) {
%s V95 V01 V05 S05 S09
%s STRING ATTRMODE TABLE
%s PSL VLT
%s VA5 SA9 PSL VLT
%s SYSCHDR SYSCINT SYSCIMP SYSCIMPH SYSCCTOR SYSCDTOR
%s IGNORE
@@ -168,14 +168,16 @@ word [a-zA-Z0-9_]+
/************************************************************************/
/* Verilog 1995 */
<V95,V01,V05,S05,S09,PSL>{
<V95,V01,V05,VA5,S05,S09,SA9,PSL>{
{ws} { } /* otherwise ignore white-space */
{crnl} { NEXTLINE(); } /* Count line numbers */
/* Extensions to Verilog set, some specified by PSL */
"$c"[0-9]* { FL; return yD_C; } /*Verilator only*/
/* System Tasks */
"$bitstoreal" { FL; return yD_BITSTOREAL; }
"$ceil" { FL; return yD_CEIL; }
"$display" { FL; return yD_DISPLAY; }
"$exp" { FL; return yD_EXP; }
"$fclose" { FL; return yD_FCLOSE; }
"$fdisplay" { FL; return yD_FDISPLAY; }
"$feof" { FL; return yD_FEOF; }
@@ -183,14 +185,18 @@ word [a-zA-Z0-9_]+
"$fgetc" { FL; return yD_FGETC; }
"$fgets" { FL; return yD_FGETS; }
"$finish" { FL; return yD_FINISH; }
"$floor" { FL; return yD_FLOOR; }
"$fopen" { FL; return yD_FOPEN; }
"$fscanf" { FL; return yD_FSCANF; }
"$fullskew" { FL; return yaTIMINGSPEC; }
"$fwrite" { FL; return yD_FWRITE; }
"$hold" { FL; return yaTIMINGSPEC; }
"$itor" { FL; return yD_ITOR; }
"$ln" { FL; return yD_LN; }
"$log10" { FL; return yD_LOG10; }
"$nochange" { FL; return yaTIMINGSPEC; }
"$period" { FL; return yaTIMINGSPEC; }
"$pow" { FL; return yD_POW; }
"$random" { FL; return yD_RANDOM; }
"$readmemb" { FL; return yD_READMEMB; }
"$readmemh" { FL; return yD_READMEMH; }
@@ -204,10 +210,12 @@ word [a-zA-Z0-9_]+
"$setuphold" { FL; return yaTIMINGSPEC; }
"$sformat" { FL; return yD_SFORMAT; }
"$skew" { FL; return yaTIMINGSPEC; }
"$sqrt" { FL; return yD_SQRT; }
"$sscanf" { FL; return yD_SSCANF; }
"$stime" { FL; return yD_STIME; }
"$stop" { FL; return yD_STOP; }
"$swrite" { FL; return yD_SWRITE; }
"$system" { FL; return yD_SYSTEM; }
"$test$plusargs" { FL; return yD_TESTPLUSARGS; }
"$time" { FL; return yD_TIME; }
"$timeskew" { FL; return yaTIMINGSPEC; }
@@ -333,7 +341,7 @@ word [a-zA-Z0-9_]+
}
/* Verilog 2001 */
<V01,V05,S05,S09,PSL>{
<V01,V05,VA5,S05,S09,SA9,PSL>{
/* System Tasks */
"$signed" { FL; return yD_SIGNED; }
"$unsigned" { FL; return yD_UNSIGNED; }
@@ -364,7 +372,7 @@ word [a-zA-Z0-9_]+
}
/* Verilog 2005 */
<V05,S05,S09,PSL>{
<V05,S05,S09,SA9,PSL>{
/* Keywords */
"uwire" { FL; return yWIRE; }
}
@@ -523,7 +531,7 @@ word [a-zA-Z0-9_]+
}
/* Default PLI rule */
<V95,V01,V05,S05,S09,PSL>{
<V95,V01,V05,VA5,S05,S09,SA9,PSL>{
"$"[a-zA-Z_$][a-zA-Z0-9_$]* { string str (yytext,yyleng);
yylval.strp = PARSEP->newString(AstNode::encodeName(str));
// Lookup unencoded name including the $, to avoid hitting normal signals
@@ -533,11 +541,104 @@ word [a-zA-Z0-9_]+
}
}
/************************************************************************/
/* AMS */
<VA5,SA9>{
/* Generic unsupported warnings */
"above" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"abs" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"absdelay" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"abstol" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"ac_stim" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"access" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"acos" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"acosh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"aliasparam" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"analog" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"analysis" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"asin" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"asinh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"assert" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"atan" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"atan2" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"atanh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"branch" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"ceil" { FL; return yD_CEIL; }
"connect" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"connectmodule" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"connectrules" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"continuous" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"cos" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"cosh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"cross" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"ddt" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"ddt_nature" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"ddx" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"discipline" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"discrete" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"domain" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"driver_update" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"endconnectrules" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"enddiscipline" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"endnature" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"endparamset" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"exclude" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"exp" { FL; return yD_EXP; }
"final_step" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"flicker_noise" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"floor" { FL; return yD_FLOOR; }
"flow" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"from" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"ground" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"hypot" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"idt" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"idt_nature" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"idtmod" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"inf" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"initial_step" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"laplace_nd" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"laplace_np" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"laplace_zd" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"laplace_zp" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"last_crossing" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"limexp" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"ln" { FL; return yD_LN; }
"log" { FL; return yD_LOG10; }
"max" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"merged" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"min" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"nature" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"net_resolution" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"noise_table" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"paramset" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"potential" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"pow" { FL; return yD_POW; }
"resolveto" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"sin" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"sinh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"slew" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"split" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"sqrt" { FL; return yD_SQRT; }
"string" { FL; return ySTRING; }
"tan" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"tanh" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"timer" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"transition" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"units" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"white_noise" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"wreal" { FL; return yWREAL; }
"zi_nd" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"zi_np" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"zi_zd" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
"zi_zp" { yyerrorf("Unsupported: AMS reserved word not implemented: %s",yytext); }
}
/************************************************************************/
/* PSL */
/*Entry into PSL; mode change */
<V95,V01,V05,S05,S09>{
<V95,V01,V05,VA5,S05,S09,SA9>{
"psl" { yy_push_state(PSL); FL; return yPSL; }
}
@@ -626,7 +727,7 @@ word [a-zA-Z0-9_]+
/* Meta comments */
/* Converted from //{cmt}verilator ...{cmt} by preprocessor */
<V95,V01,V05,S05,S09,PSL>{
<V95,V01,V05,VA5,S05,S09,SA9,PSL>{
"/*verilator"{ws}*"*/" {} /* Ignore empty comments, may be `endif // verilator */
"/*verilator clock_enable*/" { FL; return yVL_CLOCK_ENABLE; }
"/*verilator coverage_block_off*/" { FL; return yVL_COVERAGE_BLOCK_OFF; }
@@ -642,6 +743,7 @@ word [a-zA-Z0-9_]+
"/*verilator public_flat_rw*/" { FL; return yVL_PUBLIC_FLAT_RW; } // The @(edge) is converted by the preproc
"/*verilator public_module*/" { FL; return yVL_PUBLIC_MODULE; }
"/*verilator sc_clock*/" { FL; return yVL_CLOCK; }
"/*verilator sc_bv*/" { FL; return yVL_SC_BV; }
"/*verilator sformat*/" { FL; return yVL_SFORMAT; }
"/*verilator systemc_clock*/" { FL; return yVL_CLOCK; }
"/*verilator tracing_off*/" {PARSEP->fileline()->tracingOn(false); }
@@ -660,11 +762,11 @@ word [a-zA-Z0-9_]+
/************************************************************************/
/* Single character operator thingies */
<V95,V01,V05,S05,S09>{
<V95,V01,V05,VA5,S05,S09,SA9>{
"{" { FL; return yytext[0]; }
"}" { FL; return yytext[0]; }
}
<V95,V01,V05,S05,S09,PSL>{
<V95,V01,V05,VA5,S05,S09,SA9,PSL>{
"!" { FL; return yytext[0]; }
"#" { FL; return yytext[0]; }
"$" { FL; return yytext[0]; }
@@ -696,7 +798,7 @@ word [a-zA-Z0-9_]+
/* Operators and multi-character symbols */
/* Verilog 1995 Operators */
<V95,V01,V05,S05,S09,PSL>{
<V95,V01,V05,VA5,S05,S09,SA9,PSL>{
"&&" { FL; return yP_ANDAND; }
"||" { FL; return yP_OROR; }
"<=" { FL; return yP_LTE; }
@@ -718,7 +820,7 @@ word [a-zA-Z0-9_]+
}
/* Verilog 2001 Operators */
<V01,V05,S05,S09,PSL>{
<V01,V05,VA5,S05,S09,SA9,PSL>{
"<<<" { FL; return yP_SLEFT; }
">>>" { FL; return yP_SSRIGHT; }
"**" { FL; return yP_POW; }
@@ -777,7 +879,7 @@ word [a-zA-Z0-9_]+
}
/* Identifiers and numbers */
<V95,V01,V05,S05,S09,PSL,VLT>{
<V95,V01,V05,VA5,S05,S09,SA9,PSL,VLT>{
{escid} { FL; yylval.strp = PARSEP->newString
(AstNode::encodeName(string(yytext+1))); // +1 to skip the backslash
return yaID__LEX;
@@ -852,8 +954,9 @@ word [a-zA-Z0-9_]+
/************************************************************************/
/* Attributes */
<V95,V01,V05,S05,S09>{
"(*"/{ws}*[^)] { yymore(); yy_push_state(ATTRMODE); } // Doesn't match (*)
/* Note simulators vary in support for "(* /_*something*_/ foo*)" where _ doesn't exist */
<V95,V01,V05,VA5,S05,S09,SA9>{
"(*"({ws}|{crnl})*({id}|{escid}) { yymore(); yy_push_state(ATTRMODE); } // Doesn't match (*), but (* attr_spec
}
/************************************************************************/
@@ -869,7 +972,7 @@ word [a-zA-Z0-9_]+
/* Preprocessor */
/* Common for all SYSC header states */
/* OPTIMIZE: we return one per line, make it one for the entire block */
<V95,V01,V05,S05,S09,PSL,VLT,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,SYSCDTOR,IGNORE>{
<V95,V01,V05,VA5,S05,S09,SA9,PSL,VLT,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,SYSCDTOR,IGNORE>{
"`accelerate" { } // Verilog-XL compatibility
"`autoexpand_vectornets" { } // Verilog-XL compatibility
"`celldefine" { PARSEP->inCellDefine(true); }
@@ -910,9 +1013,11 @@ word [a-zA-Z0-9_]+
"`begin_keywords"[ \t]*\"1364-2001\" { yy_push_state(V01); PARSEP->pushBeginKeywords(YY_START); }
"`begin_keywords"[ \t]*\"1364-2001-noconfig\" { yy_push_state(V01); PARSEP->pushBeginKeywords(YY_START); }
"`begin_keywords"[ \t]*\"1364-2005\" { yy_push_state(V05); PARSEP->pushBeginKeywords(YY_START); }
"`begin_keywords"[ \t]*\"VAMS[-0-9.]*\" { yy_push_state(VA5); PARSEP->pushBeginKeywords(YY_START); }
"`begin_keywords"[ \t]*\"1800-2005\" { yy_push_state(S05); PARSEP->pushBeginKeywords(YY_START); }
"`begin_keywords"[ \t]*\"1800-2009\" { yy_push_state(S09); PARSEP->pushBeginKeywords(YY_START); }
"`end_keywords" { yy_pop_state(); if (!PARSEP->popBeginKeywords()) yyerrorf("`end_keywords when not inside `begin_keywords block"); }
"`begin_keywords"[ \t]*\"1800+VAMS\" { yy_push_state(SA9); PARSEP->pushBeginKeywords(YY_START); }
"`end_keywords" { yy_pop_state(); if (!PARSEP->popBeginKeywords()) yyerrorf("`end_keywords when not inside `begin_keywords block"); }
/* Verilator */
"`systemc_ctor" { BEGIN SYSCCTOR; }
@@ -942,7 +1047,7 @@ word [a-zA-Z0-9_]+
/************************************************************************/
/* Default rules - leave last */
<V95,V01,V05,S05,S09,PSL,VLT>{
<V95,V01,V05,VA5,S05,S09,SA9,PSL,VLT>{
"`"[a-zA-Z_0-9]+ { FL; yyerrorf("Define or directive not defined: %s",yytext); }
"//"[^\n]* { } /* throw away single line comments */
. { FL; return yytext[0]; } /* return single char ops. */
@@ -963,7 +1068,8 @@ double V3ParseImp::parseDouble(const char* textp, size_t length) {
*dp++ = '\0';
char* endp = strgp;
double d = strtod(strgp, &endp);
if ((endp-strgp) != length) { yyerrorf("Syntax error parsing real: %s",strgp); }
size_t parsed_len = endp-strgp;
if (parsed_len != length) { yyerrorf("Syntax error parsing real: %s",strgp); }
delete strgp;
return d;
}
+33 -6
View File
@@ -71,7 +71,7 @@ public:
m_varIO = AstVarType::UNKNOWN;
m_varDTypep = NULL;
m_pinNum = -1;
m_instModule;
m_instModule = "";
m_instParamp = NULL;
m_modp = NULL;
m_modTypeImpNum = 0;
@@ -380,16 +380,19 @@ class AstSenTree;
%token<fl> yVOID "void"
%token<fl> yWHILE "while"
%token<fl> yWIRE "wire"
%token<fl> yWREAL "wreal"
%token<fl> yXNOR "xnor"
%token<fl> yXOR "xor"
%token<fl> yD_BITS "$bits"
%token<fl> yD_BITSTOREAL "$bitstoreal"
%token<fl> yD_C "$c"
%token<fl> yD_CEIL "$ceil"
%token<fl> yD_CLOG2 "$clog2"
%token<fl> yD_COUNTONES "$countones"
%token<fl> yD_DISPLAY "$display"
%token<fl> yD_ERROR "$error"
%token<fl> yD_EXP "$exp"
%token<fl> yD_FATAL "$fatal"
%token<fl> yD_FCLOSE "$fclose"
%token<fl> yD_FDISPLAY "$fdisplay"
@@ -398,14 +401,18 @@ class AstSenTree;
%token<fl> yD_FGETC "$fgetc"
%token<fl> yD_FGETS "$fgets"
%token<fl> yD_FINISH "$finish"
%token<fl> yD_FLOOR "$floor"
%token<fl> yD_FOPEN "$fopen"
%token<fl> yD_FSCANF "$fscanf"
%token<fl> yD_FWRITE "$fwrite"
%token<fl> yD_INFO "$info"
%token<fl> yD_ISUNKNOWN "$isunknown"
%token<fl> yD_ITOR "$itor"
%token<fl> yD_LN "$ln"
%token<fl> yD_LOG10 "$log10"
%token<fl> yD_ONEHOT "$onehot"
%token<fl> yD_ONEHOT0 "$onehot0"
%token<fl> yD_POW "$pow"
%token<fl> yD_RANDOM "$random"
%token<fl> yD_READMEMB "$readmemb"
%token<fl> yD_READMEMH "$readmemh"
@@ -414,10 +421,12 @@ class AstSenTree;
%token<fl> yD_RTOI "$rtoi"
%token<fl> yD_SFORMAT "$sformat"
%token<fl> yD_SIGNED "$signed"
%token<fl> yD_SQRT "$sqrt"
%token<fl> yD_SSCANF "$sscanf"
%token<fl> yD_STIME "$stime"
%token<fl> yD_STOP "$stop"
%token<fl> yD_SWRITE "$swrite"
%token<fl> yD_SYSTEM "$system"
%token<fl> yD_TESTPLUSARGS "$test$plusargs"
%token<fl> yD_TIME "$time"
%token<fl> yD_UNIT "$unit"
@@ -440,6 +449,7 @@ class AstSenTree;
%token<fl> yVL_ISOLATE_ASSIGNMENTS "/*verilator isolate_assignments*/"
%token<fl> yVL_NO_INLINE_MODULE "/*verilator no_inline_module*/"
%token<fl> yVL_NO_INLINE_TASK "/*verilator no_inline_task*/"
%token<fl> yVL_SC_BV "/*verilator sc_bv*/"
%token<fl> yVL_SFORMAT "/*verilator sformat*/"
%token<fl> yVL_PARALLEL_CASE "/*verilator parallel_case*/"
%token<fl> yVL_PUBLIC "/*verilator public*/"
@@ -1078,6 +1088,8 @@ non_integer_type<bdtypep>: // ==IEEE: non_integer_type
yREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); }
| yREALTIME { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); }
//UNSUP ySHORTREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::FLOAT); }
// // VAMS - somewhat hackish
| yWREAL { $$ = new AstBasicDType($1,AstBasicDTypeKwd::DOUBLE); VARDECL(WIRE); }
;
signingE<signstate>: // IEEE: signing - plus empty
@@ -1520,7 +1532,7 @@ assignOne<nodep>:
delayE:
/* empty */ { }
| delay_control { } /* ignored */
| delay_control { $1->v3warn(ASSIGNDLY,"Unsupported: Ignoring delay on this assignment/primitive."); } /* ignored */
;
delay_control<fl>: //== IEEE: delay_control
@@ -1589,6 +1601,7 @@ sigAttr<nodep>:
| yVL_PUBLIC_FLAT_RW attr_event_control { $$ = new AstAttrOf($1,AstAttrType::VAR_PUBLIC_FLAT_RW);
$$ = $$->addNext(new AstAlwaysPublic($1,$2,NULL)); }
| yVL_ISOLATE_ASSIGNMENTS { $$ = new AstAttrOf($1,AstAttrType::VAR_ISOLATE_ASSIGNMENTS); }
| yVL_SC_BV { $$ = new AstAttrOf($1,AstAttrType::VAR_SC_BV); }
| yVL_SFORMAT { $$ = new AstAttrOf($1,AstAttrType::VAR_SFORMAT); }
;
@@ -1759,8 +1772,8 @@ event_control<sentreep>: // ==IEEE: event_control
event_expression<senitemp>: // IEEE: event_expression - split over several
senitem { $$ = $1; }
| event_expression yOR senitem { $$ = $1;$1->addNext($3); }
| event_expression ',' senitem { $$ = $1;$1->addNext($3); } /* Verilog 2001 */
| event_expression yOR senitem { $$ = $1;$1->addNextNull($3); }
| event_expression ',' senitem { $$ = $1;$1->addNextNull($3); } /* Verilog 2001 */
;
senitem<senitemp>: // IEEE: part of event_expression, non-'OR' ',' terms
@@ -1769,6 +1782,11 @@ senitem<senitemp>: // IEEE: part of event_expression, non-'OR' ',' terms
| '(' senitemVar ')' { $$ = $2; }
//UNSUP expr { UNSUP }
//UNSUP expr yIFF expr { UNSUP }
// Since expr is unsupported we allow and ignore constants (removed in V3Const)
| yaINTNUM { $$ = NULL; }
| yaFLOATNUM { $$ = NULL; }
| '(' yaINTNUM ')' { $$ = NULL; }
| '(' yaFLOATNUM ')' { $$ = NULL; }
;
senitemVar<senitemp>:
@@ -1922,7 +1940,7 @@ statement_item<nodep>: // IEEE: statement_item
//
//UNSUP par_block { $$ = $1; }
// // IEEE: procedural_timing_control_statement + procedural_timing_control
| delay_control stmtBlock { $$ = $2; $1->v3warn(STMTDLY,"Ignoring delay on this delayed statement."); }
| delay_control stmtBlock { $$ = $2; $1->v3warn(STMTDLY,"Unsupported: Ignoring delay on this delayed statement."); }
//UNSUP event_control stmtBlock { UNSUP }
//UNSUP cycle_delay stmtBlock { UNSUP }
//
@@ -2111,7 +2129,7 @@ system_t_call<nodep>: // IEEE: system_tf_call (as task)
| yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCStmt($1,$3)); }
| yD_FCLOSE '(' idClassSel ')' { $$ = new AstFClose($1, $3); }
| yD_FFLUSH parenE { $1->v3error("Unsupported: $fflush of all handles does not map to C++."); }
| yD_FFLUSH '(' idClassSel ')' { $$ = new AstFClose($1, $3); }
| yD_FFLUSH '(' idClassSel ')' { $$ = new AstFFlush($1, $3); }
| yD_FINISH parenE { $$ = new AstFinish($1); }
| yD_FINISH '(' expr ')' { $$ = new AstFinish($1); }
| yD_STOP parenE { $$ = new AstStop($1); }
@@ -2119,6 +2137,7 @@ system_t_call<nodep>: // IEEE: system_tf_call (as task)
//
| yD_SFORMAT '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1,$3,*$5,$6); }
| yD_SWRITE '(' expr ',' str commaEListE ')' { $$ = new AstSFormat($1,$3,*$5,$6); }
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemT($1,$3); }
//
| yD_DISPLAY parenE { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,"", NULL,NULL); }
| yD_DISPLAY '(' str commaEListE ')' { $$ = new AstDisplay($1,AstDisplayType::DT_DISPLAY,*$3,NULL,$4); }
@@ -2152,6 +2171,13 @@ system_f_call<nodep>: // IEEE: system_tf_call (as func)
| yaD_DPI parenE { $$ = new AstFuncRef($<fl>1,*$1,NULL); }
| yaD_DPI '(' exprList ')' { $$ = new AstFuncRef($2,*$1,$3); }
//
| yD_CEIL '(' expr ')' { $$ = new AstCeilD($1,$3); }
| yD_EXP '(' expr ')' { $$ = new AstExpD($1,$3); }
| yD_FLOOR '(' expr ')' { $$ = new AstFloorD($1,$3); }
| yD_LN '(' expr ')' { $$ = new AstLogD($1,$3); }
| yD_LOG10 '(' expr ')' { $$ = new AstLog10D($1,$3); }
| yD_POW '(' expr ',' expr ')' { $$ = new AstPowD($1,$3,$5); }
| yD_SQRT '(' expr ')' { $$ = new AstSqrtD($1,$3); }
| yD_BITS '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::EXPR_BITS,$3); }
| yD_BITS '(' data_type ')' { $$ = new AstAttrOf($1,AstAttrType::EXPR_BITS,$3); }
| yD_BITSTOREAL '(' expr ')' { $$ = new AstBitsToRealD($1,$3); }
@@ -2163,6 +2189,7 @@ system_f_call<nodep>: // IEEE: system_tf_call (as func)
| yD_FGETS '(' idClassSel ',' expr ')' { $$ = new AstFGetS($1,$3,$5); }
| yD_FSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstFScanF($1,*$5,$3,$6); }
| yD_SSCANF '(' expr ',' str commaVRDListE ')' { $$ = new AstSScanF($1,*$5,$3,$6); }
| yD_SYSTEM '(' expr ')' { $$ = new AstSystemF($1,$3); }
| yD_ISUNKNOWN '(' expr ')' { $$ = new AstIsUnknown($1,$3); }
| yD_ITOR '(' expr ')' { $$ = new AstIToRD($1,$3); }
| yD_ONEHOT '(' expr ')' { $$ = new AstOneHot($1,$3); }
+1 -3
View File
@@ -19,11 +19,9 @@ include Vtop.mk
# Compile flags
CPPFLAGS += -DVL_DEBUG=1
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
CPPFLAGS += -DVL_THREADED=1
CPPFLAGS += -W -Werror -Wall
#CPPFLAGS += -Wno-unused-variable # Instead, add VL_ATTR_UNUSED in gen'ed code
#CPPFLAGS += -pedantic-errors
endif
#######################################################################
+3 -3
View File
@@ -13,10 +13,10 @@
Vtop *top; // Instantiation of module
unsigned int main_time = 0; // Current simulation time
vluint64_t main_time = 0; // Current simulation time (64-bit unsigned)
double sc_time_stamp () { // Called by $time in Verilog
return main_time;
return main_time; // Note does conversion to real, to match SystemC
}
int main(int argc, char **argv, char **env) {
@@ -59,7 +59,7 @@ int main(int argc, char **argv, char **env) {
#endif
// Read outputs
VL_PRINTF ("[%d] %x %x %x %x %x_%08x_%08x\n",
VL_PRINTF ("[%" VL_PRI64 "d] %x %x %x %x %x_%08x_%08x\n",
main_time, top->clk, top->reset_l, top->passed,
top->out_small, top->out_wide[2], top->out_wide[1], top->out_wide[0]);
+2 -1
View File
@@ -35,7 +35,8 @@ endif
PRODUCTS += --vlt
ifeq ($(VERILATOR_AUTHOR_SITE),1)
# Run tests in parallel. Requires Parallel::Forker to be installed.
ifeq ($(CFG_WITH_LONGTESTS),yes)
DRIVER_FLAGS += -j 0
endif
-7
View File
@@ -25,13 +25,6 @@ VPATH += ../../$(VM_USER_DIR)
#######################################################################
ifeq ($(VERILATOR_AUTHOR_SITE),1)
#OBJCACHE := objcache --read --write
#OBJCACHE_HOSTS :=
endif
#######################################################################
# Needed by DPI tests
CPPFLAGS += -DVERILATOR=1
+12 -3
View File
@@ -39,6 +39,7 @@ autoflush STDERR 1;
our @Orig_ARGV = @ARGV;
our @Orig_ARGV_Sw; foreach (@Orig_ARGV) { push @Orig_ARGV_Sw, $_ if /^-/ && !/^-j/; }
our $Start = time();
$Debug = 0;
my $opt_atsim;
@@ -64,6 +65,7 @@ Getopt::Long::config ("pass_through");
if (! GetOptions (
"benchmark:i" => sub { $opt_benchmark = $_[1] ? $_[1] : 1; },
"debug" => \&debug,
#debugi see parameter()
"atsim|athdl!"=> \$opt_atsim,
"gdb!" => \$opt_gdb,
"gdbbt!" => \$opt_gdbbt,
@@ -83,6 +85,7 @@ if (! GetOptions (
"vcs!" => \$opt_vcs,
"verbose!" => \$opt_verbose,
"verilated_debug!" => \$Opt_Verilated_Debug,
#W see parameter()
"<>" => \&parameter,
)) {
die "%Error: Bad usage, try '$0 --help'\n";
@@ -178,7 +181,7 @@ exit(10) if $failcnt;
#----------------------------------------------------------------------
sub usage {
pod2usage(-verbose=>2, -exitval => 2);
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
exit (1);
}
@@ -204,6 +207,9 @@ sub parameter {
push @Opt_Driver_Verilator_Flags, $param;
$_Parameter_Next_Level = $param;
}
elsif ($param =~ /^-?-W/) {
push @Opt_Driver_Verilator_Flags, $param;
}
else {
die "%Error: Unknown parameter: $param\n";
}
@@ -228,14 +234,17 @@ sub report {
$fh = IO::File->new(">$filename") or die "%Error: $! writing $filename,";
}
my $delta = time() - $Start;
$fh->print("\n");
$fh->print("="x70,"\n");
$fh->print("TESTS Passed $okcnt Skipped $skcnt Failed $failcnt\n");
$fh->printf("TESTS Passed $okcnt Skipped $skcnt Failed $failcnt Time %d:%02d\n",
int($delta/60),$delta%60);
foreach my $f (@$fails) {
chomp $f;
$fh->print("$f\n");
}
$fh->print("TESTS Passed $okcnt Skipped $skcnt Failed $failcnt\n");
$fh->printf("TESTS Passed $okcnt Skipped $skcnt Failed $failcnt Time %d:%02d\n",
int($delta/60),$delta%60);
}
#######################################################################
+1 -1
View File
@@ -3,7 +3,7 @@
// Use this file as a template for submitting bugs, etc.
// This module takes a single clock input, and should either
// $write("*-* All Finished *-*\n");
// $finish
// $finish;
// on success, or $stop.
//
// The code as shown applies a random vector to the Test
+10 -2
View File
@@ -11,7 +11,7 @@ module t (/*AUTOARG*/
input clk;
integer cyc; initial cyc=1;
reg [31:0] a, b, c, d, e;
reg [31:0] a, b, c, d, e, f, g;
always @ (*) begin // Test Verilog 2001 (*)
// verilator lint_off COMBDLY
@@ -25,6 +25,14 @@ module t (/*AUTOARG*/
always @ ((d)) begin // always bug 2008/4/18
e = d;
end
parameter CONSTANT = 1;
always @ (e, 1'b0, CONSTANT) begin // not technically legal, see bug412
f = e;
end
always @ (1'b0, CONSTANT, f) begin // not technically legal, see bug412
g = f;
end
//always @ ((posedge b) or (a or b)) begin // note both illegal
always @ (posedge clk) begin
@@ -38,7 +46,7 @@ module t (/*AUTOARG*/
if (c != 32'hfeedface) $stop;
end
if (cyc==3) begin
if (e != 32'hfeedface) $stop;
if (g != 32'hfeedface) $stop;
end
if (cyc==7) begin
$write("*-* All Finished *-*\n");
+1 -1
View File
@@ -11,7 +11,7 @@ compile (
verilator_flags2 => ["--stats"],
);
if ($Self->{v3}) {
if ($Self->{vlt}) {
file_grep ($Self->{stats}, qr/Optimizations, Split always\s+6/i);
}
+1 -1
View File
@@ -11,7 +11,7 @@ compile (
verilator_flags2 => ["--stats"],
);
if ($Self->{v3}) {
if ($Self->{vlt}) {
file_grep ($Self->{stats}, qr/Optimizations, Split always\s+0/i);
}
+2 -1
View File
@@ -8,7 +8,8 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Version 2.0.
compile (
v_flags2 => [$Self->{v3}?'--assert':($Self->{nc}?'+assert':'')],
verilator_flags2 => ['--assert'],
nc_flags2 => ['+assert'],
);
execute (
+1 -1
View File
@@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
top_filename("t/t_assert_basic.v");
compile (
v_flags2 => [$Self->{v3}?'--assert --sp --coverage-user':''],
verilator_flags2 => ['--assert --sp --coverage-user'],
);
execute (
+1 -1
View File
@@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
top_filename("t/t_assert_cover.v");
compile (
v_flags2 => [$Self->{v3}?'--assert --sp --coverage-user':''],
verilator_flags2 => ['--assert --sp --coverage-user'],
nc_flags2 => ["+nccovoverwrite +nccoverage+all +nccovtest+$Self->{name}"]
);
+2 -1
View File
@@ -8,7 +8,8 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Version 2.0.
compile (
v_flags2 => [$Self->{v3}?'--assert':($Self->{nc}?'+assert':'')],
verilator_flags2 => ['--assert'],
nc_flags2 => ['+assert'],
);
execute (
+3 -2
View File
@@ -10,8 +10,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
top_filename("t/t_assert_synth.v");
compile (
v_flags2 => [$Self->{v3}?'--assert':($Self->{nc}?'+assert':''),
'+define+FAILING_FULL',],
v_flags2 => ['+define+FAILING_FULL'],
verilator_flags2 => ['--assert'],
nc_flags2 => ['+assert'],
);
execute (
+3 -2
View File
@@ -10,8 +10,9 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
top_filename("t/t_assert_synth.v");
compile (
v_flags2 => [$Self->{v3}?'--assert':($Self->{nc}?'+assert':''),
'+define+FAILING_PARALLEL',],
v_flags2 => ['+define+FAILING_PARALLEL'],
verilator_flags2 => ['--assert'],
nc_flags2 => ['+assert'],
);
execute (
+18
View File
@@ -0,0 +1,18 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
compile (
);
execute (
check_finished=>1,
);
ok(1);
1;

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