[Pkg-electronics-commits] [verilator] 01/03: Imported Upstream version 3.868
أحمد المحمودي (Ahmed El-Mahmoudy)
aelmahmoudy at sabily.org
Tue Dec 23 13:57:27 UTC 2014
This is an automated email from the git hooks/post-receive script.
aelmahmoudy-guest pushed a commit to branch experimental
in repository verilator.
commit 29747cec4bc3e7dfc7b74412374dbbf43ce7299c
Author: أحمد المحمودي (Ahmed El-Mahmoudy) <aelmahmoudy at users.sourceforge.net>
Date: Tue Dec 23 10:49:53 2014 +0200
Imported Upstream version 3.868
---
.gitignore | 1 +
Changes | 25 ++
MANIFEST.SKIP | 1 +
Makefile.in | 39 +-
README | 13 +-
README.html | 14 +-
README.pdf | Bin 112209 -> 110434 bytes
TODO | 17 -
bin/verilator | 100 ++---
bin/verilator_coverage | 291 +++++++++++++
bin/verilator_includer | 6 +-
configure | 18 +-
configure.ac | 2 +-
doxygen.config | 2 -
include/verilated.cpp | 50 +++
include/verilated.h | 4 +
include/verilated.mk.in | 10 +-
include/verilated_config.h | 2 +-
include/verilated_cov.cpp | 451 ++++++++++++++++++++
include/verilated_cov.h | 146 +++++++
include/verilated_cov_key.h | 147 +++++++
include/verilated_heavy.h | 13 +-
include/verilated_vcd_c.cpp | 2 +-
include/verilated_vcd_c.h | 2 +-
include/verilated_vcd_sc.cpp | 2 +-
include/verilated_vcd_sc.h | 2 +-
include/verilatedos.h | 7 +
internals.html | 13 +-
internals.pdf | Bin 197500 -> 195665 bytes
internals.pod | 14 +-
internals.txt | 13 +-
readme.pod | 14 +-
src/Makefile.in | 8 +-
src/Makefile_obj.in | 26 +-
src/V3Assert.cpp | 22 +-
src/V3AssertPre.cpp | 15 -
src/V3Ast.cpp | 25 --
src/V3Ast.h | 26 +-
src/V3AstNodes.cpp | 10 +-
src/V3AstNodes.h | 258 ++++++++----
src/V3Branch.cpp | 45 +-
src/V3Config.h | 1 +
src/V3Const.cpp | 10 +-
src/V3EmitC.cpp | 39 +-
src/V3EmitMk.cpp | 6 +-
src/V3EmitV.cpp | 6 +-
src/V3EmitXml.cpp | 2 +-
src/V3Error.cpp | 284 +------------
src/V3Error.h | 154 +------
src/V3File.cpp | 2 +-
src/{V3Error.cpp => V3FileLine.cpp} | 215 +---------
src/V3FileLine.h | 171 ++++++++
src/V3Global.h | 1 +
src/V3LinkDot.cpp | 17 +
src/V3LinkLevel.cpp | 7 +-
src/V3Number.cpp | 69 +++-
src/V3Number.h | 27 +-
src/V3Number_test.cpp | 1 +
src/V3Options.cpp | 24 +-
src/V3Options.h | 10 +-
src/V3ParseImp.cpp | 2 +-
src/V3ParseImp.h | 4 +-
src/V3ParseLex.cpp | 9 -
src/V3ParseSym.h | 1 +
src/V3PreLex.h | 5 +-
src/V3PreLex.l | 62 +--
src/V3PreProc.cpp | 11 +-
src/V3PreProc.h | 2 +-
src/V3PreShell.h | 1 +
src/V3Premit.cpp | 24 +-
src/V3Stats.cpp | 28 +-
src/V3Stats.h | 3 +-
src/V3Subst.cpp | 11 +-
src/V3Unknown.cpp | 8 +-
src/V3Width.cpp | 457 ++++++++++++++++++---
src/V3WidthCommit.h | 5 +-
src/Verilator.cpp | 2 +-
src/VlcBucket.h | 133 ++++++
src/VlcMain.cpp | 203 +++++++++
src/VlcOptions.h | 87 ++++
src/VlcPoint.h | 152 +++++++
src/VlcSource.h | 145 +++++++
src/VlcTest.h | 137 ++++++
src/VlcTop.cpp | 263 ++++++++++++
src/VlcTop.h | 69 ++++
src/astgen | 8 +-
src/config_build.h | 2 +-
src/config_rev.h | 2 +-
src/verilog.l | 172 ++------
src/verilog.y | 94 +----
src/vlcovgen | 173 ++++++++
test_regress/Makefile_obj | 2 +-
test_regress/driver.pl | 16 +-
test_regress/t/t_assert_basic_cover.pl | 2 +-
test_regress/t/t_assert_cover.pl | 2 +-
test_regress/t/t_bitsel_wire_array_bad.pl | 13 +-
test_regress/t/t_cover_line.out | 170 ++++++++
test_regress/t/t_cover_line_cc.pl | 9 +-
test_regress/t/t_cover_line_sp.pl | 24 --
test_regress/t/t_cover_sva_notflat.pl | 2 +-
test_regress/t/t_cover_toggle.pl | 2 +-
test_regress/t/t_dist_spdiff.pl | 23 --
.../{t_sv_enum_type_methods.pl => t_enum_name2.pl} | 3 -
test_regress/t/t_enum_name2.v | 31 ++
test_regress/t/t_enum_type_methods.v | 143 ++++---
...sv_enum_type_methods.pl => t_enum_type_pins.pl} | 0
...t_sv_enum_type_methods.v => t_enum_type_pins.v} | 0
.../{t_sv_enum_type_methods.pl => t_flag_stats.pl} | 6 +-
test_regress/t/t_flag_stats.v | 13 +
test_regress/t/t_flag_werror_bad2.pl | 2 +-
test_regress/t/t_help.pl | 22 +-
test_regress/t/t_inst_overwide.pl | 2 +-
test_regress/t/t_inst_overwide_bad.pl | 2 +-
.../t/{t_psl_basic_off.pl => t_interface_gen4.pl} | 9 +-
test_regress/t/t_interface_gen4.v | 58 +++
test_regress/t/t_math_real.v | 1 +
test_regress/t/t_mem_multidim_trace.pl | 2 +-
test_regress/t/t_preproc_psl.v | 72 ----
test_regress/t/t_preproc_psl_off.out | 99 -----
test_regress/t/t_preproc_psl_on.out | 88 ----
test_regress/t/t_psl_basic.v | 54 ---
test_regress/t/t_psl_basic_cover.pl | 26 --
test_regress/t/t_savable.v | 1 +
.../t/{t_sv_enum_type_methods.pl => t_string.pl} | 3 -
test_regress/t/t_string.v | 91 ++++
test_regress/t/t_sys_sformat.v | 4 +
test_regress/t/t_trace_ena_sp.pl | 26 --
test_regress/t/t_trace_off_sp.pl | 25 --
.../t/{t_psl_basic.pl => t_trace_scstruct.pl} | 8 +-
test_regress/t/t_trace_scstruct.v | 26 ++
test_regress/t/t_var_pins_sc1.pl | 34 +-
test_regress/t/t_var_pins_sc2.pl | 34 +-
test_regress/t/t_var_pins_sc32.pl | 34 +-
test_regress/t/t_var_pins_sc64.pl | 34 +-
test_regress/t/t_var_pins_sc_biguint.pl | 42 +-
test_regress/t/t_var_pins_sc_uint.pl | 42 +-
test_regress/t/t_var_pins_sc_uint_biguint.pl | 42 +-
test_regress/t/t_var_pins_scui.pl | 34 +-
.../{t_sv_enum_type_methods.pl => t_var_static.pl} | 3 +-
test_regress/t/t_var_static.v | 69 ++++
test_regress/t/t_vlcov_data_a.dat | 5 +
test_regress/t/t_vlcov_data_b.dat | 5 +
test_regress/t/t_vlcov_data_c.dat | 2 +
test_regress/t/t_vlcov_data_d.dat | 2 +
test_regress/t/t_vlcov_merge.out | 8 +
.../t/{t_preproc_psl_off.pl => t_vlcov_merge.pl} | 19 +-
test_regress/t/t_vlcov_rank.out | 6 +
.../t/{t_preproc_psl_on.pl => t_vlcov_rank.pl} | 21 +-
.../t/{t_preproc_psl_off.pl => t_vlcov_rewrite.pl} | 25 +-
test_sc/Makefile | 7 +-
test_sc/sc_main.cpp | 37 +-
test_sp/.gitignore | 8 -
test_sp/Makefile | 86 ----
test_sp/Makefile_obj | 37 --
test_vcs/.gitignore | 13 -
test_vcs/Makefile | 76 ----
test_vcs/bench.v | 81 ----
verilator.1 | 98 ++---
verilator.html | 93 ++---
verilator.pdf | Bin 389398 -> 386595 bytes
verilator.txt | 100 ++---
verilator_coverage.1 | 238 +++++++++++
162 files changed, 4889 insertions(+), 2705 deletions(-)
diff --git a/.gitignore b/.gitignore
index 9b7b2e8..7fc9bdb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,3 +23,4 @@ gdbrun*
internals.txt
verilator.txt
verilator_bin*
+verilator_coverage_bin*
diff --git a/Changes b/Changes
index d6a81dd..e549f08 100644
--- a/Changes
+++ b/Changes
@@ -3,6 +3,31 @@ Revision history for Verilator
The contributors that suggested a given feature are shown in []. [by ...]
indicates the contributor was also the author of the fix; Thanks!
+* Verilator 3.868 2014-12-20
+
+** New verilator_coverage program added to replace SystemPerl's vcoverage.
+
+** PSL support was removed, please use System Verilog assertions.
+
+** SystemPerl mode is deprecated and now untested.
+
+*** Support enum.first/name and similar methods, bug460, bug848.
+
+*** Add 'string' printing and comparisons, bug746, bug747, etc.
+
+*** Inline C functions that are used only once, msg1525. [Jie Xu]
+
+*** Fix tracing SystemC signals with structures, bug858. [Eivind Liland]
+ Note that SystemC traces will no longer show the signals
+ in the wrapper, they can be seen one level further down.
+
+**** Add --stats-vars, bug851. [Jeremy Bennett]
+
+**** Fix bare generates in interfaces, bug789. [Bob Newgard]
+
+**** Fix underscores in real literals, bug863. [Jonathon Donaldson]
+
+
* Verilator 3.866 2014-11-15
*** Fix +define+A+B to define A and B to match other simulators, bug847. [Adam Krolnik]
diff --git a/MANIFEST.SKIP b/MANIFEST.SKIP
index 8ff54ea..ca6161f 100644
--- a/MANIFEST.SKIP
+++ b/MANIFEST.SKIP
@@ -28,6 +28,7 @@ config.status$
verilator.log
verilator.tex
verilator_bin.*
+verilator_coverage_bin.*
.vcsmx_rebuild$
autom4te\.cache/
nodist/
diff --git a/Makefile.in b/Makefile.in
index d7cf4c9..166823d 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -100,10 +100,11 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
SHELL = /bin/sh
-SUBDIRS = src test_verilated test_c test_sc test_sp test_regress test_vcs
+SUBDIRS = src test_verilated test_c test_sc test_regress
INFOS = README README.html README.pdf internals.txt internals.html \
- internals.pdf verilator.txt verilator.html verilator.1 verilator.pdf
+ internals.pdf verilator.txt verilator.html verilator.1 verilator.pdf \
+ verilator_coverage.1
# Files that can be generated, but should be up to date for a distribution.
DISTDEP = info Makefile
@@ -122,6 +123,7 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
.*attributes */.*attributes */*/.*attributes \
src/.*ignore src/*.in src/*.cpp src/*.[chly] \
src/astgen src/bisonpre src/*fix src/cppcheck_filtered \
+ src/vlcovgen \
src/.gdbinit \
src/*.pl src/*.pod \
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
@@ -140,6 +142,7 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
INST_PROJ_FILES = \
bin/verilator \
+ bin/verilator_coverage \
bin/verilator_includer \
bin/verilator_profcfunc \
include/verilated.mk \
@@ -149,6 +152,7 @@ INST_PROJ_FILES = \
INST_PROJ_BIN_FILES = \
verilator_bin \
verilator_bin_dbg \
+ verilator_coverage_bin_dbg \
DISTFILES := $(DISTFILES_INC)
@@ -165,7 +169,8 @@ all_nomsg: verilator_exe $(VL_INST_MAN_FILES)
.PHONY:verilator_exe
.PHONY:verilator_bin
.PHONY:verilator_bin_dbg
-verilator_exe verilator_bin verilator_bin_dbg:
+.PHONY:verilator_coverage_bin_dbg
+verilator_exe verilator_bin verilator_bin_dbg verilator_coverage_bin_dbg:
@echo ------------------------------------------------------------
@echo "making verilator in src" ; \
(cd src && $(MAKE) $(OBJCACHE_JOBS) )
@@ -179,17 +184,15 @@ msg_test: all_nomsg
.PHONY:test
ifeq ($(CFG_WITH_LONGTESTS),yes) # Local... Else don't burden users
-test: test_vcs test_c test_sc test_sp test_verilated test_regress
+test: test_c test_sc test_verilated test_regress
else
-test: test_c test_sc test_sp
+test: test_c test_sc
endif
@echo "Tests passed!"
@echo
@echo "Type 'make install' to install documentation."
@echo
-test_vcs: all_nomsg
- @(cd test_vcs && $(MAKE))
test_c: all_nomsg
@(cd test_c && $(MAKE))
test_c_debug: all_nomsg
@@ -198,10 +201,6 @@ test_sc: all_nomsg
@(cd test_sc && $(MAKE))
test_sc_debug: all_nomsg
@(cd test_sc && $(MAKE) test_debug)
-test_sp: all_nomsg
- @(cd test_sp && $(MAKE))
-test_sp_debug: all_nomsg
- @(cd test_sp && $(MAKE) test_debug)
test_verilated: all_nomsg
@(cd test_verilated && $(MAKE))
test_regress: all_nomsg
@@ -213,6 +212,9 @@ info: $(INFOS)
verilator.1: ${srcdir}/bin/verilator
pod2man $< $@
+verilator_coverage.1: ${srcdir}/bin/verilator_coverage
+ pod2man $< $@
+
verilator.txt: ${srcdir}/bin/verilator
$(POD2TEXT) $< $@
@@ -261,13 +263,13 @@ internals.pdf: internals.pod Makefile
-rm -f internals.toc internals.aux internals.idx internals.out
# See uninstall also - don't put wildcards in this variable, it might uninstall other stuff
-VL_INST_BIN_FILES = verilator verilator_bin verilator_bin_dbg \
- verilator_includer verilator_profcfunc
+VL_INST_BIN_FILES = verilator verilator_bin verilator_bin_dbg verilator_coverage_bin_dbg \
+ verilator_coverage verilator_includer verilator_profcfunc
# Some scripts go into both the search path and pkgdatadir,
# so they can be found by the user, and under $VERILATOR_ROOT.
# See uninstall also - don't put wildcards in this variable, it might uninstall other stuff
-VL_INST_MAN_FILES = verilator.1
+VL_INST_MAN_FILES = verilator.1 verilator_coverage.1
VL_INST_INC_BLDDIR_FILES = \
include/verilated.mk \
@@ -281,14 +283,15 @@ 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/Makefile test_sp/Makefile_obj \
installbin:
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(bindir)
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator $(DESTDIR)$(bindir)/verilator )
+ ( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_coverage $(DESTDIR)$(bindir)/verilator_coverage )
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_profcfunc $(DESTDIR)$(bindir)/verilator_profcfunc )
( $(INSTALL_PROGRAM) verilator_bin $(DESTDIR)$(bindir)/verilator_bin )
( $(INSTALL_PROGRAM) verilator_bin_dbg $(DESTDIR)$(bindir)/verilator_bin_dbg )
+ ( $(INSTALL_PROGRAM) verilator_coverage_bin_dbg $(DESTDIR)$(bindir)/verilator_coverage_bin_dbg )
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/bin
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_includer $(DESTDIR)$(pkgdatadir)/bin/verilator_includer )
@@ -311,7 +314,6 @@ installdata:
done
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/test_c
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/test_sc
- $(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/test_sp
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples/test_v
cd $(srcdir) \
; for p in $(VL_INST_DATA_SRCDIR_FILES) ; do \
@@ -351,6 +353,7 @@ INST_PROJ_CVS = cp_if_cvs_diff
install-project: dist
@echo "Install-project to $(DIRPROJECT)"
strip verilator_bin*
+ strip verilator_coverage_bin*
$(MAKE) install-project-quick
for p in $(VL_INST_MAN_FILES) ; do \
$(INSTALL_DATA) $$p $(DIRPROJECT_PREFIX)/man/man1/$$p; \
@@ -374,6 +377,7 @@ endif
install-cadtools: dist
@echo "Install-project to $(CAD_DIR)"
strip verilator_bin*
+ strip verilator_coverage_bin*
$(MAKE) install-cadtools-quick
$(SHELL) ${srcdir}/mkinstalldirs $(VERILATOR_CAD_DIR)/man/man1
for p in $(VL_INST_MAN_FILES) ; do \
@@ -459,7 +463,8 @@ clean mostlyclean distclean maintainer-clean::
rm -f *.tex
distclean maintainer-clean::
- rm -f Makefile config.status config.cache config.log verilator_bin* TAGS
+ rm -f Makefile config.status config.cache config.log TAGS
+ rm -f verilator_bin* verilator_coverage_bin*
rm -f include/verilated.mk include/verilated_config.h
TAGFILES=${srcdir}/*/*.cpp ${srcdir}/*/*.h ${srcdir}/*/*.in \
diff --git a/README b/README
index d225e3e..76e32ba 100644
--- a/README
+++ b/README
@@ -65,12 +65,6 @@ INSTALLATION
to the directory with libsystemc.a in it. (Older installations may
set SYSTEMC and SYSTEMC_ARCH instead.)
- * If you will be using SystemPerl or coverage, download and install
- System-Perl, <http://www.veripool.org/systemperl>. Note you'll need
- to set a "SYSTEMPERL" environment variable to point to the
- downloaded kit. Optionally also set "SYSTEMPERL_INCLUDE" to point to
- the installed headers.
-
* You will need the "flex" and "bison" packages installed.
* "cd" to the Verilator directory containing this README.
@@ -79,9 +73,8 @@ INSTALLATION
kit.
Note Verilator builds the current value of VERILATOR_ROOT,
- SYSTEMC_INCLUDE, SYSTEMC_LIBDIR, SYSTEMPERL, and SYSTEMPERL_INCLUDE
- as defaults into the executable, so try to have them correct before
- configuring.
+ SYSTEMC_INCLUDE, and SYSTEMC_LIBDIR as defaults into the executable,
+ so try to have them correct before configuring.
1. Our personal favorite is to always run Verilator from the kit
directory. This allows the easiest experimentation and
@@ -167,8 +160,6 @@ DIRECTORY STRUCTURE
test_v => Example Verilog code for other test dirs
test_c => Example Verilog->C++ conversion
test_sc => Example Verilog->SystemC conversion
- test_sp => Example Verilog->SystemPerl conversion
- test_vcs => Example Verilog->VCS conversion (test the test)
test_verilated => Internal tests
test_regress => Internal tests
diff --git a/README.html b/README.html
index 6e354fd..6cefc68 100644
--- a/README.html
+++ b/README.html
@@ -100,14 +100,6 @@ instead.)</p>
</dd>
<dt>
<dd>
-<p>If you will be using SystemPerl or coverage, download and install
-System-Perl, <a href="http://www.veripool.org/systemperl">http://www.veripool.org/systemperl</a>. Note you'll need to
-set a <code>SYSTEMPERL</code> environment variable to point to the downloaded kit.
-Optionally also set <code>SYSTEMPERL_INCLUDE</code> to point to the installed
-headers.</p>
-</dd>
-<dt>
-<dd>
<p>You will need the <code>flex</code> and <code>bison</code> packages installed.</p>
</dd>
<dt>
@@ -118,8 +110,8 @@ headers.</p>
<dd>
<p>You now have to decide how you're going to eventually install the kit.</p>
<p>Note Verilator builds the current value of VERILATOR_ROOT, SYSTEMC_INCLUDE,
-SYSTEMC_LIBDIR, SYSTEMPERL, and SYSTEMPERL_INCLUDE as defaults into the
-executable, so try to have them correct before configuring.</p>
+and SYSTEMC_LIBDIR as defaults into the executable, so try to have them
+correct before configuring.</p>
<ol>
<li>
<p>Our personal favorite is to always run Verilator from the kit directory.
@@ -211,8 +203,6 @@ set.</p>
test_v => Example Verilog code for other test dirs
test_c => Example Verilog->C++ conversion
test_sc => Example Verilog->SystemC conversion
- test_sp => Example Verilog->SystemPerl conversion
- test_vcs => Example Verilog->VCS conversion (test the test)
test_verilated => Internal tests
test_regress => Internal tests</pre>
<p>
diff --git a/README.pdf b/README.pdf
index 23a73fc..3c8acf5 100644
Binary files a/README.pdf and b/README.pdf differ
diff --git a/TODO b/TODO
index 15410b5..5c84ebe 100755
--- a/TODO
+++ b/TODO
@@ -30,23 +30,6 @@ Configure/Make/Install
* Full MSVC++ compilation (does scons support this?) (4.000?)
* Distribute with flex/bison already expanded?
Flex library not needed. Probably too difficult to be worth it.
- * Integrate SystemPerl coverage
- see the SystemPerl git branch coverage_only
- (Note in /usr/include there are no upper cased include files.)
- Coverage.pm -- Need all functionality, but in C?
- Coverage/Item.pm -- Need all functionality, but in C?
- Coverage/ItemKey.pm -- Need all functionality, but in C?
- sp_preproc -- Some steps in here need to be moved to generated C
- -- -- note uses Verilog::Getopt
- src/Sp.cpp -- n/a
- src/SpCommon.h -- mostly overlaps verilatedos.h
- src/SpCoverage.cpp/h -- All needed
- src/SpFunctor.cpp/h -- No longer used
- src/SpTraceVcd.cpp/h -- MOVED
- src/SpTraceVcdC.cpp/h -- MOVED
- src/sp_log.cpp/h -- Not needed
- src/systemperl.h -- some stuff may be cut
- vcoverage -- Need all functionality, but in C?
Testing:
* Move test_c/sp/v/verilated into test_regress format (4.000?)
diff --git a/bin/verilator b/bin/verilator
index 59f2e1c..04a8278 100755
--- a/bin/verilator
+++ b/bin/verilator
@@ -24,14 +24,10 @@ BEGIN {
}
}
-use File::Path;
-use File::Basename;
use Getopt::Long;
use FindBin qw($RealBin $RealScript);
use IO::File;
use Pod::Usage;
-use Config;
-use Cwd qw(abs_path getcwd);
use strict;
use vars qw ($Debug @Opt_Verilator_Sw);
@@ -209,17 +205,13 @@ Verilator - Convert Verilog code to C++/SystemC
=head1 DESCRIPTION
Verilator converts synthesizable (not behavioral) Verilog code, plus some
-Synthesis, SystemVerilog and a small subset of Verilog AMS
-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 assertions, into
+C++ or SystemC code. It is not a complete simulator, but a compiler.
Verilator is invoked with parameters similar to GCC, Cadence
Verilog-XL/NC-Verilog, or Synopsys's VCS. It reads the specified Verilog
code, lints it, and optionally adds coverage and waveform tracing code.
-For C++ and SystemC formats, it outputs .cpp and .h files. For SystemPerl
-format, it outputs .sp files for the SystemPerl preprocessor, which greatly
-simplifies writing SystemC code and is available at
-L<http://www.veripool.org>.
+For C++ and SystemC formats, it outputs .cpp and .h files.
The files created by Verilator are then compiled with C++. The user writes
a little C++ wrapper file, which instantiates the top level module, and
@@ -316,8 +308,8 @@ descriptions in the next sections for more information.
--report-unoptflat Extra diagnostics for UNOPTFLAT
--savable Enable model save-restore
--sc Create SystemC output
- --sp Create SystemPerl output
--stats Create statistics file
+ --stats-vars Provide statistics on variables
-sv Enable SystemVerilog parsing
+systemverilogext+<ext> Synonym for +1800-2012ext+<ext>
--top-module <topname> Name of top level input module
@@ -452,7 +444,7 @@ run on the generated makefile these will be passed to the C++ compiler
=item --cc
-Specifies C++ without SystemC output mode; see also --sc and --sp.
+Specifies C++ without SystemC output mode; see also --sc.
=item --cdc
@@ -969,16 +961,18 @@ other data the process needs saved/restored. For example:
=item --sc
-Specifies SystemC output mode; see also --cc and -sp.
-
-=item --sp
-
-Specifies SystemPerl output mode; see also --cc and -sc.
+Specifies SystemC output mode; see also --cc.
=item --stats
Creates a dump file with statistics on the design in {prefix}__stats.txt.
+=item --stats-vars
+
+Creates more detailed statistics including a list of all the variables by
+size (plain --stats just gives a count). See --stats, which is implied by
+this.
+
=item -sv
Specifies SystemVerilog language features should be enabled; equivalent to
@@ -1291,7 +1285,7 @@ the test_c directory in the distribution for an example.
=head1 EXAMPLE SYSTEMC EXECUTION
-This is an example similar to the above, but using SystemPerl.
+This is an example similar to the above, but using SystemC.
mkdir test_our_sc
cd test_our_sc
@@ -1326,17 +1320,7 @@ your operating system (as an RPM), first you need to point to the kit:
Now we run Verilator on our little example.
- verilator -Wall --sp our.v
-
-Then we convert the SystemPerl output to SystemC.
-
- cd obj_dir
- export SYSTEMPERL=/path/to/where/systemperl/kit/came/from
- $SYSTEMPERL/sp_preproc --preproc *.sp
-
-(You can also skip the above sp_preproc by getting pure SystemC from
-Verilator by replacing the verilator --sp flag in the previous step with
--sc.)
+ verilator -Wall --sc our.v
We then can compile it
@@ -1365,7 +1349,7 @@ And we get the same output as the C++ example:
Really, you're better off using a Makefile to do all this for you. Then,
when your source changes it will automatically run all of these steps. See
-the test_sp directory in the distribution for an example.
+the test_sc directory in the distribution for an example.
=head1 BENCHMARKING & OPTIMIZATION
@@ -1423,6 +1407,10 @@ especially if you link in DPI code. To enable LTO on GCC, pass "-flto" in
both compilation and link. Note LTO may cause excessive compile times on
large designs.
+If you are using your own makefiles, you may want to compile the Verilated
+code with -DVL_INLINE_OPT=inline. This will inline functions, however this
+requires that all cpp files be compiled in a single compiler run.
+
You may uncover further tuning possibilities by profiling the Verilog code.
Use Verilator's --profile-cfuncs, then GCC's -g -pg. You can then run
either oprofile or gprof to see where in the C++ code the time is spent.
@@ -1450,11 +1438,6 @@ For -cc and -sc mode, it also creates:
{prefix}{each_verilog_module}.cpp // Lower level internal C++ files
{prefix}{each_verilog_module}.h // Lower level internal header files
-For -sp mode, instead of .cpp and .h it creates:
-
- {prefix}.sp // Top level SystemC file
- {prefix}{each_verilog_module}.sp // Lower level internal SC files
-
In certain optimization modes, it also creates:
{prefix}__Dpi.h // DPI import and export declarations
@@ -1529,21 +1512,6 @@ specified, it will come from a default optionally specified at configure
time (before Verilator was compiled), or computed from
SYSTEMC/lib-SYSTEMC_ARCH.
-=item SYSTEMPERL
-
-Specifies the directory containing the SystemPerl distribution kit. This
-is used to find the SystemPerl library and include files. If not
-specified, it will come from a default optionally specified at configure
-time (before Verilator was compiled). See also SYSTEMPERL_INCLUDE.
-
-=item SYSTEMPERL_INCLUDE
-
-Specifies the directory containing the Verilog-Perl include .cpp files,
-from the src/ directory of the SystemPerl kit. If not specified, it will
-be computed from the SYSTEMPERL environment variable if it is set, and if
-SYSTEMPERL is not set SYSTEMPERL_INCLUDE will come from a default
-optionally specified at configure time (before Verilator was compiled).
-
=item VCS_HOME
If set, specifies the directory containing the Synopsys VCS distribution.
@@ -2180,8 +2148,8 @@ Specifies the module the comment appears in may be inlined into any modules
that use this module. This is useful to speed up simulation time with some
small loss of trace visibility and modularity. Note signals under inlined
submodules will be named I<submodule>__DOT__I<subsignal> as C++ does not
-allow "." in signal names. SystemPerl when tracing such signals will
-replace the __DOT__ with the period.
+allow "." in signal names. When tracing such signals the tracing routines
+will replace the __DOT__ with the period.
=item /*verilator isolate_assignments*/
@@ -2636,8 +2604,9 @@ All specify blocks and timing checks are ignored.
=item string
-String is supported only to the point that they can be passed to DPI
-imports.
+String is supported only to the point that they can be assigned,
+concatenated, compared, and passed to DPI imports. Standard method calls
+on strings are not supported.
=item timeunit, timeprecision
@@ -3459,10 +3428,6 @@ flag.
Note you can also call ->trace on multiple Verilated objects with the same
trace file if you want all data to land in the same output file.
-Note also older versions of Verilator used the SystemPerl package and
-SpTraceVcdC class. This still works, but is depreciated as it requires
-strong coupling between the Verilator and SystemPerl versions.
-
#include "verilated_vcd_c.h"
...
int main(int argc, char **argv, char **env) {
@@ -3485,7 +3450,7 @@ Add the --trace switch to Verilator, and in your top level C sc_main code,
include verilated_vcd_sc.h. Then call Verilated::traceEverOn(true). Then
create a VerilatedVcdSc object as you would create a normal SystemC trace
file. For an example, see the call to VerilatedVcdSc in the
-test_sp/sc_main.cpp file of the distribution, and below.
+test_sc/sc_main.cpp file of the distribution, and below.
Alternatively you may use the C++ trace mechanism described in the previous
question, however the timescale and timeprecision will not inherited from
@@ -3537,22 +3502,21 @@ network disk. Network disks are generally far slower.
=item How do I do coverage analysis?
Verilator supports both block (line) coverage and user inserted functional
-coverage. Both require the SystemPerl package to be installed but do not
-require use of the SystemPerl output mode.
+coverage.
First, run verilator with the --coverage option. If you're using your own
-makefile, compile the model with the GCC flag -DSP_COVERAGE (if using
+makefile, compile the model with the GCC flag -DVM_COVERAGE (if using
Verilator's, it will do this for you.)
Run your tests in different directories. Each test will create a
logs/coverage.pl file.
-After running all of your tests, the vcoverage utility (from the SystemPerl
-package) is executed. Vcoverage reads the logs/coverage.pl file(s), and
-creates an annotated source code listing showing code coverage details.
+After running all of your tests, verilator_coverage is executed.
+Verilator_coverage reads the logs/coverage.pl file(s), and creates an
+annotated source code listing showing code coverage details.
For an example, after running 'make test' in the Verilator distribution,
-see the test_sp/logs/coverage_source directory. Grep for lines starting
+see the test_sc/logs directory. Grep for lines starting
with '%' to see what lines Verilator believes need more coverage.
=item Where is the translate_off command? (How do I ignore a construct?)
@@ -3844,7 +3808,7 @@ Major concepts by Paul Wasson and Duane Galbi.
=head1 SEE ALSO
-L<verilator_profcfunc>, L<systemperl>, L<vcoverage>, L<make>,
+L<verilator_coverage>, L<verilator_profcfunc>, L<make>,
L<verilator --help> which is the source for this document,
diff --git a/bin/verilator_coverage b/bin/verilator_coverage
new file mode 100755
index 0000000..33bce7c
--- /dev/null
+++ b/bin/verilator_coverage
@@ -0,0 +1,291 @@
+: # -*-Mode: perl;-*- use perl, wherever it is
+eval 'exec perl -wS $0 ${1+"$@"}'
+ if 0;
+######################################################################
+#
+# Copyright 2003-2014 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.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+######################################################################
+
+require 5.006_001;
+use warnings;
+BEGIN {
+ if ($ENV{DIRPROJECT} && $ENV{DIRPROJECT_PERL_BOOT}) {
+ # Magic to allow author testing of perl packages in local directory
+ require $ENV{DIRPROJECT}."/".$ENV{DIRPROJECT_PERL_BOOT};
+ }
+}
+
+use Getopt::Long;
+use FindBin qw($RealBin $RealScript);
+use IO::File;
+use Pod::Usage;
+use Cwd qw(abs_path getcwd);
+
+use strict;
+use vars qw ($Debug @Opt_Verilator_Sw);
+
+#######################################################################
+#######################################################################
+# main
+
+autoflush STDOUT 1;
+autoflush STDERR 1;
+
+$Debug = 0;
+
+# No arguments can't do anything useful. Give help
+if ($#ARGV < 0) {
+ pod2usage(-exitstatus=>2, -verbose=>0);
+}
+
+# We sneak a look at the flags so we can do some pre-environment checks
+# All flags will hit verilator...
+foreach my $sw (@ARGV) {
+ $sw = "'$sw'" if $sw =~ m![^---a-zA-Z0-9_/\\:.+]!;
+ push @Opt_Verilator_Sw, $sw;
+}
+
+Getopt::Long::config ("no_auto_abbrev","pass_through");
+if (! GetOptions (
+ # Major operating modes
+ "help" => \&usage,
+ "debug:s" => \&debug,
+ # "version!" => \&version, # Also passthru'ed
+ # Additional parameters
+ "<>" => sub {}, # Ignored
+ )) {
+ pod2usage(-exitstatus=>2, -verbose=>0);
+}
+
+# Normal, non gdb
+run (verilator_coverage_bin()
+ ." ".join(' ', at Opt_Verilator_Sw));
+
+#----------------------------------------------------------------------
+
+sub usage {
+ pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
+}
+
+sub debug {
+ shift;
+ my $level = shift;
+ $Debug = $level||3;
+}
+
+#######################################################################
+#######################################################################
+# Builds
+
+sub verilator_coverage_bin {
+ my $bin = "";
+ # Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path
+ my $basename = ($ENV{VERILATOR_COVERAGE_BIN}
+ || "verilator_coverage_bin_dbg");
+ if (defined($ENV{VERILATOR_ROOT})) {
+ my $dir = $ENV{VERILATOR_ROOT};
+ if (-x "$dir/bin/$basename") { # From a "make install" into VERILATOR_ROOT
+ $bin = "$dir/bin/$basename";
+ } else {
+ $bin = "$dir/$basename"; # From pointing to kit directory
+ }
+ } else {
+ if (-x "$RealBin/$basename") {
+ $bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed
+ } else {
+ $bin = $basename; # Find in PATH
+ }
+ # Note we don't look under bin/$basename which would be right if running
+ # in the kit dir. Running that would likely break, since
+ # VERILATOR_ROOT wouldn't be set and Verilator won't find internal files.
+ }
+ return $bin;
+}
+
+#######################################################################
+#######################################################################
+# Utilities
+
+sub run {
+ # Run command, check errors
+ my $command = shift;
+ $! = undef; # Cleanup -x
+ print "\t$command\n" if $Debug>=3;
+ system($command);
+ my $status = $?;
+ if ($status) {
+ if ($! =~ /no such file or directory/i) {
+ warn "%Error: verilator_coverage: Misinstalled, or VERILATOR_ROOT might need to be in environment\n";
+ }
+ if ($Debug) { # For easy rerunning
+ warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n";
+ warn "%Error: $command\n";
+ }
+ if ($status & 127) {
+ if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV
+ warn "%Error: Verilator_coverage internal fault, sorry.\n" if !$Debug;
+ } elsif (($status & 127) == 6) { # SIGABRT
+ warn "%Error: Verilator_coverage aborted.\n" if !$Debug;
+ } else {
+ warn "%Error: Verilator_coverage threw signal $status.\n" if !$Debug;
+ }
+ }
+ die "%Error: Command Failed $command\n";
+ }
+}
+
+#######################################################################
+#######################################################################
+package main;
+__END__
+
+=pod
+
+=head1 NAME
+
+verilator_coverage - Verilator coverage analyzer
+
+=head1 SYNOPSIS
+
+ verilator_coverage --help
+ verilator_coverage --version
+
+ verilator_coverage --annotate <obj>
+
+ verilator_coverage -write merged.dat -read <datafiles>...
+
+Verilator_coverage processes Verilator coverage reports.
+
+With --anotate, it reads the specified data file and generates annotated
+source code with coverage metrics annotated. If multiple coverage points
+exist on the same line, additional lines will be inserted to report the
+additional points.
+
+Additional Verilog-standard arguments specify the search paths necessary to
+find the source code that the coverage analysis was performed on.
+
+To get correct coverage percentages, you may wish to read logs/coverage.pl
+into Emacs and do a M-x keep-lines to include only those statistics of
+interest.
+
+For Verilog conditions that should never occur, you should add a $stop
+statement. This will remove the coverage during the next build.
+
+=head1 ARGUMENTS
+
+=over 4
+
+=item I<filename>
+
+Specify input data file, may be repeated to read multiple inputs. If no
+data file is specified, by default coverage.dat is read.
+
+=item --annotate I<output_directory>
+
+Sprcifies the directory name that source files with annotated coverage data
+should be written to.
+
+=item --annotate-all
+
+Specifies all files should be shown. By default, only those source files
+which have low coverage are written to the output directory.
+
+=item --annotate-min I<count>
+
+Specifies the minimum occurrence count that should be flagged if the
+coverage point does not include a specified threshold. Defaults to 10.
+
+=item --help
+
+Displays this message and program version and exits.
+
+=item --rank
+
+Print an experimental report listing the relative importance of each test
+in covering all of the coverage points. The report shows "Covered" which
+indicates the number of points that test covers; a test is considered to
+cover a point if it has a bucket count of at least 1. The "rank" column has
+a higher number t indicate the test is more important, and rank 0 means the
+test does not need to be run to cover the points. "RankPts" indicates the
+number of coverage points this test will contribute to overall coverage if
+all tests are run in the order of highest to lowest rank.
+
+=item --unlink
+
+When using --write to combine coverage data, unlink all input files after
+the output has been created.
+
+=item --version
+
+Displays program version and exits.
+
+=item --write I<filename>
+
+Specifies the aggregate coverage results, summed across all the files,
+should be written to the given filename. This is useful in scripts to
+combine many sequential runs into one master coverage file.
+
+=back
+
+=head1 VERILOG ARGUMENTS
+
+The following arguments are compatible with GCC, VCS and most Verilog
+programs.
+
+=over 4
+
+=item +libext+I<ext>+I<ext>...
+
+Defines the extensions for Verilog files.
+
+=item +define+I<var>+I<value>
+=item -DI<var>=I<value>
+
+Defines the given variable.
+
+=item +incdir+I<dir>
+=item -II<dir>
+
+Specifies a directory for finding include files.
+
+=item -f I<file>
+
+Specifies a file containing additional command line arguments.
+
+=item -y I<dir>
+
+Specifies a module search directory.
+
+=back
+
+=head1 DISTRIBUTION
+
+The latest version is available from L<http://www.veripool.org/>.
+
+Copyright 2003-2014 by Wilson Snyder. Verilator is free software; you can
+redistribute it and/or modify the Verilator internals under the terms of
+either the GNU Lesser General Public License Version 3 or the Perl Artistic
+License Version 2.0.
+
+=head1 AUTHORS
+
+Wilson Snyder <wsnyder at wsnyder.org>
+
+=head1 SEE ALSO
+
+C<verilator>
+
+L<verilator_coverage --help> which is the source for this document.
+
+=cut
+
+######################################################################
diff --git a/bin/verilator_includer b/bin/verilator_includer
index 28d50c8..59bf66f 100755
--- a/bin/verilator_includer
+++ b/bin/verilator_includer
@@ -12,5 +12,9 @@ require 5.005;
use warnings;
print "// DESCR"."IPTION: Generated by verilator_includer via makefile\n";
foreach my $param (@ARGV) {
- print "#include \"$param\"\n"
+ if ($param =~ /^-D([^=]+)=(.*)/) {
+ print "#define $1 $2\n"
+ } else {
+ print "#include \"$param\"\n"
+ }
}
diff --git a/configure b/configure
index 2d8c517..c72e84d 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.68 for Verilator 3.866 2014-11-15.
+# Generated by GNU Autoconf 2.68 for Verilator 3.868 2014-12-20.
#
#
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -557,8 +557,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='Verilator'
PACKAGE_TARNAME='verilator'
-PACKAGE_VERSION='3.866 2014-11-15'
-PACKAGE_STRING='Verilator 3.866 2014-11-15'
+PACKAGE_VERSION='3.868 2014-12-20'
+PACKAGE_STRING='Verilator 3.868 2014-12-20'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1223,7 +1223,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures Verilator 3.866 2014-11-15 to adapt to many kinds of systems.
+\`configure' configures Verilator 3.868 2014-12-20 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1284,7 +1284,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of Verilator 3.866 2014-11-15:";;
+ short | recursive ) echo "Configuration of Verilator 3.868 2014-12-20:";;
esac
cat <<\_ACEOF
@@ -1376,7 +1376,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-Verilator configure 3.866 2014-11-15
+Verilator configure 3.868 2014-12-20
generated by GNU Autoconf 2.68
Copyright (C) 2010 Free Software Foundation, Inc.
@@ -1633,7 +1633,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by Verilator $as_me 3.866 2014-11-15, which was
+It was created by Verilator $as_me 3.868 2014-12-20, which was
generated by GNU Autoconf 2.68. Invocation command line was
$ $0 $@
@@ -4625,7 +4625,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by Verilator $as_me 3.866 2014-11-15, which was
+This file was extended by Verilator $as_me 3.868 2014-12-20, which was
generated by GNU Autoconf 2.68. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -4687,7 +4687,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-Verilator config.status 3.866 2014-11-15
+Verilator config.status 3.868 2014-12-20
configured by $0, generated by GNU Autoconf 2.68,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index 21386f3..66111de 100644
--- a/configure.ac
+++ b/configure.ac
@@ -6,7 +6,7 @@
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
#AC_INIT([Verilator],[#.### devel])
-AC_INIT([Verilator],[3.866 2014-11-15])
+AC_INIT([Verilator],[3.868 2014-12-20])
AC_CONFIG_HEADER(src/config_build.h)
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h)
diff --git a/doxygen.config b/doxygen.config
index 8fb0072..9a29b3c 100644
--- a/doxygen.config
+++ b/doxygen.config
@@ -635,9 +635,7 @@ INPUT = doxygen-mainpage \
test_c \
test_regress \
test_sc \
- test_sp \
test_v \
- test_vcs \
test_verilated
# This tag can be used to specify the character encoding of the source files
diff --git a/include/verilated.cpp b/include/verilated.cpp
index eca6b49..af0c0a4 100644
--- a/include/verilated.cpp
+++ b/include/verilated.cpp
@@ -343,6 +343,12 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
output += cstrp;
break;
}
+ case '@': { // Verilog/C++ string
+ va_arg(ap, int); // # bits is ignored
+ const string* cstrp = va_arg(ap, const string*);
+ output += *cstrp;
+ break;
+ }
case 'e':
case 'f':
case 'g': {
@@ -762,6 +768,50 @@ void VL_FCLOSE_I(IData fdi) {
VerilatedImp::fdDelete(fdi);
}
+void VL_SFORMAT_X(int obits, CData& destr, const char* formatp, ...) {
+ VL_STATIC_OR_THREAD string output; // static only for speed
+ output = "";
+ va_list ap;
+ va_start(ap,formatp);
+ _vl_vsformat(output, formatp, ap);
+ va_end(ap);
+
+ _VL_STRING_TO_VINT(obits, &destr, (int)output.length(), output.c_str());
+}
+
+void VL_SFORMAT_X(int obits, SData& destr, const char* formatp, ...) {
+ VL_STATIC_OR_THREAD string output; // static only for speed
+ output = "";
+ va_list ap;
+ va_start(ap,formatp);
+ _vl_vsformat(output, formatp, ap);
+ va_end(ap);
+
+ _VL_STRING_TO_VINT(obits, &destr, (int)output.length(), output.c_str());
+}
+
+void VL_SFORMAT_X(int obits, IData& destr, const char* formatp, ...) {
+ VL_STATIC_OR_THREAD string output; // static only for speed
+ output = "";
+ va_list ap;
+ va_start(ap,formatp);
+ _vl_vsformat(output, formatp, ap);
+ va_end(ap);
+
+ _VL_STRING_TO_VINT(obits, &destr, (int)output.length(), output.c_str());
+}
+
+void VL_SFORMAT_X(int obits, QData& destr, const char* formatp, ...) {
+ VL_STATIC_OR_THREAD string output; // static only for speed
+ output = "";
+ va_list ap;
+ va_start(ap,formatp);
+ _vl_vsformat(output, formatp, ap);
+ va_end(ap);
+
+ _VL_STRING_TO_VINT(obits, &destr, (int)output.length(), output.c_str());
+}
+
void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) {
VL_STATIC_OR_THREAD string output; // static only for speed
output = "";
diff --git a/include/verilated.h b/include/verilated.h
index 9454f60..7dbb10c 100644
--- a/include/verilated.h
+++ b/include/verilated.h
@@ -375,6 +375,10 @@ extern IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...);
extern IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...);
extern IData VL_SSCANF_IWX(int lbits, WDataInP lwp, const char* formatp, ...);
+extern void VL_SFORMAT_X(int obits, CData& destr, const char* formatp, ...);
+extern void VL_SFORMAT_X(int obits, SData& destr, const char* formatp, ...);
+extern void VL_SFORMAT_X(int obits, IData& destr, const char* formatp, ...);
+extern void VL_SFORMAT_X(int obits, QData& destr, const char* formatp, ...);
extern void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...);
extern IData VL_SYSTEM_IW(int lhsnwords, WDataInP lhs);
diff --git a/include/verilated.mk.in b/include/verilated.mk.in
index 87feb6d..9412f9c 100644
--- a/include/verilated.mk.in
+++ b/include/verilated.mk.in
@@ -23,7 +23,9 @@ CFG_CXXFLAGS_NO_UNUSED = @CFG_CXXFLAGS_NO_UNUSED@
# Programs
SP_PREPROC = sp_preproc
-SP_INCLUDER = $(PERL) $(VERILATOR_ROOT)/bin/verilator_includer
+SP_INCLUDER = $(VERILATOR_INCLUDER)
+VERILATOR_COVERAGE = $(PERL) $(VERILATOR_ROOT)/bin/verilator_coverage
+VERILATOR_INCLUDER = $(PERL) $(VERILATOR_ROOT)/bin/verilator_includer
######################################################################
# Make checks
@@ -151,15 +153,15 @@ VK_USER_OBJS = $(addsuffix .o, $(VM_USER_CLASSES))
VK_GLOBAL_OBJS = $(addsuffix .o, $(VM_GLOBAL_FAST) $(VM_GLOBAL_SLOW))
-ifneq ($(VM_PARALLEL_BUILDS),1)
+ifneq ($(VM_PARALLEL_BUILDS),0)
# Fast building, all .cpp's in one fell swoop
# This saves about 5 sec per module, but can be slower if only a little changes
VK_OBJS += $(VM_PREFIX)__ALLcls.o $(VM_PREFIX)__ALLsup.o
all_cpp: $(VM_PREFIX)__ALLcls.cpp $(VM_PREFIX)__ALLsup.cpp
$(VM_PREFIX)__ALLcls.cpp: $(VK_CLASSES_CPP)
- $(SP_INCLUDER) $^ > $@
+ $(VERILATOR_INCLUDER) -DVL_INCLUDE_OPT=include $^ > $@
$(VM_PREFIX)__ALLsup.cpp: $(VK_SUPPORT_CPP)
- $(SP_INCLUDER) $^ > $@
+ $(VERILATOR_INCLUDER) -DVL_INCLUDE_OPT=include $^ > $@
else
#Slow way of building... Each .cpp file by itself
VK_OBJS += $(addsuffix .o, $(VM_CLASSES) $(VM_SUPPORT))
diff --git a/include/verilated_config.h b/include/verilated_config.h
index 1bbe02c..2f86a87 100644
--- a/include/verilated_config.h
+++ b/include/verilated_config.h
@@ -25,4 +25,4 @@
// Autoconf substitutes this with the strings from AC_INIT.
#define VERILATOR_PRODUCT "Verilator"
-#define VERILATOR_VERSION "3.866 2014-11-15"
+#define VERILATOR_VERSION "3.868 2014-12-20"
diff --git a/include/verilated_cov.cpp b/include/verilated_cov.cpp
new file mode 100644
index 0000000..9091277
--- /dev/null
+++ b/include/verilated_cov.cpp
@@ -0,0 +1,451 @@
+// -*- mode: C++; c-file-style: "cc-mode" -*-
+//=============================================================================
+//
+// THIS MODULE IS PUBLICLY LICENSED
+//
+// Copyright 2001-2014 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.
+//
+// This is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+//=============================================================================
+///
+/// \file
+/// \brief Verilator coverage analysis
+///
+/// AUTHOR: Wilson Snyder
+///
+//=============================================================================
+
+#include "verilatedos.h"
+#include "verilated.h"
+#include "verilated_cov.h"
+#include "verilated_cov_key.h"
+
+#include <map>
+#include <deque>
+#include <fstream>
+
+//=============================================================================
+// VerilatedCovImpBase
+/// Implementation base class for constants
+
+struct VerilatedCovImpBase {
+ // TYPES
+ enum { MAX_KEYS = 33 }; /// Maximum user arguments + filename+lineno
+ enum { KEY_UNDEF = 0 }; /// Magic key # for unspecified values
+};
+
+//=============================================================================
+// VerilatedCovImpItem
+/// Implementation class for a VerilatedCov item
+
+class VerilatedCovImpItem : VerilatedCovImpBase {
+public: // But only local to this file
+ // MEMBERS
+ int m_keys[MAX_KEYS]; ///< Key
+ int m_vals[MAX_KEYS]; ///< Value for specified key
+ // CONSTRUCTORS
+ // Derived classes should call zero() in their constructor
+ VerilatedCovImpItem() {
+ for (int i=0; i<MAX_KEYS; i++) m_keys[i]=KEY_UNDEF;
+ }
+ virtual ~VerilatedCovImpItem() {}
+ virtual vluint64_t count() const = 0;
+ virtual void zero() const = 0;
+};
+
+//=============================================================================
+/// VerilatedCoverItem templated for a specific class
+/// Creates a new coverage item for the specified type.
+/// This isn't in the header file for auto-magic conversion because it
+/// inlines to too much code and makes compilation too slow.
+
+template <class T> class VerilatedCoverItemSpec : public VerilatedCovImpItem {
+private:
+ // MEMBERS
+ T* m_countp; ///< Count value
+public:
+ // METHODS
+ virtual vluint64_t count() const { return *m_countp; }
+ virtual void zero() const { *m_countp = 0; }
+ // CONSTRUCTORS
+ VerilatedCoverItemSpec(T* countp) : m_countp(countp) { zero(); }
+ virtual ~VerilatedCoverItemSpec() {}
+};
+
+//=============================================================================
+// VerilatedCovImp
+/// Implementation class for VerilatedCov. See that class for public method information.
+/// All value and keys are indexed into a unique number. Thus we can greatly reduce
+/// the storage requirements for otherwise identical keys.
+
+class VerilatedCovImp : VerilatedCovImpBase {
+private:
+ // TYPES
+ typedef map<string,int> ValueIndexMap;
+ typedef map<int,string> IndexValueMap;
+ typedef deque<VerilatedCovImpItem*> ItemList;
+
+private:
+ // MEMBERS
+ ValueIndexMap m_valueIndexes; ///< For each key/value a unique arbitrary index value
+ IndexValueMap m_indexValues; ///< For each key/value a unique arbitrary index value
+ ItemList m_items; ///< List of all items
+
+ VerilatedCovImpItem* m_insertp; ///< Item about to insert
+ const char* m_insertFilenamep; ///< Filename about to insert
+ int m_insertLineno; ///< Line number about to insert
+
+ // CONSTRUCTORS
+ VerilatedCovImp() {
+ m_insertp = NULL;
+ m_insertFilenamep = NULL;
+ m_insertLineno = 0;
+ }
+public:
+ ~VerilatedCovImp() { clear(); }
+ static VerilatedCovImp& imp() {
+ static VerilatedCovImp s_singleton;
+ return s_singleton;
+ }
+
+private:
+ // PRIVATE METHODS
+ int valueIndex(const string& value) {
+ static int nextIndex = KEY_UNDEF+1;
+ ValueIndexMap::iterator iter = m_valueIndexes.find(value);
+ if (iter != m_valueIndexes.end()) return iter->second;
+ nextIndex++; assert(nextIndex>0);
+ m_valueIndexes.insert(make_pair(value, nextIndex));
+ m_indexValues.insert(make_pair(nextIndex, value));
+ return nextIndex;
+ }
+ string dequote(const string& text) {
+ // Quote any special characters
+ string rtn;
+ for (const char* pos = text.c_str(); *pos; pos++) {
+ if (!isprint(*pos) || *pos=='%' || *pos=='"') {
+ char hex[10]; sprintf(hex,"%%%02X",pos[0]);
+ rtn += hex;
+ } else {
+ rtn += *pos;
+ }
+ }
+ return rtn;
+ }
+ bool legalKey(const string& key) {
+ // Because we compress long keys to a single letter, and
+ // don't want applications to either get confused if they use
+ // a letter differently, nor want them to rely on our compression...
+ // (Considered using numeric keys, but will remain back compatible.)
+ if (key.length()<2) return false;
+ if (key.length()==2 && isdigit(key[1])) return false;
+ return true;
+ }
+ string keyValueFormatter (const string& key, const string& value) {
+ string name;
+ if (key.length()==1 && isalpha(key[0])) {
+ name += string("\001")+key;
+ } else {
+ name += string("\001")+dequote(key);
+ }
+ name += string("\002")+dequote(value);
+ return name;
+ }
+ string combineHier (const string& old, const string& add) {
+ // (foo.a.x, foo.b.x) => foo.*.x
+ // (foo.a.x, foo.b.y) => foo.*
+ // (foo.a.x, foo.b) => foo.*
+ if (old == add) return add;
+ if (old == "") return add;
+ if (add == "") return old;
+
+ const char* a = old.c_str();
+ const char* b = add.c_str();
+
+ // Scan forward to first mismatch
+ const char* apre = a;
+ const char* bpre = b;
+ while (*apre == *bpre) { apre++; bpre++; }
+
+ // We used to backup and split on only .'s but it seems better to be verbose
+ // and not assume . is the separator
+ string prefix = string(a,apre-a);
+
+ // Scan backward to last mismatch
+ const char* apost = a+strlen(a)-1;
+ const char* bpost = b+strlen(b)-1;
+ while (*apost == *bpost
+ && apost>apre && bpost>bpre) { apost--; bpost--; }
+
+ // Forward to . so we have a whole word
+ string suffix = *bpost ? string(bpost+1) : "";
+
+ string out = prefix+"*"+suffix;
+
+ //cout << "\nch pre="<<prefix<<" s="<<suffix<<"\nch a="<<old<<"\nch b="<<add<<"\nch o="<<out<<endl;
+ return out;
+ }
+ bool itemMatchesString(VerilatedCovImpItem* itemp, const string& match) {
+ for (int i=0; i<MAX_KEYS; i++) {
+ if (itemp->m_keys[i] != KEY_UNDEF) {
+ // We don't compare keys, only values
+ string val = m_indexValues[itemp->m_vals[i]];
+ if (string::npos != val.find(match)) { // Found
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ void selftest() {
+ // Little selftest
+ if (combineHier ("a.b.c","a.b.c") !="a.b.c") vl_fatal(__FILE__,__LINE__,"","%Error: selftest\n");
+ if (combineHier ("a.b.c","a.b") !="a.b*") vl_fatal(__FILE__,__LINE__,"","%Error: selftest\n");
+ if (combineHier ("a.x.c","a.y.c") !="a.*.c") vl_fatal(__FILE__,__LINE__,"","%Error: selftest\n");
+ if (combineHier ("a.z.z.z.c","a.b.c") !="a.*.c") vl_fatal(__FILE__,__LINE__,"","%Error: selftest\n");
+ if (combineHier ("z","a") !="*") vl_fatal(__FILE__,__LINE__,"","%Error: selftest\n");
+ if (combineHier ("q.a","q.b") !="q.*") vl_fatal(__FILE__,__LINE__,"","%Error: selftest\n");
+ if (combineHier ("q.za","q.zb") !="q.z*") vl_fatal(__FILE__,__LINE__,"","%Error: selftest\n");
+ if (combineHier ("1.2.3.a","9.8.7.a") !="*.a") vl_fatal(__FILE__,__LINE__,"","%Error: selftest\n");
+ }
+
+public:
+ // PUBLIC METHODS
+ void clear() {
+ for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
+ VerilatedCovImpItem* itemp = *(it);
+ delete itemp;
+ }
+ m_items.clear();
+ m_indexValues.clear();
+ m_valueIndexes.clear();
+ }
+ void clearNonMatch (const char* matchp) {
+ if (matchp && matchp[0]) {
+ ItemList newlist;
+ for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
+ VerilatedCovImpItem* itemp = *(it);
+ if (!itemMatchesString(itemp, matchp)) {
+ delete itemp;
+ } else {
+ newlist.push_back(itemp);
+ }
+ }
+ m_items = newlist;
+ }
+ }
+ void zero() {
+ for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
+ (*it)->zero();
+ }
+ }
+
+ // We assume there's always call to i/f/p in that order
+ void inserti (VerilatedCovImpItem* itemp) {
+ assert(!m_insertp);
+ m_insertp = itemp;
+ }
+ void insertf (const char* filenamep, int lineno) {
+ m_insertFilenamep = filenamep;
+ m_insertLineno = lineno;
+ }
+ void insertp (const char* ckeyps[MAX_KEYS],
+ const char* valps[MAX_KEYS]) {
+ assert(m_insertp);
+ // First two key/vals are filename
+ ckeyps[0]="filename"; valps[0]=m_insertFilenamep;
+ VlCovCvtToCStr linestrp (m_insertLineno);
+ ckeyps[1]="lineno"; valps[1]=linestrp;
+ // Default page if not specified
+ const char* fnstartp = m_insertFilenamep;
+ while (const char* foundp = strchr(fnstartp,'/')) fnstartp=foundp+1;
+ const char* fnendp = fnstartp;
+ while (*fnendp && *fnendp!='.') fnendp++;
+ string page_default = "sp_user/"+string(fnstartp,fnendp-fnstartp);
+ ckeyps[2]="page"; valps[2]=page_default.c_str();
+
+ // Keys -> strings
+ string keys[MAX_KEYS];
+ for (int i=0; i<MAX_KEYS; i++) {
+ if (ckeyps[i] && ckeyps[i][0]) {
+ keys[i] = ckeyps[i];
+ }
+ }
+ // Ignore empty keys
+ for (int i=0; i<MAX_KEYS; i++) {
+ if (keys[i]!="") {
+ for (int j=i+1; j<MAX_KEYS; j++) {
+ if (keys[i] == keys[j]) { // Duplicate key. Keep the last one
+ keys[i] = "";
+ break;
+ }
+ }
+ }
+ }
+ // Insert the values
+ int addKeynum=0;
+ for (int i=0; i<MAX_KEYS; i++) {
+ const string key = keys[i];
+ if (keys[i]!="") {
+ const string val = valps[i];
+ //cout<<" "<<__FUNCTION__<<" "<<key<<" = "<<val<<endl;
+ m_insertp->m_keys[addKeynum] = valueIndex(key);
+ m_insertp->m_vals[addKeynum] = valueIndex(val);
+ addKeynum++;
+ if (!legalKey(key)) {
+ string msg = "%Error: Coverage keys of one character, or letter+digit are illegal: "+key;
+ vl_fatal("",0,"",msg.c_str());
+ }
+ }
+ }
+ m_items.push_back(m_insertp);
+ // Prepare for next
+ m_insertp = NULL;
+ }
+
+ void write (const char* filename) {
+#ifndef VM_COVERAGE
+ vl_fatal("",0,"","%Error: Called VerilatedCov::write when VM_COVERAGE disabled\n");
+#endif
+ selftest();
+
+ ofstream os (filename);
+ if (os.fail()) {
+ string msg = (string)"%Error: Can't write '"+filename+"'";
+ vl_fatal("",0,"",msg.c_str());
+ return;
+ }
+ os << "# SystemC::Coverage-3\n";
+
+ // Build list of events; totalize if collapsing hierarchy
+ typedef map<string,pair<string,vluint64_t> > EventMap;
+ EventMap eventCounts;
+ for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
+ VerilatedCovImpItem* itemp = *(it);
+ string name;
+ string hier;
+ bool per_instance = false;
+
+ for (int i=0; i<MAX_KEYS; i++) {
+ if (itemp->m_keys[i] != KEY_UNDEF) {
+ string key = VerilatedCovKey::shortKey(m_indexValues[itemp->m_keys[i]]);
+ string val = m_indexValues[itemp->m_vals[i]];
+ if (key == VL_CIK_PER_INSTANCE) {
+ if (val != "0") per_instance = true;
+ }
+ if (key == VL_CIK_HIER) {
+ hier = val;
+ } else {
+ // Print it
+ name += keyValueFormatter(key,val);
+ }
+ }
+ }
+ if (per_instance) { // Not collapsing hierarchies
+ name += keyValueFormatter(VL_CIK_HIER,hier);
+ hier = "";
+ }
+
+ // Group versus point labels don't matter here, downstream
+ // deals with it. Seems bad for sizing though and doesn't
+ // allow easy addition of new group codes (would be
+ // inefficient)
+
+ // Find or insert the named event
+ EventMap::iterator cit = eventCounts.find(name);
+ if (cit != eventCounts.end()) {
+ const string& oldhier = cit->second.first;
+ cit->second.second += itemp->count();
+ cit->second.first = combineHier(oldhier, hier);
+ } else {
+ eventCounts.insert(make_pair(name, make_pair(hier,itemp->count())));
+ }
+ }
+
+ // Output body
+ for (EventMap::iterator it=eventCounts.begin(); it!=eventCounts.end(); ++it) {
+ os<<"C '"<<dec;
+ os<<it->first;
+ if (it->second.first != "") os<<keyValueFormatter(VL_CIK_HIER,it->second.first);
+ os<<"' "<<it->second.second;
+ os<<endl;
+ }
+ }
+};
+
+//=============================================================================
+// VerilatedCov
+
+void VerilatedCov::clear() {
+ VerilatedCovImp::imp().clear();
+}
+void VerilatedCov::clearNonMatch (const char* matchp) {
+ VerilatedCovImp::imp().clearNonMatch(matchp);
+}
+void VerilatedCov::zero() {
+ VerilatedCovImp::imp().zero();
+}
+void VerilatedCov::write (const char* filenamep) {
+ VerilatedCovImp::imp().write(filenamep);
+}
+void VerilatedCov::_inserti (vluint32_t* itemp) {
+ VerilatedCovImp::imp().inserti(new VerilatedCoverItemSpec<vluint32_t>(itemp));
+}
+void VerilatedCov::_inserti (vluint64_t* itemp) {
+ VerilatedCovImp::imp().inserti(new VerilatedCoverItemSpec<vluint64_t>(itemp));
+}
+void VerilatedCov::_insertf (const char* filename, int lineno) {
+ VerilatedCovImp::imp().insertf(filename,lineno);
+}
+
+#define K(n) const char* key ## n
+#define A(n) const char* key ## n, const char* val ## n // Argument list
+#define C(n) key ## n, val ## n // Calling argument list
+#define N(n) "","" // Null argument list
+void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
+ A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19),
+ A(20),A(21),A(22),A(23),A(24),A(25),A(26),A(27),A(28),A(29)) {
+ const char* keyps[VerilatedCovImpBase::MAX_KEYS]
+ = {NULL,NULL,NULL, // filename,lineno,page
+ key0,key1,key2,key3,key4,key5,key6,key7,key8,key9,
+ key10,key11,key12,key13,key14,key15,key16,key17,key18,key19,
+ key20,key21,key22,key23,key24,key25,key26,key27,key28,key29};
+ const char* valps[VerilatedCovImpBase::MAX_KEYS]
+ = {NULL,NULL,NULL, // filename,lineno,page
+ val0,val1,val2,val3,val4,val5,val6,val7,val8,val9,
+ val10,val11,val12,val13,val14,val15,val16,val17,val18,val19,
+ val20,val21,val22,val23,val24,val25,val26,val27,val28,val29};
+ VerilatedCovImp::imp().insertp(keyps, valps);
+}
+
+// And versions with fewer arguments (oh for a language with named parameters!)
+void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)) {
+ _insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9),
+ N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19),
+ N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
+}
+void VerilatedCov::_insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
+ A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19)) {
+ _insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9),
+ C(10),C(11),C(12),C(13),C(14),C(15),C(16),C(17),C(18),C(19),
+ N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
+}
+// Backward compatibility for Verilator
+void VerilatedCov::_insertp (A(0), A(1), K(2),int val2, K(3),int val3,
+ K(4),const string& val4, A(5),A(6)) {
+ _insertp(C(0),C(1),
+ key2,VlCovCvtToCStr(val2), key3,VlCovCvtToCStr(val3), key4, val4.c_str(),
+ C(5),C(6),N(7),N(8),N(9),
+ N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19),
+ N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
+}
+#undef A
+#undef C
+#undef N
+#undef K
diff --git a/include/verilated_cov.h b/include/verilated_cov.h
new file mode 100644
index 0000000..dac339d
--- /dev/null
+++ b/include/verilated_cov.h
@@ -0,0 +1,146 @@
+// -*- mode: C++; c-file-style: "cc-mode" -*-
+//=============================================================================
+//
+// THIS MODULE IS PUBLICLY LICENSED
+//
+// Copyright 2001-2014 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.
+//
+// This is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+//=============================================================================
+///
+/// \file
+/// \brief Coverage analysis support
+///
+/// AUTHOR: Wilson Snyder
+///
+//=============================================================================
+
+#ifndef _VERILATED_COV_H_
+#define _VERILATED_COV_H_ 1
+
+#include "verilatedos.h"
+
+#include <iostream>
+#include <sstream>
+#include <string>
+using namespace std;
+
+//=============================================================================
+/// Conditionally compile coverage code
+
+#ifdef VM_COVERAGE
+# define VL_IF_COVER(stmts) do { stmts ; } while(0)
+#else
+# define VL_IF_COVER(stmts) do { if(0) { stmts ; } } while(0)
+#endif
+
+//=============================================================================
+/// Insert a item for coverage analysis.
+/// The first argument is a pointer to the count to be dumped.
+/// The remaining arguments occur in pairs: A string key, and a value.
+/// The value may be a string, or another type which will be auto-converted to a string.
+///
+/// Some typical keys:
+/// filename File the recording occurs in. Defaults to __FILE__
+/// lineno Line number the recording occurs in. Defaults to __LINE__
+/// column Column number (or occurrence# for dup file/lines). Defaults to undef.
+/// hier Hierarchical name. Defaults to name()
+/// type Type of coverage. Defaults to "user"
+/// Other types are 'block', 'fsm', 'toggle'.
+/// comment Description of the coverage event. Should be set by the user.
+/// Comments for type==block: 'if', 'else', 'elsif', 'case'
+/// thresh Threshold to consider fully covered.
+/// If unspecified, downstream tools will determine it.
+///
+/// Examples:
+///
+/// vluint32_t m_cases[10];
+/// constructor {
+/// for (int i=0; i<10; i++) { m_cases[i]=0; }
+/// }
+/// for (int i=0; i<10; i++) {
+/// VL_COVER_INSERT(&m_cases[i], "comment", "Coverage Case", "i", cvtToNumStr(i));
+/// }
+
+#define VL_COVER_INSERT(countp,args...) \
+ VL_IF_COVER(VerilatedCov::_inserti(countp); \
+ VerilatedCov::_insertf(__FILE__,__LINE__); \
+ VerilatedCov::_insertp("hier", name(), args))
+
+//=============================================================================
+/// Convert VL_COVER_INSERT value arguments to strings
+
+template< class T> std::string vlCovCvtToStr (const T& t) {
+ ostringstream os; os<<t; return os.str();
+}
+
+/// Usage: something(VlCovCvtToCStr(i))
+/// Note the pointer will only be valid for as long as the object remains
+/// in scope!
+struct VlCovCvtToCStr {
+ string m_str;
+ // Casters
+ template< class T> VlCovCvtToCStr (const T& t) {
+ ostringstream os; os<<t; m_str=os.str();
+ }
+ ~VlCovCvtToCStr() {}
+ operator const char* () const { return m_str.c_str(); };
+};
+
+//=============================================================================
+// VerilatedCov
+/// Verilator coverage global class
+////
+/// Global class with methods affecting all coverage data.
+
+class VerilatedCov {
+public:
+ // GLOBAL METHODS
+ /// Return default filename
+ static const char* defaultFilename() { return "coverage.dat"; }
+ /// Write all coverage data to a file
+ static void write (const char* filenamep = defaultFilename());
+ /// Insert a coverage item
+ /// We accept from 1-30 key/value pairs, all as strings.
+ /// Call _insert1, followed by _insert2 and _insert3
+ /// Do not call directly; use VL_COVER_INSERT or higher level macros instead
+ // _insert1: Remember item pointer with count. (Not const, as may add zeroing function)
+ static void _inserti (vluint32_t* itemp);
+ static void _inserti (vluint64_t* itemp);
+ // _insert2: Set default filename and line number
+ static void _insertf (const char* filename, int lineno);
+ // _insert3: Set parameters
+ // We could have just the maximum argument version, but this compiles
+ // much slower (nearly 2x) than having smaller versions also. However
+ // there's not much more gain in having a version for each number of args.
+#define K(n) const char* key ## n
+#define A(n) const char* key ## n, const char* valp ## n // Argument list
+#define D(n) const char* key ## n = NULL, const char* valp ## n = NULL // Argument list
+ static void _insertp (D(0),D(1),D(2),D(3),D(4),D(5),D(6),D(7),D(8),D(9));
+ static void _insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)
+ ,A(10),D(11),D(12),D(13),D(14),D(15),D(16),D(17),D(18),D(19));
+ static void _insertp (A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)
+ ,A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19)
+ ,A(20),D(21),D(22),D(23),D(24),D(25),D(26),D(27),D(28),D(29));
+ // Backward compatibility for Verilator
+ static void _insertp (A(0), A(1), K(2),int val2, K(3),int val3,
+ K(4),const string& val4, A(5),A(6));
+
+#undef K
+#undef A
+#undef D
+ /// Clear coverage points (and call delete on all items)
+ static void clear();
+ /// Clear items not matching the provided string
+ static void clearNonMatch (const char* matchp);
+ /// Zero coverage points
+ static void zero();
+};
+
+#endif // guard
diff --git a/include/verilated_cov_key.h b/include/verilated_cov_key.h
new file mode 100644
index 0000000..3276a4a
--- /dev/null
+++ b/include/verilated_cov_key.h
@@ -0,0 +1,147 @@
+// -*- mode: C++; c-file-style: "cc-mode" -*-
+//=============================================================================
+//
+// THIS MODULE IS PUBLICLY LICENSED
+//
+// Copyright 2001-2014 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.
+//
+// This is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+// for more details.
+//
+//=============================================================================
+///
+/// \file
+/// \brief Coverage item keys
+///
+/// AUTHOR: Wilson Snyder
+///
+//=============================================================================
+
+#ifndef _VERILATED_COV_KEY_H_
+#define _VERILATED_COV_KEY_H_ 1
+
+#include "verilatedos.h"
+
+#include <string>
+using namespace std;
+
+//=============================================================================
+// Data used to edit below file, using vlcovgen
+
+#define VLCOVGEN_ITEM(string_parsed_by_vlcovgen)
+
+VLCOVGEN_ITEM("name=>'col0_name', short=>'C0', group=>1, default=>undef, descr=>'The column title for the header line of this column'")
+VLCOVGEN_ITEM("name=>'col1_name', short=>'C1', group=>1, default=>undef, ")
+VLCOVGEN_ITEM("name=>'col2_name', short=>'C2', group=>1, default=>undef, ")
+VLCOVGEN_ITEM("name=>'col3_name', short=>'C3', group=>1, default=>undef, ")
+VLCOVGEN_ITEM("name=>'column', short=>'n', group=>1, default=>0, descr=>'Column number for the item. Used to disambiguate multiple coverage points on the same line number'")
+VLCOVGEN_ITEM("name=>'filename', short=>'f', group=>1, default=>undef, descr=>'Filename of the item'")
+VLCOVGEN_ITEM("name=>'groupdesc', short=>'d', group=>1, default=>'', descr=>'Description of the covergroup this item belongs to'")
+VLCOVGEN_ITEM("name=>'groupname', short=>'g', group=>1, default=>'', descr=>'Group name of the covergroup this item belongs to'")
+VLCOVGEN_ITEM("name=>'groupcmt', short=>'O', group=>1, default=>'', ")
+VLCOVGEN_ITEM("name=>'per_instance',short=>'P', group=>1, default=>0, descr=>'True if every hierarchy is independently counted; otherwise all hierarchies will be combined into a single count'")
+VLCOVGEN_ITEM("name=>'row0_name', short=>'R0', group=>1, default=>undef, descr=>'The row title for the header line of this row'")
+VLCOVGEN_ITEM("name=>'row1_name', short=>'R1', group=>1, default=>undef, ")
+VLCOVGEN_ITEM("name=>'row2_name', short=>'R2', group=>1, default=>undef, ")
+VLCOVGEN_ITEM("name=>'row3_name', short=>'R3', group=>1, default=>undef, ")
+VLCOVGEN_ITEM("name=>'table', short=>'T', group=>1, default=>undef, descr=>'The name of the table for automatically generated tables'")
+VLCOVGEN_ITEM("name=>'thresh', short=>'s', group=>1, default=>undef, ")
+VLCOVGEN_ITEM("name=>'type', short=>'t', group=>1, default=>'', descr=>'Type of coverage (block, line, fsm, etc)'")
+// Bin attributes
+VLCOVGEN_ITEM("name=>'col0', short=>'c0', group=>0, default=>undef, descr=>'The (enumeration) value name for this column in a table cross' ")
+VLCOVGEN_ITEM("name=>'col1', short=>'c1', group=>0, default=>undef, ")
+VLCOVGEN_ITEM("name=>'col2', short=>'c2', group=>0, default=>undef, ")
+VLCOVGEN_ITEM("name=>'col3', short=>'c3', group=>0, default=>undef, ")
+VLCOVGEN_ITEM("name=>'comment', short=>'o', group=>0, default=>'', descr=>'Textual description for the item'")
+VLCOVGEN_ITEM("name=>'hier', short=>'h', group=>0, default=>'', descr=>'Hierarchy path name for the item'")
+VLCOVGEN_ITEM("name=>'limit', short=>'L', group=>0, default=>undef, ")
+VLCOVGEN_ITEM("name=>'lineno', short=>'l', group=>0, default=>0, descr=>'Line number for the item'")
+VLCOVGEN_ITEM("name=>'row0', short=>'r0', group=>0, default=>undef, descr=>'The (enumeration) value name for this row in a table cross'")
+VLCOVGEN_ITEM("name=>'row1', short=>'r1', group=>0, default=>undef, ")
+VLCOVGEN_ITEM("name=>'row2', short=>'r2', group=>0, default=>undef, ")
+VLCOVGEN_ITEM("name=>'row3', short=>'r3', group=>0, default=>undef, ")
+VLCOVGEN_ITEM("name=>'weight', short=>'w', group=>0, default=>undef, descr=>'For totaling items, weight of this item'")
+
+//=============================================================================
+// VerilatedCovKey
+/// Verilator coverage global class
+////
+/// Global class with methods affecting all coverage data.
+
+// VLCOVGEN_CIK_AUTO_EDIT_BEGIN
+#define VL_CIK_COL0 "c0"
+#define VL_CIK_COL0_NAME "C0"
+#define VL_CIK_COL1 "c1"
+#define VL_CIK_COL1_NAME "C1"
+#define VL_CIK_COL2 "c2"
+#define VL_CIK_COL2_NAME "C2"
+#define VL_CIK_COL3 "c3"
+#define VL_CIK_COL3_NAME "C3"
+#define VL_CIK_COLUMN "n"
+#define VL_CIK_COMMENT "o"
+#define VL_CIK_FILENAME "f"
+#define VL_CIK_GROUPCMT "O"
+#define VL_CIK_GROUPDESC "d"
+#define VL_CIK_GROUPNAME "g"
+#define VL_CIK_HIER "h"
+#define VL_CIK_LIMIT "L"
+#define VL_CIK_LINENO "l"
+#define VL_CIK_PER_INSTANCE "P"
+#define VL_CIK_ROW0 "r0"
+#define VL_CIK_ROW0_NAME "R0"
+#define VL_CIK_ROW1 "r1"
+#define VL_CIK_ROW1_NAME "R1"
+#define VL_CIK_ROW2 "r2"
+#define VL_CIK_ROW2_NAME "R2"
+#define VL_CIK_ROW3 "r3"
+#define VL_CIK_ROW3_NAME "R3"
+#define VL_CIK_TABLE "T"
+#define VL_CIK_THRESH "s"
+#define VL_CIK_TYPE "t"
+#define VL_CIK_WEIGHT "w"
+// VLCOVGEN_CIK_AUTO_EDIT_END
+
+class VerilatedCovKey {
+public:
+ static string shortKey(const string& key) {
+ // VLCOVGEN_SHORT_AUTO_EDIT_BEGIN
+ if (key == "col0") return VL_CIK_COL0;
+ if (key == "col0_name") return VL_CIK_COL0_NAME;
+ if (key == "col1") return VL_CIK_COL1;
+ if (key == "col1_name") return VL_CIK_COL1_NAME;
+ if (key == "col2") return VL_CIK_COL2;
+ if (key == "col2_name") return VL_CIK_COL2_NAME;
+ if (key == "col3") return VL_CIK_COL3;
+ if (key == "col3_name") return VL_CIK_COL3_NAME;
+ if (key == "column") return VL_CIK_COLUMN;
+ if (key == "comment") return VL_CIK_COMMENT;
+ if (key == "filename") return VL_CIK_FILENAME;
+ if (key == "groupcmt") return VL_CIK_GROUPCMT;
+ if (key == "groupdesc") return VL_CIK_GROUPDESC;
+ if (key == "groupname") return VL_CIK_GROUPNAME;
+ if (key == "hier") return VL_CIK_HIER;
+ if (key == "limit") return VL_CIK_LIMIT;
+ if (key == "lineno") return VL_CIK_LINENO;
+ if (key == "per_instance") return VL_CIK_PER_INSTANCE;
+ if (key == "row0") return VL_CIK_ROW0;
+ if (key == "row0_name") return VL_CIK_ROW0_NAME;
+ if (key == "row1") return VL_CIK_ROW1;
+ if (key == "row1_name") return VL_CIK_ROW1_NAME;
+ if (key == "row2") return VL_CIK_ROW2;
+ if (key == "row2_name") return VL_CIK_ROW2_NAME;
+ if (key == "row3") return VL_CIK_ROW3;
+ if (key == "row3_name") return VL_CIK_ROW3_NAME;
+ if (key == "table") return VL_CIK_TABLE;
+ if (key == "thresh") return VL_CIK_THRESH;
+ if (key == "type") return VL_CIK_TYPE;
+ if (key == "weight") return VL_CIK_WEIGHT;
+ // VLCOVGEN_SHORT_AUTO_EDIT_END
+ return key;
+ }
+};
+
+#endif // guard
diff --git a/include/verilated_heavy.h b/include/verilated_heavy.h
index 940c669..3da1b20 100644
--- a/include/verilated_heavy.h
+++ b/include/verilated_heavy.h
@@ -41,13 +41,24 @@ inline string VL_CVT_PACK_STR_NQ(QData lhs) {
IData lw[2]; VL_SET_WQ(lw, lhs);
return VL_CVT_PACK_STR_NW(2, lw);
}
-inline string VL_CVT_PACK_STR_NQ(string lhs) {
+inline string VL_CVT_PACK_STR_NQ(const string& lhs) {
return lhs;
}
inline string VL_CVT_PACK_STR_NI(IData lhs) {
IData lw[1]; lw[0] = lhs;
return VL_CVT_PACK_STR_NW(1, lw);
}
+inline string VL_CONCATN_NNN(const string& lhs, const string& rhs) {
+ return lhs+rhs;
+}
+inline string VL_REPLICATEN_NNQ(int,int,int rbits, const string& lhs, IData rep) {
+ string out; out.reserve(lhs.length() * rep);
+ for (unsigned times=0; times<rep; times++) out += lhs;
+ return out;
+}
+inline string VL_REPLICATEN_NNI(int obits,int lbits,int rbits, const string& lhs, IData rep) {
+ return VL_REPLICATEN_NNQ(obits,lbits,rbits,lhs,rep);
+}
extern void VL_SFORMAT_X(int obits_ignored, string &output, const char* formatp, ...);
extern string VL_SFORMATF_NX(const char* formatp, ...);
diff --git a/include/verilated_vcd_c.cpp b/include/verilated_vcd_c.cpp
index 8aa36e2..202e9cd 100644
--- a/include/verilated_vcd_c.cpp
+++ b/include/verilated_vcd_c.cpp
@@ -57,7 +57,7 @@ vector<VerilatedVcd*> VerilatedVcd::s_vcdVecp; ///< List of all created traces
// VerilatedVcdCallInfo
/// Internal callback routines for each module being traced.
////
-/// Each SystemPerl module that wishes to be traced registers a set of
+/// Each module that wishes to be traced registers a set of
/// callbacks stored in this class. When the trace file is being
/// constructed, this class provides the callback routines to be executed.
diff --git a/include/verilated_vcd_c.h b/include/verilated_vcd_c.h
index daf4c3b..228c7b2 100644
--- a/include/verilated_vcd_c.h
+++ b/include/verilated_vcd_c.h
@@ -395,7 +395,7 @@ public:
/// Create a VCD dump file in C standalone (no SystemC) simulations.
class VerilatedVcdC {
- VerilatedVcd m_sptrace; ///< SystemPerl trace file being created
+ VerilatedVcd m_sptrace; ///< Trace file being created
public:
// CONSTRUCTORS
VerilatedVcdC() {}
diff --git a/include/verilated_vcd_sc.cpp b/include/verilated_vcd_sc.cpp
index a6935c4..14ea6a6 100644
--- a/include/verilated_vcd_sc.cpp
+++ b/include/verilated_vcd_sc.cpp
@@ -15,7 +15,7 @@
//=============================================================================
///
/// \file
-/// \brief SystemPerl Tracing in VCD Format
+/// \brief Verilator tracing in VCD Format
///
/// AUTHOR: Wilson Snyder
///
diff --git a/include/verilated_vcd_sc.h b/include/verilated_vcd_sc.h
index 9ae96cd..08a6567 100644
--- a/include/verilated_vcd_sc.h
+++ b/include/verilated_vcd_sc.h
@@ -15,7 +15,7 @@
//=============================================================================
///
/// \file
-/// \brief SystemPerl tracing in VCD format
+/// \brief Verilator tracing in VCD format
///
/// AUTHOR: Wilson Snyder
///
diff --git a/include/verilatedos.h b/include/verilatedos.h
index c2068f1..a82eb59 100644
--- a/include/verilatedos.h
+++ b/include/verilatedos.h
@@ -106,6 +106,13 @@
#endif
//=========================================================================
+// Optimization
+
+#ifndef VL_INLINE_OPT
+# define VL_INLINE_OPT ///< "inline" if compiling all objects in single compiler run
+#endif
+
+//=========================================================================
// Warning disabled
#ifndef VL_WARNINGS
diff --git a/internals.html b/internals.html
index d2890cf..e6e1c40 100644
--- a/internals.html
+++ b/internals.html
@@ -502,10 +502,10 @@ be warning free.</p>
<dt><strong><a name="enable_longtests" class="item">--enable-longtests</a></strong></dt>
<dd>
-<p>In addition to the standard C, SystemC and SystemPerl tests also run the
-tests in the <code>test_vcs</code>, <code>test_verilated</code> and <code>test_regress</code> directories
-when using <em>make test</em>. This is disabled by default as SystemC/SystemPerl
-installation problems would otherwise falsely indicate a Verilator problem.</p>
+<p>In addition to the standard C, SystemC tests also run the tests in the
+<code>test_verilated</code> and <code>test_regress</code> directories when using <em>make test</em>.
+This is disabled by default as SystemC installation problems would
+otherwise falsely indicate a Verilator problem.</p>
</dd>
</dl>
<p>When enabling the long tests, some additional PERL modules are needed, which
@@ -515,11 +515,6 @@ you can install using cpan.</p>
<p>There are some traps to avoid when running regression tests</p>
<ul>
<li>
-<p>The regression tests will assume that you have a version of SystemPerl to
-match. Typically if working on Verilator from git, also use SystemPerl from
-git.</p>
-</li>
-<li>
<p>When checking the MANIFEST, the test will barf on unexpected code in the
Verilator tree. So make sure to keep any such code outside the tree.</p>
</li>
diff --git a/internals.pdf b/internals.pdf
index 1f649cf..c5d025d 100644
Binary files a/internals.pdf and b/internals.pdf differ
diff --git a/internals.pod b/internals.pod
index 1a458ba..83ae109 100644
--- a/internals.pod
+++ b/internals.pod
@@ -473,10 +473,10 @@ be warning free.
=item --enable-longtests
-In addition to the standard C, SystemC and SystemPerl tests also run the
-tests in the C<test_vcs>, C<test_verilated> and C<test_regress> directories
-when using I<make test>. This is disabled by default as SystemC/SystemPerl
-installation problems would otherwise falsely indicate a Verilator problem.
+In addition to the standard C, SystemC tests also run the tests in the
+C<test_verilated> and C<test_regress> directories when using I<make test>.
+This is disabled by default as SystemC installation problems would
+otherwise falsely indicate a Verilator problem.
=back
@@ -491,12 +491,6 @@ There are some traps to avoid when running regression tests
=item *
-The regression tests will assume that you have a version of SystemPerl to
-match. Typically if working on Verilator from git, also use SystemPerl from
-git.
-
-=item *
-
When checking the MANIFEST, the test will barf on unexpected code in the
Verilator tree. So make sure to keep any such code outside the tree.
diff --git a/internals.txt b/internals.txt
index 59626e4..b47730b 100644
--- a/internals.txt
+++ b/internals.txt
@@ -441,11 +441,10 @@ TESTING
SystemC) may not be warning free.
--enable-longtests
- In addition to the standard C, SystemC and SystemPerl tests also run
- the tests in the "test_vcs", "test_verilated" and "test_regress"
- directories when using *make test*. This is disabled by default as
- SystemC/SystemPerl installation problems would otherwise falsely
- indicate a Verilator problem.
+ In addition to the standard C, SystemC tests also run the tests in
+ the "test_verilated" and "test_regress" directories when using *make
+ test*. This is disabled by default as SystemC installation problems
+ would otherwise falsely indicate a Verilator problem.
When enabling the long tests, some additional PERL modules are needed,
which you can install using cpan.
@@ -454,10 +453,6 @@ TESTING
There are some traps to avoid when running regression tests
- * The regression tests will assume that you have a version of
- SystemPerl to match. Typically if working on Verilator from git,
- also use SystemPerl from git.
-
* When checking the MANIFEST, the test will barf on unexpected code in
the Verilator tree. So make sure to keep any such code outside the
tree.
diff --git a/readme.pod b/readme.pod
index d4340f0..42b87db 100644
--- a/readme.pod
+++ b/readme.pod
@@ -76,14 +76,6 @@ instead.)
=item
-If you will be using SystemPerl or coverage, download and install
-System-Perl, L<http://www.veripool.org/systemperl>. Note you'll need to
-set a C<SYSTEMPERL> environment variable to point to the downloaded kit.
-Optionally also set C<SYSTEMPERL_INCLUDE> to point to the installed
-headers.
-
-=item
-
You will need the C<flex> and C<bison> packages installed.
=item
@@ -95,8 +87,8 @@ C<cd> to the Verilator directory containing this README.
You now have to decide how you're going to eventually install the kit.
Note Verilator builds the current value of VERILATOR_ROOT, SYSTEMC_INCLUDE,
-SYSTEMC_LIBDIR, SYSTEMPERL, and SYSTEMPERL_INCLUDE as defaults into the
-executable, so try to have them correct before configuring.
+and SYSTEMC_LIBDIR as defaults into the executable, so try to have them
+correct before configuring.
=over 4
@@ -198,8 +190,6 @@ The directories in the kit after de-taring are as follows:
test_v => Example Verilog code for other test dirs
test_c => Example Verilog->C++ conversion
test_sc => Example Verilog->SystemC conversion
- test_sp => Example Verilog->SystemPerl conversion
- test_vcs => Example Verilog->VCS conversion (test the test)
test_verilated => Internal tests
test_regress => Internal tests
diff --git a/src/Makefile.in b/src/Makefile.in
index efdd7b4..4fdd7ee 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -46,7 +46,7 @@ obj_opt:
obj_dbg:
mkdir $@
-.PHONY: ../verilator_bin ../verilator_bin_dbg
+.PHONY: ../verilator_bin ../verilator_bin_dbg ../verilator_coverage_bin_dbg
opt: ../verilator_bin
ifeq ($(VERILATOR_NO_OPT_BUILD),1) # Faster laptop development... One build
@@ -59,11 +59,15 @@ else
cd obj_opt && $(MAKE) TGT=../$@ -f ../Makefile_obj
endif
-dbg: ../verilator_bin_dbg
+dbg: ../verilator_bin_dbg ../verilator_coverage_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) TGT=../$@ VL_DEBUG=1 -f ../Makefile_obj
+../verilator_coverage_bin_dbg: obj_dbg prefiles
+ cd obj_dbg && $(MAKE) TGT=../$@ VL_DEBUG=1 VL_VLCOV=1 -f ../Makefile_obj serial_vlcov
+ cd obj_dbg && $(MAKE) TGT=../$@ VL_DEBUG=1 VL_VLCOV=1 -f ../Makefile_obj
+
prefiles::
prefiles:: config_rev.h
ifneq ($(UNDER_GIT),) # If local git tree... Else don't burden users
diff --git a/src/Makefile_obj.in b/src/Makefile_obj.in
index 57685d9..786030e 100644
--- a/src/Makefile_obj.in
+++ b/src/Makefile_obj.in
@@ -127,6 +127,7 @@ HEADERS = $(wildcard V*.h v*.h)
ASTGEN = $(srcdir)/astgen
BISONPRE = $(srcdir)/bisonpre
FLEXFIX = $(srcdir)/flexfix
+VLCOVGEN = $(srcdir)/vlcovgen
######################################################################
#### Top level
@@ -186,6 +187,7 @@ RAW_OBJS = \
V3Error.o \
V3Expand.o \
V3File.o \
+ V3FileLine.o \
V3Gate.o \
V3GenClk.o \
V3Graph.o \
@@ -233,26 +235,30 @@ RAW_OBJS = \
V3WidthSel.o \
# Non-concatable
-OBJS += \
+NC_OBJS += \
V3ParseImp.o \
V3ParseGrammar.o \
V3ParseLex.o \
V3PreProc.o \
+# verilator_coverage
+VLCOV_OBJS = \
+ VlcMain.o \
+
#### Linking
-ifeq ($(VL_DEBUG),)
-# Building with fewer objects to better optimize
-#OBJS += V3__CONCAT.o
-OBJS += $(RAW_OBJS)
+ifeq ($(VL_VLCOV),)
+PREDEP_H = V3Ast__gen_classes.h
+OBJS += $(RAW_OBJS) $(NC_OBJS)
else
-OBJS += $(RAW_OBJS)
+PREDEP_H =
+OBJS += $(VLCOV_OBJS)
endif
V3__CONCAT.cpp: $(addsuffix .cpp, $(basename $(RAW_OBJS)))
$(PERL) $(srcdir)/../bin/verilator_includer $^ > $@
-$(TGT): V3Ast__gen_classes.h $(OBJS)
+$(TGT): $(PREDEP_H) $(OBJS)
@echo " Linking $@..."
-rm -rf $@ $@.exe
${LINK} ${LDFLAGS} -o $@ $(OBJS) $(CCMALLOC) ${LIBS}
@@ -287,6 +293,12 @@ V3PreProc.o: V3PreProc.cpp V3PreLex.yy.cpp
# Target rule called before parallel build to make generated files
serial:: V3Ast__gen_classes.h V3ParseBison.c
+serial_vlcov:: vlcovgen.d
+
+vlcovgen.d: $(VLCOVGEN) $(srcdir)/include/verilated_cov_key.h
+ $(PERL) $(VLCOVGEN) --srcdir $(srcdir)
+ touch $@
+
V3Ast__gen_classes.h : $(ASTGEN) V3Ast.h V3AstNodes.h
$(PERL) $(ASTGEN) -I$(srcdir) --classes
diff --git a/src/V3Assert.cpp b/src/V3Assert.cpp
index 4163c28..c2b3dc4 100644
--- a/src/V3Assert.cpp
+++ b/src/V3Assert.cpp
@@ -131,19 +131,13 @@ private:
if (message!="") covincp->declp()->comment(message);
bodysp = covincp;
}
- } else if (nodep->castPslAssert()) {
- bodysp = newFireAssert(nodep,message);
- // We assert the property is always true... so report when it fails
- // (Note this is opposite the behavior of coverage statements.)
- // Need: 'never' operator: not hold in current or any future cycle
- propp = new AstLogNot (nodep->fileline(), propp);
} else {
nodep->v3fatalSrc("Unknown node type");
}
if (stmtsp) bodysp = bodysp->addNext(stmtsp);
AstIf* ifp = new AstIf (nodep->fileline(), propp, bodysp, NULL);
bodysp = ifp;
- if (nodep->castPslAssert()) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
+ if (nodep->castVAssert()) ifp->branchPred(AstBranchPred::BP_UNLIKELY);
//
AstNode* newp = new AstAlways (nodep->fileline(),
VAlwaysKwd::ALWAYS,
@@ -309,12 +303,6 @@ private:
nodep->stmtsp(), nodep->name()); nodep=NULL;
++m_statAsCover;
}
- virtual void visit(AstPslAssert* nodep, AstNUser*) {
- nodep->iterateChildren(*this);
- newPslAssertion(nodep, nodep->propp(), nodep->sentreep(),
- NULL, nodep->name()); nodep=NULL;
- ++m_statAsPsl;
- }
virtual void visit(AstVAssert* nodep, AstNUser*) {
nodep->iterateChildren(*this);
newVAssertion(nodep, nodep->propp()); nodep=NULL;
@@ -339,14 +327,6 @@ private:
m_beginp = lastp;
}
- // VISITORS //========== Temporal Layer
-
- // VISITORS //========== Boolean Layer
- virtual void visit(AstPslBool* nodep, AstNUser*) {
- nodep->replaceWith(nodep->exprp()->unlinkFrBack());
- pushDeletep(nodep); nodep=NULL;
- }
-
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
diff --git a/src/V3AssertPre.cpp b/src/V3AssertPre.cpp
index f80775b..2523891 100644
--- a/src/V3AssertPre.cpp
+++ b/src/V3AssertPre.cpp
@@ -73,14 +73,6 @@ private:
}
// VISITORS //========== Statements
- virtual void visit(AstPslDefClock* nodep, AstNUser*) {
- nodep->iterateChildren(*this);
- // Store the new default clock, reset on new module
- m_seniDefaultp = nodep->sensesp();
- // Trash it
- nodep->unlinkFrBack();
- pushDeletep(nodep); nodep=NULL;
- }
virtual void visit(AstClocking* nodep, AstNUser*) {
UINFO(8," CLOCKING"<<nodep<<endl);
// Store the new default clock, reset on new module
@@ -101,13 +93,6 @@ private:
nodep->sentreep(newSenTree(nodep));
clearAssertInfo();
}
- virtual void visit(AstPslAssert* nodep, AstNUser*) {
- if (nodep->sentreep()) return; // Already processed
- clearAssertInfo();
- nodep->iterateChildren(*this);
- nodep->sentreep(newSenTree(nodep));
- clearAssertInfo();
- }
virtual void visit(AstPslClocked* nodep, AstNUser*) {
nodep->iterateChildren(*this);
if (m_senip) {
diff --git a/src/V3Ast.cpp b/src/V3Ast.cpp
index 5b980d6..1fa1cb4 100644
--- a/src/V3Ast.cpp
+++ b/src/V3Ast.cpp
@@ -203,31 +203,6 @@ string AstNode::prettyTypeName() const {
return string(typeName())+" '"+prettyName()+"'";
}
-string AstNode::quoteName(const string& namein) {
- // Encode control chars into C style escapes
- // Reverse is V3Parse::deQuote
- const char* start = namein.c_str();
- string out;
- for (const char* pos = start; *pos; pos++) {
- if (pos[0]=='\\' || pos[0]=='"') {
- out += string("\\")+pos[0];
- } else if (pos[0]=='\n') {
- out += "\\n";
- } else if (pos[0]=='\r') {
- out += "\\r";
- } else if (pos[0]=='\t') {
- out += "\\t";
- } else if (isprint(pos[0])) {
- out += pos[0];
- } else {
- // This will also cover \a etc
- char octal[10]; sprintf(octal,"\\%03o",pos[0]);
- out += octal;
- }
- }
- return out;
-}
-
//######################################################################
// Insertion
diff --git a/src/V3Ast.h b/src/V3Ast.h
index f14284a..4099d28 100644
--- a/src/V3Ast.h
+++ b/src/V3Ast.h
@@ -23,6 +23,7 @@
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
+#include "V3FileLine.h"
#include "V3Number.h"
#include "V3Global.h"
#include <vector>
@@ -238,6 +239,13 @@ public:
//
DT_PUBLIC, // V3LinkParse moves to AstTypedef::attrPublic
//
+ ENUM_FIRST, // V3Width processes
+ ENUM_LAST, // V3Width processes
+ ENUM_NUM, // V3Width processes
+ ENUM_NEXT, // V3Width processes
+ ENUM_PREV, // V3Width processes
+ ENUM_NAME, // V3Width processes
+ //
MEMBER_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes
//
VAR_BASE, // V3LinkResolve creates for AstPreSel, V3LinkParam removes
@@ -258,6 +266,7 @@ public:
"DIM_BITS", "DIM_DIMENSIONS", "DIM_HIGH", "DIM_INCREMENT", "DIM_LEFT",
"DIM_LOW", "DIM_RIGHT", "DIM_SIZE", "DIM_UNPK_DIMENSIONS",
"DT_PUBLIC",
+ "ENUM_FIRST", "ENUM_LAST", "ENUM_NUM", "ENUM_NEXT", "ENUM_PREV", "ENUM_NAME",
"MEMBER_BASE",
"VAR_BASE", "VAR_CLOCK", "VAR_CLOCK_ENABLE", "VAR_PUBLIC",
"VAR_PUBLIC_FLAT", "VAR_PUBLIC_FLAT_RD","VAR_PUBLIC_FLAT_RW",
@@ -383,9 +392,8 @@ public:
bool isOpaque() const { // IE not a simple number we can bit optimize
return (m_e==STRING || m_e==SCOPEPTR || m_e==CHARPTR || m_e==DOUBLE || m_e==FLOAT);
}
- bool isDouble() const {
- return (m_e==DOUBLE);
- }
+ bool isDouble() const { return m_e==DOUBLE; }
+ bool isString() const { return m_e==STRING; }
};
inline bool operator== (AstBasicDTypeKwd lhs, AstBasicDTypeKwd rhs) { return (lhs.m_e == rhs.m_e); }
inline bool operator== (AstBasicDTypeKwd lhs, AstBasicDTypeKwd::en rhs) { return (lhs.m_e == rhs); }
@@ -1007,6 +1015,7 @@ public:
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 instrCountString() { return 100; } ///< Instruction cycles to do string ops
static int instrCountCall() { return instrCountBranch()+10; } ///< Instruction cycles to call subroutine
static int instrCountTime() { return instrCountCall()+5; } ///< Instruction cycles to determine simulation time
@@ -1016,7 +1025,6 @@ public:
virtual string verilogKwd() const { return ""; }
string shortName() const; // Name with __PVT__ removed for concatenating scopes
static string dedotName(const string& namein); // Name with dots removed
- static string quoteName(const string& namein); // Name with control chars quoted
static string prettyName(const string& namein); // Name for printing out to the user
static string encodeName(const string& namein); // Encode user name into internal C representation
static string encodeNumber(vlsint64_t numin); // Encode number into internal C representation
@@ -1042,6 +1050,7 @@ public:
bool isWide() const { return (width()>VL_QUADSIZE); }
bool isDouble() const;
bool isSigned() const;
+ bool isString() const;
AstNUser* user1p() const {
// Slows things down measurably, so disabled by default
@@ -1119,6 +1128,7 @@ public:
void dtypeSetLogicSized(int width, int widthMin, AstNumeric numeric) { dtypep(findLogicDType(width,widthMin,numeric)); }
void dtypeSetLogicBool() { dtypep(findLogicBoolDType()); }
void dtypeSetDouble() { dtypep(findDoubleDType()); }
+ void dtypeSetString() { dtypep(findStringDType()); }
void dtypeSetSigned32() { dtypep(findSigned32DType()); }
void dtypeSetUInt32() { dtypep(findUInt32DType()); } // Twostate
void dtypeSetUInt64() { dtypep(findUInt64DType()); } // Twostate
@@ -1126,6 +1136,7 @@ public:
// Data type locators
AstNodeDType* findLogicBoolDType() { return findBasicDType(AstBasicDTypeKwd::LOGIC); }
AstNodeDType* findDoubleDType() { return findBasicDType(AstBasicDTypeKwd::DOUBLE); }
+ AstNodeDType* findStringDType() { return findBasicDType(AstBasicDTypeKwd::STRING); }
AstNodeDType* findSigned32DType() { return findBasicDType(AstBasicDTypeKwd::INTEGER); }
AstNodeDType* findUInt32DType() { return findBasicDType(AstBasicDTypeKwd::UINT32); } // Twostate
AstNodeDType* findUInt64DType() { return findBasicDType(AstBasicDTypeKwd::UINT64); } // Twostate
@@ -1263,8 +1274,9 @@ public:
virtual void numberOperate(V3Number& out, const V3Number& lhs) = 0; // Set out to evaluation of a AstConst'ed lhs
virtual bool cleanLhs() = 0;
virtual bool sizeMattersLhs() = 0; // True if output result depends on lhs size
- virtual bool signedFlavor() const { return false; } // Signed flavor of nodes with both flavors?
virtual bool doubleFlavor() const { return false; } // D flavor of nodes with both flavors?
+ virtual bool signedFlavor() const { return false; } // Signed flavor of nodes with both flavors?
+ virtual bool stringFlavor() const { return false; } // N flavor of nodes with both flavors?
virtual int instrCount() const { return widthInstrs(); }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode*) const { return true; }
@@ -1287,8 +1299,9 @@ public:
virtual bool cleanRhs() = 0; // True if RHS must have extra upper bits zero
virtual bool sizeMattersLhs() = 0; // True if output result depends on lhs size
virtual bool sizeMattersRhs() = 0; // True if output result depends on rhs size
- virtual bool signedFlavor() const { return false; } // Signed flavor of nodes with both flavors?
virtual bool doubleFlavor() const { return false; } // D flavor of nodes with both flavors?
+ virtual bool signedFlavor() const { return false; } // Signed flavor of nodes with both flavors?
+ virtual bool stringFlavor() const { return false; } // N flavor of nodes with both flavors?
virtual int instrCount() const { return widthInstrs(); }
virtual V3Hash sameHash() const { return V3Hash(); }
virtual bool same(AstNode*) const { return true; }
@@ -1886,6 +1899,7 @@ inline int AstNode::widthMin() const { return dtypep() ? dtypep()->widthMin() :
inline bool AstNode::width1() const { return dtypep() && dtypep()->width()==1; } // V3Const uses to know it can optimize
inline int AstNode::widthInstrs() const { return (!dtypep() ? 1 : (dtypep()->isWide() ? dtypep()->widthWords() : 1)); }
inline bool AstNode::isDouble() const { return dtypep() && dtypep()->castBasicDType() && dtypep()->castBasicDType()->isDouble(); }
+inline bool AstNode::isString() const { return dtypep() && dtypep()->basicp() && dtypep()->basicp()->isString(); }
inline bool AstNode::isSigned() const { return dtypep() && dtypep()->isSigned(); }
inline bool AstNode::isZero() { return (this->castConst() && this->castConst()->num().isEqZero()); }
diff --git a/src/V3AstNodes.cpp b/src/V3AstNodes.cpp
index afd2ce3..fd3aa70 100644
--- a/src/V3AstNodes.cpp
+++ b/src/V3AstNodes.cpp
@@ -737,7 +737,10 @@ void AstNode::dump(ostream& str) {
} else { // V3Broken will throw an error
if (dtypep()) str<<" %Error-dtype-exp=null,got="<<(void*)dtypep();
}
- if (name()!="") str<<" "<<AstNode::quoteName(name());
+ if (name()!="") {
+ if (castConst()) str<<" "<<name(); // Already quoted
+ else str<<" "<<V3Number::quoteNameControls(name());
+ }
}
void AstAlways::dump(ostream& str) {
@@ -850,7 +853,10 @@ void AstNodeDType::dumpSmall(ostream& str) {
<<((isSigned()&&!isDouble())?"s":"")
<<(isNosign()?"n":"")
<<(isDouble()?"d":"")
- <<"w"<<(widthSized()?"":"u")<<width();
+ <<(isString()?"str":"");
+ if (!isDouble() && !isString()) {
+ str<<"w"<<(widthSized()?"":"u")<<width();
+ }
if (!widthSized()) str<<"/"<<widthMin();
str<<")";
}
diff --git a/src/V3AstNodes.h b/src/V3AstNodes.h
index 391c434..a33d7ae 100644
--- a/src/V3AstNodes.h
+++ b/src/V3AstNodes.h
@@ -49,6 +49,8 @@ public:
,m_num(num) {
if (m_num.isDouble()) {
dtypeSetDouble();
+ } else if (m_num.isString()) {
+ dtypeSetString();
} else {
dtypeSetLogicSized(m_num.width(), m_num.sized()?0:m_num.widthMin(),
m_num.isSigned() ? AstNumeric::SIGNED
@@ -74,6 +76,10 @@ public:
AstConst(FileLine* fl, RealDouble, double num)
:AstNodeMath(fl)
,m_num(V3Number(fl,64)) { m_num.setDouble(num); dtypeSetDouble(); }
+ class String {}; // for creator type-overload selection
+ AstConst(FileLine* fl, String, const string& num)
+ :AstNodeMath(fl)
+ ,m_num(V3Number(V3Number::String(), fl, num)) { dtypeSetString(); }
class LogicFalse {};
AstConst(FileLine* fl, LogicFalse) // Shorthand const 0, know the dtype should be a logic of size 1
:AstNodeMath(fl)
@@ -100,34 +106,6 @@ public:
bool isEqAllOnesV() const { return num().isEqAllOnes(widthMin()); }
};
-class AstConstString : public AstNodeMath {
- // A constant string
-private:
- string m_name;
-public:
- AstConstString(FileLine* fl, const string& name)
- : AstNodeMath(fl), m_name(name) {
- rewidth();
- }
- void rewidth() {
- if (m_name.length()==0) {
- dtypeSetLogicSized(1,1,AstNumeric::UNSIGNED); // 0 width isn't allowed due to historic special cases
- } else {
- dtypeSetLogicSized(((int)m_name.length())*8, ((int)m_name.length())*8, AstNumeric::UNSIGNED);
- }
- }
- ASTNODE_NODE_FUNCS(ConstString, CONSTSTRING)
- virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
- virtual string emitC() { V3ERROR_NA; return ""; }
- virtual bool cleanOut() { return true; }
- virtual V3Hash sameHash() const { return V3Hash(name()); }
- virtual bool same(AstNode* samep) const {
- return name()==samep->castConstString()->name(); }
- virtual int instrCount() const { return 2; } // C just loads a pointer
- virtual string name() const { return m_name; }
- void name(const string& flag) { m_name = flag; rewidth(); }
-};
-
class AstRange : public AstNode {
// Range specification, for use under variables and cells
private:
@@ -400,6 +378,7 @@ public:
bool isBitLogic() const { return keyword().isBitLogic(); }
bool isDouble() const { return keyword().isDouble(); }
bool isOpaque() const { return keyword().isOpaque(); }
+ bool isString() const { return keyword().isString(); }
bool isSloppy() const { return keyword().isSloppy(); }
bool isZeroInit() const { return keyword().isZeroInit(); }
bool isRanged() const { return rangep() || m.m_nrange.ranged(); }
@@ -902,6 +881,32 @@ public:
void fromp(AstNode* nodep) { setOp1p(nodep); }
};
+class AstMethodSel : public AstNode {
+ // A reference to a member task (or function)
+ // We do not support generic member calls yet, so this is only enough to make built-in methods work
+private:
+ string m_name; // Name of variable
+public:
+ AstMethodSel(FileLine* fl, AstNode* fromp, VFlagChildDType, const string& name, AstNode* pinsp)
+ : AstNode(fl), m_name(name) {
+ setOp1p(fromp);
+ dtypep(NULL); // V3Width will resolve
+ addNOp2p(pinsp);
+ }
+ AstMethodSel(FileLine* fl, AstNode* fromp, const string& name, AstNode* pinsp)
+ :AstNode(fl), m_name(name) {
+ setOp1p(fromp);
+ addNOp2p(pinsp);
+ }
+ ASTNODE_NODE_FUNCS(MethodSel, METHODSEL)
+ virtual string name() const { return m_name; } // * = Var name
+ virtual void name(const string& name) { m_name = name; }
+ AstNode* fromp() const { return op1p()->castNode(); } // op1 = Extracting what (NULL=TBD during parsing)
+ void fromp(AstNode* nodep) { setOp1p(nodep); }
+ AstNode* pinsp() const { return op2p()->castNode(); } // op2 = Pin interconnection list
+ void addPinsp(AstNode* nodep) { addOp2p(nodep); }
+};
+
class AstVar : public AstNode {
// A variable (in/out/wire/reg/param) inside a module
private:
@@ -935,6 +940,7 @@ private:
bool m_isPulldown:1; // Tri0
bool m_isPullup:1; // Tri1
bool m_isIfaceParent:1; // dtype is reference to interface present in this module
+ bool m_noSubst:1; // Do not substitute out references
bool m_trace:1; // Trace this variable
void init() {
@@ -947,6 +953,7 @@ private:
m_attrClockEn=false; m_attrScBv=false; m_attrIsolateAssign=false; m_attrSFormat=false;
m_fileDescr=false; m_isConst=false; m_isStatic=false; m_isPulldown=false; m_isPullup=false;
m_isIfaceParent=false;
+ m_noSubst=false;
m_trace=false;
}
public:
@@ -1039,7 +1046,9 @@ public:
void isIfaceParent(bool flag) { m_isIfaceParent = flag; }
void funcLocal(bool flag) { m_funcLocal = flag; }
void funcReturn(bool flag) { m_funcReturn = flag; }
- void trace(bool flag) { m_trace=flag; }
+ void noSubst(bool flag) { m_noSubst=flag; }
+ bool noSubst() const { return m_noSubst; }
+ void trace(bool flag) { m_trace=flag; }
// METHODS
virtual void name(const string& name) { m_name = name; }
virtual string directionName() const { return (isInout() ? "inout" : isInput() ? "input"
@@ -3521,10 +3530,10 @@ public:
};
class AstCvtPackString : public AstNodeUniop {
- // Convert to Verilator Packed Pack (aka Pack)
+ // Convert to Verilator Packed String (aka verilog "string")
public:
AstCvtPackString(FileLine* fl, AstNode* lhsp) : AstNodeUniop(fl, lhsp) {
- dtypeSetUInt64(); } // Really, width should be dtypep -> STRING
+ dtypeSetString(); } // Really, width should be dtypep -> STRING
ASTNODE_NODE_FUNCS(CvtPackString, CVTPACKSTRING)
virtual void numberOperate(V3Number& out, const V3Number& lhs) { V3ERROR_NA; }
virtual string emitVerilog() { return "%f$_CAST(%l)"; }
@@ -3794,6 +3803,21 @@ public:
virtual int instrCount() const { return instrCountDouble(); }
virtual bool doubleFlavor() const { return true; }
};
+class AstEqN : public AstNodeBiCom {
+public:
+ AstEqN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
+ dtypeSetLogicBool(); }
+ ASTNODE_NODE_FUNCS(EqN, EQN)
+ virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opEqN(lhs,rhs); }
+ virtual string emitVerilog() { return "%k(%l %f== %r)"; }
+ virtual string emitC() { V3ERROR_NA; return ""; }
+ virtual string emitSimpleOperator() { return "=="; }
+ virtual bool cleanOut() {return true;}
+ virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
+ virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
+ virtual int instrCount() const { return instrCountString(); }
+ virtual bool stringFlavor() const { return true; }
+};
class AstNeq : public AstNodeBiCom {
public:
AstNeq(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
@@ -3822,6 +3846,21 @@ public:
virtual int instrCount() const { return instrCountDouble(); }
virtual bool doubleFlavor() const { return true; }
};
+class AstNeqN : public AstNodeBiCom {
+public:
+ AstNeqN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiCom(fl, lhsp, rhsp) {
+ dtypeSetLogicBool(); }
+ ASTNODE_NODE_FUNCS(NeqN, NEQN)
+ virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opNeqN(lhs,rhs); }
+ virtual string emitVerilog() { return "%k(%l %f!= %r)"; }
+ virtual string emitC() { V3ERROR_NA; return ""; }
+ virtual string emitSimpleOperator() { return "!="; }
+ virtual bool cleanOut() {return true;}
+ virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
+ virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
+ virtual int instrCount() const { return instrCountString(); }
+ virtual bool stringFlavor() const { return true; }
+};
class AstLt : public AstNodeBiop {
public:
AstLt(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
@@ -3864,6 +3903,21 @@ public:
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
virtual bool signedFlavor() const { return true; }
};
+class AstLtN : public AstNodeBiop {
+public:
+ AstLtN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
+ dtypeSetLogicBool(); }
+ ASTNODE_NODE_FUNCS(LtN, LTN)
+ virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLtN(lhs,rhs); }
+ virtual string emitVerilog() { return "%k(%l %f< %r)"; }
+ virtual string emitC() { V3ERROR_NA; return ""; }
+ virtual string emitSimpleOperator() { return "<"; }
+ virtual bool cleanOut() {return true;}
+ virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
+ virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
+ virtual int instrCount() const { return instrCountString(); }
+ virtual bool stringFlavor() const { return true; }
+};
class AstGt : public AstNodeBiop {
public:
AstGt(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
@@ -3906,6 +3960,21 @@ public:
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
virtual bool signedFlavor() const { return true; }
};
+class AstGtN : public AstNodeBiop {
+public:
+ AstGtN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
+ dtypeSetLogicBool(); }
+ ASTNODE_NODE_FUNCS(GtN, GTN)
+ virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGtN(lhs,rhs); }
+ virtual string emitVerilog() { return "%k(%l %f> %r)"; }
+ virtual string emitC() { V3ERROR_NA; return ""; }
+ virtual string emitSimpleOperator() { return ">"; }
+ virtual bool cleanOut() {return true;}
+ virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
+ virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
+ virtual int instrCount() const { return instrCountString(); }
+ virtual bool stringFlavor() const { return true; }
+};
class AstGte : public AstNodeBiop {
public:
AstGte(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
@@ -3949,6 +4018,21 @@ public:
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
virtual bool signedFlavor() const { return true; }
};
+class AstGteN : public AstNodeBiop {
+public:
+ AstGteN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
+ dtypeSetLogicBool(); }
+ ASTNODE_NODE_FUNCS(GteN, GTEN)
+ virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opGteN(lhs,rhs); }
+ virtual string emitVerilog() { return "%k(%l %f>= %r)"; }
+ virtual string emitC() { V3ERROR_NA; return ""; }
+ virtual string emitSimpleOperator() { return ">="; }
+ virtual bool cleanOut() {return true;}
+ virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
+ virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
+ virtual int instrCount() const { return instrCountString(); }
+ virtual bool stringFlavor() const { return true; }
+};
class AstLte : public AstNodeBiop {
public:
AstLte(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
@@ -3992,6 +4076,21 @@ public:
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
virtual bool signedFlavor() const { return true; }
};
+class AstLteN : public AstNodeBiop {
+public:
+ AstLteN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
+ dtypeSetLogicBool(); }
+ ASTNODE_NODE_FUNCS(LteN, LTEN)
+ virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opLteN(lhs,rhs); }
+ virtual string emitVerilog() { return "%k(%l %f<= %r)"; }
+ virtual string emitC() { V3ERROR_NA; return ""; }
+ virtual string emitSimpleOperator() { return "<="; }
+ virtual bool cleanOut() {return true;}
+ virtual bool cleanLhs() {return false;} virtual bool cleanRhs() {return false;}
+ virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
+ virtual int instrCount() const { return instrCountString(); }
+ virtual bool stringFlavor() const { return true; }
+};
class AstShiftL : public AstNodeBiop {
public:
AstShiftL(FileLine* fl, AstNode* lhsp, AstNode* rhsp, int setwidth=0)
@@ -4352,6 +4451,22 @@ public:
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
virtual int instrCount() const { return widthInstrs()*2; }
};
+class AstConcatN : public AstNodeBiop {
+ // String concatenate
+public:
+ AstConcatN(FileLine* fl, AstNode* lhsp, AstNode* rhsp) : AstNodeBiop(fl, lhsp, rhsp) {
+ dtypeSetString();
+ }
+ ASTNODE_NODE_FUNCS(ConcatN, CONCATN)
+ virtual string emitVerilog() { return "%f{%l, %k%r}"; }
+ virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opConcatN(lhs,rhs); }
+ virtual string emitC() { return "VL_CONCATN_NNN(%li, %ri)"; }
+ virtual bool cleanOut() {return true;}
+ virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
+ virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
+ virtual int instrCount() const { return instrCountString(); }
+ virtual bool stringFlavor() const { return true; }
+};
class AstReplicate : public AstNodeBiop {
// Also used as a "Uniop" flavor of Concat, e.g. "{a}"
// Verilog {rhs{lhs}} - Note rhsp() is the replicate value, not the lhsp()
@@ -4377,6 +4492,25 @@ public:
virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
virtual int instrCount() const { return widthInstrs()*2; }
};
+class AstReplicateN : public AstNodeBiop {
+ // String replicate
+private:
+ void init() { dtypeSetString(); }
+public:
+ AstReplicateN(FileLine* fl, AstNode* lhsp, AstNode* rhsp)
+ : AstNodeBiop(fl, lhsp, rhsp) { init(); }
+ AstReplicateN(FileLine* fl, AstNode* lhsp, uint32_t repCount)
+ : AstNodeBiop(fl, lhsp, new AstConst(fl, repCount)) { init(); }
+ ASTNODE_NODE_FUNCS(ReplicateN, REPLICATEN)
+ virtual void numberOperate(V3Number& out, const V3Number& lhs, const V3Number& rhs) { out.opReplN(lhs,rhs); }
+ virtual string emitVerilog() { return "%f{%r{%k%l}}"; }
+ virtual string emitC() { return "VL_REPLICATEN_NN%rq(0,0,%rw, %li, %ri)"; }
+ virtual bool cleanOut() {return false;}
+ virtual bool cleanLhs() {return true;} virtual bool cleanRhs() {return true;}
+ virtual bool sizeMattersLhs() {return false;} virtual bool sizeMattersRhs() {return false;}
+ virtual int instrCount() const { return widthInstrs()*2; }
+ virtual bool stringFlavor() const { return true; }
+};
class AstStreamL : public AstNodeStream {
// Verilog {rhs{lhs}} - Note rhsp() is the slice size, not the lhsp()
public:
@@ -4520,19 +4654,6 @@ public:
//======================================================================
// PSL
-class AstPslDefClock : public AstNode {
- // Set default PSL clock
- // Parents: MODULE
- // Children: SENITEM
-public:
- AstPslDefClock(FileLine* fl, AstNodeSenItem* sensesp)
- : AstNode(fl) {
- addNOp1p(sensesp);
- }
- ASTNODE_NODE_FUNCS(PslDefClock, PSLDEFCLOCK)
- AstNodeSenItem* sensesp() const { return op1p()->castNodeSenItem(); } // op1 = Sensitivity list
-};
-
class AstPslClocked : public AstNode {
// A clocked property
// Parents: ASSERT|COVER (property)
@@ -4551,27 +4672,6 @@ public:
AstNode* propp() const { return op3p(); } // op3 = property
};
-class AstPslAssert : public AstNodeStmt {
- // Psl Assertion
- // Parents: {statement list}
- // Children: expression, report string
-private:
- string m_name; // Name to report
-public:
- AstPslAssert(FileLine* fl, AstNode* propp, const string& name="")
- : AstNodeStmt(fl)
- , m_name(name) {
- addOp1p(propp);
- }
- ASTNODE_NODE_FUNCS(PslAssert, PSLASSERT)
- virtual string name() const { return m_name; } // * = Var name
- virtual V3Hash sameHash() const { return V3Hash(name()); }
- virtual bool same(AstNode* samep) const { return samep->name() == name(); }
- AstNode* propp() const { return op1p(); } // op1 = property
- AstSenTree* sentreep() const { return op2p()->castSenTree(); } // op2 = clock domain
- void sentreep(AstSenTree* sentreep) { addOp2p(sentreep); } // op2 = clock domain
-};
-
class AstPslCover : public AstNodeStmt {
// Psl Cover
// Parents: {statement list}
@@ -4599,29 +4699,6 @@ public:
};
//======================================================================
-// PSL Expressions
-
-class AstPslBool : public AstNode {
- // Separates PSL Sere/sequences from the normal expression boolean layer below.
- // Note this excludes next() and similar functions; they are time domain, so not under AstPslBool.
- // Parents: Sequences, etc.
- // Children: math
-public:
- AstPslBool(FileLine* fileline, AstNode* exprp)
- : AstNode(fileline) {
- addOp1p(exprp);
- }
- ASTNODE_NODE_FUNCS(PslBool, PSLBOOL)
- AstNode* exprp() const { return op1p()->castNode(); } // op1= expression
- virtual bool hasDType() const { return true; }
- virtual bool isGateOptimizable() const { return false; } // Not relevant
- virtual bool isPredictOptimizable() const { return false; } // Not relevant
- virtual int instrCount() const { return 0; }
- virtual V3Hash sameHash() const { return V3Hash(); }
- virtual bool same(AstNode* samep) const { return true; }
-};
-
-//======================================================================
// Text based nodes
class AstText : public AstNodeText {
@@ -4756,6 +4833,7 @@ private:
bool m_formCallTree:1; // Make a global function to call entire tree of functions
bool m_slow:1; // Slow routine, called once or just at init time
bool m_funcPublic:1; // From user public task/function
+ bool m_isInline:1; // Inline function
bool m_isStatic:1; // Function is declared static (no this)
bool m_symProlog:1; // Setup symbol table for later instructions
bool m_entryPoint:1; // User may call into this top level function
@@ -4776,6 +4854,7 @@ public:
m_formCallTree = false;
m_slow = false;
m_funcPublic = false;
+ m_isInline = false;
m_isStatic = true; // Note defaults to static, later we see where thisp is needed
m_symProlog = false;
m_entryPoint = false;
@@ -4805,6 +4884,7 @@ public:
string rtnTypeVoid() const { return ((m_rtnType=="") ? "void" : m_rtnType); }
bool dontCombine() const { return m_dontCombine || funcType()!=AstCFuncType::FT_NORMAL; }
void dontCombine(bool flag) { m_dontCombine = flag; }
+ bool dontInline() const { return dontCombine() || slow() || skipDecl() || funcPublic(); }
bool skipDecl() const { return m_skipDecl; }
void skipDecl(bool flag) { m_skipDecl = flag; }
bool declPrivate() const { return m_declPrivate; }
@@ -4819,6 +4899,8 @@ public:
string argTypes() const { return m_argTypes; }
void funcType(AstCFuncType flag) { m_funcType = flag; }
AstCFuncType funcType() const { return m_funcType; }
+ bool isInline() const { return m_isInline; }
+ void isInline(bool flag) { m_isInline = flag; }
bool isStatic() const { return m_isStatic; }
void isStatic(bool flag) { m_isStatic = flag; }
bool symProlog() const { return m_symProlog; }
diff --git a/src/V3Branch.cpp b/src/V3Branch.cpp
index 699f9b8..c887d75 100644
--- a/src/V3Branch.cpp
+++ b/src/V3Branch.cpp
@@ -21,6 +21,9 @@
// At each IF/(IF else).
// Count underneath $display/$stop statements.
// If more on if than else, this branch is unlikely, or vice-versa.
+// At each FTASKREF,
+// Count calls into the function
+// Then, if FTASK is called only once, add inline attribute
//
//*************************************************************************
@@ -40,9 +43,18 @@
class BranchVisitor : public AstNVisitor {
private:
+ // NODE STATE
+ // Entire netlist:
+ // AstFTask::user1() -> int. Number of references
+ AstUser1InUse m_inuser1;
+
+ // TYPES
+ typedef vector<AstCFunc*> CFuncVec;
+
// STATE
int m_likely; // Excuses for branch likely taken
int m_unlikely; // Excuses for branch likely not taken
+ CFuncVec m_cfuncsp; // List of all tasks
// METHODS
static int debug() {
@@ -55,6 +67,12 @@ private:
m_likely = false;
m_unlikely = false;
}
+ void checkUnlikely(AstNode* nodep) {
+ if (nodep->isUnlikely()) {
+ UINFO(4," UNLIKELY: "<<nodep<<endl);
+ m_unlikely++;
+ }
+ }
// VISITORS
virtual void visit(AstNodeIf* nodep, AstNUser*) {
@@ -83,20 +101,37 @@ private:
m_likely = lastLikely;
m_unlikely = lastUnlikely;
}
+ virtual void visit(AstCCall* nodep, AstNUser*) {
+ checkUnlikely(nodep);
+ nodep->funcp()->user1Inc();
+ nodep->iterateChildren(*this);
+ }
+ virtual void visit(AstCFunc* nodep, AstNUser*) {
+ checkUnlikely(nodep);
+ m_cfuncsp.push_back(nodep);
+ nodep->iterateChildren(*this);
+ }
virtual void visit(AstNode* nodep, AstNUser*) {
- // Default: Just iterate
- if (nodep->isUnlikely()) {
- UINFO(4," UNLIKELY: "<<nodep<<endl);
- m_unlikely++;
- }
+ checkUnlikely(nodep);
nodep->iterateChildren(*this);
}
+ // METHODS
+ void calc_tasks() {
+ for (CFuncVec::iterator it=m_cfuncsp.begin(); it!=m_cfuncsp.end(); ++it) {
+ AstCFunc* nodep = *it;
+ if (!nodep->dontInline()) {
+ nodep->isInline(true);
+ }
+ }
+ }
+
public:
// CONSTUCTORS
BranchVisitor(AstNetlist* nodep) {
reset();
nodep->iterateChildren(*this);
+ calc_tasks();
}
virtual ~BranchVisitor() {}
};
diff --git a/src/V3Config.h b/src/V3Config.h
index d9098fc..c129277 100644
--- a/src/V3Config.h
+++ b/src/V3Config.h
@@ -24,6 +24,7 @@
#include "verilatedos.h"
#include <string>
#include "V3Error.h"
+#include "V3FileLine.h"
//######################################################################
diff --git a/src/V3Const.cpp b/src/V3Const.cpp
index 259c5a5..a0b7484 100644
--- a/src/V3Const.cpp
+++ b/src/V3Const.cpp
@@ -624,7 +624,7 @@ private:
void replaceConstString (AstNode* oldp, const string& num) {
// Replace oldp node with a constant set to specified value
UASSERT (oldp, "Null old\n");
- AstNode* newp = new AstConstString(oldp->fileline(), num);
+ AstNode* newp = new AstConst(oldp->fileline(), AstConst::String(), num);
if (debug()>5) oldp->dumpTree(cout," const_old: ");
if (debug()>5) newp->dumpTree(cout," _new: ");
oldp->replaceWith(newp);
@@ -1457,6 +1457,7 @@ private:
&& v3Global.opt.oConst()
&& !(nodep->varp()->isFuncLocal() // Default value, not a "known" constant for this usage
&& nodep->varp()->isInput())
+ && !nodep->varp()->noSubst()
&& !nodep->varp()->isSigPublic())
|| nodep->varp()->isParam())) {
if (operandConst(valuep)) {
@@ -2141,22 +2142,28 @@ private:
TREEOP ("AstXor {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstEq {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X.
TREEOP ("AstEqD {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X.
+ TREEOP ("AstEqN {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)"); // We let X==X -> 1, although in a true 4-state sim it's X.
TREEOP ("AstEqCase {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP ("AstEqWild {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP ("AstGt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstGtD {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
+ TREEOP ("AstGtN {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstGtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstGte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP ("AstGteD {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
+ TREEOP ("AstGteN {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP ("AstGteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP ("AstLt {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstLtD {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
+ TREEOP ("AstLtN {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstLtS {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstLte {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP ("AstLteD {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
+ TREEOP ("AstLteN {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP ("AstLteS {operandsSame($lhsp,,$rhsp)}", "replaceNum(nodep,1)");
TREEOP ("AstNeq {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstNeqD {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
+ TREEOP ("AstNeqN {operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstNeqCase{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstNeqWild{operandsSame($lhsp,,$rhsp)}", "replaceZero(nodep)");
TREEOP ("AstLogAnd {operandsSame($lhsp,,$rhsp), $lhsp.width1}", "replaceWLhs(nodep)");
@@ -2212,6 +2219,7 @@ private:
TREEOPV("AstExtend {$lhsp.castExtend}", "replaceExtend(nodep, nodep->lhsp()->castExtend()->lhsp())");
TREEOPV("AstExtendS{$lhsp.castExtendS}", "replaceExtend(nodep, nodep->lhsp()->castExtendS()->lhsp())");
TREEOPV("AstReplicate{$lhsp, $rhsp.isOne, $lhsp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs
+ TREEOPV("AstReplicateN{$lhsp, $rhsp.isOne, $lhsp->width()==nodep->width()}", "replaceWLhs(nodep)"); // {1{lhs}}->lhs
// Next rule because AUTOINST puts the width of bits in
// to pins, even when the widths are exactly the same across the hierarchy.
TREEOPV("AstSel{operandSelExtend(nodep)}", "DONE");
diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp
index 3d3d69a..a26f9c6 100644
--- a/src/V3EmitC.cpp
+++ b/src/V3EmitC.cpp
@@ -227,9 +227,9 @@ public:
puts("&(vlSymsp->__Vcoverage[");
puts(cvtToStr(nodep->dataDeclThisp()->binNum())); puts("])");
// If this isn't the first instantiation of this module under this
- // design, don't really count the bucket, and rely on SystemPerl to
+ // design, don't really count the bucket, and rely on verilator_cov to
// aggregate counts. This is because Verilator combines all
- // hiearchies itself, and if SystemPerl also did it, you'd end up
+ // hiearchies itself, and if verilator_cov also did it, you'd end up
// with (number-of-instant) times too many counts in this bin.
puts(", first"); // Enable, passed from __Vconfigure parameter
puts(", "); putsQuoted(nodep->fileline()->filename());
@@ -620,6 +620,10 @@ public:
// Put out constant set to the specified variable, or given variable in a string
if (nodep->num().isFourState()) {
nodep->v3error("Unsupported: 4-state numbers in this context");
+ } else if (nodep->num().isString()) {
+ putbs("string(");
+ putsQuoted(nodep->num().toString());
+ puts(")");
} else if (nodep->isWide()) {
putbs("VL_CONST_W_");
puts(cvtToStr(VL_WORDS_I(nodep->num().widthMin())));
@@ -680,9 +684,6 @@ public:
emitConstant(nodep, NULL, "");
}
}
- virtual void visit(AstConstString* nodep, AstNUser*) {
- putsQuoted(nodep->name());
- }
// Just iterate
virtual void visit(AstNetlist* nodep, AstNUser*) {
@@ -829,6 +830,7 @@ class EmitCImp : EmitCStmts {
splitSizeInc(nodep);
puts("\n");
+ if (nodep->isInline()) puts("VL_INLINE_OPT ");
puts(nodep->rtnTypeVoid()); puts(" ");
puts(modClassName(m_modp)+"::"+nodep->name()
+"("+cFuncArgs(nodep)+") {\n");
@@ -1167,17 +1169,20 @@ void EmitCStmts::emitOpName(AstNode* nodep, const string& format,
struct EmitDispState {
string m_format; // "%s" and text from user
+ vector<char> m_argsChar; // Format of each argument to be printed
vector<AstNode*> m_argsp; // Each argument to be printed
vector<string> m_argsFunc; // Function before each argument to be printed
EmitDispState() { clear(); }
void clear() {
m_format = "";
+ m_argsChar.clear();
m_argsp.clear();
m_argsFunc.clear();
}
void pushFormat(const string& fmt) { m_format += fmt; }
void pushFormat(char fmt) { m_format += fmt; }
- void pushArg(AstNode* nodep, const string& func) {
+ void pushArg(char fmtChar, AstNode* nodep, const string& func) {
+ m_argsChar.push_back(fmtChar);
m_argsp.push_back(nodep); m_argsFunc.push_back(func);
}
} emitDispState;
@@ -1230,6 +1235,7 @@ void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) {
// Arguments
for (unsigned i=0; i < emitDispState.m_argsp.size(); i++) {
puts(",");
+ char fmt = emitDispState.m_argsChar[i];
AstNode* argp = emitDispState.m_argsp[i];
string func = emitDispState.m_argsFunc[i];
ofp()->indentInc();
@@ -1237,8 +1243,10 @@ void EmitCStmts::displayEmit(AstNode* nodep, bool isScan) {
if (func!="") puts(func);
if (argp) {
if (isScan) puts("&(");
+ else if (fmt == '@') puts("&(");
argp->iterate(*this);
if (isScan) puts(")");
+ else if (fmt == '@') puts(")");
}
ofp()->indentDec();
}
@@ -1287,8 +1295,8 @@ void EmitCStmts::displayArg(AstNode* dispp, AstNode** elistp, bool isScan,
pfmt = string("%") + vfmt + fmtLetter;
}
emitDispState.pushFormat(pfmt);
- emitDispState.pushArg(NULL,cvtToStr(argp->widthMin()));
- emitDispState.pushArg(argp,"");
+ emitDispState.pushArg(' ',NULL,cvtToStr(argp->widthMin()));
+ emitDispState.pushArg(fmtLetter,argp,"");
// Next parameter
*elistp = (*elistp)->nextp();
@@ -1327,6 +1335,7 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep,
break;
// Special codes
case '~': displayArg(nodep,&elistp,isScan, vfmt,'d'); break; // Signed decimal
+ case '@': displayArg(nodep,&elistp,isScan, vfmt,'@'); break; // Packed string
// Spec: h d o b c l
case 'b': displayArg(nodep,&elistp,isScan, vfmt,'b'); break;
case 'c': displayArg(nodep,&elistp,isScan, vfmt,'c'); break;
@@ -1344,7 +1353,7 @@ void EmitCStmts::displayNode(AstNode* nodep, AstScopeName* scopenamep,
string suffix = scopenamep->scopePrettyName();
if (suffix=="") emitDispState.pushFormat("%S");
else emitDispState.pushFormat("%N"); // Add a . when needed
- emitDispState.pushArg(NULL, "vlSymsp->name()");
+ emitDispState.pushArg(' ',NULL, "vlSymsp->name()");
emitDispState.pushFormat(suffix);
break;
}
@@ -1383,9 +1392,6 @@ void EmitCImp::emitVarResets(AstNodeModule* modp) {
if (varp->isIO() && modp->isTop() && optSystemC()) {
// System C top I/O doesn't need loading, as the lower level subinst code does it.
}
- else if (varp->basicp() && varp->basicp()->keyword() == AstBasicDTypeKwd::STRING) {
- // Constructor deals with it
- }
else if (varp->isParam()) {
if (!varp->valuep()) nodep->v3fatalSrc("No init for a param?");
// If a simple CONST value we initialize it using an enum
@@ -1404,6 +1410,9 @@ void EmitCImp::emitVarResets(AstNodeModule* modp) {
varp->v3fatalSrc("InitArray under non-arrayed var");
}
}
+ else if (varp->basicp() && varp->basicp()->keyword() == AstBasicDTypeKwd::STRING) {
+ // Constructor deals with it
+ }
else {
int vects = 0;
// This isn't very robust and may need cleanup for other data types
@@ -1508,7 +1517,7 @@ void EmitCImp::emitConfigureImp(AstNodeModule* modp) {
void EmitCImp::emitCoverageImp(AstNodeModule* modp) {
if (v3Global.opt.coverage() ) {
puts("\n// Coverage\n");
- // Rather than putting out SP_COVER_INSERT calls directly, we do it via this function
+ // Rather than putting out VL_COVER_INSERT calls directly, we do it via this function
// This gets around gcc slowness constructing all of the template arguments
// SystemPerl 1.301 is much faster, but it's nice to remain back
// compatible, and have a common wrapper.
@@ -1517,7 +1526,7 @@ void EmitCImp::emitCoverageImp(AstNodeModule* modp) {
puts( "static uint32_t fake_zero_count = 0;\n"); // static doesn't need save-restore as constant
puts( "if (!enable) countp = &fake_zero_count;\n"); // Used for second++ instantiation of identical bin
puts( "*countp = 0;\n");
- puts( "SP_COVER_INSERT(countp,");
+ puts( "VL_COVER_INSERT(countp,");
puts( " \"filename\",filenamep,");
puts( " \"lineno\",lineno,");
puts( " \"column\",column,\n");
@@ -1827,7 +1836,7 @@ void EmitCImp::emitInt(AstNodeModule* modp) {
puts("#include \"verilated_save.h\"\n");
}
if (v3Global.opt.coverage()) {
- puts("#include \"SpCoverage.h\"\n");
+ puts("#include \"verilated_cov.h\"\n");
if (v3Global.opt.savable()) v3error("--coverage and --savable not supported together");
}
if (v3Global.needHInlines()) { // Set by V3EmitCInlines; should have been called before us
diff --git a/src/V3EmitMk.cpp b/src/V3EmitMk.cpp
index 272b007..1c7a827 100644
--- a/src/V3EmitMk.cpp
+++ b/src/V3EmitMk.cpp
@@ -83,13 +83,13 @@ public:
if (v3Global.opt.savable()) {
putMakeClassEntry(of, "verilated_save.cpp");
}
+ if (v3Global.opt.coverage()) {
+ putMakeClassEntry(of, "verilated_cov.cpp");
+ }
if (v3Global.opt.systemPerl()) {
putMakeClassEntry(of, "Sp.cpp"); // Note Sp.cpp includes SpTraceVcdC
}
else {
- if (v3Global.opt.coverage()) {
- putMakeClassEntry(of, "SpCoverage.cpp");
- }
if (v3Global.opt.trace()) {
putMakeClassEntry(of, "verilated_vcd_c.cpp");
if (v3Global.opt.systemC()) {
diff --git a/src/V3EmitV.cpp b/src/V3EmitV.cpp
index b7c7c99..35d8cc6 100644
--- a/src/V3EmitV.cpp
+++ b/src/V3EmitV.cpp
@@ -57,7 +57,7 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
// Don't use to quote a filename for #include - #include doesn't \ escape.
// Duplicate in V3File - here so we can print to string
putsNoTracking("\"");
- putsNoTracking(AstNode::quoteName(str));
+ putsNoTracking(V3Number::quoteNameControls(str));
putsNoTracking("\"");
}
@@ -553,10 +553,6 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
virtual void visit(AstConst* nodep, AstNUser*) {
putfs(nodep,nodep->num().ascii(true,true));
}
- virtual void visit(AstConstString* nodep, AstNUser*) {
- putfs(nodep,"");
- putsQuoted(nodep->name());
- }
// Just iterate
virtual void visit(AstTopScope* nodep, AstNUser*) {
diff --git a/src/V3EmitXml.cpp b/src/V3EmitXml.cpp
index 851bd26..9e2dd8c 100644
--- a/src/V3EmitXml.cpp
+++ b/src/V3EmitXml.cpp
@@ -59,7 +59,7 @@ class EmitXmlFileVisitor : public EmitCBaseVisitor {
// Don't use to quote a filename for #include - #include doesn't \ escape.
// Duplicate in V3File - here so we can print to string
putsNoTracking("\"");
- putsNoTracking(AstNode::quoteName(str));
+ putsNoTracking(V3Number::quoteNameControls(str));
putsNoTracking("\"");
}
diff --git a/src/V3Error.cpp b/src/V3Error.cpp
index 8eb7c56..514a40f 100644
--- a/src/V3Error.cpp
+++ b/src/V3Error.cpp
@@ -27,7 +27,6 @@
# include "V3Ast.h"
# include "V3Global.h"
# include "V3Stats.h"
-# include "V3Config.h"
#endif
//======================================================================
@@ -36,6 +35,8 @@
int V3Error::s_errCount = 0;
int V3Error::s_warnCount = 0;
int V3Error::s_debugDefault = 0;
+int V3Error::s_errorLimit = V3Error::MAX_ERRORS;
+bool V3Error::s_warnFatal = true;
int V3Error::s_tellManual = 0;
ostringstream V3Error::s_errorStr; // Error string being formed
V3ErrorCode V3Error::s_errorCode = V3ErrorCode::EC_FATAL;
@@ -66,270 +67,6 @@ V3ErrorCode::V3ErrorCode(const char* msgp) {
}
//######################################################################
-// FileLineSingleton class functions
-
-const string FileLineSingleton::filenameLetters(int no) {
- const int size = 1 + (64 / 4); // Each letter retires more than 4 bits of a > 64 bit number
- char out[size];
- char* op = out+size-1;
- *--op = '\0'; // We build backwards
- int num = no;
- do {
- *--op = 'a'+num%26;
- num /= 26;
- } while (num);
- return op;
-}
-
-//! 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.
-
-//! We associate a language with each source file, so we also set the default
-//! for this.
-int FileLineSingleton::nameToNumber(const string& filename) {
- FileNameNumMap::const_iterator it = m_namemap.find(filename);
- if (VL_LIKELY(it != m_namemap.end())) return it->second;
- int num = m_names.size();
- m_names.push_back(filename);
- m_languages.push_back(V3LangCode::mostRecent());
- m_namemap.insert(make_pair(filename,num));
- return num;
-}
-
-//! Support XML output
-
-//! Experimental. Updated to also put out the language.
-void FileLineSingleton::fileNameNumMapDumpXml(ostream& os) {
- os<<"<files>\n";
- for (FileNameNumMap::const_iterator it = m_namemap.begin(); it != m_namemap.end(); ++it) {
- os<<"<file id=\""<<filenameLetters(it->second)
- <<"\" filename=\""<<it->first
- <<"\" language=\""<<numberToLang(it->second).ascii()<<"\"/>\n";
- }
- os<<"</files>\n";
-}
-
-//######################################################################
-// FileLine class functions
-
-FileLine::FileLine(FileLine::EmptySecret) {
- // Sort of a singleton
- m_lineno=0;
- m_filenameno=singleton().nameToNumber("AstRoot");
-
- m_warnOn=0;
- for (int codei=V3ErrorCode::EC_MIN; codei<V3ErrorCode::_ENUM_MAX; codei++) {
- V3ErrorCode code = (V3ErrorCode)codei;
- warnOff(code, code.defaultsOff());
- }
-}
-
-string FileLine::lineDirectiveStrg(int enterExit) const {
- char numbuf[20]; sprintf(numbuf, "%d", lineno());
- char levelbuf[20]; sprintf(levelbuf, "%d", enterExit);
- return ((string)"`line "+numbuf+" \""+filename()+"\" "+levelbuf+"\n");
-}
-
-void FileLine::lineDirective(const char* textp, int& enterExitRef) {
- // Handle `line directive
- // Skip `line
- while (*textp && isspace(*textp)) textp++;
- while (*textp && !isspace(*textp)) textp++;
- while (*textp && (isspace(*textp) || *textp=='"')) textp++;
-
- // Grab linenumber
- const char *ln = textp;
- while (*textp && !isspace(*textp)) textp++;
- if (isdigit(*ln)) {
- this->lineno(atoi(ln));
- }
- while (*textp && (isspace(*textp) || *textp=='"')) textp++;
-
- // Grab filename
- const char *fn = textp;
- while (*textp && !(isspace(*textp) || *textp=='"')) textp++;
- if (textp != fn) {
- string strfn = fn;
- strfn = strfn.substr(0, textp-fn);
- this->filename(strfn);
- }
-
- // Grab level
- while (*textp && (isspace(*textp) || *textp=='"')) textp++;
- if (isdigit(*textp)) enterExitRef = atoi(textp);
- else enterExitRef = 0;
-
- //printf ("PPLINE %d '%s'\n", s_lineno, s_filename.c_str());
-}
-
-FileLine* FileLine::copyOrSameFileLine() {
- // When a fileline is "used" to produce a node, calls this function.
- // Return this, or a copy of this
- // There are often more than one token per line, thus we use the
- // same pointer as long as we're on the same line, file & warn state.
-#ifndef _V3ERROR_NO_GLOBAL_
- V3Config::applyIgnores(this); // Toggle warnings based on global config file
-#endif
- static FileLine* lastNewp = NULL;
- if (lastNewp && *lastNewp == *this) { // Compares lineno, filename, etc
- return lastNewp;
- }
- FileLine* newp = new FileLine(this);
- lastNewp = newp;
- return newp;
-}
-
-void FileLine::updateLanguage () {
- language(v3Global.opt.fileLanguage(filename()));
-}
-
-const string FileLine::filebasename() const {
- string name = filename();
- string::size_type pos;
- if ((pos = name.rfind("/")) != string::npos) {
- name.erase(0,pos+1);
- }
- return name;
-}
-
-const string FileLine::filebasenameNoExt() const {
- string name = filebasename();
- string::size_type pos;
- if ((pos = name.find(".")) != string::npos) {
- name = name.substr(0,pos);
- }
- return name;
-}
-
-const string FileLine::profileFuncname() const {
- // Return string that is OK as a function name - for profiling
- string name = filebasenameNoExt();
- string::size_type pos;
- while ((pos = name.find_first_not_of("abcdefghijlkmnopqrstuvwxyzABCDEFGHIJLKMNOPQRSTUVWXYZ0123456789_"))
- != string::npos) {
- name.replace(pos, 1, "_");
- }
- name += "__l"+cvtToStr(lineno());
- return name;
-}
-
-string FileLine::ascii() const {
- return filename()+":"+cvtToStr(lineno());
-}
-ostream& operator<<(ostream& os, FileLine* fileline) {
- os <<fileline->ascii()<<": "<<hex;
- return(os);
-}
-
-bool FileLine::warnOff(const string& msg, bool flag) {
- V3ErrorCode code (msg.c_str());
- if (code < V3ErrorCode::EC_FIRST_WARN) {
- return false;
- } else if (v3Global.opt.lintOnly() // Lint mode is allowed to suppress some errors
- && code < V3ErrorCode::EC_MIN) {
- return false;
- } else {
- warnOff(code, flag);
- return true;
- }
-}
-
-void FileLine::warnLintOff(bool flag) {
- for (int codei=V3ErrorCode::EC_MIN; codei<V3ErrorCode::_ENUM_MAX; codei++) {
- V3ErrorCode code = (V3ErrorCode)codei;
- if (code.lintError()) warnOff(code, flag);
- }
-}
-
-void FileLine::warnStyleOff(bool flag) {
- for (int codei=V3ErrorCode::EC_MIN; codei<V3ErrorCode::_ENUM_MAX; codei++) {
- V3ErrorCode code = (V3ErrorCode)codei;
- if (code.styleError()) warnOff(code, flag);
- }
-}
-
-bool FileLine::warnIsOff(V3ErrorCode code) const {
- if (!m_warnOn.test(code)) return true;
- if (!defaultFileLine().m_warnOn.test(code)) return true; // Global overrides local
- // UNOPTFLAT implies UNOPT
- if (code==V3ErrorCode::UNOPT && !m_warnOn.test(V3ErrorCode::UNOPTFLAT)) return true;
- if ((code.lintError() || code.styleError()) && !m_warnOn.test(V3ErrorCode::I_LINT)) return true;
- return false;
-}
-
-void FileLine::modifyStateInherit(const FileLine* fromp) {
- // Any warnings that are off in "from", become off in "this".
- for (int codei=V3ErrorCode::EC_MIN; codei<V3ErrorCode::_ENUM_MAX; codei++) {
- V3ErrorCode code = (V3ErrorCode)codei;
- if (fromp->warnIsOff(code)) {
- this->warnOff(code, true);
- }
- }
-}
-
-void FileLine::v3errorEnd(ostringstream& str) {
- if (this && m_lineno) {
- ostringstream nsstr;
- nsstr<<this<<str.str();
- if (warnIsOff(V3Error::errorCode())) V3Error::suppressThisWarning();
- V3Error::v3errorEnd(nsstr);
- } else {
- V3Error::v3errorEnd(str);
- }
-}
-
-string FileLine::warnMore() const {
- if (this && m_lineno) {
- return V3Error::warnMore()+ascii()+": ";
- } else {
- return V3Error::warnMore();
- }
-}
-
-#ifdef VL_LEAK_CHECKS
-typedef set<FileLine*> FileLineCheckSet;
-FileLineCheckSet fileLineLeakChecks;
-
-void* FileLine::operator new(size_t size) {
- FileLine* objp = static_cast<FileLine*>(::operator new(size));
- fileLineLeakChecks.insert(objp);
- return objp;
-}
-
-void FileLine::operator delete(void* objp, size_t size) {
- if (!objp) return;
- FileLine* flp = static_cast<FileLine*>(objp);
- FileLineCheckSet::iterator it = fileLineLeakChecks.find(flp);
- if (it != fileLineLeakChecks.end()) {
- fileLineLeakChecks.erase(it);
- } else {
- flp->v3fatalSrc("Deleting FileLine object that was never tracked\n");
- }
- ::operator delete(objp);
-}
-#endif
-
-void FileLine::deleteAllRemaining() {
-#ifdef VL_LEAK_CHECKS
- // FileLines are allocated, but never nicely freed, as it's much faster
- // that way. Unfortunately this makes our leak checking a big mess, so
- // only when leak checking we'll track them all and cleanup.
- while (1) {
- FileLineCheckSet::iterator it=fileLineLeakChecks.begin();
- if (it==fileLineLeakChecks.end()) break;
- delete *it;
- // Operator delete will remove the iterated object from the list.
- // Eventually the list will be empty and terminate the loop.
- }
- fileLineLeakChecks.clear();
- singleton().clear();
-#endif
-}
-
-//######################################################################
// V3Error class functions
void V3Error::init() {
@@ -354,26 +91,15 @@ string V3Error::lineStr (const char* filename, int lineno) {
return out.str();
}
-void V3Error::incWarnings() {
- s_warnCount++;
- // We don't exit on a lot of warnings.
-}
-
void V3Error::incErrors() {
s_errCount++;
- if (errorCount() == v3Global.opt.errorLimit()) { // Not >= as would otherwise recurse
+ if (errorCount() == errorLimit()) { // Not >= as would otherwise recurse
v3fatal ("Exiting due to too many errors encountered; --error-limit="<<errorCount()<<endl);
}
}
-void V3Error::abortIfErrors() {
- if (errorCount()) {
- abortIfWarnings();
- }
-}
-
void V3Error::abortIfWarnings() {
- bool exwarn = v3Global.opt.warnFatal() && warnCount();
+ bool exwarn = warnFatal() && warnCount();
if (errorCount() && exwarn) {
v3fatal ("Exiting due to "<<dec<<errorCount()<<" error(s), "<<warnCount()<<" warning(s)\n");
} else if (errorCount()) {
@@ -423,7 +149,9 @@ void V3Error::vlAbort () {
void V3Error::suppressThisWarning() {
if (s_errorCode>=V3ErrorCode::EC_MIN) {
+#ifndef _V3ERROR_NO_GLOBAL_
V3Stats::addStatSum(string("Warnings, Suppressed ")+s_errorCode.ascii(), 1);
+#endif
s_errorSuppressed = true;
}
}
diff --git a/src/V3Error.h b/src/V3Error.h
index 441a791..2e810ec 100644
--- a/src/V3Error.h
+++ b/src/V3Error.h
@@ -30,8 +30,6 @@
#include <set>
#include <deque>
-#include "V3LangCode.h"
-
//######################################################################
class V3ErrorCode {
@@ -191,9 +189,11 @@ class V3Error {
static bool s_describedWarnings; // Told user how to disable warns
static bool s_describedEachWarn[V3ErrorCode::_ENUM_MAX]; // Told user specifics about this warning
static bool s_pretendError[V3ErrorCode::_ENUM_MAX]; // Pretend this warning is an error
- static int s_debugDefault; // Default debugging level
+ static int s_debugDefault; // Option: --debugi Default debugging level
+ static int s_errorLimit; // Option: --error-limit Number of errors before exit
+ static bool s_warnFatal; // Option: --warnFatal Warnings are fatal
static int s_errCount; // Error count
- static int s_warnCount; // Error count
+ static int s_warnCount; // Warning count
static int s_tellManual; // Tell user to see manual, 0=not yet, 1=doit, 2=disable
static ostringstream s_errorStr; // Error string being formed
static V3ErrorCode s_errorCode; // Error string being formed will abort
@@ -210,15 +210,19 @@ class V3Error {
// ACCESSORS
static void debugDefault(int level) { s_debugDefault = level; }
static int debugDefault() { return s_debugDefault; }
+ static void errorLimit(int level) { s_errorLimit = level; }
+ static int errorLimit() { return s_errorLimit; }
+ static void warnFatal(bool flag) { s_warnFatal = flag; }
+ static bool warnFatal() { return s_warnFatal; }
static string msgPrefix(); // returns %Error/%Warn
static int errorCount() { return s_errCount; }
static int warnCount() { return s_warnCount; }
static int errorOrWarnCount() { return errorCount()+warnCount(); }
// METHODS
static void incErrors();
- static void incWarnings();
+ static void incWarnings() { s_warnCount++; }
static void init();
- static void abortIfErrors();
+ static void abortIfErrors() { if (errorCount()) abortIfWarnings(); }
static void abortIfWarnings();
static void suppressThisWarning(); // Suppress next %Warn if user has it off
static void pretendError(V3ErrorCode code, bool flag) { s_pretendError[code]=flag; }
@@ -243,7 +247,7 @@ class V3Error {
inline int debug() { return V3Error::debugDefault(); }
inline void v3errorEnd(ostringstream& sstr) { V3Error::v3errorEnd(sstr); }
-// These allow errors using << operators: v3error("foo"<<"bar");
+// Theses allow errors using << operators: v3error("foo"<<"bar");
// Careful, you can't put () around msg, as you would in most macro definitions
// Note the commas are the comma operator, not separating arguments. These are needed to insure
// evaluation order as otherwise we couldn't insure v3errorPrep is called first.
@@ -285,140 +289,4 @@ inline string ucfirst(const string& text) {
return out;
}
-//######################################################################
-
-class FileLine;
-
-//! Singleton class with tables of per-file data.
-
-//! This singleton class contains tables of data that are unchanging in each
-//! source file (each with its own unique filename number).
-class FileLineSingleton {
- // TYPES
- typedef map<string,int> FileNameNumMap;
- typedef map<string,V3LangCode> FileLangNumMap;
- // MEMBERS
- FileNameNumMap m_namemap; // filenameno for each filename
- deque<string> m_names; // filename text for each filenameno
- deque<V3LangCode> m_languages; // language for each filenameno
- // COSNTRUCTORS
- FileLineSingleton() { }
- ~FileLineSingleton() { }
-protected:
- friend class FileLine;
- // METHODS
- int nameToNumber(const string& filename);
- const string numberToName(int filenameno) const { return m_names[filenameno]; }
- const V3LangCode numberToLang(int filenameno) const { return m_languages[filenameno]; }
- void numberToLang(int filenameno, const V3LangCode& l) { m_languages[filenameno] = l; }
- void clear() { m_namemap.clear(); m_names.clear(); m_languages.clear(); }
- void fileNameNumMapDumpXml(ostream& os);
- static const string filenameLetters(int fileno);
-};
-
-//! File and line number of an object, mostly for error reporting
-
-//! This class is instantiated for every source code line (potentially
-//! millions). To save space, per-file information (e.g. filename, source
-//! language is held in tables in the FileLineSingleton class.
-class FileLine {
- int m_lineno;
- int m_filenameno;
- bitset<V3ErrorCode::_ENUM_MAX> m_warnOn;
-
-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 language (V3LangCode lang) { singleton().numberToLang(m_filenameno, lang); }
- 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_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); }
- FileLine* create(int lineno) { return create(filename(), lineno); }
- static void deleteAllRemaining();
-#ifdef VL_LEAK_CHECKS
- static void* operator new(size_t size);
- static void operator delete(void* obj, size_t size);
-#endif
-
- int lineno () const { return m_lineno; }
- V3LangCode language () const { return singleton().numberToLang(m_filenameno); }
- void updateLanguage ();
- string ascii() const;
- const string filename () const { return singleton().numberToName(m_filenameno); }
- const string filenameLetters() const { return singleton().filenameLetters(m_filenameno); }
- const string filebasename () const;
- const string filebasenameNoExt () const;
- const string profileFuncname() const;
- const string xml() const { return "fl=\""+filenameLetters()+cvtToStr(lineno())+"\""; }
- string lineDirectiveStrg(int enter_exit_level) const;
- void warnOn(V3ErrorCode code, bool flag) { m_warnOn.set(code,flag); } // Turn on/off warning messages on this line.
- void warnOff(V3ErrorCode code, bool flag) { warnOn(code,!flag); }
- bool warnOff(const string& code, bool flag); // Returns 1 if ok
- bool warnIsOff(V3ErrorCode code) const;
- void warnLintOff(bool flag);
- void warnStyleOff(bool flag);
- void warnStateFrom(const FileLine& from) { m_warnOn=from.m_warnOn; }
- void warnResetDefault() { warnStateFrom(defaultFileLine()); }
-
- // Specific flag ACCESSORS/METHODS
- bool coverageOn() const { return m_warnOn.test(V3ErrorCode::I_COVERAGE); }
- void coverageOn(bool flag) { warnOn(V3ErrorCode::I_COVERAGE,flag); }
- bool tracingOn() const { return m_warnOn.test(V3ErrorCode::I_TRACING); }
- void tracingOn(bool flag) { warnOn(V3ErrorCode::I_TRACING,flag); }
-
- // METHODS - Global
- 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); }
- static void fileNameNumMapDumpXml(ostream& os) {
- singleton().fileNameNumMapDumpXml(os); }
-
- // METHODS - Called from netlist
- // Merge warning disables from another fileline
- void modifyStateInherit(const FileLine* fromp);
- // Change the current fileline due to actions discovered after parsing
- // and may have side effects on other nodes sharing this FileLine.
- // Use only when this is intended
- void modifyWarnOff(V3ErrorCode code, bool flag) { warnOff(code,flag); }
-
- // OPERATORS
- void v3errorEnd(ostringstream& str);
- string warnMore() const;
- 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);
-
#endif // Guard
diff --git a/src/V3File.cpp b/src/V3File.cpp
index aad16a6..0247b73 100644
--- a/src/V3File.cpp
+++ b/src/V3File.cpp
@@ -757,7 +757,7 @@ void V3OutFormatter::putsQuoted(const char* strg) {
// Quote \ and " for use inside C programs
// Don't use to quote a filename for #include - #include doesn't \ escape.
putcNoTracking('"');
- string quoted = AstNode::quoteName(strg);
+ string quoted = V3Number::quoteNameControls(strg);
for (const char* cp=quoted.c_str(); *cp; cp++) {
putcNoTracking (*cp);
}
diff --git a/src/V3Error.cpp b/src/V3FileLine.cpp
similarity index 56%
copy from src/V3Error.cpp
copy to src/V3FileLine.cpp
index 8eb7c56..7286a59 100644
--- a/src/V3Error.cpp
+++ b/src/V3FileLine.cpp
@@ -23,6 +23,7 @@
#include <cstring>
#include <set>
#include "V3Error.h"
+#include "V3FileLine.h"
#ifndef _V3ERROR_NO_GLOBAL_
# include "V3Ast.h"
# include "V3Global.h"
@@ -30,41 +31,6 @@
# include "V3Config.h"
#endif
-//======================================================================
-// Statics
-
-int V3Error::s_errCount = 0;
-int V3Error::s_warnCount = 0;
-int V3Error::s_debugDefault = 0;
-int V3Error::s_tellManual = 0;
-ostringstream V3Error::s_errorStr; // Error string being formed
-V3ErrorCode V3Error::s_errorCode = V3ErrorCode::EC_FATAL;
-bool V3Error::s_errorSuppressed = false;
-bool V3Error::s_describedEachWarn[V3ErrorCode::_ENUM_MAX];
-bool V3Error::s_describedWarnings = false;
-bool V3Error::s_pretendError[V3ErrorCode::_ENUM_MAX];
-V3Error::MessagesSet V3Error::s_messages;
-V3Error::ErrorExitCb V3Error::s_errorExitCb = NULL;
-
-struct v3errorIniter {
- v3errorIniter() { V3Error::init(); }
-};
-v3errorIniter v3errorInit;
-
-//######################################################################
-// ErrorCode class functions
-
-V3ErrorCode::V3ErrorCode(const char* msgp) {
- // Return error encoding for given string, or ERROR, which is a bad code
- for (int codei=V3ErrorCode::EC_MIN; codei<V3ErrorCode::_ENUM_MAX; codei++) {
- V3ErrorCode code = (V3ErrorCode)codei;
- if (0==strcasecmp(msgp,code.ascii())) {
- m_e = code; return;
- }
- }
- m_e = V3ErrorCode::EC_ERROR;
-}
-
//######################################################################
// FileLineSingleton class functions
@@ -182,10 +148,6 @@ FileLine* FileLine::copyOrSameFileLine() {
return newp;
}
-void FileLine::updateLanguage () {
- language(v3Global.opt.fileLanguage(filename()));
-}
-
const string FileLine::filebasename() const {
string name = filename();
string::size_type pos;
@@ -228,9 +190,11 @@ bool FileLine::warnOff(const string& msg, bool flag) {
V3ErrorCode code (msg.c_str());
if (code < V3ErrorCode::EC_FIRST_WARN) {
return false;
+#ifndef _V3ERROR_NO_GLOBAL_
} else if (v3Global.opt.lintOnly() // Lint mode is allowed to suppress some errors
&& code < V3ErrorCode::EC_MIN) {
return false;
+#endif
} else {
warnOff(code, flag);
return true;
@@ -328,176 +292,3 @@ void FileLine::deleteAllRemaining() {
singleton().clear();
#endif
}
-
-//######################################################################
-// V3Error class functions
-
-void V3Error::init() {
- for (int i=0; i<V3ErrorCode::_ENUM_MAX; i++) {
- s_describedEachWarn[i] = false;
- s_pretendError[i] = V3ErrorCode(i).pretendError();
- }
-
- if (string(V3ErrorCode(V3ErrorCode::_ENUM_MAX).ascii()) != " MAX") {
- v3fatalSrc("Enum table in V3ErrorCode::EC_ascii() is munged");
- }
-}
-
-string V3Error::lineStr (const char* filename, int lineno) {
- ostringstream out;
- const char* fnslashp = strrchr (filename, '/');
- if (fnslashp) filename = fnslashp+1;
- out<<filename<<":"<<dec<<lineno<<":";
- const char* spaces = " ";
- size_t numsp = out.str().length(); if (numsp>20) numsp = 20;
- out<<(spaces + numsp);
- return out.str();
-}
-
-void V3Error::incWarnings() {
- s_warnCount++;
- // We don't exit on a lot of warnings.
-}
-
-void V3Error::incErrors() {
- s_errCount++;
- if (errorCount() == v3Global.opt.errorLimit()) { // Not >= as would otherwise recurse
- v3fatal ("Exiting due to too many errors encountered; --error-limit="<<errorCount()<<endl);
- }
-}
-
-void V3Error::abortIfErrors() {
- if (errorCount()) {
- abortIfWarnings();
- }
-}
-
-void V3Error::abortIfWarnings() {
- 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");
- }
-}
-
-bool V3Error::isError(V3ErrorCode code, bool supp) {
- if (supp) return false;
- else if (code==V3ErrorCode::EC_INFO) return false;
- else if (code==V3ErrorCode::EC_FATAL) return true;
- else if (code==V3ErrorCode::EC_FATALSRC) return true;
- else if (code==V3ErrorCode::EC_ERROR) return true;
- else if (code<V3ErrorCode::EC_FIRST_WARN
- || s_pretendError[code]) return true;
- else return false;
-}
-
-string V3Error::msgPrefix() {
- V3ErrorCode code=s_errorCode;
- bool supp=s_errorSuppressed;
- if (supp) return "-arning-suppressed: ";
- else if (code==V3ErrorCode::EC_INFO) return "-Info: ";
- else if (code==V3ErrorCode::EC_FATAL) return "%Error: ";
- else if (code==V3ErrorCode::EC_FATALSRC) return "%Error: Internal Error: ";
- else if (code==V3ErrorCode::EC_ERROR) return "%Error: ";
- else if (isError(code, supp)) return "%Error-"+(string)code.ascii()+": ";
- else return "%Warning-"+(string)code.ascii()+": ";
-}
-
-//======================================================================
-// Abort/exit
-
-void V3Error::vlAbort () {
- if (V3Error::debugDefault()) {
- cerr<<msgPrefix()<<"Aborting since under --debug"<<endl;
- abort();
- } else {
- exit(10);
- }
-}
-
-//======================================================================
-// Global Functions
-
-void V3Error::suppressThisWarning() {
- if (s_errorCode>=V3ErrorCode::EC_MIN) {
- V3Stats::addStatSum(string("Warnings, Suppressed ")+s_errorCode.ascii(), 1);
- s_errorSuppressed = true;
- }
-}
-
-string V3Error::warnMore() {
- return msgPrefix();
-}
-
-void V3Error::v3errorEnd (ostringstream& sstr) {
-#if defined(__COVERITY__) || defined(__cppcheck__)
- if (s_errorCode==V3ErrorCode::EC_FATAL) __coverity_panic__(x);
-#endif
- // Skip suppressed messages
- if (s_errorSuppressed
- // On debug, show only non default-off warning to prevent pages of warnings
- && (!debug() || s_errorCode.defaultsOff())) return;
- string msg = msgPrefix()+sstr.str();
- if (msg[msg.length()-1] != '\n') msg += '\n';
- // Suppress duplicates
- if (s_messages.find(msg) != s_messages.end()) return;
- s_messages.insert(msg);
- // Output
- cerr<<msg;
- if (!s_errorSuppressed && s_errorCode!=V3ErrorCode::EC_INFO) {
- if (!s_describedEachWarn[s_errorCode]
- && !s_pretendError[s_errorCode]) {
- s_describedEachWarn[s_errorCode] = true;
- if (s_errorCode>=V3ErrorCode::EC_FIRST_WARN && !s_describedWarnings) {
- cerr<<msgPrefix()<<"Use \"/* verilator lint_off "<<s_errorCode.ascii()
- <<" */\" and lint_on around source to disable this message."<<endl;
- s_describedWarnings = true;
- }
- if (s_errorCode.dangerous()) {
- cerr<<msgPrefix()<<"*** See the manual before disabling this,"<<endl;
- cerr<<msgPrefix()<<"else you may end up with different sim results."<<endl;
- }
- }
- // If first warning is not the user's fault (internal/unsupported) then give the website
- // Not later warnings, as a internal may be caused by an earlier problem
- if (s_tellManual == 0) {
- if (s_errorCode.mentionManual()
- || sstr.str().find("Unsupported") != string::npos) {
- s_tellManual = 1;
- } else {
- s_tellManual = 2;
- }
- }
- if (isError(s_errorCode, s_errorSuppressed)) incErrors();
- else incWarnings();
- if (s_errorCode==V3ErrorCode::EC_FATAL
- || s_errorCode==V3ErrorCode::EC_FATALSRC) {
- static bool inFatal = false;
- if (!inFatal) {
- inFatal = true;
- if (s_tellManual==1) {
- cerr<<msgPrefix()<<"See the manual and http://www.veripool.org/verilator for more assistance."<<endl;
- s_tellManual = 2;
- }
-#ifndef _V3ERROR_NO_GLOBAL_
- if (debug()) {
- v3Global.rootp()->dumpTreeFile(v3Global.debugFilename("final.tree",990));
- if (s_errorExitCb) s_errorExitCb();
- V3Stats::statsFinalAll(v3Global.rootp());
- V3Stats::statsReport();
- }
-#endif
- }
-
- vlAbort();
- }
- else if (isError(s_errorCode, s_errorSuppressed)) {
- // We don't dump tree on any error because a Visitor may be in middle of
- // a tree cleanup and cause a false broken problem.
- if (s_errorExitCb) s_errorExitCb();
- }
- }
-}
diff --git a/src/V3FileLine.h b/src/V3FileLine.h
new file mode 100644
index 0000000..93d1144
--- /dev/null
+++ b/src/V3FileLine.h
@@ -0,0 +1,171 @@
+// -*- mode: C++; c-file-style: "cc-mode" -*-
+//*************************************************************************
+// DESCRIPTION: Verilator: Error handling
+//
+// Code available from: http://www.veripool.org/verilator
+//
+//*************************************************************************
+//
+// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
+// redistribute it and/or modify it under the terms of either the GNU
+// Lesser General Public License Version 3 or the Perl Artistic License
+// Version 2.0.
+//
+// Verilator is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+//*************************************************************************
+
+#ifndef _V3FileLine_H_
+#define _V3FileLine_H_ 1
+#include "config_build.h"
+#include "verilatedos.h"
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <bitset>
+#include <map>
+#include <set>
+#include <deque>
+
+#include "V3Error.h"
+#include "V3LangCode.h"
+
+//######################################################################
+
+class FileLine;
+
+//! Singleton class with tables of per-file data.
+
+//! This singleton class contains tables of data that are unchanging in each
+//! source file (each with its own unique filename number).
+class FileLineSingleton {
+ // TYPES
+ typedef map<string,int> FileNameNumMap;
+ typedef map<string,V3LangCode> FileLangNumMap;
+ // MEMBERS
+ FileNameNumMap m_namemap; // filenameno for each filename
+ deque<string> m_names; // filename text for each filenameno
+ deque<V3LangCode> m_languages; // language for each filenameno
+ // COSNTRUCTORS
+ FileLineSingleton() { }
+ ~FileLineSingleton() { }
+protected:
+ friend class FileLine;
+ // METHODS
+ int nameToNumber(const string& filename);
+ const string numberToName(int filenameno) const { return m_names[filenameno]; }
+ const V3LangCode numberToLang(int filenameno) const { return m_languages[filenameno]; }
+ void numberToLang(int filenameno, const V3LangCode& l) { m_languages[filenameno] = l; }
+ void clear() { m_namemap.clear(); m_names.clear(); m_languages.clear(); }
+ void fileNameNumMapDumpXml(ostream& os);
+ static const string filenameLetters(int fileno);
+};
+
+//! File and line number of an object, mostly for error reporting
+
+//! This class is instantiated for every source code line (potentially
+//! millions). To save space, per-file information (e.g. filename, source
+//! language is held in tables in the FileLineSingleton class.
+class FileLine {
+ int m_lineno;
+ int m_filenameno;
+ bitset<V3ErrorCode::_ENUM_MAX> m_warnOn;
+
+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 language (V3LangCode lang) { singleton().numberToLang(m_filenameno, lang); }
+ 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_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); }
+ FileLine* create(int lineno) { return create(filename(), lineno); }
+ static void deleteAllRemaining();
+#ifdef VL_LEAK_CHECKS
+ static void* operator new(size_t size);
+ static void operator delete(void* obj, size_t size);
+#endif
+
+ int lineno () const { return m_lineno; }
+ V3LangCode language () const { return singleton().numberToLang(m_filenameno); }
+ string ascii() const;
+ const string filename () const { return singleton().numberToName(m_filenameno); }
+ const string filenameLetters() const { return singleton().filenameLetters(m_filenameno); }
+ const string filebasename () const;
+ const string filebasenameNoExt () const;
+ const string profileFuncname() const;
+ const string xml() const { return "fl=\""+filenameLetters()+cvtToStr(lineno())+"\""; }
+ string lineDirectiveStrg(int enter_exit_level) const;
+ void warnOn(V3ErrorCode code, bool flag) { m_warnOn.set(code,flag); } // Turn on/off warning messages on this line.
+ void warnOff(V3ErrorCode code, bool flag) { warnOn(code,!flag); }
+ bool warnOff(const string& code, bool flag); // Returns 1 if ok
+ bool warnIsOff(V3ErrorCode code) const;
+ void warnLintOff(bool flag);
+ void warnStyleOff(bool flag);
+ void warnStateFrom(const FileLine& from) { m_warnOn=from.m_warnOn; }
+ void warnResetDefault() { warnStateFrom(defaultFileLine()); }
+
+ // Specific flag ACCESSORS/METHODS
+ bool coverageOn() const { return m_warnOn.test(V3ErrorCode::I_COVERAGE); }
+ void coverageOn(bool flag) { warnOn(V3ErrorCode::I_COVERAGE,flag); }
+ bool tracingOn() const { return m_warnOn.test(V3ErrorCode::I_TRACING); }
+ void tracingOn(bool flag) { warnOn(V3ErrorCode::I_TRACING,flag); }
+
+ // METHODS - Global
+ 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); }
+ static void fileNameNumMapDumpXml(ostream& os) {
+ singleton().fileNameNumMapDumpXml(os); }
+
+ // METHODS - Called from netlist
+ // Merge warning disables from another fileline
+ void modifyStateInherit(const FileLine* fromp);
+ // Change the current fileline due to actions discovered after parsing
+ // and may have side effects on other nodes sharing this FileLine.
+ // Use only when this is intended
+ void modifyWarnOff(V3ErrorCode code, bool flag) { warnOff(code,flag); }
+
+ // OPERATORS
+ void v3errorEnd(ostringstream& str);
+ string warnMore() const;
+ 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);
+
+#endif // Guard
diff --git a/src/V3Global.h b/src/V3Global.h
index af98327..a4b4fac 100644
--- a/src/V3Global.h
+++ b/src/V3Global.h
@@ -26,6 +26,7 @@
#include <string>
#include "V3Error.h"
+#include "V3FileLine.h"
#include "V3Options.h"
class AstNetlist;
diff --git a/src/V3LinkDot.cpp b/src/V3LinkDot.cpp
index 82b0937..204d29b 100644
--- a/src/V3LinkDot.cpp
+++ b/src/V3LinkDot.cpp
@@ -1805,6 +1805,15 @@ private:
// EnumItemRef may be under a dot. Should already be resolved.
nodep->iterateChildren(*this);
}
+ virtual void visit(AstMethodSel* nodep, AstNUser*) {
+ // Created here so should already be resolved.
+ DotStates lastStates = m_ds;
+ {
+ m_ds.init(m_curSymp);
+ nodep->iterateChildren(*this);
+ }
+ m_ds = lastStates;
+ }
virtual void visit(AstVar* nodep, AstNUser*) {
checkNoDot(nodep);
nodep->iterateChildren(*this);
@@ -1823,6 +1832,14 @@ private:
m_ds.m_dotp = NULL;
} else if (m_ds.m_dotp && m_ds.m_dotPos == DP_FINAL) {
nodep->dotted(m_ds.m_dotText); // Maybe ""
+ } else if (m_ds.m_dotp && m_ds.m_dotPos == DP_MEMBER) {
+ // Found a Var, everything following is method call. {scope}.{var}.HERE {method} ( ARGS )
+ AstNode* varEtcp = m_ds.m_dotp->lhsp()->unlinkFrBack();
+ AstNode* argsp = NULL; if (nodep->pinsp()) argsp = nodep->pinsp()->unlinkFrBackWithNext();
+ AstNode* newp = new AstMethodSel(nodep->fileline(), varEtcp, VFlagChildDType(), nodep->name(), argsp);
+ nodep->replaceWith(newp);
+ pushDeletep(nodep); nodep=NULL;
+ return;
} else {
checkNoDot(nodep);
}
diff --git a/src/V3LinkLevel.cpp b/src/V3LinkLevel.cpp
index 3b924c7..9d9c393 100644
--- a/src/V3LinkLevel.cpp
+++ b/src/V3LinkLevel.cpp
@@ -130,7 +130,12 @@ void V3LinkLevel::wrapTopCell(AstNetlist* netlistp) {
oldvarp->primaryIO(true);
varp->primaryIO(true);
}
- if (varp->isIO() && v3Global.opt.systemC()) varp->sc(true);
+ if (varp->isIO() && v3Global.opt.systemC()) {
+ varp->sc(true);
+ // User can see trace one level down from the wrapper
+ // Avoids packing & unpacking SC signals a second time
+ varp->trace(false);
+ }
AstPin* pinp = new AstPin(oldvarp->fileline(),0,oldvarp->name(),
new AstVarRef(varp->fileline(),
diff --git a/src/V3Number.cpp b/src/V3Number.cpp
index 79c6814..73606a7 100644
--- a/src/V3Number.cpp
+++ b/src/V3Number.cpp
@@ -34,7 +34,7 @@
// Read class functions
// CREATION
-V3Number::V3Number(VerilogString, FileLine* fileline, const string& str) {
+V3Number::V3Number(VerilogStringLiteral, 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
@@ -365,6 +365,8 @@ string V3Number::ascii(bool prefixed, bool cleanVerilog) const {
if (width()!=64) out<<"%E-bad-width-double";
else out<<toDouble();
return out.str();
+ } else if (isString()) {
+ return '"'+toString()+'"';
} else {
if ((m_value[words()-1] | m_valueX[words()-1]) & ~hiWordMask()) out<<"%E-hidden-bits";
}
@@ -404,6 +406,31 @@ string V3Number::ascii(bool prefixed, bool cleanVerilog) const {
return out.str();
}
+string V3Number::quoteNameControls(const string& namein) {
+ // Encode control chars into C style escapes
+ // Reverse is V3Parse::deQuote
+ const char* start = namein.c_str();
+ string out;
+ for (const char* pos = start; *pos; pos++) {
+ if (pos[0]=='\\' || pos[0]=='"') {
+ out += string("\\")+pos[0];
+ } else if (pos[0]=='\n') {
+ out += "\\n";
+ } else if (pos[0]=='\r') {
+ out += "\\r";
+ } else if (pos[0]=='\t') {
+ out += "\\t";
+ } else if (isprint(pos[0])) {
+ out += pos[0];
+ } else {
+ // This will also cover \a etc
+ char octal[10]; sprintf(octal,"\\%03o",pos[0]);
+ out += octal;
+ }
+ }
+ return out;
+}
+
bool V3Number::displayedFmtLegal(char format) {
// Is this a valid format letter?
switch (tolower(format)) {
@@ -418,6 +445,7 @@ bool V3Number::displayedFmtLegal(char format) {
case 's': return true;
case 't': return true;
case 'x': return true;
+ case '@': return true; // Packed string
case '~': return true; // Signed decimal
default: return false;
}
@@ -473,6 +501,9 @@ string V3Number::displayed(const string& vformat) const {
str += (char)(v);
return str;
}
+ case '@': { // Packed string
+ return toString();
+ }
case 's': {
// Spec says always drop leading zeros, this isn't quite right, we space pad.
int bit=this->width()-1;
@@ -581,6 +612,7 @@ vlsint64_t V3Number::toSQuad() const {
string V3Number::toString() const {
UASSERT(!isFourState(),"toString with 4-state "<<*this);
// Spec says always drop leading zeros, this isn't quite right, we space pad.
+ if (isString()) return m_stringVal;
int bit=this->width()-1;
bool start=true;
while ((bit%8)!=7) bit++;
@@ -1626,3 +1658,38 @@ V3Number& V3Number::opLtD (const V3Number& lhs, const V3Number& rhs) {
V3Number& V3Number::opLteD (const V3Number& lhs, const V3Number& rhs) {
return setSingleBits(lhs.toDouble() <= rhs.toDouble());
}
+
+//======================================================================
+// Ops - String
+
+V3Number& V3Number::opConcatN (const V3Number& lhs, const V3Number& rhs) {
+ return setString(lhs.toString() + rhs.toString());
+}
+V3Number& V3Number::opReplN (const V3Number& lhs, const V3Number& rhs) {
+ return opReplN(lhs, rhs.toUInt());
+}
+V3Number& V3Number::opReplN (const V3Number& lhs, uint32_t rhsval) {
+ string out; out.reserve(lhs.toString().length() * rhsval);
+ for (unsigned times=0; times<rhsval; times++) {
+ out += lhs.toString();
+ }
+ return setString(out);
+}
+V3Number& V3Number::opEqN (const V3Number& lhs, const V3Number& rhs) {
+ return setSingleBits(lhs.toString() == rhs.toString());
+}
+V3Number& V3Number::opNeqN (const V3Number& lhs, const V3Number& rhs) {
+ return setSingleBits(lhs.toString() != rhs.toString());
+}
+V3Number& V3Number::opGtN (const V3Number& lhs, const V3Number& rhs) {
+ return setSingleBits(lhs.toString() > rhs.toString());
+}
+V3Number& V3Number::opGteN (const V3Number& lhs, const V3Number& rhs) {
+ return setSingleBits(lhs.toString() >= rhs.toString());
+}
+V3Number& V3Number::opLtN (const V3Number& lhs, const V3Number& rhs) {
+ return setSingleBits(lhs.toString() < rhs.toString());
+}
+V3Number& V3Number::opLteN (const V3Number& lhs, const V3Number& rhs) {
+ return setSingleBits(lhs.toString() <= rhs.toString());
+}
diff --git a/src/V3Number.h b/src/V3Number.h
index c6bfd53..e002eaa 100644
--- a/src/V3Number.h
+++ b/src/V3Number.h
@@ -25,6 +25,7 @@
#include <vector>
#include "V3Error.h"
+#include "V3FileLine.h"
//============================================================================
@@ -34,13 +35,16 @@ class V3Number {
bool m_sized:1; // True if the user specified the width, else we track it.
bool m_signed:1; // True if signed value
bool m_double:1; // True if double real value
- bool m_fromString:1; // True if from string
+ bool m_isString:1; // True if string
+ bool m_fromString:1; // True if from string literal
bool m_autoExtend:1; // True if SystemVerilog extend-to-any-width
FileLine* m_fileline;
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
+ string m_stringVal; // If isString, the value of the string
// METHODS
V3Number& setSingleBits(char value);
+ V3Number& setString(const string& str) { m_isString=true; m_stringVal=str; return *this; }
void opCleanThis();
public:
FileLine* fileline() const { return m_fileline; }
@@ -115,19 +119,22 @@ private:
V3Number& opModDivGuts(const V3Number& lhs, const V3Number& rhs, bool is_modulus);
public:
- class VerilogString {}; // for creator type-overload selection
// CONSTRUCTORS
V3Number(FileLine* fileline) { init(fileline, 1); }
V3Number(FileLine* fileline, int width) { init(fileline, width); } // 0=unsized
V3Number(FileLine* fileline, int width, uint32_t value) { init(fileline, width); m_value[0]=value; opCleanThis(); }
V3Number(FileLine* fileline, const char* source); // Create from a verilog 32'hxxxx number.
- V3Number(VerilogString, FileLine* fileline, const string& vvalue);
+ class VerilogStringLiteral {}; // for creator type-overload selection
+ V3Number(VerilogStringLiteral, FileLine* fileline, const string& vvalue);
+ class String {};
+ V3Number(String, FileLine* fileline, const string& value) { init(fileline, 0); setString(value); }
private:
void init(FileLine* fileline, int swidth) {
m_fileline = fileline;
m_signed = false;
m_double = false;
+ m_isString = false;
m_autoExtend = false;
m_fromString = false;
width(swidth);
@@ -154,6 +161,7 @@ public:
// ACCESSORS
string ascii(bool prefixed=true, bool cleanVerilog=false) const;
+ static string quoteNameControls(const string& namein); // Add backslash quotes to strings
string displayed(const string& format) const;
static bool displayedFmtLegal(char format); // Is this a valid format letter?
int width() const { return m_width; }
@@ -164,6 +172,8 @@ public:
bool isSigned() const { return m_signed; } // Only correct for parsing of numbers from strings, otherwise not used (use AstConst::isSigned())
bool isDouble() const { return m_double; } // Only correct for parsing of numbers from strings, otherwise not used (use AstConst::isSigned())
void isDouble(bool flag) { m_double=flag; } // Only if have 64 bit value loaded, and want to indicate it's real
+ bool isString() const { return m_isString; }
+ void isString(bool flag) { m_isString=flag; }
bool isNegative() const { return bitIs1(width()-1); }
bool isFourState() const { for (int i=0;i<words();i++) {if (m_valueX[i]) return true;} return false; }
bool hasZ() const { for(int i=0;i<words();i++) {if((~m_value[i]) & m_valueX[i]) return true;} return false;}
@@ -293,6 +303,17 @@ public:
V3Number& opGteD (const V3Number& lhs, const V3Number& rhs);
V3Number& opLtD (const V3Number& lhs, const V3Number& rhs);
V3Number& opLteD (const V3Number& lhs, const V3Number& rhs);
+
+ // "N" - string operations
+ V3Number& opConcatN (const V3Number& lhs, const V3Number& rhs);
+ V3Number& opReplN (const V3Number& lhs, const V3Number& rhs);
+ V3Number& opReplN (const V3Number& lhs, uint32_t rhs);
+ V3Number& opEqN (const V3Number& lhs, const V3Number& rhs);
+ V3Number& opNeqN (const V3Number& lhs, const V3Number& rhs);
+ V3Number& opGtN (const V3Number& lhs, const V3Number& rhs);
+ V3Number& opGteN (const V3Number& lhs, const V3Number& rhs);
+ V3Number& opLtN (const V3Number& lhs, const V3Number& rhs);
+ V3Number& opLteN (const V3Number& lhs, const V3Number& rhs);
};
inline ostream& operator<<(ostream& os, V3Number rhs) { return os<<rhs.ascii(); }
diff --git a/src/V3Number_test.cpp b/src/V3Number_test.cpp
index fe3321d..868ba32 100644
--- a/src/V3Number_test.cpp
+++ b/src/V3Number_test.cpp
@@ -22,6 +22,7 @@
#define V3NUMBER_ASCII_BINARY
#define _V3ERROR_NO_GLOBAL_ 1
#include "V3Error.cpp"
+#include "V3FileLine.cpp"
#include "V3Number.cpp"
#include <config_build.h>
diff --git a/src/V3Options.cpp b/src/V3Options.cpp
index a5b582d..3f81aeb 100644
--- a/src/V3Options.cpp
+++ b/src/V3Options.cpp
@@ -275,18 +275,18 @@ bool V3Options::filenameIsRel(const string& filename) {
}
bool V3Options::fileStatDir(const string& filename) {
- struct stat m_stat; // Stat information
- int err = stat(filename.c_str(), &m_stat);
+ struct stat sstat; // Stat information
+ int err = stat(filename.c_str(), &sstat);
if (err!=0) return false;
- if (!S_ISDIR(m_stat.st_mode)) return false;
+ if (!S_ISDIR(sstat.st_mode)) return false;
return true;
}
bool V3Options::fileStatNormal(const string& filename) {
- struct stat m_stat; // Stat information
- int err = stat(filename.c_str(), &m_stat);
+ struct stat sstat; // Stat information
+ int err = stat(filename.c_str(), &sstat);
if (err!=0) return false;
- if (S_ISDIR(m_stat.st_mode)) return false;
+ if (S_ISDIR(sstat.st_mode)) return false;
return true;
}
@@ -754,14 +754,14 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
else if ( onoff (sw, "-pins-uint8", flag/*ref*/) ){ m_pinsUint8 = flag; }
else if ( !strcmp (sw, "-private") ) { m_public = false; }
else if ( onoff (sw, "-profile-cfuncs", flag/*ref*/) ) { m_profileCFuncs = flag; }
- else if ( onoff (sw, "-psl-deprecated", flag/*ref*/) ) { m_psl = flag; } // Undocumented
else if ( onoff (sw, "-public", flag/*ref*/) ) { m_public = flag; }
else if ( onoff (sw, "-report-unoptflat", flag/*ref*/) ) { m_reportUnoptflat = flag; }
else if ( onoff (sw, "-savable", flag/*ref*/) ) { m_savable = flag; }
else if ( !strcmp (sw, "-sc") ) { m_outFormatOk = true; m_systemC = true; m_systemPerl = false; }
else if ( onoff (sw, "-skip-identical", flag/*ref*/) ) { m_skipIdentical = flag; }
- else if ( !strcmp (sw, "-sp") ) { m_outFormatOk = true; m_systemC = true; m_systemPerl = true; }
+ else if ( !strcmp (sw, "-sp-deprecated") ) { m_outFormatOk = true; m_systemC = true; m_systemPerl = true; } // Undocumented, old
else if ( onoff (sw, "-stats", flag/*ref*/) ) { m_stats = flag; }
+ else if ( onoff (sw, "-stats-vars", flag/*ref*/) ) { m_statsVars = flag; m_stats |= flag; }
else if ( !strcmp (sw, "-sv") ) { m_defaultLanguage = V3LangCode::L1800_2005; }
else if ( onoff (sw, "-trace", flag/*ref*/) ) { m_trace = flag; }
else if ( onoff (sw, "-trace-dups", flag/*ref*/) ) { m_traceDups = flag; }
@@ -833,7 +833,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
}
else if ( !strcmp (sw, "-error-limit") && (i+1)<argc ) {
shift;
- m_errorLimit = atoi(argv[i]);
+ V3Error::errorLimit(atoi(argv[i]));
}
else if ( !strncmp (sw, "-I", 2)) {
addIncDirUser (parseFileArg(optdir, string (sw+strlen("-I"))));
@@ -947,7 +947,7 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
FileLine::globalWarnStyleOff(true);
}
else if (!strcmp (sw, "-Wno-fatal")) {
- m_warnFatal = false;
+ V3Error::warnFatal(false);
}
else {
string msg = sw+strlen("-Wno-");
@@ -1221,16 +1221,15 @@ V3Options::V3Options() {
m_makePhony = false;
m_orderClockDly = true;
m_outFormatOk = false;
- m_warnFatal = true;
m_pinsBv = 65;
m_profileCFuncs = false;
m_preprocOnly = false;
m_preprocNoLine = false;
- m_psl = false;
m_public = false;
m_savable = false;
m_skipIdentical = true;
m_stats = false;
+ m_statsVars = false;
m_systemC = false;
m_systemPerl = false;
m_trace = false;
@@ -1245,7 +1244,6 @@ V3Options::V3Options() {
m_convergeLimit = 100;
m_dumpTree = 0;
- m_errorLimit = 50;
m_ifDepth = 0;
m_inlineMult = 2000;
m_outputSplit = 0;
diff --git a/src/V3Options.h b/src/V3Options.h
index 4e1c936..6eb2200 100644
--- a/src/V3Options.h
+++ b/src/V3Options.h
@@ -77,18 +77,17 @@ class V3Options {
bool m_lintOnly; // main switch: --lint-only
bool m_orderClockDly;// main switch: --order-clock-delay
bool m_outFormatOk; // main switch: --cc, --sc or --sp was specified
- bool m_warnFatal; // main switch: --warnFatal
bool m_pinsScUint; // main switch: --pins-sc-uint
bool m_pinsScBigUint;// main switch: --pins-sc-biguint
bool m_pinsUint8; // main switch: --pins-uint8
bool m_profileCFuncs;// main switch: --profile-cfuncs
- bool m_psl; // main switch: --psl
bool m_public; // main switch: --public
bool m_savable; // main switch: --savable
bool m_systemC; // main switch: --sc: System C instead of simple C++
bool m_skipIdentical;// main switch: --skip-identical
bool m_systemPerl; // main switch: --sp: System Perl instead of SystemC (m_systemC also set)
bool m_stats; // main switch: --stats
+ bool m_statsVars; // main switch: --stats-vars
bool m_trace; // main switch: --trace
bool m_traceDups; // main switch: --trace-dups
bool m_traceParams; // main switch: --trace-params
@@ -101,7 +100,6 @@ class V3Options {
int m_convergeLimit;// main switch: --converge-limit
int m_dumpTree; // main switch: --dump-tree
- int m_errorLimit; // main switch: --error-limit
int m_ifDepth; // main switch: --if-depth
int m_inlineMult; // main switch: --inline-mult
int m_outputSplit; // main switch: --output-split
@@ -201,10 +199,11 @@ class V3Options {
bool systemC() const { return m_systemC; }
bool systemPerl() const { return m_systemPerl; }
bool usingSystemCLibs() const { return !lintOnly() && (systemPerl() || systemC()); }
- bool usingSystemPerlLibs() const { return !lintOnly() && (systemPerl() || coverage()); }
+ bool usingSystemPerlLibs() const { return !lintOnly() && systemPerl(); }
bool savable() const { return m_savable; }
bool skipIdentical() const { return m_skipIdentical; }
bool stats() const { return m_stats; }
+ bool statsVars() const { return m_statsVars; }
bool assertOn() const { return m_assert; } // assertOn as __FILE__ may be defined
bool autoflush() const { return m_autoflush; }
bool bboxSys() const { return m_bboxSys; }
@@ -225,12 +224,10 @@ class V3Options {
bool orderClockDly() const { return m_orderClockDly; }
bool outFormatOk() const { return m_outFormatOk; }
bool keepTempFiles() const { return (V3Error::debugDefault()!=0); }
- bool warnFatal() const { return m_warnFatal; }
bool pinsScUint() const { return m_pinsScUint; }
bool pinsScBigUint() const { return m_pinsScBigUint; }
bool pinsUint8() const { return m_pinsUint8; }
bool profileCFuncs() const { return m_profileCFuncs; }
- bool psl() const { return m_psl; }
bool allPublic() const { return m_public; }
bool l2Name() const { return m_l2Name; }
bool lintOnly() const { return m_lintOnly; }
@@ -242,7 +239,6 @@ class V3Options {
int convergeLimit() const { return m_convergeLimit; }
int dumpTree() const { return m_dumpTree; }
- int errorLimit() const { return m_errorLimit; }
int ifDepth() const { return m_ifDepth; }
int inlineMult() const { return m_inlineMult; }
int outputSplit() const { return m_outputSplit; }
diff --git a/src/V3ParseImp.cpp b/src/V3ParseImp.cpp
index 48fb58b..819a743 100644
--- a/src/V3ParseImp.cpp
+++ b/src/V3ParseImp.cpp
@@ -104,7 +104,7 @@ void V3ParseImp::parseFile(FileLine* fileline, const string& modfilename, bool i
// of this source file is updated here, in case there have been any
// intervening +<lang>ext+ options since it was first ecountered.
FileLine *modfileline = new FileLine (modfilename, 0);
- modfileline->updateLanguage();
+ modfileline->language(v3Global.opt.fileLanguage(modfilename));
ppPushText((string)"`begin_keywords \""+modfileline->language().ascii()+"\"\n");
}
diff --git a/src/V3ParseImp.h b/src/V3ParseImp.h
index 84b9085..b439ca6 100644
--- a/src/V3ParseImp.h
+++ b/src/V3ParseImp.h
@@ -23,6 +23,7 @@
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
+#include "V3FileLine.h"
#include "V3Global.h"
#include "V3Parse.h"
#include "V3ParseSym.h"
@@ -131,7 +132,6 @@ public:
// Functions called by lex rules:
int yylexThis();
- static bool optPsl() { return v3Global.opt.psl(); }
static bool optFuture(const string& flag) { return v3Global.opt.isFuture(flag); }
void ppline (const char* text);
@@ -190,8 +190,6 @@ public:
// Interactions with lexer
void lexNew(int debug);
void lexDestroy();
- void stateExitPsl(); // Parser -> lexer communication
- void statePushVlg(); // Parser -> lexer communication
void statePop(); // Parser -> lexer communication
static int stateVerilogRecent(); // Parser -> lexer communication
int prevLexToken() { return m_prevLexToken; } // Parser -> lexer communication
diff --git a/src/V3ParseLex.cpp b/src/V3ParseLex.cpp
index 1379734..f412ae7 100644
--- a/src/V3ParseLex.cpp
+++ b/src/V3ParseLex.cpp
@@ -47,13 +47,6 @@ public:
V3Lexer() : V3LexerBase(NULL) {}
~V3Lexer() {}
// METHODS
- void stateExitPsl() {
- if (YY_START != PSL) yyerrorf("Internal error: Exiting PSL state when not in PSL state");
- yy_pop_state();
- }
- void statePushVlg() {
- yy_push_state(STATE_VERILOG_RECENT);
- }
void statePop() {
yy_pop_state();
}
@@ -65,8 +58,6 @@ public:
}
}
};
-void V3ParseImp::stateExitPsl() { parsep()->m_lexerp->stateExitPsl(); }
-void V3ParseImp::statePushVlg() { parsep()->m_lexerp->stateExitPsl(); }
void V3ParseImp::statePop() { parsep()->m_lexerp->statePop(); }
void V3ParseImp::unputString(const char* textp, size_t length) { parsep()->m_lexerp->unputString(textp, length); }
diff --git a/src/V3ParseSym.h b/src/V3ParseSym.h
index cb7d507..da68ddd 100644
--- a/src/V3ParseSym.h
+++ b/src/V3ParseSym.h
@@ -23,6 +23,7 @@
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
+#include "V3FileLine.h"
#include "V3Global.h"
#include "V3SymTable.h"
#include <deque>
diff --git a/src/V3PreLex.h b/src/V3PreLex.h
index 1c5cf17..589d8d2 100644
--- a/src/V3PreLex.h
+++ b/src/V3PreLex.h
@@ -31,6 +31,7 @@
#include <stack>
#include "V3Error.h"
+#include "V3FileLine.h"
//======================================================================
@@ -166,8 +167,6 @@ class V3PreLex {
// State from lexer
int m_formalLevel; // Parenthesis counting inside def formals
int m_parenLevel; // Parenthesis counting inside def args
- int m_pslParenLevel;// PSL Parenthesis (){} counting, so we can find final ;
- bool m_pslMoreNeeded;// Next // comment is really psl
bool m_defCmtSlash; // /*...*/ comment in define had \ ending
bool m_defQuote; // Definition value inside quote
string m_defValue; // Definition value being built.
@@ -186,8 +185,6 @@ class V3PreLex {
m_defCmtSlash = false;
m_tokFilelinep = filelinep;
m_enterExit = 0;
- m_pslParenLevel = 0;
- m_pslMoreNeeded = false;
initFirstBuffer(filelinep);
}
~V3PreLex() {
diff --git a/src/V3PreLex.l b/src/V3PreLex.l
index 58191a9..2592a29 100644
--- a/src/V3PreLex.l
+++ b/src/V3PreLex.l
@@ -42,24 +42,14 @@ void yyourtext(const char* textp, size_t size) { yytext=(char*)textp; yyleng=siz
// Prevent conflicts from perl version
static void linenoInc() {LEXP->linenoInc();}
-static bool optPsl() { return V3PreProc::optPsl(); }
static bool pedantic() { return LEXP->m_pedantic; }
static void yyerror(char* msg) { LEXP->curFilelinep()->v3error(msg); }
static void yyerrorf(const char* msg) { LEXP->curFilelinep()->v3error(msg); }
static void appendDefValue(const char* t, size_t l) { LEXP->appendDefValue(t,l); }
-static int pslParenLevel() { return LEXP->m_pslParenLevel; }
-static void pslParenLevelInc() { LEXP->m_pslParenLevel++; }
-static void pslParenLevelDec() { if (pslParenLevel()) LEXP->m_pslParenLevel--; }
-static bool pslMoreNeeded() { return LEXP->m_pslMoreNeeded; }
-static void pslMoreNeeded(bool flag) { LEXP->m_pslMoreNeeded = flag; }
/**********************************************************************/
%}
-%x PSLONEM
-%x PSLONEE
-%x PSLMULM
-%x PSLMUL1
%x CMTONEM
%x CMTBEGM
%x CMTMODE
@@ -86,7 +76,6 @@ symb ([a-zA-Z_][a-zA-Z0-9_$]*|\\[^ \t\f\r\n]+)
symbdef ([a-zA-Z_][a-zA-Z0-9_$]*|\\[^ \t\f\r\n`]+)
word [a-zA-Z0-9_]+
drop [\032]
-psl [p]sl
/**************************************************************/
%%
@@ -117,7 +106,7 @@ psl [p]sl
<INITIAL>"`error" { if (!pedantic()) return (VP_ERROR); else return(VP_DEFREF); }
/* Pass-through strings */
-<INITIAL,PSLMULM,PSLONEM>{quote} { yy_push_state(STRMODE); yymore(); }
+<INITIAL>{quote} { yy_push_state(STRMODE); yymore(); }
<STRMODE><<EOF>> { linenoInc(); yyerrorf("EOF in unterminated string"); yyleng=0; yyterminate(); }
<STRMODE>{crnl} { linenoInc(); yyerrorf("Unterminated string"); BEGIN(INITIAL); }
<STRMODE>{word} { yymore(); }
@@ -233,57 +222,36 @@ psl [p]sl
<ARGMODE>. { appendDefValue(yytext,yyleng); }
/* One line comments. */
-<INITIAL>"//"{ws}*{psl} { if (optPsl()) { pslMoreNeeded(true); yy_push_state(PSLONEM); return(VP_PSL); }
- else { yy_push_state(CMTONEM); yymore(); } }
<INITIAL>"//"{ws}*{crnl} { linenoInc(); yytext=(char*)"\n"; yyleng=1; return (VP_WHITE); }
-<INITIAL>"//" { if (pslMoreNeeded()) { pslMoreNeeded(true); yy_push_state(PSLONEM); return(VP_PSL); }
- else { yy_push_state(CMTONEM); yymore(); } }
+<INITIAL>"//" { yy_push_state(CMTONEM); yymore(); }
<CMTONEM>[^\n\r]* { yy_pop_state(); return (VP_COMMENT); }
- /* Psl oneline comments */
-<PSLONEM>[{(] { pslParenLevelInc(); return (VP_TEXT); }
-<PSLONEM>[})] { pslParenLevelDec(); return (VP_TEXT); }
-<PSLONEM>[;] { if (!pslParenLevel()) {BEGIN PSLONEE; pslMoreNeeded(false);} return (VP_TEXT); }
-<PSLONEM>{crnl} { linenoInc(); yy_pop_state(); yytext=(char*)"\n"; yyleng=1; return(VP_WHITE); }
-
- /* Completed psl oneline comments */
-<PSLONEE>{crnl} { linenoInc(); yy_pop_state(); yytext=(char*)"\n"; yyleng=1; return(VP_WHITE); }
-<PSLONEE>{ws}+ { yymore(); }
-<PSLONEE>. { yyerrorf("Unexpected text following psl assertion\n"); }
-
/* C-style comments. */
/**** See also DEFCMT */
- /* We distinguish between the start of a comment, and later, so we may find a "psl" prefix */
-<INITIAL>"/*" { yy_push_state(optPsl() ? CMTBEGM : CMTMODE); yymore(); }
-<CMTBEGM>{psl} { yyleng -= 3; BEGIN PSLMUL1; return (VP_COMMENT); }
+ /* We distinguish between the start of a comment, and later, to look for prefix comments (deprecated) */
+<INITIAL>"/*" { yy_push_state(CMTMODE); yymore(); }
<CMTBEGM>{ws}+ { yymore(); }
<CMTBEGM,CMTMODE>"*/" { yy_pop_state(); return(VP_COMMENT); }
<CMTBEGM,CMTMODE>{crnl} { linenoInc(); yymore(); }
<CMTBEGM,CMTMODE><<EOF>> { yyerrorf("EOF in '/* ... */' block comment\n"); yyleng=0; yyterminate(); }
<CMTMODE>{word} { yymore(); }
-<CMTBEGM>. { BEGIN CMTMODE; yymore(); } /* Non 'psl' beginning in comment */
+<CMTBEGM>. { BEGIN CMTMODE; yymore(); } /* beginning in comment */
<CMTMODE>. { yymore(); }
- /* Psl C-style comments. */
- /* EOFs are normal because / * `foo(..) * / hits a unputString EOF */
-<PSLMUL1>.|{crnl} { yyless(0); BEGIN PSLMULM; return(VP_PSL); }
-<PSLMULM>"*/" { yy_pop_state(); return(VP_COMMENT); }
-<PSLMULM>"//"[^\n\r]* { return (VP_COMMENT); } /* Comments inside block comments get literal inclusion (later removal) */
-
/* Define calls */
/* symbdef prevents normal lex rules from making `\`"foo a symbol {`"foo} instead of a BACKQUOTE */
-<INITIAL,PSLMULM,PSLONEM>"`"{symbdef} { return (VP_DEFREF); }
-<INITIAL,PSLMULM,PSLONEM>"`"{symbdef}`` { yyleng-=2; return (VP_DEFREF_JOIN); }
+<INITIAL>"`"{symbdef} { return (VP_DEFREF); }
+<INITIAL>"`"{symbdef}`` { yyleng-=2; return (VP_DEFREF_JOIN); }
/* Generics */
-<INITIAL,PSLMULM>{crnl} { linenoInc(); yytext=(char*)"\n"; yyleng=1; return(VP_WHITE); }
-<INITIAL,PSLMULM,PSLONEM><<EOF>> { yyterminate(); } /* A "normal" EOF */
-<INITIAL,PSLMULM,PSLONEM>{symb} { return (VP_SYMBOL); }
-<INITIAL,PSLMULM,PSLONEM>{symb}`` { yyleng-=2; return (VP_SYMBOL_JOIN); }
-<INITIAL,PSLMULM,PSLONEM>{wsn}+ { return (VP_WHITE); }
-<INITIAL,PSLMULM,PSLONEM>{drop} { }
-<INITIAL,PSLMULM,PSLONEM>[\r] { }
-<INITIAL,PSLMULM,PSLONEM>. { return (VP_TEXT); }
+<INITIAL>{crnl} { linenoInc(); yytext=(char*)"\n"; yyleng=1; return(VP_WHITE); }
+<INITIAL><<EOF>> { yyterminate(); } /* A "normal" EOF */
+<INITIAL>{symb} { return (VP_SYMBOL); }
+<INITIAL>{symb}`` { yyleng-=2; return (VP_SYMBOL_JOIN); }
+<INITIAL>{wsn}+ { return (VP_WHITE); }
+<INITIAL>{drop} { }
+<INITIAL>[\r] { }
+<INITIAL>. { return (VP_TEXT); }
%%
void V3PreLex::pushStateDefArg(int level) {
diff --git a/src/V3PreProc.cpp b/src/V3PreProc.cpp
index e5b7b16..f83e1d4 100644
--- a/src/V3PreProc.cpp
+++ b/src/V3PreProc.cpp
@@ -282,10 +282,6 @@ V3PreProc* V3PreProc::createPreProc(FileLine* fl) {
return preprocp;
}
-bool V3PreProc::optPsl() {
- return v3Global.opt.psl();
-}
-
//*************************************************************************
// Defines
@@ -483,7 +479,6 @@ const char* V3PreProcImp::tokenName(int tok) {
case VP_IFNDEF : return("IFNDEF");
case VP_INCLUDE : return("INCLUDE");
case VP_LINE : return("LINE");
- case VP_PSL : return("PSL");
case VP_STRIFY : return("STRIFY");
case VP_STRING : return("STRING");
case VP_SYMBOL : return("SYMBOL");
@@ -1103,7 +1098,7 @@ int V3PreProcImp::getStateToken() {
// Value of building argument is data before the lower defref
// we'll append it when we push the argument.
break;
- } else if (tok==VP_SYMBOL || tok==VP_STRING || VP_TEXT || VP_WHITE || VP_PSL) {
+ } else if (tok==VP_SYMBOL || tok==VP_STRING || VP_TEXT || VP_WHITE) {
string rtn; rtn.assign(yyourtext(),yyourleng());
refp->nextarg(refp->nextarg()+rtn);
goto next_tok;
@@ -1340,7 +1335,6 @@ int V3PreProcImp::getStateToken() {
goto next_tok;
case VP_SYMBOL:
case VP_STRING:
- case VP_PSL:
case VP_TEXT: {
m_defDepth = 0;
if (!m_off) return tok;
@@ -1436,9 +1430,6 @@ string V3PreProcImp::getline() {
}
gotEof = true;
}
- else if (tok==VP_PSL) {
- m_lineChars.append(" psl ");
- }
else {
m_lineChars.append(buf);
}
diff --git a/src/V3PreProc.h b/src/V3PreProc.h
index 9e47d3c..ff2feed 100644
--- a/src/V3PreProc.h
+++ b/src/V3PreProc.h
@@ -26,6 +26,7 @@
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
+#include "V3FileLine.h"
#include <string>
#include <map>
@@ -75,7 +76,6 @@ public:
return !(v3Global.opt.preprocOnly() && v3Global.opt.preprocNoLine());
}
static bool pedantic() { return false; } // Obey standard; Don't substitute `error
- static bool optPsl();
// CALLBACK METHODS
// This probably will want to be overridden for given child users of this class.
diff --git a/src/V3PreShell.h b/src/V3PreShell.h
index 42cbfd9..b59e2a5 100644
--- a/src/V3PreShell.h
+++ b/src/V3PreShell.h
@@ -24,6 +24,7 @@
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
+#include "V3FileLine.h"
class V3ParseImp;
class V3InFilter;
diff --git a/src/V3Premit.cpp b/src/V3Premit.cpp
index 1fe71fb..23e0c31 100644
--- a/src/V3Premit.cpp
+++ b/src/V3Premit.cpp
@@ -138,7 +138,7 @@ private:
//UINFO(9, " Detail stmtp="<<(m_stmtp?"Y":"N")<<" U="<<(nodep->user1()?"Y":"N")<<" IW "<<(nodep->isWide()?"Y":"N")<<endl);
if (m_stmtp
&& !nodep->user1()) { // Not already done
- if (nodep->isWide()) { // Else might be cell interconnect or something
+ if (nodep->isWide()) {
if (m_assignLhs) {
} else if (nodep->firstAbovep()
&& nodep->firstAbovep()->castNodeAssign()
@@ -148,7 +148,7 @@ private:
&& nodep->firstAbovep()->castArraySel()) { // ArraySel's are pointer refs, ignore
} else {
UINFO(4,"Cre Temp: "<<nodep<<endl);
- createDeepTemp(nodep);
+ createDeepTemp(nodep, false);
}
}
}
@@ -157,7 +157,7 @@ private:
AstVar* getBlockTemp(AstNode* nodep) {
string newvarname = ((string)"__Vtemp"+cvtToStr(m_modp->varNumGetInc()));
AstVar* varp = new AstVar (nodep->fileline(), AstVarType::STMTTEMP, newvarname,
- VFlagLogicPacked(), nodep->widthMin());
+ nodep->dtypep());
m_funcp->addInitsp(varp);
return varp;
}
@@ -180,13 +180,14 @@ private:
}
}
- void createDeepTemp(AstNode* nodep) {
+ void createDeepTemp(AstNode* nodep, bool noSubst) {
if (debug()>8) nodep->dumpTree(cout,"deepin:");
AstNRelinker linker;
nodep->unlinkFrBack(&linker);
AstVar* varp = getBlockTemp(nodep);
+ if (noSubst) varp->noSubst(true); // Do not remove varrefs to this in V3Const
// Replace node tree with reference to var
AstVarRef* newp = new AstVarRef (nodep->fileline(), varp, false);
linker.relink(newp);
@@ -236,7 +237,7 @@ private:
if (noopt && !nodep->user1()) {
// Need to do this even if not wide, as e.g. a select may be on a wide operator
UINFO(4,"Deep temp for LHS/RHS\n");
- createDeepTemp(nodep->rhsp());
+ createDeepTemp(nodep->rhsp(), false);
}
}
nodep->rhsp()->iterateAndNext(*this);
@@ -337,7 +338,7 @@ private:
&& !nodep->condp()->castVarRef()) {
// We're going to need the expression several times in the expanded code,
// so might as well make it a common expression
- createDeepTemp(nodep->condp());
+ createDeepTemp(nodep->condp(), false);
}
checkNode(nodep);
}
@@ -361,6 +362,17 @@ private:
}
}
}
+ virtual void visit(AstSFormatF* nodep, AstNUser*) {
+ nodep->iterateChildren(*this);
+ // Any strings sent to a display must be var of string data type,
+ // to avoid passing a pointer to a temporary.
+ for (AstNode* expp=nodep->exprsp(); expp; expp = expp->nextp()) {
+ if (expp->dtypep()->basicp()->isString()
+ && !expp->castVarRef()) {
+ createDeepTemp(expp, true);
+ }
+ }
+ }
//--------------------
// Default: Just iterate
diff --git a/src/V3Stats.cpp b/src/V3Stats.cpp
index 5299bc0..ab36974 100644
--- a/src/V3Stats.cpp
+++ b/src/V3Stats.cpp
@@ -40,6 +40,9 @@
class StatsVisitor : public AstNVisitor {
private:
// NODE STATE/TYPES
+
+ typedef map<string,int> NameMap; // Number of times a name appears
+
// STATE
string m_stage; // Name of the stage we are scanning
bool m_fast; // Counting only fastpath
@@ -54,7 +57,8 @@ private:
V3Double0 m_statPred[AstBranchPred::_ENUM_END]; // Nodes of given type
V3Double0 m_statInstr; // Instruction count
V3Double0 m_statInstrFast; // Instruction count
- vector<V3Double0> m_statVarWidths; // Variables of given type
+ vector<V3Double0> m_statVarWidths; // Variables of given width
+ vector<NameMap> m_statVarWidthNames; // Var names of given width
V3Double0 m_statVarArray; // Statistic tracking
V3Double0 m_statVarBytes; // Statistic tracking
V3Double0 m_statVarClock; // Statistic tracking
@@ -100,8 +104,18 @@ private:
else m_statVarBytes += nodep->dtypeSkipRefp()->widthTotalBytes();
if (int(m_statVarWidths.size()) <= nodep->width()) {
m_statVarWidths.resize(nodep->width()+5);
+ if (v3Global.opt.statsVars()) m_statVarWidthNames.resize(nodep->width()+5);
}
++ m_statVarWidths.at(nodep->width());
+ string pn = nodep->prettyName();
+ if (v3Global.opt.statsVars()) {
+ NameMap& nameMapr = m_statVarWidthNames.at(nodep->width());
+ if (nameMapr.find(pn) != nameMapr.end()) {
+ nameMapr[pn]++;
+ } else {
+ nameMapr[pn]=1;
+ }
+ }
}
}
virtual void visit(AstVarScope* nodep, AstNUser*) {
@@ -208,8 +222,16 @@ public:
}
for (unsigned i=0; i<m_statVarWidths.size(); i++) {
if (double count = double(m_statVarWidths.at(i))) {
- ostringstream os; os<<"Vars, width "<<setw(4)<<dec<<i;
- V3Stats::addStat(m_stage, os.str(), count);
+ if (v3Global.opt.statsVars()) {
+ NameMap& nameMapr = m_statVarWidthNames.at(i);
+ for (NameMap::iterator it=nameMapr.begin(); it!=nameMapr.end(); ++it) {
+ ostringstream os; os<<"Vars, width "<<setw(5)<<dec<<i<<" "<<it->first;
+ V3Stats::addStat(m_stage, os.str(), it->second);
+ }
+ } else {
+ ostringstream os; os<<"Vars, width "<<setw(5)<<dec<<i;
+ V3Stats::addStat(m_stage, os.str(), count);
+ }
}
}
// Node types
diff --git a/src/V3Stats.h b/src/V3Stats.h
index 59fe5a8..df49adf 100644
--- a/src/V3Stats.h
+++ b/src/V3Stats.h
@@ -23,7 +23,8 @@
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
-#include "V3Ast.h"
+
+class AstNetlist;
//============================================================================
diff --git a/src/V3Subst.cpp b/src/V3Subst.cpp
index 150e6f4..e44e2d6 100644
--- a/src/V3Subst.cpp
+++ b/src/V3Subst.cpp
@@ -258,6 +258,9 @@ private:
return entryp;
}
}
+ inline bool isSubstVar(AstVar* nodep) {
+ return nodep->isStatementTemp() && !nodep->noSubst();
+ }
// VISITORS
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
@@ -266,7 +269,7 @@ private:
nodep->rhsp()->iterateAndNext(*this);
bool hit=false;
if (AstVarRef* varrefp = nodep->lhsp()->castVarRef()) {
- if (varrefp->varp()->isStatementTemp()) {
+ if (isSubstVar(varrefp->varp())) {
SubstVarEntry* entryp = getEntryp(varrefp);
hit = true;
if (m_ops > SUBST_MAX_OPS_SUBST) {
@@ -281,7 +284,7 @@ private:
else if (AstWordSel* wordp = nodep->lhsp()->castWordSel()) {
if (AstVarRef* varrefp = wordp->lhsp()->castVarRef()) {
if (wordp->rhsp()->castConst()
- && varrefp->varp()->isStatementTemp()) {
+ && isSubstVar(varrefp->varp())) {
int word = wordp->rhsp()->castConst()->toUInt();
SubstVarEntry* entryp = getEntryp(varrefp);
hit = true;
@@ -314,7 +317,7 @@ private:
nodep->rhsp()->accept(*this);
AstVarRef* varrefp = nodep->lhsp()->castVarRef();
AstConst* constp = nodep->rhsp()->castConst();
- if (varrefp && varrefp->varp()->isStatementTemp()
+ if (varrefp && isSubstVar(varrefp->varp())
&& !varrefp->lvalue()
&& constp) {
// Nicely formed lvalues handled in NodeAssign
@@ -344,7 +347,7 @@ private:
nodep->varp()->user2(m_assignStep);
UINFO(9, " ASSIGNstep u2="<<nodep->varp()->user2()<<" "<<nodep<<endl);
}
- if (nodep->varp()->isStatementTemp()) {
+ if (isSubstVar(nodep->varp())) {
SubstVarEntry* entryp = getEntryp (nodep);
if (nodep->lvalue()) {
UINFO(8," ASSIGNcpx "<<nodep<<endl);
diff --git a/src/V3Unknown.cpp b/src/V3Unknown.cpp
index d1d9f70..79e39e7 100644
--- a/src/V3Unknown.cpp
+++ b/src/V3Unknown.cpp
@@ -410,12 +410,16 @@ private:
condp->deleteTree();
}
else if (!lvalue
- && !nodep->backp()->castArraySel()) { // Too complicated and slow if mid-multidimension
+ && !nodep->backp()->castArraySel()) { // Too complicated and slow if mid-multidimension
// ARRAYSEL(...) -> COND(LT(bit<maxbit), ARRAYSEL(...), {width{1'bx}})
AstNRelinker replaceHandle;
nodep->unlinkFrBack(&replaceHandle);
V3Number xnum (nodep->fileline(), nodep->width());
- xnum.setAllBitsX();
+ if (nodep->isString()) {
+ xnum = V3Number(V3Number::String(), nodep->fileline(), "");
+ } else {
+ xnum.setAllBitsX();
+ }
AstNode* newp = new AstCondBound (nodep->fileline(),
condp,
nodep,
diff --git a/src/V3Width.cpp b/src/V3Width.cpp
index 2a8fd9d..bb77134 100644
--- a/src/V3Width.cpp
+++ b/src/V3Width.cpp
@@ -77,6 +77,7 @@
#include "V3Width.h"
#include "V3Number.h"
#include "V3Const.h"
+#include "V3String.h"
#include "V3Task.h"
// More code; this file was getting too large; see actions there
@@ -154,6 +155,10 @@ ostream& operator<<(ostream& str, const WidthVP* vup) {
class WidthVisitor : public AstNVisitor {
private:
+ // TYPES
+ typedef map<pair<AstNodeDType*,AstAttrType>, AstVar*> TableMap;
+ typedef map<int,AstPatMember*> PatVecMap;
+
// STATE
bool m_paramsOnly; // Computing parameter value; limit operation
AstRange* m_cellRangep; // Range for arrayed instantiations, NULL for normal instantiations
@@ -162,9 +167,7 @@ private:
AstAttrOf* m_attrp; // Current attribute
bool m_doGenerate; // Do errors later inside generate statement
int m_dtTables; // Number of created data type tables
-
- // TYPES
- typedef map<int,AstPatMember*> PatVecMap;
+ TableMap m_tableMap; // Created tables so can remove duplicates
// ENUMS
enum ExtendRule {
@@ -189,7 +192,6 @@ private:
// Widths: 1 bit out, lhs 1 bit; Real: converts via compare with 0
virtual void visit(AstLogNot* nodep, AstNUser* vup) { visit_log_not(nodep,vup); }
- virtual void visit(AstPslBool* nodep, AstNUser* vup) { visit_log_not(nodep,vup); }
// Widths: 1 bit out, lhs 1 bit, rhs 1 bit; Real: converts via compare with 0
virtual void visit(AstLogAnd* nodep, AstNUser* vup) { visit_log_and_or(nodep,vup); }
virtual void visit(AstLogOr* nodep, AstNUser* vup) { visit_log_and_or(nodep,vup); }
@@ -230,6 +232,13 @@ private:
virtual void visit(AstLteD* nodep, AstNUser* vup) { visit_cmp_real(nodep,vup); }
virtual void visit(AstGtD* nodep, AstNUser* vup) { visit_cmp_real(nodep,vup); }
virtual void visit(AstGteD* nodep, AstNUser* vup) { visit_cmp_real(nodep,vup); }
+ // ... String compares
+ virtual void visit(AstEqN* nodep, AstNUser* vup) { visit_cmp_string(nodep,vup); }
+ virtual void visit(AstNeqN* nodep, AstNUser* vup) { visit_cmp_string(nodep,vup); }
+ virtual void visit(AstLtN* nodep, AstNUser* vup) { visit_cmp_string(nodep,vup); }
+ virtual void visit(AstLteN* nodep, AstNUser* vup) { visit_cmp_string(nodep,vup); }
+ virtual void visit(AstGtN* nodep, AstNUser* vup) { visit_cmp_string(nodep,vup); }
+ virtual void visit(AstGteN* nodep, AstNUser* vup) { visit_cmp_string(nodep,vup); }
// Widths: out width = lhs width = rhs width
// Signed: Output signed iff LHS & RHS signed.
@@ -369,6 +378,29 @@ private:
return;
}
}
+ if (nodep->lhsp()->isString()
+ || nodep->rhsp()->isString()) {
+ AstNode* newp = new AstConcatN (nodep->fileline(),nodep->lhsp()->unlinkFrBack(),
+ nodep->rhsp()->unlinkFrBack());
+ nodep->replaceWith(newp);
+ pushDeletep(nodep); nodep=NULL;
+ return;
+ }
+ }
+ if (vup->c()->final()) {
+ if (!nodep->dtypep()->widthSized()) {
+ // See also error in V3Number
+ nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in concatenations.");
+ }
+ }
+ }
+ virtual void visit(AstConcatN* nodep, AstNUser* vup) {
+ // String concatenate.
+ // Already did AstConcat simplifications
+ if (vup->c()->prelim()) {
+ iterateCheckString(nodep,"LHS",nodep->lhsp(),BOTH);
+ iterateCheckString(nodep,"RHS",nodep->rhsp(),BOTH);
+ nodep->dtypeSetString();
}
if (vup->c()->final()) {
if (!nodep->dtypep()->widthSized()) {
@@ -391,9 +423,38 @@ private:
if (times==0 && !nodep->backp()->castConcat()) { // Concat Visitor will clean it up.
nodep->v3error("Replication value of 0 is only legal under a concatenation."); times=1;
}
- nodep->dtypeSetLogicSized((nodep->lhsp()->width() * times),
- (nodep->lhsp()->widthMin() * times),
- AstNumeric::UNSIGNED);
+ if (nodep->lhsp()->isString()) {
+ AstNode* newp = new AstReplicateN(nodep->fileline(),nodep->lhsp()->unlinkFrBack(),
+ nodep->rhsp()->unlinkFrBack());
+ nodep->replaceWith(newp);
+ pushDeletep(nodep); nodep=NULL;
+ return;
+ } else {
+ nodep->dtypeSetLogicSized((nodep->lhsp()->width() * times),
+ (nodep->lhsp()->widthMin() * times),
+ AstNumeric::UNSIGNED);
+ }
+ }
+ if (vup->c()->final()) {
+ if (!nodep->dtypep()->widthSized()) {
+ // See also error in V3Number
+ nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in replications.");
+ }
+ }
+ }
+ virtual void visit(AstReplicateN* nodep, AstNUser* vup) {
+ // Replicate with string
+ if (vup->c()->prelim()) {
+ iterateCheckString(nodep,"LHS",nodep->lhsp(),BOTH);
+ iterateCheckSizedSelf(nodep,"RHS",nodep->rhsp(),SELF,BOTH);
+ V3Const::constifyParamsEdit(nodep->rhsp()); // rhsp may change
+ AstConst* constp = nodep->rhsp()->castConst();
+ if (!constp) { nodep->v3error("Replication value isn't a constant."); return; }
+ uint32_t times = constp->toUInt();
+ if (times==0 && !nodep->backp()->castConcat()) { // Concat Visitor will clean it up.
+ nodep->v3error("Replication value of 0 is only legal under a concatenation."); times=1;
+ }
+ nodep->dtypeSetString();
}
if (vup->c()->final()) {
if (!nodep->dtypep()->widthSized()) {
@@ -650,7 +711,9 @@ private:
// However a later operation may have changed the node->signed w/o changing
// the number's sign. So we don't: nodep->dtypeChgSigned(nodep->num().isSigned());
if (vup && vup->c()->prelim()) {
- if (nodep->num().sized()) {
+ if (nodep->num().isString()) {
+ nodep->dtypeSetString();
+ } else if (nodep->num().sized()) {
nodep->dtypeChgWidth(nodep->num().width(), nodep->num().width());
} else {
nodep->dtypeChgWidth(nodep->num().width(), nodep->num().widthMin());
@@ -659,9 +722,6 @@ private:
// We don't size the constant until we commit the widths, as need parameters
// to remain unsized, and numbers to remain unsized to avoid backp() warnings
}
- virtual void visit(AstConstString* nodep, AstNUser* vup) {
- nodep->rewidth();
- }
virtual void visit(AstRand* nodep, AstNUser* vup) {
if (vup->c()->prelim()) {
nodep->dtypeSetSigned32(); // Says the spec
@@ -763,45 +823,55 @@ private:
m_attrp = nodep;
nodep->fromp()->iterateAndNext(*this,WidthVP(SELF,BOTH).p());
// Don't iterate children, don't want to lose VarRef.
- if (nodep->attrType()==AstAttrType::VAR_BASE) {
+ switch (nodep->attrType()) {
+ case AstAttrType::VAR_BASE:
// Soon to be handled in V3LinkWidth SEL generation, under attrp() and newSubLsbOf
- } else if (nodep->attrType()==AstAttrType::MEMBER_BASE) {
+ break;
+ case AstAttrType::MEMBER_BASE:
// Soon to be handled in V3LinkWidth SEL generation, under attrp() and newSubLsbOf
- } else if (nodep->attrType()==AstAttrType::DIM_DIMENSIONS
- || nodep->attrType()==AstAttrType::DIM_UNPK_DIMENSIONS) {
+ break;
+ case AstAttrType::DIM_DIMENSIONS:
+ case AstAttrType::DIM_UNPK_DIMENSIONS: {
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
pair<uint32_t,uint32_t> dim = nodep->fromp()->dtypep()->dimensions(true);
int val = (nodep->attrType()==AstAttrType::DIM_UNPK_DIMENSIONS
? dim.second : (dim.first+dim.second));
nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Signed32(), val)); nodep->deleteTree(); nodep=NULL;
- } else if (nodep->attrType()==AstAttrType::DIM_BITS
- || nodep->attrType()==AstAttrType::DIM_HIGH
- || nodep->attrType()==AstAttrType::DIM_INCREMENT
- || nodep->attrType()==AstAttrType::DIM_LEFT
- || nodep->attrType()==AstAttrType::DIM_LOW
- || nodep->attrType()==AstAttrType::DIM_RIGHT
- || nodep->attrType()==AstAttrType::DIM_SIZE) {
+ break;
+ }
+ case AstAttrType::DIM_BITS:
+ case AstAttrType::DIM_HIGH:
+ case AstAttrType::DIM_INCREMENT:
+ case AstAttrType::DIM_LEFT:
+ case AstAttrType::DIM_LOW:
+ case AstAttrType::DIM_RIGHT:
+ case AstAttrType::DIM_SIZE: {
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
pair<uint32_t,uint32_t> dim = nodep->fromp()->dtypep()->skipRefp()->dimensions(true);
- uint32_t maxdim = dim.first+dim.second;
- if (!nodep->dimp() || nodep->dimp()->castConst() || maxdim<1) {
+ uint32_t msbdim = dim.first+dim.second;
+ if (!nodep->dimp() || nodep->dimp()->castConst() || msbdim<1) {
int dim = !nodep->dimp() ? 1 : nodep->dimp()->castConst()->toSInt();
- int val = dimensionValue(nodep->fromp()->dtypep(), nodep->attrType(), dim);
- nodep->replaceWith(new AstConst(nodep->fileline(), AstConst::Signed32(), val)); nodep->deleteTree(); nodep=NULL;
+ AstConst* newp = dimensionValue(nodep->fromp()->dtypep(), nodep->attrType(), dim);
+ nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
}
else { // Need a runtime lookup table. Yuk.
if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
- AstVar* varp = dimensionVarp(nodep->fromp()->dtypep(), nodep->attrType());
+ AstVar* varp = dimensionVarp(nodep->fromp()->dtypep(), nodep->attrType(), msbdim);
AstNode* dimp = nodep->dimp()->unlinkFrBack();
AstVarRef* varrefp = new AstVarRef(nodep->fileline(), varp, false);
varrefp->packagep(v3Global.rootp()->dollarUnitPkgAddp());
AstNode* newp = new AstArraySel(nodep->fileline(), varrefp, dimp);
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
}
- } else { // Everything else resolved earlier
+ break;
+ }
+ default: {
+ // Everything else resolved earlier
nodep->dtypeSetLogicSized(32,1,AstNumeric::UNSIGNED); // Approximation, unsized 32
UINFO(1,"Missing ATTR type case node: "<<nodep<<endl);
nodep->v3fatalSrc("Missing ATTR type case");
+ break;
+ }
}
m_attrp = oldAttr;
}
@@ -1244,21 +1314,29 @@ private:
if (debug()>=9) nodep->dumpTree("-ms-in-");
nodep->iterateChildren(*this,WidthVP(SELF,BOTH).p());
// Find the fromp dtype - should be a class
- AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefp();
+ AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefToEnump();
UINFO(9," from dt "<<fromDtp<<endl);
- AstNodeClassDType* fromClassp = fromDtp->castNodeClassDType();
AstMemberDType* memberp = NULL; // NULL=error below
- if (!fromClassp) {
- nodep->v3error("Member selection of non-struct/union object '"
- <<nodep->fromp()->prettyTypeName()<<"' which is a '"<<nodep->fromp()->dtypep()->prettyTypeName()<<"'");
- }
- else {
- // No need to width-resolve the fromClassp, as it was done when we did the child
- memberp = fromClassp->findMember(nodep->name());
+ if (AstNodeClassDType* adtypep = fromDtp->castNodeClassDType()) {
+ // No need to width-resolve the class, as it was done when we did the child
+ memberp = adtypep->findMember(nodep->name());
if (!memberp) {
nodep->v3error("Member '"<<nodep->prettyName()<<"' not found in structure");
}
}
+ else if (fromDtp->castEnumDType()) {
+ // Method call on enum without following parenthesis, e.g. "ENUM.next"
+ // Convert this into a method call, and let that visitor figure out what to do next
+ AstNode* newp = new AstMethodSel(nodep->fileline(), nodep->fromp()->unlinkFrBack(), nodep->name(), NULL);
+ nodep->replaceWith(newp);
+ pushDeletep(nodep); nodep=NULL;
+ newp->accept(*this,vup);
+ return;
+ }
+ else {
+ nodep->v3error("Member selection of non-struct/union object '"
+ <<nodep->fromp()->prettyTypeName()<<"' which is a '"<<nodep->fromp()->dtypep()->prettyTypeName()<<"'");
+ }
if (memberp) {
if (m_attrp) { // Looking for the base of the attribute
nodep->dtypep(memberp);
@@ -1280,6 +1358,94 @@ private:
}
}
+ virtual void visit(AstMethodSel* nodep, AstNUser* vup) {
+ UINFO(5," METHODSEL "<<nodep<<endl);
+ if (debug()>=9) nodep->dumpTree("-ms-in-");
+ // Should check types the method requires, but at present we don't do much
+ nodep->fromp()->accept(*this,WidthVP(SELF,BOTH).p());
+ for (AstArg* argp = nodep->pinsp()->castArg(); argp; argp = argp->nextp()->castArg()) {
+ if (argp->exprp()) argp->exprp()->accept(*this,WidthVP(SELF,BOTH).p());
+ }
+ // Find the fromp dtype - should be a class
+ if (!nodep->fromp() || !nodep->fromp()->dtypep()) nodep->v3fatalSrc("Unsized expression");
+ AstNodeDType* fromDtp = nodep->fromp()->dtypep()->skipRefToEnump();
+ UINFO(9," from dt "<<fromDtp<<endl);
+ if (AstEnumDType* adtypep = fromDtp->castEnumDType()) {
+ // Method call on enum without following parenthesis, e.g. "ENUM.next"
+ // Convert this into a method call, and let that visitor figure out what to do next
+ if (adtypep) {}
+ if (nodep->name() == "num"
+ || nodep->name() == "first"
+ || nodep->name() == "last") {
+ // Constant value
+ AstConst* newp = NULL;
+ if (nodep->pinsp()) nodep->v3error("Arguments passed to enum.num method, but it does not take arguments");
+ if (nodep->name() == "num") {
+ int items = 0;
+ for (AstNode* itemp = adtypep->itemsp(); itemp; itemp = itemp->nextp()) ++items;
+ newp = new AstConst(nodep->fileline(), AstConst::Signed32(), items);
+ } else if (nodep->name() == "first") {
+ AstEnumItem* itemp = adtypep->itemsp();
+ if (!itemp) newp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0); // Spec doesn't say what to do
+ else newp = itemp->valuep()->cloneTree(false)->castConst(); // A const
+ } else if (nodep->name() == "last") {
+ AstEnumItem* itemp = adtypep->itemsp();
+ while (itemp && itemp->nextp()) itemp = itemp->nextp()->castEnumItem();
+ if (!itemp) newp = new AstConst(nodep->fileline(), AstConst::Signed32(), 0); // Spec doesn't say what to do
+ else newp = itemp->valuep()->cloneTree(false)->castConst(); // A const
+ }
+ if (!newp) nodep->v3fatalSrc("Enum method (perhaps enum item) not const");
+ newp->fileline(nodep->fileline()); // Use method's filename/line number to be clearer; may have warning disables
+ nodep->replaceWith(newp);
+ pushDeletep(nodep); nodep=NULL;
+ }
+ else if (nodep->name() == "name"
+ || nodep->name() == "next"
+ || nodep->name() == "prev") {
+ AstAttrType attrType;
+ if (nodep->name() == "name") attrType = AstAttrType::ENUM_NAME;
+ else if (nodep->name() == "next") attrType = AstAttrType::ENUM_NEXT;
+ else if (nodep->name() == "prev") attrType = AstAttrType::ENUM_PREV;
+ else nodep->v3fatalSrc("Bad case");
+
+ if (nodep->pinsp() && nodep->name() == "name") {
+ nodep->v3error("Arguments passed to enum.name method, but it does not take arguments");
+ } else if (nodep->pinsp() && !(nodep->pinsp()->castArg()->exprp()->castConst()
+ && nodep->pinsp()->castArg()->exprp()->castConst()->toUInt()==1
+ && !nodep->pinsp()->nextp())) {
+ nodep->v3error("Unsupported: Arguments passed to enum.next method");
+ }
+ // Need a runtime lookup table. Yuk.
+ // Ideally we would have a fast algorithm when a number is
+ // of small width and complete and so can use an array, and
+ // a map for when the value is many bits and sparse.
+ uint64_t msbdim = 0;
+ {
+ for (AstEnumItem* itemp = adtypep->itemsp(); itemp; itemp = itemp->nextp()->castEnumItem()) {
+ AstConst* vconstp = itemp->valuep()->castConst();
+ if (!vconstp) nodep->v3fatalSrc("Enum item without constified value");
+ if (vconstp->toUQuad() >= msbdim) msbdim = vconstp->toUQuad();
+ }
+ if (adtypep->itemsp()->width() > 64 || msbdim >= 1024) {
+ nodep->v3error("Unsupported; enum next/prev method on enum with > 10 bits");
+ return;
+ }
+ }
+ AstVar* varp = enumVarp(adtypep, attrType, msbdim);
+ AstVarRef* varrefp = new AstVarRef(nodep->fileline(), varp, false);
+ varrefp->packagep(v3Global.rootp()->dollarUnitPkgAddp());
+ AstNode* newp = new AstArraySel(nodep->fileline(), varrefp, nodep->fromp()->unlinkFrBack());
+ nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
+ } else {
+ nodep->v3error("Unknown built-in enum method '"<<nodep->fromp()->prettyTypeName()<<"'");
+ }
+ }
+ else {
+ nodep->v3error("Unsupported: Member call on non-enum object '"
+ <<nodep->fromp()->prettyTypeName()<<"' which is a '"<<nodep->fromp()->dtypep()->prettyTypeName()<<"'");
+ }
+ }
+
virtual void visit(AstPattern* nodep, AstNUser* vup) {
if (nodep->didWidthAndSet()) return;
UINFO(9,"PATTERN "<<nodep<<endl);
@@ -1702,6 +1868,13 @@ private:
if (argp) argp=argp->nextp();
break;
}
+ case 's': { // Convert string to pack string
+ if (argp && argp->dtypep()->basicp()->isString()) { // Convert it
+ ch = '@';
+ }
+ if (argp) argp=argp->nextp();
+ break;
+ }
default: { // Most operators, just move to next argument
if (argp) argp=argp->nextp();
break;
@@ -1810,10 +1983,6 @@ private:
iterateCheckBool(nodep,"Property",nodep->propp(),BOTH); // it's like an if() condition.
nodep->stmtsp()->iterateAndNext(*this);
}
- virtual void visit(AstPslAssert* nodep, AstNUser* vup) {
- assertAtStatement(nodep,vup);
- iterateCheckBool(nodep,"Property",nodep->propp(),BOTH); // it's like an if() condition.
- }
virtual void visit(AstVAssert* nodep, AstNUser* vup) {
assertAtStatement(nodep,vup);
iterateCheckBool(nodep,"Property",nodep->propp(),BOTH); // it's like an if() condition.
@@ -2131,8 +2300,7 @@ private:
}
void visit_log_not(AstNode* nodep, AstNUser* vup) {
- // CALLER: LogNot, PslBool
- // Note AstPslBool isn't a AstNodeUniop, or we'd only allow that here
+ // CALLER: LogNot
// Width-check: lhs 1 bit
// Real: Allowed; implicitly compares with zero
// We calculate the width of the UNDER expression.
@@ -2207,6 +2375,12 @@ private:
iterateCheckReal(nodep,"LHS",nodep->lhsp(),FINAL);
iterateCheckReal(nodep,"RHS",nodep->rhsp(),FINAL);
}
+ } else if (nodep->lhsp()->isString() || nodep->rhsp()->isString()) {
+ if (AstNodeBiop* newp=replaceWithNVersion(nodep)) { nodep=NULL;
+ nodep = newp; // Process new node instead
+ iterateCheckString(nodep,"LHS",nodep->lhsp(),FINAL);
+ iterateCheckString(nodep,"RHS",nodep->rhsp(),FINAL);
+ }
} else {
bool signedFl = nodep->lhsp()->isSigned() && nodep->rhsp()->isSigned();
if (AstNodeBiop* newp=replaceWithUOrSVersion(nodep, signedFl)) { nodep=NULL;
@@ -2236,6 +2410,19 @@ private:
nodep->dtypeSetLogicBool();
}
}
+ void visit_cmp_string(AstNodeBiop* nodep, AstNUser* vup) {
+ // CALLER: EqN, LtN
+ // Widths: 1 bit out, lhs width == rhs width
+ // String compare (not output)
+ // Real if and only if real_allow set
+ if (!nodep->rhsp()) nodep->v3fatalSrc("For binary ops only!");
+ if (vup->c()->prelim()) {
+ // See similar handling in visit_cmp_eq_gt where created
+ iterateCheckString(nodep,"LHS",nodep->lhsp(),BOTH);
+ iterateCheckString(nodep,"RHS",nodep->rhsp(),BOTH);
+ nodep->dtypeSetLogicBool();
+ }
+ }
void visit_negate_not(AstNodeUniop* nodep, AstNUser* vup, bool real_ok) {
// CALLER: (real_ok=false) Not
@@ -2602,6 +2789,15 @@ private:
underp = iterateCheck(nodep,side,underp,SELF,FINAL,expDTypep,EXTEND_EXP);
}
}
+ void iterateCheckString (AstNode* nodep, const char* side, AstNode* underp, Stage stage) {
+ if (stage & PRELIM) {
+ underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,PRELIM).p());
+ }
+ if (stage & FINAL) {
+ AstNodeDType* expDTypep = nodep->findStringDType();
+ underp = iterateCheck(nodep,side,underp,SELF,FINAL,expDTypep,EXTEND_EXP);
+ }
+ }
void iterateCheckSizedSelf (AstNode* nodep, const char* side, AstNode* underp,
Determ determ, Stage stage) {
// Coerce child to any sized-number data type; child is self-determined i.e. isolated from expected type.
@@ -2685,6 +2881,9 @@ private:
} else if (!expDTypep->isDouble() && underp->isDouble()) {
underp = spliceCvtS(underp, true); // Round RHS
underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p());
+ } else if (expDTypep->isString() && !underp->dtypep()->isString()) {
+ underp = spliceCvtString(underp);
+ underp = underp->acceptSubtreeReturnEdits(*this,WidthVP(SELF,FINAL).p());
} else {
AstBasicDType* expBasicp = expDTypep->basicp();
AstBasicDType* underBasicp = underp->dtypep()->basicp();
@@ -2828,6 +3027,20 @@ private:
return nodep;
}
}
+ AstNode* spliceCvtString(AstNode* nodep) {
+ // IEEE-2012 11.8.1: Signed: Type coercion creates signed
+ // 11.8.2: Argument to convert is self-determined
+ if (nodep && !nodep->dtypep()->basicp()->isString()) {
+ UINFO(6," spliceCvtString: "<<nodep<<endl);
+ AstNRelinker linker;
+ nodep->unlinkFrBack(&linker);
+ AstNode* newp = new AstCvtPackString(nodep->fileline(), nodep);
+ linker.relink(newp);
+ return newp;
+ } else {
+ return nodep;
+ }
+ }
AstNodeBiop* replaceWithUOrSVersion(AstNodeBiop* nodep, bool signedFlavorNeeded) {
// Given a signed/unsigned node type, create the opposite type
// Return new node or NULL if nothing
@@ -2910,6 +3123,34 @@ private:
pushDeletep(nodep); nodep=NULL;
return newp;
}
+ AstNodeBiop* replaceWithNVersion(AstNodeBiop* nodep) {
+ // Given a signed/unsigned node type, replace with string version
+ // Return new node or NULL if nothing
+ if (nodep->stringFlavor()) {
+ return NULL;
+ }
+ FileLine* fl = nodep->fileline();
+ AstNode* lhsp = nodep->lhsp()->unlinkFrBack();
+ AstNode* rhsp = nodep->rhsp()->unlinkFrBack();
+ AstNodeBiop* newp = NULL;
+ // No width change on output;... // All below have bool or double outputs
+ switch (nodep->type()) {
+ case AstType::atEQ: case AstType::atEQCASE: newp = new AstEqN (fl,lhsp,rhsp); break;
+ case AstType::atNEQ: case AstType::atNEQCASE: newp = new AstNeqN (fl,lhsp,rhsp); break;
+ case AstType::atGT: case AstType::atGTS: newp = new AstGtN (fl,lhsp,rhsp); break;
+ case AstType::atGTE: case AstType::atGTES: newp = new AstGteN (fl,lhsp,rhsp); break;
+ case AstType::atLT: case AstType::atLTS: newp = new AstLtN (fl,lhsp,rhsp); break;
+ case AstType::atLTE: case AstType::atLTES: newp = new AstLteN (fl,lhsp,rhsp); break;
+ default:
+ nodep->v3fatalSrc("Node needs conversion to string, but bad case: "<<nodep<<endl);
+ break;
+ }
+ UINFO(6," ReplaceWithNVersion: "<<nodep<<" w/ "<<newp<<endl);
+ nodep->replaceWith(newp);
+ // No width change; the default created type (bool or string) is correct
+ pushDeletep(nodep); nodep=NULL;
+ return newp;
+ }
AstNodeUniop* replaceWithDVersion(AstNodeUniop* nodep) {
// Given a signed/unsigned node type, create the opposite type
// Return new node or NULL if nothing
@@ -2960,7 +3201,7 @@ private:
return nodep;
}
- int dimensionValue(AstNodeDType* nodep, AstAttrType attrType, int dim) {
+ AstConst* dimensionValue(AstNodeDType* nodep, AstAttrType attrType, int dim) {
// Return the dimension value for the specified attribute and constant dimension
AstNodeDType* dtypep = nodep->skipRefp();
VNumRange declRange; // ranged() set false
@@ -2981,8 +3222,10 @@ private:
}
break;
}
+ AstConst* valp = NULL; // If NULL, construct from val
int val = 0;
- if (attrType==AstAttrType::DIM_BITS) {
+ switch (attrType) {
+ case AstAttrType::DIM_BITS: {
int bits = 1;
while (dtypep) {
//UINFO(9, " bits at "<<bits<<" "<<dtypep<<endl);
@@ -3006,36 +3249,46 @@ private:
} else {
val = bits;
}
- } else if (attrType==AstAttrType::DIM_HIGH) {
+ break; }
+ case AstAttrType::DIM_HIGH:
val = !declRange.ranged() ? 0 : declRange.hi();
- } else if (attrType==AstAttrType::DIM_LEFT) {
+ break;
+ case AstAttrType::DIM_LEFT:
val = !declRange.ranged() ? 0 : declRange.left();
- } else if (attrType==AstAttrType::DIM_LOW) {
+ break;
+ case AstAttrType::DIM_LOW:
val = !declRange.ranged() ? 0 : declRange.lo();
- } else if (attrType==AstAttrType::DIM_RIGHT) {
+ break;
+ case AstAttrType::DIM_RIGHT:
val = !declRange.ranged() ? 0 : declRange.right();
- } else if (attrType==AstAttrType::DIM_INCREMENT) {
+ break;
+ case AstAttrType::DIM_INCREMENT:
val = (declRange.ranged() && declRange.littleEndian()) ? -1 : 1;
- } else if (attrType==AstAttrType::DIM_SIZE) {
+ break;
+ case AstAttrType::DIM_SIZE:
val = !declRange.ranged() ? 0 : declRange.elements();
- } else {
+ break;
+ default:
nodep->v3fatalSrc("Missing DIM ATTR type case");
+ break;
}
- UINFO(9," $dimension "<<attrType.ascii()<<"("<<((void*)dtypep)<<","<<dim<<")="<<val<<endl);
- return val;
+ if (!valp) valp = new AstConst(nodep->fileline(), AstConst::Signed32(), val);
+ UINFO(9," $dimension "<<attrType.ascii()<<"("<<((void*)dtypep)<<","<<dim<<")="<<valp<<endl);
+ return valp;
}
- AstVar* dimensionVarp(AstNodeDType* nodep, AstAttrType attrType) {
+ AstVar* dimensionVarp(AstNodeDType* nodep, AstAttrType attrType, uint32_t msbdim) {
// Return a variable table which has specified dimension properties for this variable
- pair<uint32_t,uint32_t> dim = nodep->skipRefp()->dimensions(true);
- uint32_t maxdim = dim.first+dim.second;
- //
+ TableMap::iterator pos = m_tableMap.find(make_pair(nodep,attrType));
+ if (pos != m_tableMap.end()) {
+ return pos->second;
+ }
AstNodeArrayDType* vardtypep = new AstUnpackArrayDType(nodep->fileline(),
nodep->findSigned32DType(),
- new AstRange(nodep->fileline(), maxdim, 0));
+ new AstRange(nodep->fileline(), msbdim, 0));
AstInitArray* initp = new AstInitArray (nodep->fileline(), vardtypep, NULL);
v3Global.rootp()->typeTablep()->addTypesp(vardtypep);
AstVar* varp = new AstVar (nodep->fileline(), AstVarType::MODULETEMP,
- "__Vdimtable" + cvtToStr(m_dtTables++),
+ "__Vdimtab_" + VString::downcase(attrType.ascii()) + cvtToStr(m_dtTables++),
vardtypep);
varp->isConst(true);
varp->isStatic(true);
@@ -3043,13 +3296,87 @@ private:
// Add to root, as don't know module we are in, and aids later structure sharing
v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(varp);
// Element 0 is a non-index and has speced values
- initp->addInitsp(new AstConst(nodep->fileline(), AstConst::Signed32(),
- dimensionValue(nodep, attrType, 0)));
- for (unsigned i=1; i<maxdim+1; ++i) {
- initp->addInitsp(new AstConst(nodep->fileline(), AstConst::Signed32(),
- dimensionValue(nodep, attrType, i)));
+ initp->addInitsp(dimensionValue(nodep, attrType, 0));
+ for (unsigned i=1; i<msbdim+1; ++i) {
+ initp->addInitsp(dimensionValue(nodep, attrType, i));
+ }
+ varp->iterate(*this); // May have already done $unit so must do this var
+ m_tableMap.insert(make_pair(make_pair(nodep,attrType), varp));
+ return varp;
+ }
+ AstVar* enumVarp(AstEnumDType* nodep, AstAttrType attrType, uint32_t msbdim) {
+ // Return a variable table which has specified dimension properties for this variable
+ TableMap::iterator pos = m_tableMap.find(make_pair(nodep,attrType));
+ if (pos != m_tableMap.end()) {
+ return pos->second;
+ }
+ UINFO(9, "Construct Venumtab attr="<<attrType.ascii()<<" max="<<msbdim<<" for "<<nodep<<endl);
+ AstNodeDType* basep;
+ if (attrType == AstAttrType::ENUM_NAME) {
+ basep = nodep->findStringDType();
+ } else {
+ basep = nodep->findSigned32DType();
+ }
+ AstNodeArrayDType* vardtypep = new AstUnpackArrayDType(nodep->fileline(),
+ basep,
+ new AstRange(nodep->fileline(), msbdim, 0));
+ AstInitArray* initp = new AstInitArray (nodep->fileline(), vardtypep, NULL);
+ v3Global.rootp()->typeTablep()->addTypesp(vardtypep);
+ AstVar* varp = new AstVar (nodep->fileline(), AstVarType::MODULETEMP,
+ "__Venumtab_" + VString::downcase(attrType.ascii()) + cvtToStr(m_dtTables++),
+ vardtypep);
+ varp->isConst(true);
+ varp->isStatic(true);
+ varp->valuep(initp);
+ // Add to root, as don't know module we are in, and aids later structure sharing
+ v3Global.rootp()->dollarUnitPkgAddp()->addStmtp(varp);
+
+ // Find valid values and populate
+ if (!nodep->itemsp()) nodep->v3fatalSrc("enum without items");
+ vector<AstNode*> values;
+ values.reserve(msbdim+1);
+ for (unsigned i=0; i<(msbdim+1); ++i) {
+ values[i] = NULL;
+ }
+ {
+ AstEnumItem* firstp = nodep->itemsp();
+ AstEnumItem* prevp = firstp; // Prev must start with last item
+ while (prevp->nextp()) prevp = prevp->nextp()->castEnumItem();
+ for (AstEnumItem* itemp = firstp; itemp;) {
+ AstEnumItem* nextp = itemp->nextp()->castEnumItem();
+ AstConst* vconstp = itemp->valuep()->castConst();
+ if (!vconstp) nodep->v3fatalSrc("Enum item without constified value");
+ uint32_t i = vconstp->toUInt();
+ if (attrType == AstAttrType::ENUM_NAME) {
+ values[i] = new AstConst(nodep->fileline(), AstConst::String(), itemp->name());
+ } else if (attrType == AstAttrType::ENUM_NEXT) {
+ values[i] = (nextp ? nextp : firstp)->valuep()->cloneTree(false); // A const
+ } else if (attrType == AstAttrType::ENUM_PREV) {
+ values[i] = prevp->valuep()->cloneTree(false); // A const
+ } else {
+ nodep->v3fatalSrc("Bad case");
+ }
+ prevp = itemp;
+ itemp = nextp;
+ }
+ }
+ // Fill in all unspecified values and add to table
+ for (unsigned i=0; i<(msbdim+1); ++i) {
+ AstNode* valp = values[i];
+ if (!valp) {
+ if (attrType == AstAttrType::ENUM_NAME) {
+ valp = new AstConst(nodep->fileline(), AstConst::String(), "");
+ } else if (attrType == AstAttrType::ENUM_NEXT
+ || attrType == AstAttrType::ENUM_PREV) {
+ valp = new AstConst(nodep->fileline(), V3Number(nodep->fileline(), nodep->width(), 0));
+ } else {
+ nodep->v3fatalSrc("Bad case");
+ }
+ }
+ initp->addInitsp(valp);
}
varp->iterate(*this); // May have already done $unit so must do this var
+ m_tableMap.insert(make_pair(make_pair(nodep,attrType), varp));
return varp;
}
diff --git a/src/V3WidthCommit.h b/src/V3WidthCommit.h
index ba2a8d1..e2deb28 100644
--- a/src/V3WidthCommit.h
+++ b/src/V3WidthCommit.h
@@ -72,8 +72,9 @@ class WidthCommitVisitor : public AstNVisitor {
public:
// METHODS
static AstConst* newIfConstCommitSize (AstConst* nodep) {
- if ((nodep->dtypep()->width() != nodep->num().width())
- || !nodep->num().sized()) { // Need to force the number rrom unsized to sized
+ if (((nodep->dtypep()->width() != nodep->num().width())
+ || !nodep->num().sized())
+ && !nodep->num().isString()) { // Need to force the number rrom unsized to sized
V3Number num (nodep->fileline(), nodep->dtypep()->width());
num.opAssign(nodep->num());
num.isSigned(nodep->isSigned());
diff --git a/src/Verilator.cpp b/src/Verilator.cpp
index 44c30bd..a33eb76 100644
--- a/src/Verilator.cpp
+++ b/src/Verilator.cpp
@@ -630,7 +630,7 @@ int main(int argc, char** argv, char** env) {
&& !v3Global.opt.lintOnly()
&& !v3Global.opt.xmlOnly()
&& !v3Global.opt.cdc()) {
- v3fatal("verilator: Need --cc, --sc, --sp, --cdc, --lint-only, --xml_only or --E option");
+ v3fatal("verilator: Need --cc, --sc, --cdc, --lint-only, --xml_only or --E option");
}
// Check environment
V3Options::getenvSYSTEMC();
diff --git a/src/VlcBucket.h b/src/VlcBucket.h
new file mode 100644
index 0000000..1dd9bf1
--- /dev/null
+++ b/src/VlcBucket.h
@@ -0,0 +1,133 @@
+// -*- mode: C++; c-file-style: "cc-mode" -*-
+//*************************************************************************
+// DESCRIPTION: verilator_coverage: Bucket container
+//
+// Code available from: http://www.veripool.org/verilator
+//
+//*************************************************************************
+//
+// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
+// redistribute it and/or modify it under the terms of either the GNU
+// Lesser General Public License Version 3 or the Perl Artistic License
+// Version 2.0.
+//
+// Verilator is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+//*************************************************************************
+
+#ifndef _VLCBUCKET_H_
+#define _VLCBUCKET_H_ 1
+
+#include "config_build.h"
+#include "verilatedos.h"
+
+//********************************************************************
+// VlcBuckets - Container of all coverage point hits for a given test
+// This is a bitmap array - we store a single bit to indicate a test
+// has hit that point with sufficient coverage.
+
+class VlcBuckets {
+private:
+ // MEMBERS
+ vluint64_t* m_datap; ///< Pointer to first bucket (dynamically allocated)
+ vluint64_t m_dataSize; ///< Current entries in m_datap
+ vluint64_t m_bucketsCovered; ///< Num buckets with sufficient coverage
+
+private:
+ static inline vluint64_t covBit(vluint64_t point) { return 1ULL<<(point & 63); }
+ inline vluint64_t allocSize() const { return sizeof(vluint64_t) * m_dataSize / 64; }
+ void allocate(vluint64_t point) {
+ vluint64_t oldsize = m_dataSize;
+ if (m_dataSize<point) m_dataSize=(point+64) & ~63ULL; // Keep power of two
+ m_dataSize *= 2;
+ //UINFO(9, "Realloc "<<allocSize()<<" for "<<point<<" "<<(void*)(m_datap)<<endl);
+ m_datap = (vluint64_t*)realloc(m_datap, allocSize());
+ if (!m_datap) {v3fatal("Out of memory increasing buckets"); }
+ for (vluint64_t i=oldsize; i<m_dataSize; i+=64) m_datap[i/64] = 0;
+ }
+
+public:
+ // CONSTRUCTORS
+ VlcBuckets() {
+ m_dataSize = 0;
+ m_datap = NULL;
+ m_bucketsCovered = 0;
+ allocate(1024);
+ }
+ ~VlcBuckets() {
+ m_dataSize = 0;
+ free(m_datap); m_datap=NULL;
+ }
+
+ // ACCESSORS
+ static vluint64_t sufficient() { return 1; }
+ vluint64_t bucketsCovered() const { return m_bucketsCovered; }
+
+ // METHODS
+ void addData(vluint64_t point, vluint64_t hits) {
+ if (hits >= sufficient()) {
+ //UINFO(9," addData "<<point<<" "<<hits<<" size="<<m_dataSize<<endl);
+ if (point >= m_dataSize) allocate(point);
+ m_datap[point/64] |= covBit(point);
+ m_bucketsCovered++;
+ }
+ }
+ void clearHits(vluint64_t point) const {
+ if (point >= m_dataSize) {
+ return;
+ } else {
+ m_datap[point/64] &= ~covBit(point);
+ }
+ }
+ bool exists(vluint64_t point) const {
+ if (point >= m_dataSize) {
+ return false;
+ } else {
+ return (m_datap[point/64] & covBit(point)) ? 1:0;
+ }
+ }
+ vluint64_t hits(vluint64_t point) const {
+ if (point >= m_dataSize) {
+ return 0;
+ } else {
+ return (m_datap[point/64] & covBit(point)) ? 1:0;
+ }
+ }
+ vluint64_t popCount() const {
+ vluint64_t pop = 0;
+ for (vluint64_t i=0; i<m_dataSize; i++) {
+ if (hits(i)) pop++;
+ }
+ return pop;
+ }
+ vluint64_t dataPopCount(const VlcBuckets& remaining) {
+ vluint64_t pop = 0;
+ for (vluint64_t i=0; i<m_dataSize; i++) {
+ if (hits(i) && remaining.hits(i)) pop++;
+ }
+ return pop;
+ }
+ void orData(const VlcBuckets& ordata) {
+ for (vluint64_t i=0; i<m_dataSize; i++) {
+ if (hits(i) && ordata.hits(i)) {
+ clearHits(i);
+ }
+ }
+ }
+
+ void dump() const {
+ cout<<"# ";
+ for (vluint64_t i=0; i<m_dataSize; i++) {
+ if (hits(i)) cout<<","<<i;
+ }
+ cout<<endl;
+ }
+};
+
+
+//######################################################################
+
+#endif // guard
diff --git a/src/VlcMain.cpp b/src/VlcMain.cpp
new file mode 100644
index 0000000..3aaf6df
--- /dev/null
+++ b/src/VlcMain.cpp
@@ -0,0 +1,203 @@
+// -*- mode: C++; c-file-style: "cc-mode" -*-
+//*************************************************************************
+// DESCRIPTION: verilator_coverage: main()
+//
+// Code available from: http://www.veripool.org/verilator
+//
+//*************************************************************************
+//
+// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
+// redistribute it and/or modify it under the terms of either the GNU
+// Lesser General Public License Version 3 or the Perl Artistic License
+// Version 2.0.
+//
+// Verilator is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+//*************************************************************************
+
+// Cheat for speed and compile .cpp files into one object
+#define _V3ERROR_NO_GLOBAL_ 1
+#include "V3Error.cpp"
+#include "VlcTop.cpp"
+
+#include "VlcOptions.h"
+#include "VlcTop.h"
+
+#include <fstream>
+#include <algorithm>
+#include <unistd.h>
+
+//######################################################################
+// VlcOptions
+
+void VlcOptions::addReadFile(const string& filename) {
+ if (m_readFiles.find(filename) == m_readFiles.end()) {
+ m_readFiles.insert(filename);
+ }
+}
+
+string VlcOptions::version() {
+ string ver = DTVERSION;
+ ver += " rev "+cvtToStr(DTVERSION_rev);
+ return ver;
+}
+
+bool VlcOptions::onoff(const char* sw, const char* arg, bool& flag) {
+ // if sw==arg, then return true (found it), and flag=true
+ // if sw=="-no-arg", then return true (found it), and flag=false
+ // if sw=="-noarg", then return true (found it), and flag=false
+ // else return false
+ if (arg[0]!='-') v3fatalSrc("OnOff switches must have leading dash.\n");
+ if (0==strcmp(sw,arg)) { flag=true; return true; }
+ else if (0==strncmp(sw,"-no",3) && (0==strcmp(sw+3,arg+1))) { flag=false; return true; }
+ else if (0==strncmp(sw,"-no-",4) && (0==strcmp(sw+4,arg+1))) { flag=false; return true; }
+ return false;
+}
+
+void VlcOptions::parseOptsList(int argc, char** argv) {
+ // Parse parameters
+ // Note argc and argv DO NOT INCLUDE the filename in [0]!!!
+ // May be called recursively when there are -f files.
+#define shift { ++i; }
+ for (int i=0; i<argc; ) {
+ UINFO(9, " Option: "<<argv[i]<<endl);
+ if (argv[i][0]=='-') {
+ const char *sw = argv[i];
+ bool flag = true;
+ // Allow gnu -- switches
+ if (sw[0]=='-' && sw[1]=='-') ++sw;
+ if (0) {}
+ // Single switches
+ else if ( onoff (sw, "-annotate-all", flag/*ref*/) ) { m_annotateAll = flag; }
+ else if ( onoff (sw, "-rank", flag/*ref*/) ) { m_rank = flag; }
+ else if ( onoff (sw, "-unlink", flag/*ref*/) ) { m_unlink = flag; }
+ // Parameterized switches
+ else if ( !strcmp (sw, "-annotate") && (i+1)<argc ) {
+ shift;
+ m_annotateOut = argv[i];
+ }
+ else if ( !strcmp (sw, "-debug") ) {
+ V3Error::debugDefault(3);
+ }
+ else if ( !strcmp (sw, "-debugi") && (i+1)<argc ) {
+ shift;
+ V3Error::debugDefault(atoi(argv[i]));
+ }
+ else if ( !strcmp (sw, "-V") ) {
+ showVersion(true);
+ exit(0);
+ }
+ else if ( !strcmp (sw, "-version") ) {
+ showVersion(false);
+ exit(0);
+ }
+ else if ( !strcmp (sw, "-write") && (i+1)<argc ) {
+ shift;
+ m_writeFile = argv[i];
+ }
+ else {
+ v3fatal ("Invalid option: "<<argv[i]);
+ }
+ shift;
+ } // - options
+ else if (1) {
+ addReadFile(argv[i]);
+ shift;
+ }
+ else {
+ v3fatal ("Invalid argument: "<<argv[i]);
+ shift;
+ }
+ }
+#undef shift
+}
+
+void VlcOptions::showVersion(bool verbose) {
+ cout <<version();
+ cout <<endl;
+ if (!verbose) return;
+
+ cout <<endl;
+ cout << "Copyright 2003-2014 by Wilson Snyder. Verilator is free software; you can\n";
+ cout << "redistribute it and/or modify the Verilator internals under the terms of\n";
+ cout << "either the GNU Lesser General Public License Version 3 or the Perl Artistic\n";
+ cout << "License Version 2.0.\n";
+
+ cout <<endl;
+ cout << "See http://www.veripool.org/verilator for documentation\n";
+}
+
+//######################################################################
+// File searching
+// (TODO: Make a V3Os with these functions and share with Verilator)
+
+string VlcOptions::filenameNonDir (const string& filename) {
+ string::size_type pos;
+ if ((pos = filename.rfind("/")) != string::npos) {
+ return filename.substr(pos+1);
+ } else {
+ return filename;
+ }
+}
+
+//######################################################################
+
+int main(int argc, char** argv, char** env) {
+ // General initialization
+ ios::sync_with_stdio();
+
+ VlcTop top;
+
+ // Command option parsing
+ top.opt.parseOptsList(argc-1, argv+1);
+
+ if (top.opt.readFiles().empty()) {
+ top.opt.addReadFile("vlt_coverage.pl");
+ }
+
+ const VlStringSet& readFiles = top.opt.readFiles();
+ for (VlStringSet::iterator it = readFiles.begin(); it != readFiles.end(); ++it) {
+ string filename = *it;
+ top.readCoverage(filename);
+ }
+
+ if (debug() >= 9) {
+ top.tests().dump(true);
+ top.points().dump();
+ }
+
+ V3Error::abortIfWarnings();
+ if (top.opt.annotateOut() != "") {
+ top.annotate(top.opt.annotateOut());
+ }
+
+ if (top.opt.rank()) {
+ top.rank();
+ top.tests().dump(false);
+ }
+
+ if (top.opt.writeFile() != "") {
+ top.writeCoverage(top.opt.writeFile());
+ V3Error::abortIfWarnings();
+ if (top.opt.unlink()) {
+ const VlStringSet& readFiles = top.opt.readFiles();
+ for (VlStringSet::iterator it = readFiles.begin(); it != readFiles.end(); ++it) {
+ string filename = *it;
+ unlink(filename.c_str());
+ }
+ }
+ }
+
+ // Final writing shouldn't throw warnings, but...
+ V3Error::abortIfWarnings();
+
+ UINFO(1,"Done, Exiting...\n");
+}
+
+// Local Variables:
+// compile-command: "v4make bin/verilator_coverage --debugi 9 test_regress/t/t_vlcov_data_*.dat"
+// End:
+
diff --git a/src/VlcOptions.h b/src/VlcOptions.h
new file mode 100644
index 0000000..d644085
--- /dev/null
+++ b/src/VlcOptions.h
@@ -0,0 +1,87 @@
+// -*- mode: C++; c-file-style: "cc-mode" -*-
+//*************************************************************************
+// DESCRIPTION: verilator_coverage: Command line options
+//
+// Code available from: http://www.veripool.org/verilator
+//
+//*************************************************************************
+//
+// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
+// redistribute it and/or modify it under the terms of either the GNU
+// Lesser General Public License Version 3 or the Perl Artistic License
+// Version 2.0.
+//
+// Verilator is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+//*************************************************************************
+
+#ifndef _VLCOPTIONS_H_
+#define _VLCOPTIONS_H_ 1
+
+#include "config_build.h"
+#include "verilatedos.h"
+#include <string>
+#include <vector>
+#include <map>
+#include <set>
+
+#include "config_rev.h"
+
+//######################################################################
+// V3Options - Command line options
+
+typedef vector<string> VlStringList;
+typedef set<string> VlStringSet;
+
+class VlcOptions {
+ // MEMBERS (general options)
+ string m_annotateOut; // main switch: --annotate I<output_directory>
+ bool m_annotateAll; // main switch: --annotate-all
+ int m_annotateMin; // main switch: --annotate-min I<count>
+ VlStringSet m_readFiles; // main switch: --read
+ bool m_rank; // main switch: --rank
+ bool m_unlink; // main switch: --unlink
+ string m_writeFile; // main switch: --write
+
+private:
+ // METHODS
+ void showVersion(bool verbose);
+ bool onoff(const char* sw, const char* arg, bool& flag);
+
+public:
+ // CREATORS
+ VlcOptions() {
+ m_annotateAll = false;
+ m_annotateMin = 10;
+ m_rank = false;
+ m_unlink = false;
+ }
+ ~VlcOptions() {}
+ void setDebugMode(int level);
+
+ // METHODS
+ void parseOptsList(int argc, char** argv);
+ void addReadFile(const string& filename);
+
+ // ACCESSORS (options)
+ const VlStringSet& readFiles() const { return m_readFiles; }
+ string annotateOut() const { return m_annotateOut; }
+ bool annotateAll() const { return m_annotateAll; }
+ int annotateMin() const { return m_annotateMin; }
+ bool rank() const { return m_rank; }
+ bool unlink() const { return m_unlink; }
+ string writeFile() const { return m_writeFile; }
+
+ // METHODS (from main)
+ static string version();
+
+ // METHODS (file searching)
+ static string filenameNonDir(const string& filename);
+};
+
+//######################################################################
+
+#endif // guard
diff --git a/src/VlcPoint.h b/src/VlcPoint.h
new file mode 100644
index 0000000..a2aabb3
--- /dev/null
+++ b/src/VlcPoint.h
@@ -0,0 +1,152 @@
+// -*- mode: C++; c-file-style: "cc-mode" -*-
+//*************************************************************************
+// DESCRIPTION: verilator_coverage: Coverage points
+//
+// Code available from: http://www.veripool.org/verilator
+//
+//*************************************************************************
+//
+// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
+// redistribute it and/or modify it under the terms of either the GNU
+// Lesser General Public License Version 3 or the Perl Artistic License
+// Version 2.0.
+//
+// Verilator is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+//*************************************************************************
+
+#ifndef _VLCPOINT_H_
+#define _VLCPOINT_H_ 1
+
+#include "config_build.h"
+#include "verilatedos.h"
+#include "verilated_cov_key.h"
+#include <map>
+#include <vector>
+#include <iomanip>
+
+//********************************************************************
+// VlcPoint - A coverage point (across all tests)
+
+class VlcPoint {
+private:
+ // MEMBERS
+ string m_name; //< Name of the point
+ vluint64_t m_pointNum; //< Point number
+ vluint64_t m_testsCovering;//< Number tests with non-zero coverage of this point
+ vluint64_t m_count; //< Count of hits across all tests
+
+public:
+ // CONSTRUCTORS
+ VlcPoint(const string& name, int pointNum) {
+ m_name = name;
+ m_pointNum = pointNum;
+ m_testsCovering = 0;
+ m_count = 0;
+ }
+ ~VlcPoint() {}
+ // ACCESSORS
+ const string& name() const { return m_name; }
+ vluint64_t pointNum() const { return m_pointNum; }
+ vluint64_t testsCovering() const { return m_testsCovering; }
+ void countInc(vluint64_t inc) { m_count += inc; }
+ vluint64_t count() const { return m_count; }
+ void testsCoveringInc() { m_testsCovering++; }
+ // KEY ACCESSORS
+ string filename() const { return keyExtract(VL_CIK_FILENAME); }
+ string comment() const { return keyExtract(VL_CIK_COMMENT); }
+ string type() const { return keyExtract(VL_CIK_TYPE); }
+ string thresh() const { return keyExtract(VL_CIK_THRESH); } // string as maybe ""
+ int lineno() const { return atoi(keyExtract(VL_CIK_LINENO).c_str()); }
+ int column() const { return atoi(keyExtract(VL_CIK_COLUMN).c_str()); }
+ // METHODS
+ string keyExtract(const char* shortKey) const {
+ // Hot function
+ size_t shortLen = strlen(shortKey);
+ const string namestr = name();
+ for (const char* cp = namestr.c_str(); *cp; ++cp) {
+ if (*cp == '\001') {
+ if (0==strncmp(cp+1, shortKey, shortLen)
+ && cp[shortLen+1] == '\002') {
+ cp += shortLen+2; // Skip \001+short+\002
+ const char* ep = cp;
+ while (*ep && *ep != '\001') ++ep;
+ return string(cp, ep-cp);
+ }
+ }
+ }
+ return "";
+ }
+ static void dumpHeader() {
+ cout<<"Points:\n";
+ cout<<" Num, TestsCover, Count, Name"<<endl;
+ }
+ void dump() const {
+ cout<<" "<<setw(8)<<setfill('0')<<pointNum()
+ <<", "<<setw(7)<<setfill(' ')<<testsCovering()
+ <<", "<<setw(7)<<setfill(' ')<<count()
+ <<", \""<<name()<<"\""<<endl;
+ }
+};
+
+//********************************************************************
+// VlcPoints - Container of all points
+
+class VlcPoints {
+private:
+ // MEMBERS
+ typedef std::map<string,vluint64_t> NameMap;
+ NameMap m_nameMap; //< Name to point-number
+ vector<VlcPoint> m_points; //< List of all points
+ vluint64_t m_numPoints; //< Total unique points
+
+public:
+ // ITERATORS
+ typedef NameMap ByName;
+ typedef ByName::iterator iterator;
+ ByName::iterator begin() { return m_nameMap.begin(); }
+ ByName::iterator end() { return m_nameMap.end(); }
+
+public:
+ // CONSTRUCTORS
+ VlcPoints() {
+ m_numPoints = 0;
+ }
+ ~VlcPoints() {}
+
+ // METHODS
+ void dump() {
+ UINFO(2,"dumpPoints...\n");
+ VlcPoint::dumpHeader();
+ for (VlcPoints::ByName::iterator it=begin(); it!=end(); ++it) {
+ const VlcPoint& point = pointNumber(it->second);
+ point.dump();
+ }
+ }
+ VlcPoint& pointNumber(vluint64_t num) {
+ return m_points[num];
+ }
+ vluint64_t findAddPoint(const string& name, vluint64_t count) {
+ vluint64_t pointnum;
+ NameMap::iterator iter = m_nameMap.find(name);
+ if (iter != m_nameMap.end()) {
+ pointnum = iter->second;
+ m_points[pointnum].countInc(count);
+ }
+ else {
+ pointnum = m_numPoints++;
+ VlcPoint point (name, pointnum);
+ point.countInc(count);
+ m_points.push_back(point);
+ m_nameMap.insert(make_pair(point.name(), point.pointNum()));
+ }
+ return pointnum;
+ }
+};
+
+//######################################################################
+
+#endif // guard
diff --git a/src/VlcSource.h b/src/VlcSource.h
new file mode 100644
index 0000000..fc7e344
--- /dev/null
+++ b/src/VlcSource.h
@@ -0,0 +1,145 @@
+// -*- mode: C++; c-file-style: "cc-mode" -*-
+//*************************************************************************
+// DESCRIPTION: verilator_coverage: Source file to annotate with line coverage
+//
+// Code available from: http://www.veripool.org/verilator
+//
+//*************************************************************************
+//
+// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
+// redistribute it and/or modify it under the terms of either the GNU
+// Lesser General Public License Version 3 or the Perl Artistic License
+// Version 2.0.
+//
+// Verilator is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+//*************************************************************************
+
+#ifndef _VLCSOURCE_H_
+#define _VLCSOURCE_H_ 1
+
+#include "config_build.h"
+#include "verilatedos.h"
+#include <map>
+#include <vector>
+
+//********************************************************************
+// VlcColumnCount - count at specific source file, line and column
+
+class VlcSourceCount {
+private:
+ // MEMBERS
+ int m_lineno; ///< Line number
+ int m_column; ///< Column number
+ vluint64_t m_count; ///< Count
+ bool m_ok; ///< Coverage is above threshold
+
+public:
+ // CONSTRUCTORS
+ VlcSourceCount(int lineno, int column) {
+ m_lineno = lineno;
+ m_column = column;
+ m_count = 0;
+ m_ok = false;
+ }
+ ~VlcSourceCount() {}
+
+ // ACCESSORS
+ int lineno() const { return m_lineno; }
+ int column() const { return m_column; }
+ vluint64_t count() const { return m_count; }
+ bool ok() const { return m_ok; }
+
+ // METHODS
+ void incCount(vluint64_t count, bool ok) {
+ m_count += count;
+ if (ok) m_ok = true;
+ }
+};
+
+//********************************************************************
+// VlcSource - source file to annotate
+
+class VlcSource {
+public:
+ // TYPES
+ typedef map<int,VlcSourceCount> ColumnMap; // Map of {column}
+ typedef map<int,ColumnMap> LinenoMap; // Map of {lineno}{column}
+
+private:
+ // MEMBERS
+ string m_name; //< Name of the source file
+ bool m_needed; //< Need to annotate; has low coverage
+ LinenoMap m_lines; //< Map of each annotated line
+
+public:
+ // CONSTRUCTORS
+ VlcSource(const string& name) {
+ m_name = name;
+ m_needed = false;
+ }
+ ~VlcSource() {}
+
+ // ACCESSORS
+ const string& name() const { return m_name; }
+ void needed(bool flag) { m_needed = flag; }
+ bool needed() const { return m_needed; }
+ LinenoMap& lines() { return m_lines; }
+
+ // METHODS
+ void incCount(int lineno, int column, vluint64_t count, bool ok) {
+ LinenoMap::iterator lit = m_lines.find(lineno);
+ if (lit == m_lines.end()) {
+ lit = m_lines.insert(make_pair(lineno,ColumnMap())).first;
+ }
+ ColumnMap& cmap = lit->second;
+ ColumnMap::iterator cit = cmap.find(column);
+ if (cit == cmap.end()) {
+ cit = cmap.insert(make_pair(column,VlcSourceCount(lineno, column))).first;
+ }
+ VlcSourceCount& sc = cit->second;
+ sc.incCount(count,ok);
+ }
+};
+
+//********************************************************************
+// VlcSources - Container of all source files
+
+class VlcSources {
+public:
+ // TYPES
+ typedef map<string,VlcSource> NameMap;
+private:
+ // MEMBERS
+ NameMap m_sources; //< List of all sources
+
+public:
+ // ITERATORS
+ typedef NameMap::iterator iterator;
+ NameMap::iterator begin() { return m_sources.begin(); }
+ NameMap::iterator end() { return m_sources.end(); }
+
+public:
+ // CONSTRUCTORS
+ VlcSources() {}
+ ~VlcSources() {}
+
+ // METHODS
+ VlcSource& findNewSource(const string& name) {
+ NameMap::iterator iter = m_sources.find(name);
+ if (iter != m_sources.end()) {
+ return iter->second;
+ }
+ else {
+ iter = m_sources.insert(make_pair(name, VlcSource(name))).first;
+ return iter->second;
+ }
+ }
+};
+
+//######################################################################
+
+#endif // Guard
diff --git a/src/VlcTest.h b/src/VlcTest.h
new file mode 100644
index 0000000..63675de
--- /dev/null
+++ b/src/VlcTest.h
@@ -0,0 +1,137 @@
+// -*- mode: C++; c-file-style: "cc-mode" -*-
+//*************************************************************************
+// DESCRIPTION: verilator_coverage: Test/coverage file container
+//
+// Code available from: http://www.veripool.org/verilator
+//
+//*************************************************************************
+//
+// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
+// redistribute it and/or modify it under the terms of either the GNU
+// Lesser General Public License Version 3 or the Perl Artistic License
+// Version 2.0.
+//
+// Verilator is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+//*************************************************************************
+
+#ifndef _VLCTEST_H_
+#define _VLCTEST_H_ 1
+
+#include "config_build.h"
+#include "verilatedos.h"
+#include "VlcPoint.h"
+#include "VlcBucket.h"
+#include <map>
+#include <vector>
+
+//********************************************************************
+// VlcTest - a single testrun i.e. a file containing coverage data
+
+class VlcTest {
+private:
+ // MEMBERS
+ string m_name; //< Name of the test
+ double m_computrons; //< Runtime for the test
+ vluint64_t m_testrun; //< Test run number, for database use
+ vluint64_t m_rank; //< Execution rank suggestion
+ vluint64_t m_rankPoints; //< Ranked additional points
+ vluint64_t m_user; //< User data for algorithms (not persisted in .dat file)
+ VlcBuckets m_buckets; //< Coverage data for each coverage point
+
+public:
+ // CONSTRUCTORS
+ VlcTest(const string& name, vluint64_t testrun, double comp) {
+ m_name = name;
+ m_computrons = comp;
+ m_testrun = testrun;
+ m_rank = 0;
+ m_rankPoints = 0;
+ m_user = 0;
+ }
+ ~VlcTest() {}
+
+ // ACCESSORS
+ const string& name() const { return m_name; }
+ double computrons() const { return m_computrons; }
+ vluint64_t testrun() const { return m_testrun; }
+ VlcBuckets& buckets() { return m_buckets; }
+ vluint64_t bucketsCovered() const { return m_buckets.bucketsCovered(); }
+ vluint64_t rank() const { return m_rank; }
+ void rank(vluint64_t flag) { m_rank = flag; }
+ vluint64_t rankPoints() const { return m_rankPoints; }
+ void rankPoints(vluint64_t flag) { m_rankPoints = flag; }
+ vluint64_t user() const { return m_user; }
+ void user(vluint64_t flag) { m_user = flag; }
+
+ // METHODS
+ static void dumpHeader() {
+ cout<<"Tests:\n";
+ //cout<<" Testrun, Computrons,"; // Currently not loaded
+ cout<<" Covered, Rank, RankPts, Filename"<<endl;
+ }
+ void dump(bool bucketsToo) {
+ if (testrun() || computrons()) {
+ cout<<" "<<setw(8)<<setfill('0')<<testrun()
+ <<", "<<setw(7)<<setfill(' ')<<computrons()<<",";
+ }
+ cout<<" "<<setw(7)<<setfill(' ')<<bucketsCovered()
+ <<", "<<setw(7)<<setfill(' ')<<rank()
+ <<", "<<setw(7)<<setfill(' ')<<rankPoints()
+ <<", \""<<name()<<"\""<<endl;
+ if (bucketsToo) m_buckets.dump();
+ }
+};
+
+//********************************************************************
+// VlcTests - Container of all tests
+
+class VlcTests {
+public:
+ // TYPES
+ typedef vector<VlcTest*> ByName;
+private:
+ // MEMBERS
+ ByName m_tests; //< List of all tests
+
+public:
+ // ITERATORS
+ typedef ByName::iterator iterator;
+ ByName::iterator begin() { return m_tests.begin(); }
+ ByName::iterator end() { return m_tests.end(); }
+
+public:
+ // CONSTRUCTORS
+ VlcTests() {}
+ ~VlcTests() {
+ for (VlcTests::ByName::iterator it=begin(); it!=end(); ++it) {
+ delete *it; *it=NULL;
+ }
+ }
+
+ // METHODS
+ void dump(bool bucketsToo) {
+ UINFO(2,"dumpTests...\n");
+ VlcTest::dumpHeader();
+ for (VlcTests::ByName::iterator it=begin(); it!=end(); ++it) {
+ (*it)->dump(bucketsToo);
+ }
+ }
+ VlcTest* newTest(const string& name, vluint64_t testrun, double comp) {
+ VlcTest* testp = new VlcTest(name, testrun, comp);
+ m_tests.push_back(testp);
+ return testp;
+ }
+ void clearUser() {
+ for (ByName::iterator it = m_tests.begin(); it != m_tests.end(); ++it) {
+ (*it)->user(0);
+ }
+ }
+};
+
+//######################################################################
+
+#endif // Guard
diff --git a/src/VlcTop.cpp b/src/VlcTop.cpp
new file mode 100644
index 0000000..b71be0d
--- /dev/null
+++ b/src/VlcTop.cpp
@@ -0,0 +1,263 @@
+// -*- mode: C++; c-file-style: "cc-mode" -*-
+//*************************************************************************
+// DESCRIPTION: verilator_coverage: top implementation
+//
+// Code available from: http://www.veripool.org/verilator
+//
+//*************************************************************************
+//
+// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
+// redistribute it and/or modify it under the terms of either the GNU
+// Lesser General Public License Version 3 or the Perl Artistic License
+// Version 2.0.
+//
+// Verilator is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+//*************************************************************************
+
+// Cheat for speed and compile .cpp files into one object
+#include "V3Error.h"
+#include "VlcOptions.h"
+#include "VlcTop.h"
+
+#include <sys/stat.h>
+#include <fstream>
+#include <algorithm>
+
+//######################################################################
+
+void VlcTop::readCoverage(const string& filename, bool nonfatal) {
+ UINFO(2,"readCoverage "<<filename<<endl);
+
+ ifstream is (filename.c_str());
+ if (!is) {
+ if (!nonfatal) v3fatal("Can't read "<<filename);
+ return;
+ }
+
+ // Testrun and computrons argument unsupported as yet
+ VlcTest* testp = tests().newTest(filename, 0, 0);
+
+ while (!is.eof()) {
+ string line;
+ getline(is, line);
+ //UINFO(9," got "<<line<<endl);
+ if (line[0] == 'C') {
+ string::size_type secspace=3;
+ for (; secspace<line.length(); secspace++) {
+ if (line[secspace]=='\'' && line[secspace+1]==' ') break;
+ }
+ string point = line.substr(3,secspace-3);
+ vluint64_t hits = atoll(line.c_str()+secspace+1);
+ //UINFO(9," point '"<<point<<"'"<<" "<<hits<<endl);
+
+ vluint64_t pointnum = points().findAddPoint(point, hits);
+ if (pointnum) {} // Prevent unused
+ if (opt.rank()) { // Only if ranking - uses a lot of memory
+ if (hits >= VlcBuckets::sufficient()) {
+ points().pointNumber(pointnum).testsCoveringInc();
+ testp->buckets().addData(pointnum, hits);
+ }
+ }
+ }
+ }
+}
+
+void VlcTop::writeCoverage(const string& filename) {
+ UINFO(2,"writeCoverage "<<filename<<endl);
+
+ ofstream os (filename.c_str());
+ if (!os) {
+ v3fatal("Can't write "<<filename);
+ return;
+ }
+
+ os << "# SystemC::Coverage-3" << endl;
+ for (VlcPoints::ByName::iterator it=m_points.begin(); it!=m_points.end(); ++it) {
+ const VlcPoint& point = m_points.pointNumber(it->second);
+ os <<"C '"<<point.name()<<"' " << point.count()<<endl;
+ }
+}
+
+//********************************************************************
+
+struct CmpComputrons {
+ inline bool operator () (const VlcTest* lhsp, const VlcTest* rhsp) const {
+ if (lhsp->computrons() != rhsp->computrons()) {
+ return lhsp->computrons() < rhsp->computrons();
+ }
+ return lhsp->bucketsCovered() > rhsp->bucketsCovered();
+ }
+};
+
+void VlcTop::rank() {
+ UINFO(2,"rank...\n");
+ vluint64_t nextrank=1;
+
+ // Sort by computrons, so fast tests get selected first
+ vector<VlcTest*> bytime;
+ for (VlcTests::ByName::iterator it=m_tests.begin(); it!=m_tests.end(); ++it) {
+ VlcTest* testp = *it;
+ if (testp->bucketsCovered()) { // else no points, so can't help us
+ bytime.push_back(*it);
+ }
+ }
+ sort(bytime.begin(), bytime.end(), CmpComputrons()); // Sort the vector
+
+ VlcBuckets remaining;
+ for (VlcPoints::ByName::iterator it=m_points.begin(); it!=m_points.end(); ++it) {
+ VlcPoint* pointp = &points().pointNumber(it->second);
+ // If any tests hit this point, then we'll need to cover it.
+ if (pointp->testsCovering()) { remaining.addData(pointp->pointNum(), 1); }
+ }
+
+ // Additional Greedy algorithm
+ // O(n^2) Ouch. Probably the thing to do is randomize the order of data
+ // then hierarchically solve a small subset of tests, and take resulting
+ // solution and move up to larger subset of tests. (Aka quick sort.)
+ while (1) {
+ if (debug()) { UINFO(9,"Left on iter"<<nextrank<<": "); remaining.dump(); }
+ VlcTest* bestTestp = NULL;
+ vluint64_t bestRemain = 0;
+ for (vector<VlcTest*>::iterator it=bytime.begin(); it!=bytime.end(); ++it) {
+ VlcTest* testp = *it;
+ if (!testp->rank()) {
+ vluint64_t remain = testp->buckets().dataPopCount(remaining);
+ if (remain > bestRemain) {
+ bestTestp = testp;
+ bestRemain = remain;
+ }
+ }
+ }
+ if (VlcTest* testp = bestTestp) {
+ testp->rank(nextrank++);
+ testp->rankPoints(bestRemain);
+ remaining.orData(bestTestp->buckets());
+ } else {
+ break; // No test covering more stuff found
+ }
+ }
+}
+
+//######################################################################
+
+void VlcTop::annotateCalc() {
+ // Calculate per-line information into filedata structure
+ for (VlcPoints::ByName::iterator it=m_points.begin(); it!=m_points.end(); ++it) {
+ const VlcPoint& point = m_points.pointNumber(it->second);
+ string filename = point.filename();
+ int lineno = point.lineno();
+ if (filename!="" && lineno!=0) {
+ int column = point.column();
+ VlcSource& source = sources().findNewSource(filename);
+ string threshStr = point.thresh();
+ unsigned thresh = (threshStr!="") ? atoi(threshStr.c_str()) : opt.annotateMin();
+ bool ok = (point.count() >= thresh);
+ UINFO(9, "AnnoCalc count "<<filename<<" "<<lineno<<" "<<point.count()<<endl);
+ source.incCount(lineno, column, point.count(), ok);
+ }
+ }
+}
+
+void VlcTop::annotateCalcNeeded() {
+ // Compute which files are needed. A file isn't needed if it has appropriate
+ // coverage in all categories
+ int totCases = 0;
+ int totOk = 0;
+ for (VlcSources::NameMap::iterator sit=m_sources.begin(); sit!=m_sources.end(); ++sit) {
+ VlcSource& source = sit->second;
+ //UINFO(1,"Source "<<source.name()<<endl);
+ if (opt.annotateAll()) source.needed(true);
+ VlcSource::LinenoMap& lines = source.lines();
+ for (VlcSource::LinenoMap::iterator lit=lines.begin(); lit!=lines.end(); ++lit) {
+ VlcSource::ColumnMap& cmap = lit->second;
+ for (VlcSource::ColumnMap::iterator cit=cmap.begin(); cit!=cmap.end(); ++cit) {
+ VlcSourceCount& col = cit->second;
+ //UINFO(0,"Source "<<source.name()<<" lineno="<<col.lineno()<<" col="<<col.column()<<endl);
+ ++totCases;
+ if (col.ok()) {
+ ++totOk;
+ } else {
+ source.needed(true);
+ }
+ }
+ }
+ }
+ float pct = totCases ? (100*totOk / totCases) : 0;
+ cout<<"Total coverage ("<<totOk<<"/"<<totCases<<") "
+ <<fixed<<setw(3)<<setprecision(2)<<pct<<"%"<<endl;
+ if (totOk != totCases) cout<<"See lines with '%00' in "<<opt.annotateOut()<<endl;
+}
+
+void VlcTop::annotateOutputFiles(const string& dirname) {
+ // Create if uncreated, ignore errors
+ mkdir(dirname.c_str(), 0777);
+ for (VlcSources::NameMap::iterator sit=m_sources.begin(); sit!=m_sources.end(); ++sit) {
+ VlcSource& source = sit->second;
+ if (!source.needed()) continue;
+ string filename = source.name();
+ string outfilename = dirname+"/"+VlcOptions::filenameNonDir(filename);
+
+ UINFO(1,"annotateOutputFile "<<filename<<" -> "<<outfilename<<endl);
+
+ ifstream is (filename.c_str());
+ if (!is) {
+ v3error("Can't read "<<filename);
+ return;
+ }
+
+ ofstream os (outfilename.c_str());
+ if (!os) {
+ v3fatal("Can't write "<<outfilename);
+ return;
+ }
+
+ os << "\t// verilator_coverage annotation"<<endl;
+
+ int lineno = 0;
+ while (!is.eof()) {
+ lineno++;
+ string line;
+ getline(is, line);
+
+ bool first = true;
+
+ VlcSource::LinenoMap& lines = source.lines();
+ VlcSource::LinenoMap::iterator lit=lines.find(lineno);
+ if (lit != lines.end()) {
+ VlcSource::ColumnMap& cmap = lit->second;
+ for (VlcSource::ColumnMap::iterator cit=cmap.begin(); cit!=cmap.end(); ++cit) {
+ VlcSourceCount& col = cit->second;
+ //UINFO(0,"Source "<<source.name()<<" lineno="<<col.lineno()<<" col="<<col.column()<<endl);
+ os<<(col.ok()?" ":"%")
+ <<setfill('0')<<setw(6)<<col.count()
+ <<"\t"<<line<<endl;
+ if (first) {
+ first = false;
+ // Multiple columns on same line; print line just once
+ string indent = "";
+ for (const char* cp=line.c_str(); isspace(*cp); ++cp) {
+ indent += *cp;
+ }
+ line = indent + "verilator_coverage: (next point on previous line)\n";
+ }
+ }
+ }
+
+ if (first) {
+ os<<"\t"<<line<<endl;
+ }
+ }
+ }
+}
+
+void VlcTop::annotate(const string& dirname) {
+ // Calculate per-line information into filedata structure
+ annotateCalc();
+ annotateCalcNeeded();
+ annotateOutputFiles(dirname);
+}
+
diff --git a/src/VlcTop.h b/src/VlcTop.h
new file mode 100644
index 0000000..5c34c18
--- /dev/null
+++ b/src/VlcTop.h
@@ -0,0 +1,69 @@
+// -*- mode: C++; c-file-style: "cc-mode" -*-
+//*************************************************************************
+// DESCRIPTION: verilator_coverage: Top global container
+//
+// Code available from: http://www.veripool.org/verilator
+//
+//*************************************************************************
+//
+// Copyright 2003-2014 by Wilson Snyder. This program is free software; you can
+// redistribute it and/or modify it under the terms of either the GNU
+// Lesser General Public License Version 3 or the Perl Artistic License
+// Version 2.0.
+//
+// Verilator is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+//*************************************************************************
+
+#ifndef _VLCTOP_H_
+#define _VLCTOP_H_ 1
+
+#include "config_build.h"
+#include "verilatedos.h"
+#include "VlcOptions.h"
+#include "VlcTest.h"
+#include "VlcPoint.h"
+#include "VlcSource.h"
+
+//######################################################################
+// VlcTop - Top level options container
+
+class VlcTop {
+public:
+ // PUBLIC MEMBERS
+ VlcOptions opt; //< Runtime options
+private:
+ // MEMBERS
+ VlcTests m_tests; //< List of all tests (all coverage files)
+ VlcPoints m_points; //< List of all points
+ VlcSources m_sources; //< List of all source files to annotate
+
+ // METHODS
+ void annotateCalc();
+ void annotateCalcNeeded();
+ void annotateOutputFiles(const string& dirname);
+
+public:
+ // CONSTRUCTORS
+ VlcTop() {}
+ ~VlcTop() {}
+
+ // ACCESSORS
+ VlcTests& tests() { return m_tests; }
+ VlcPoints& points() { return m_points; }
+ VlcSources& sources() { return m_sources; }
+
+ // METHODS
+ void annotate(const string& dirname);
+ void readCoverage(const string& filename, bool nonfatal=false);
+ void writeCoverage(const string& filename);
+
+ void rank();
+};
+
+//######################################################################
+
+#endif // guard
diff --git a/src/astgen b/src/astgen
index 042f9ba..e0c7885 100755
--- a/src/astgen
+++ b/src/astgen
@@ -19,8 +19,8 @@ my @Opt_Cpt;
my @Opt_I;
Getopt::Long::config ("pass_through", "no_auto_abbrev");
if (! GetOptions (
- "help" => \&report,
- "debug" => \&debug,
+ "help" => \&usage,
+ "debug" => sub { $Debug = 1; },
"classes!" => \$opt_classes,
"report!" => \$opt_report,
"<>" => \¶meter,
@@ -54,10 +54,6 @@ sub usage {
exit (1);
}
-sub debug {
- $Debug = 1;
-}
-
sub parameter {
my $param = shift;
if ($param =~ /^-+I(\S+)/) {
diff --git a/src/config_build.h b/src/config_build.h
index b254886..3e3b8c9 100644
--- a/src/config_build.h
+++ b/src/config_build.h
@@ -27,7 +27,7 @@
//**** Version and host name
// Autoconf substitutes this with the strings from AC_INIT.
-#define PACKAGE_STRING "Verilator 3.866 2014-11-15"
+#define PACKAGE_STRING "Verilator 3.868 2014-12-20"
#define DTVERSION PACKAGE_STRING
diff --git a/src/config_rev.h b/src/config_rev.h
index 42c6ac1..af201f2 100644
--- a/src/config_rev.h
+++ b/src/config_rev.h
@@ -1 +1 @@
-static const char* DTVERSION_rev = "verilator_3_864-18-g55f0d4d";
+static const char* DTVERSION_rev = "verilator_3_866-36-g1a3378e";
diff --git a/src/verilog.l b/src/verilog.l
index f45b20b..d73342c 100644
--- a/src/verilog.l
+++ b/src/verilog.l
@@ -103,8 +103,6 @@ void V3ParseImp::verilatorCmtBad(const char* textp) {
}
// See V3Read.cpp
-//void V3ParseImp::stateExitPsl() { BEGIN VLG; }
-//void V3ParseImp::statePushVlg() { yy_push_state(VLG); }
//void V3ParseImp::statePop() { yy_pop_state(); }
//======================================================================
@@ -138,7 +136,7 @@ void yyerrorf(const char* format, ...) {
%s V95 V01 V05 S05 S09 S12
%s STRING ATTRMODE TABLE
-%s VA5 SAX PSL VLT
+%s VA5 SAX VLT
%s SYSCHDR SYSCINT SYSCIMP SYSCIMPH SYSCCTOR SYSCDTOR
%s IGNORE
@@ -179,7 +177,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
/************************************************************************/
/* Verilog 1995 */
-<V95,V01,V05,VA5,S05,S09,S12,SAX,PSL>{
+<V95,V01,V05,VA5,S05,S09,S12,SAX>{
{ws} { } /* otherwise ignore white-space */
{crnl} { NEXTLINE(); } /* Count line numbers */
/* Extensions to Verilog set, some specified by PSL */
@@ -352,7 +350,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
}
/* Verilog 2001 */
-<V01,V05,VA5,S05,S09,S12,SAX,PSL>{
+<V01,V05,VA5,S05,S09,S12,SAX>{
/* System Tasks */
"$signed" { FL; return yD_SIGNED; }
"$unsigned" { FL; return yD_UNSIGNED; }
@@ -383,13 +381,13 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
}
/* Verilog 2005 */
-<V05,S05,S09,S12,SAX,PSL>{
+<V05,S05,S09,S12,SAX>{
/* Keywords */
"uwire" { FL; return yWIRE; }
}
/* System Verilog 2005 */
-<S05,S09,S12,SAX,PSL>{
+<S05,S09,S12,SAX>{
/* System Tasks */
"$bits" { FL; return yD_BITS; }
"$clog2" { FL; return yD_CLOG2; }
@@ -414,18 +412,21 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"always_comb" { FL; return yALWAYS_COMB; }
"always_ff" { FL; return yALWAYS_FF; }
"always_latch" { FL; return yALWAYS_LATCH; }
+ "assert" { FL; return yASSERT; }
"bind" { FL; return yBIND; }
"bit" { FL; return yBIT; }
"break" { FL; return yBREAK; }
"byte" { FL; return yBYTE; }
"chandle" { FL; return yCHANDLE; }
"clocking" { FL; return yCLOCKING; }
+ "const" { FL; return yCONST__LEX; }
"context" { FL; return yCONTEXT; }
"continue" { FL; return yCONTINUE; }
+ "cover" { FL; return yCOVER; }
"do" { FL; return yDO; }
"endclocking" { FL; return yENDCLOCKING; }
- "endpackage" { FL; return yENDPACKAGE; }
"endinterface" { FL; return yENDINTERFACE; }
+ "endpackage" { FL; return yENDPACKAGE; }
"endprogram" { FL; return yENDPROGRAM; }
"endproperty" { FL; return yENDPROPERTY; }
"enum" { FL; return yENUM; }
@@ -434,8 +435,8 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"iff" { FL; return yIFF; }
"import" { FL; return yIMPORT; }
"inside" { FL; return yINSIDE; }
- "interface" { FL; return yINTERFACE; }
"int" { FL; return yINT; }
+ "interface" { FL; return yINTERFACE; }
"logic" { FL; return yLOGIC; }
"longint" { FL; return yLONGINT; }
"modport" { FL; return yMODPORT; }
@@ -443,6 +444,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"packed" { FL; return yPACKED; }
"priority" { FL; return yPRIORITY; }
"program" { FL; return yPROGRAM; }
+ "property" { FL; return yPROPERTY; }
"pure" { FL; return yPURE; }
"rand" { FL; return yRAND; }
"randc" { FL; return yRANDC; }
@@ -454,6 +456,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"timeprecision" { FL; return yTIMEPRECISION; }
"timeunit" { FL; return yTIMEUNIT; }
"typedef" { FL; return yTYPEDEF; }
+ "union" { FL; return yUNION; }
"unique" { FL; return yUNIQUE; }
"var" { FL; return yVAR; }
"void" { FL; return yVOID; }
@@ -461,6 +464,8 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
/* Note assert_strobe was in SystemVerilog 3.1, but removed for SystemVerilog 2005 */
"$root" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"alias" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
+ "assume" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
+ "before" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"bins" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"binsof" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"class" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
@@ -492,6 +497,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"randomize" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"randsequence" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"ref" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
+ "sequence" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"shortreal" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"solve" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"super" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
@@ -503,25 +509,11 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"wait_order" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"wildcard" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
"with" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
-}
-
- /* SystemVerilog 2005 ONLY not PSL; different rules for PSL as specified below */
-<S05,S09,S12,SAX>{
- /* Keywords */
- "assert" { FL; return yASSERT; }
- "const" { FL; return yCONST__LEX; }
- "cover" { FL; return yCOVER; }
- "property" { FL; return yPROPERTY; }
- "union" { FL; return yUNION; }
- /* Generic unsupported warnings */
- "assume" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented in non-PSL context: %s",yytext); }
- "before" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented in non-PSL context: %s",yytext); }
- "sequence" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented in non-PSL context: %s",yytext); }
- "within" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented in non-PSL context: %s",yytext); }
+ "within" { yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext); }
}
/* SystemVerilog 2009 */
-<S09,S12,SAX,PSL>{
+<S09,S12,SAX>{
/* Keywords */
"global" { FL; return yGLOBAL__LEX; }
"unique0" { FL; return yUNIQUE0; }
@@ -550,7 +542,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
}
/* System Verilog 2012 */
-<S12,SAX,PSL>{
+<S12,SAX>{
/* Keywords */
"implements" { yyerrorf("Unsupported: SystemVerilog 2012 reserved word not implemented: %s",yytext); }
"interconnect" { yyerrorf("Unsupported: SystemVerilog 2012 reserved word not implemented: %s",yytext); }
@@ -559,7 +551,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
}
/* Default PLI rule */
-<V95,V01,V05,VA5,S05,S09,S12,SAX,PSL>{
+<V95,V01,V05,VA5,S05,S09,S12,SAX>{
"$"[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
@@ -663,99 +655,10 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
}
/************************************************************************/
- /* PSL */
-
- /*Entry into PSL; mode change */
-<V95,V01,V05,VA5,S05,S09,S12,SAX>{
- "psl" { yy_push_state(PSL); FL; return yPSL; }
-}
-
-<PSL>{
- /* Special things */
- "psl" { ; } // 'psl' may occur in middle of statement, so easier just to suppress
- /* Keywords */
- "assert" { FL; return yPSL_ASSERT; }
- "assume" { FL; return yPSL_ASSERT; } //==assert
- "before_!" { yyerrorf("Illegal syntax, use before!_ instead of %s",yytext); }
- "clock" { FL; return yPSL_CLOCK; }
- "countones" { FL; return yD_COUNTONES; }
- "cover" { FL; return yPSL_COVER; }
- "isunknown" { FL; return yD_ISUNKNOWN; }
- "onehot" { FL; return yD_ONEHOT; }
- "onehot0" { FL; return yD_ONEHOT0; }
- "until_!" { yyerrorf("Illegal syntax, use until!_ instead of %s",yytext); }
- "report" { FL; return yPSL_REPORT; }
- "true" { FL; return yTRUE; }
- /* Generic unsupported warnings */
- /*"A" { yyerrorf("Unsupported: PSL branching reserved word not implemented: %s",yytext); } */
- /*"AF" { yyerrorf("Unsupported: PSL branching reserved word not implemented: %s",yytext); } */
- /*"AG" { yyerrorf("Unsupported: PSL branching reserved word not implemented: %s",yytext); } */
- /*"AX" { yyerrorf("Unsupported: PSL branching reserved word not implemented: %s",yytext); } */
- /*"E" { yyerrorf("Unsupported: PSL branching reserved word not implemented: %s",yytext); } */
- /*"EF" { yyerrorf("Unsupported: PSL branching reserved word not implemented: %s",yytext); } */
- /*"EG" { yyerrorf("Unsupported: PSL branching reserved word not implemented: %s",yytext); } */
- /*"EX" { yyerrorf("Unsupported: PSL branching reserved word not implemented: %s",yytext); } */
- /*"F" { FL; return yEVENTUALLYB; } */
- /*"G" { FL; return yALWAYS; } */
- /*"U" { FL; return yUNTILB; } */
- /*"W" { FL; return yUNTIL; } */
- /*"X" { FL; return yNEXT; } */
- /*"X!" { FL; return yNEXTB; } */
- /*"restrict" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } S09 instead */
- /*"strong" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } S09 instead */
- /*"until" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } S09 instead */
- "%for" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "%if" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "abort" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "assume_guarantee" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } //Unsup in other tools
- "before" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "before!" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "before!_" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "before_" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "boolean" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "const" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "endpoint" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "eventually!" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "fairness" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } //Unsup in other tools
- "fell" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "forall" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } //Unsup in other tools
- "in" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "inf" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "inherit" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } //Unsup in other tools
- "never" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "next" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "next!" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "next_a" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "next_a!" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "next_e" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "next_e!" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "next_event" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "next_event!" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "next_event_a" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "next_event_a!" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "next_event_e" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "next_event_e!" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "prev" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "property" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "restrict_guarantee" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } //Unsup in other tools
- "rose" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "sequence" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "stable" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "union" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "until!" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "until!_" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "until_" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "vmode" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } //Unsup in other tools
- "vprop" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); } //Unsup in other tools
- "vunit" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
- "within" { yyerrorf("Unsupported: PSL reserved word not implemented: %s",yytext); }
-}
-
- /************************************************************************/
/* Meta comments */
/* Converted from //{cmt}verilator ...{cmt} by preprocessor */
-<V95,V01,V05,VA5,S05,S09,S12,SAX,PSL>{
+<V95,V01,V05,VA5,S05,S09,S12,SAX>{
"/*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; }
@@ -793,8 +696,6 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
<V95,V01,V05,VA5,S05,S09,S12,SAX>{
"{" { FL; return yytext[0]; }
"}" { FL; return yytext[0]; }
-}
-<V95,V01,V05,VA5,S05,S09,S12,SAX,PSL>{
"!" { FL; return yytext[0]; }
"#" { FL; return yytext[0]; }
"$" { FL; return yytext[0]; }
@@ -826,7 +727,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
/* Operators and multi-character symbols */
/* Verilog 1995 Operators */
-<V95,V01,V05,VA5,S05,S09,S12,SAX,PSL>{
+<V95,V01,V05,VA5,S05,S09,S12,SAX>{
"&&" { FL; return yP_ANDAND; }
"||" { FL; return yP_OROR; }
"<=" { FL; return yP_LTE; }
@@ -848,7 +749,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
}
/* Verilog 2001 Operators */
-<V01,V05,VA5,S05,S09,S12,SAX,PSL>{
+<V01,V05,VA5,S05,S09,S12,SAX>{
"<<<" { FL; return yP_SLEFT; }
">>>" { FL; return yP_SSRIGHT; }
"**" { FL; return yP_POW; }
@@ -891,23 +792,8 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"["{ws}*"->" { FL; return yP_BRAMINUSGT; }
}
- /* PSL Operators */
-<PSL>{
- "{" { FL; return yPSL_BRA; } // Avoid parser hitting concatenate.
- "}" { FL; return yPSL_KET; } // Avoid parser hitting concatenate.
- "<->" { yyerrorf("Unsupported: PSL operator not implemented: %s",yytext); } //Unsup in other tools
- "[*" { yyerrorf("Unsupported: PSL operator not implemented: %s",yytext); } // yP_BRA_STAR
- "[*]" { yyerrorf("Unsupported: PSL operator not implemented: %s",yytext); } // yP_BRA_STAR_KET
- "[+]" { yyerrorf("Unsupported: PSL operator not implemented: %s",yytext); } // yP_BRA_PLUS_KET
- "[->" { yyerrorf("Unsupported: PSL operator not implemented: %s",yytext); } // yP_BRA_MINUS_GT
- "[->]" { yyerrorf("Unsupported: PSL operator not implemented: %s",yytext); } // yP_BRA_MINUS_GT_KET
- "[=" { yyerrorf("Unsupported: PSL operator not implemented: %s",yytext); } // yP_BRA_EQ
- "|->" { yyerrorf("Unsupported: PSL operator not implemented: %s",yytext); } // yP_ORMINUSGT
- "|=>" { yyerrorf("Unsupported: PSL operator not implemented: %s",yytext); } // yP_OREQGT
-}
-
/* Identifiers and numbers */
-<V95,V01,V05,VA5,S05,S09,S12,SAX,PSL,VLT>{
+<V95,V01,V05,VA5,S05,S09,S12,SAX,VLT>{
{escid} { FL; yylval.strp = PARSEP->newString
(AstNode::encodeName(string(yytext+1))); // +1 to skip the backslash
return yaID__LEX;
@@ -997,7 +883,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
/* Preprocessor */
/* Common for all SYSC header states */
/* OPTIMIZE: we return one per line, make it one for the entire block */
-<V95,V01,V05,VA5,S05,S09,S12,SAX,PSL,VLT,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,SYSCDTOR,IGNORE>{
+<V95,V01,V05,VA5,S05,S09,S12,SAX,VLT,SYSCHDR,SYSCINT,SYSCIMP,SYSCIMPH,SYSCCTOR,SYSCDTOR,IGNORE>{
"`accelerate" { } // Verilog-XL compatibility
"`autoexpand_vectornets" { } // Verilog-XL compatibility
"`celldefine" { PARSEP->inCellDefine(true); }
@@ -1026,7 +912,6 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
"`portcoerce" { }
"`pragma"{ws}+[^\n\r]* { } // Verilog 2005
"`protect" { }
- "`psl" { if (PARSEP->optPsl()) { BEGIN PSL; } else { BEGIN IGNORE; } }
"`remove_gatenames" { } // Verilog-XL compatibility
"`remove_netnames" { } // Verilog-XL compatibility
"`resetall" { PARSEP->fileline()->warnOn(V3ErrorCode::I_DEF_NETTYPE_WIRE,true); } // Rest handled by preproc
@@ -1073,7 +958,7 @@ vnum {vnum1}|{vnum2}|{vnum3}|{vnum4}|{vnum5}
/************************************************************************/
/* Default rules - leave last */
-<V95,V01,V05,VA5,S05,S09,S12,SAX,PSL,VLT>{
+<V95,V01,V05,VA5,S05,S09,S12,SAX,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. */
@@ -1087,15 +972,14 @@ int V3ParseImp::stateVerilogRecent() { return STATE_VERILOG_RECENT; }
double V3ParseImp::parseDouble(const char* textp, size_t length) {
char* strgp = new char[length+1];
char* dp=strgp;
- for (const char* sp=textp; sp<(textp+length);) {
- if (*sp != '_') *dp++ = *sp++;
- else sp++;
+ for (const char* sp=textp; sp<(textp+length); ++sp) {
+ if (*sp != '_') *dp++ = *sp;
}
*dp++ = '\0';
char* endp = strgp;
double d = strtod(strgp, &endp);
size_t parsed_len = endp-strgp;
- if (parsed_len != length) { yyerrorf("Syntax error parsing real: %s",strgp); }
+ if (parsed_len != strlen(strgp)) { yyerrorf("Syntax error parsing real: %s",strgp); }
delete strgp;
return d;
}
diff --git a/src/verilog.y b/src/verilog.y
index 4cdeb17..d77a53d 100644
--- a/src/verilog.y
+++ b/src/verilog.y
@@ -488,12 +488,6 @@ class AstSenTree;
%token<fl> yD_WARNING "$warning"
%token<fl> yD_WRITE "$write"
-%token<fl> yPSL "psl"
-%token<fl> yPSL_ASSERT "PSL assert"
-%token<fl> yPSL_CLOCK "PSL clock"
-%token<fl> yPSL_COVER "PSL cover"
-%token<fl> yPSL_REPORT "PSL report"
-
%token<fl> yVL_CLOCK "/*verilator sc_clock*/"
%token<fl> yVL_CLOCK_ENABLE "/*verilator clock_enable*/"
%token<fl> yVL_COVERAGE_BLOCK_OFF "/*verilator coverage_block_off*/"
@@ -566,8 +560,6 @@ class AstSenTree;
%token<fl> yP_SRIGHTEQ ">>="
%token<fl> yP_SSRIGHTEQ ">>>="
-%token<fl> yPSL_BRA "{"
-%token<fl> yPSL_KET "}"
%token<fl> yP_LOGIFF
// [* is not a operator, as "[ * ]" is legal
@@ -578,7 +570,6 @@ class AstSenTree;
// PSL op precedence
%right yP_MINUSGT yP_LOGIFF
%right yP_ORMINUSGT yP_OREQGT
-%left<fl> prPSLCLK
// Verilog op precedence
%right '?' ':'
@@ -638,20 +629,6 @@ class AstSenTree;
%%
//**********************************************************************
-// Feedback to the Lexer
-// Note we read a parenthesis ahead, so this may not change the lexer at the right point.
-
-stateExitPsl: // For PSL lexing, return from PSL state
- /* empty */ { PARSEP->stateExitPsl(); }
- ;
-statePushVlg: // For PSL lexing, escape current state into Verilog state
- /* empty */ { PARSEP->statePushVlg(); }
- ;
-statePop: // Return to previous lexing state
- /* empty */ { PARSEP->statePop(); }
- ;
-
-//**********************************************************************
// Files
source_text: // ==IEEE: source_text
@@ -994,7 +971,8 @@ interface_itemList<nodep>:
interface_item<nodep>: // IEEE: interface_item + non_port_interface_item
port_declaration ';' { $$ = $1; }
// // IEEE: non_port_interface_item
- //UNSUP generate_region { $$ = $1; }
+ // // IEEE: generate_region
+ | interface_generate_region { $$ = $1; }
| interface_or_generate_item { $$ = $1; }
//UNSUP program_declaration { $$ = $1; }
//UNSUP interface_declaration { $$ = $1; }
@@ -1003,6 +981,11 @@ interface_item<nodep>: // IEEE: interface_item + non_port_interface_item
| module_common_item { $$ = $1; }
;
+interface_generate_region<nodep>: // ==IEEE: generate_region
+ yGENERATE interface_itemList yENDGENERATE { $$ = new AstGenerate($1, $2); }
+ | yGENERATE yENDGENERATE { $$ = NULL; }
+ ;
+
interface_or_generate_item<nodep>: // ==IEEE: interface_or_generate_item
// // module_common_item in interface_item, as otherwise duplicated
// // with module_or_generate_item's module_common_item
@@ -1698,8 +1681,6 @@ module_common_item<nodep>: // ==IEEE: module_common_item
| yALWAYS_LATCH event_controlE stmtBlock { $$ = new AstAlways($1,VAlwaysKwd::ALWAYS_LATCH, $2,$3); }
| loop_generate_construct { $$ = $1; }
| conditional_generate_construct { $$ = $1; }
- // // Verilator only
- | pslStmt { $$ = $1; }
//
| error ';' { $$ = NULL; }
;
@@ -2987,7 +2968,7 @@ expr<nodep>: // IEEE: part of expression/constant_expression/primary
| ~noPar__IGNORE~'(' expr ')' { $$ = $2; }
//UNSUP ~noPar__IGNORE~'(' expr ':' expr ':' expr ')' { $$ = $4; }
// // PSL rule
- | '_' '(' statePushVlg expr statePop ')' { $$ = $4; } // Arbitrary Verilog inside PSL
+ | '_' '(' expr ')' { $$ = $3; } // Arbitrary Verilog inside PSL
//
// // IEEE: cast/constant_cast
| casting_type yP_TICK '(' expr ')' { $$ = new AstCast($2,$4,$1); }
@@ -3087,11 +3068,6 @@ fexprScope<nodep>: // exprScope, For use as first part of statement (disambigua
BISONPRE_COPY(exprScope,{s/~l~/f/g}) // {copied}
;
-// Psl excludes {}'s by lexer converting to different token
-exprPsl<nodep>:
- expr { $$ = $1; }
- ;
-
// PLI calls exclude "" as integers, they're strings
// For $c("foo","bar") we want "bar" as a string, not a Verilog integer.
exprStrText<nodep>:
@@ -3514,7 +3490,7 @@ str<strp>: // yaSTRING but with \{escapes} need decoded
;
strAsInt<nodep>:
- yaSTRING { $$ = new AstConst($<fl>1,V3Number(V3Number::VerilogString(),$<fl>1,GRAMMARP->deQuote($<fl>1,*$1)));}
+ yaSTRING { $$ = new AstConst($<fl>1,V3Number(V3Number::VerilogStringLiteral(),$<fl>1,GRAMMARP->deQuote($<fl>1,*$1)));}
;
strAsIntIgnore<nodep>: // strAsInt, but never matches for when expr shouldn't parse strings
@@ -3622,56 +3598,6 @@ package_scopeIdFollows<packagep>: // IEEE: package_scope
//UNSUP /*cont*/ yP_COLONCOLON { UNSUP }
;
-//************************************************
-// PSL Statements
-
-pslStmt<nodep>:
- yPSL pslDir stateExitPsl { $$ = $2; }
- | yPSL pslDecl stateExitPsl { $$ = $2; }
- ;
-
-pslDir<nodep>:
- id ':' pslDirOne { $$ = $3; }
- | pslDirOne { $$ = $1; }
- ;
-
-pslDirOne<nodep>:
- yPSL_ASSERT pslProp ';' { $$ = new AstPslAssert($1,$2); }
- | yPSL_ASSERT pslProp yPSL_REPORT yaSTRING ';' { $$ = new AstPslAssert($1,$2,*$4); }
- | yPSL_COVER pslProp ';' { $$ = new AstPslCover($1,$2,NULL); }
- | yPSL_COVER pslProp yPSL_REPORT yaSTRING ';' { $$ = new AstPslCover($1,$2,NULL,*$4); }
- ;
-
-pslDecl<nodep>:
- yDEFAULT yPSL_CLOCK '=' senitemEdge ';' { $$ = new AstPslDefClock($3, $4); }
- | yDEFAULT yPSL_CLOCK '=' '(' senitemEdge ')' ';' { $$ = new AstPslDefClock($3, $5); }
- ;
-
-//************************************************
-// PSL Properties, Sequences and SEREs
-// Don't use '{' or '}'; in PSL they're yPSL_BRA and yPSL_KET to avoid expr concatenates
-
-pslProp<nodep>:
- pslSequence { $$ = $1; }
- | pslSequence '@' %prec prPSLCLK '(' senitemEdge ')' { $$ = new AstPslClocked($2,$4,NULL,$1); } // or pslSequence @ ...?
- ;
-
-pslSequence<nodep>:
- yPSL_BRA pslSere yPSL_KET { $$ = $2; }
- ;
-
-pslSere<nodep>:
- pslExpr { $$ = $1; }
- | pslSequence { $$ = $1; } // Sequence containing sequence
- ;
-
-// Undocumented PSL rule is that {} is always a SERE; concatenation is not allowed.
-// This can be bypassed with the _(...) embedding of any arbitrary expression.
-pslExpr<nodep>:
- exprPsl { $$ = new AstPslBool($1->fileline(), $1); }
- | yTRUE { $$ = new AstPslBool($1, new AstConst($1, AstConst::LogicTrue())); }
- ;
-
//**********************************************************************
// VLT Files
@@ -3815,7 +3741,7 @@ AstVar* V3ParseGrammar::createVariable(FileLine* fileline, string name, AstRange
string V3ParseGrammar::deQuote(FileLine* fileline, string text) {
// Fix up the quoted strings the user put in, for example "\"" becomes "
- // Reverse is AstNode::quoteName(...)
+ // Reverse is V3Number::quoteNameControls(...)
bool quoted = false;
string newtext;
unsigned char octal_val = 0;
diff --git a/src/vlcovgen b/src/vlcovgen
new file mode 100755
index 0000000..533505f
--- /dev/null
+++ b/src/vlcovgen
@@ -0,0 +1,173 @@
+#!/usr/bin/perl -w
+# See copyright, etc in below POD section.
+######################################################################
+
+#require 5.006_001;
+use Getopt::Long;
+use IO::File;
+use Pod::Usage;
+use strict;
+use vars qw ($Debug);
+
+our @Items;
+
+#======================================================================
+# main
+
+$Debug = 0;
+my $Opt_Srcdir = ".";
+Getopt::Long::config ("pass_through", "no_auto_abbrev");
+if (! GetOptions (
+ "help" => \&usage,
+ "debug" => sub { $Debug = 1; },
+ "srcdir=s" => \$Opt_Srcdir,
+ "<>" => sub { die "%Error: Unknown parameter: $_[0],"; },
+ )) {
+ usage();
+}
+
+read_keys("$Opt_Srcdir/../include/verilated_cov_key.h");
+lint();
+write_keys("$Opt_Srcdir/../include/verilated_cov_key.h");
+
+#----------------------------------------------------------------------
+
+sub usage {
+ pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
+ exit (1);
+}
+
+#######################################################################
+
+sub read_keys {
+ my $filename = shift;
+
+ my $fh = IO::File->new("<$filename") or die "%Error: $! $filename,";
+ while (defined (my $line = $fh->getline())) {
+ $line =~ s/\/\/.*$//;
+ next if $line =~ /^\s*$/;
+ if ($line =~ /^\s*VLCOVGEN_ITEM/) {
+ $line =~ /^\s*VLCOVGEN_ITEM *\( *"([^"]+)" *\)/
+ or die "%Error: $filename:$.: Misformed VLCOVGEN_ITEM line,";
+ my @data;
+ my $code = "\@data = ($1);";
+ eval $code;
+ die "%Error: $filename:$.: Parsing '$code': $@," if $@;
+ push @Items, {@data};
+ }
+ }
+}
+
+#######################################################################
+
+sub lint {
+ my %shorts;
+ my $ok = 1;
+ foreach my $itemref (@Items) {
+ if ($shorts{$itemref->{short}}) {
+ warn "%Error: Duplicate short code: $itemref->{short},";
+ $ok = 0;
+ }
+ $shorts{$itemref->{short}} = 1;
+ }
+ return $ok;
+}
+
+sub write_keys {
+ my $filename = shift;
+
+ my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n";
+
+ my @in;
+ my @out;
+ my $deleting;
+ while (defined(my $line = $fh->getline)) {
+ push @in, $line;
+ if ($line =~ /VLCOVGEN_CIK_AUTO_EDIT_BEGIN/) {
+ $deleting = 1;
+ push @out, $line;
+ foreach my $keyref (sort {$a->{name} cmp $b->{name}} @Items) {
+ push @out, sprintf("#define VL_CIK_%s \"%s\"\n",
+ uc $keyref->{name}, $keyref->{short});
+ }
+ }
+ elsif ($line =~ /VLCOVGEN_SHORT_AUTO_EDIT_BEGIN/) {
+ $deleting = 1;
+ push @out, $line;
+ foreach my $keyref (sort {$a->{name} cmp $b->{name}} @Items) {
+ push @out, sprintf("\tif (key == \"%s\") return VL_CIK_%s;\n",
+ $keyref->{name}, uc $keyref->{name});
+ }
+ }
+ elsif ($line =~ /VLCOVGEN_.*AUTO_EDIT_END/) {
+ $deleting = 0;
+ push @out, $line;
+ }
+ elsif ($deleting) {
+ }
+ else {
+ push @out, $line;
+ }
+ }
+ $fh->close;
+
+ my $ok = join("", @out) eq join("", @in);
+ if (!$ok) {
+ my $fh = IO::File->new(">$filename") or die "%Error: $! writing $filename\n";
+ $fh->print(join "", @out);
+ $fh->close;
+ }
+}
+
+
+#######################################################################
+__END__
+
+=pod
+
+=head1 NAME
+
+vlcovgen - Generate verilated_cov headers to reduce C++ code duplication
+
+=head1 SYNOPSIS
+
+ (called from make rules)
+ vlcovgen
+
+=head1 DESCRIPTION
+
+Generates several files for Verilator compilations.
+
+=head1 ARGUMENTS
+
+=over 4
+
+=item --help
+
+Displays this message and program version and exits.
+
+=back
+
+=head1 DISTRIBUTION
+
+Copyright 2002-2014 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.
+
+This program is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+more details.
+
+=head1 AUTHORS
+
+Wilson Snyder <wsnyder at wsnyder.org>
+
+=head1 SEE ALSO
+
+=cut
+
+######################################################################
+### Local Variables:
+### compile-command: "./vlcovgen --srcdir ."
+### End:
diff --git a/test_regress/Makefile_obj b/test_regress/Makefile_obj
index 0a487eb..2b68424 100644
--- a/test_regress/Makefile_obj
+++ b/test_regress/Makefile_obj
@@ -52,7 +52,7 @@ endif
#Our own compile rules; Faster compile, all in one file
$(VM_PREFIX)__ALLboth.cpp: $(VK_CLASSES_CPP) $(VK_SUPPORT_CPP)
- $(SP_INCLUDER) $^ > $@
+ $(VERILATOR_INCLUDER) -DVL_INLINE_OPT=inline $^ > $@
$(VM_PREFIX)__ALLboth.o: $(VM_PREFIX)__ALLboth.cpp
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<
diff --git a/test_regress/driver.pl b/test_regress/driver.pl
index abee28c..d13e33b 100755
--- a/test_regress/driver.pl
+++ b/test_regress/driver.pl
@@ -115,9 +115,15 @@ if ($#opt_tests<0) {
foreach my $dir (@Test_Dirs) {
my @stats = stat($dir); # Uniquify by inode, so different paths to same place get combined
next if !$stats[1] || $uniq{$stats[1]}++;
- push @opt_tests, glob ("${dir}/t_*.pl");
+ push @opt_tests, sort(glob ("${dir}/t_*.pl"));
}
}
+if ($#opt_tests>=2 && $opt_jobs>=2) {
+ # Without this tests such as t_debug_sigsegv_bt_bad.pl will occasionally
+ # block on input and cause a SIGSTOP, then a "fg" was needed to resume testing.
+ print STDERR "== Many jobs; redirecting STDIN\n";
+ open(STDIN, "+>/dev/null");
+}
mkdir "obj_dir";
@@ -388,7 +394,7 @@ sub new {
$self->{stats} ||= "$self->{obj_dir}/V".$self->{name}."__stats.txt";
$self->{status_filename} ||= "$self->{obj_dir}/V".$self->{name}.".status";
$self->{run_log_filename} ||= "$self->{obj_dir}/vlt_sim.log";
- $self->{coverage_filename} ||= "$self->{obj_dir}/vlt_coverage.pl";
+ $self->{coverage_filename} ||= "$self->{obj_dir}/coverage.dat";
$self->{vcd_filename} ||= "$self->{obj_dir}/sim.vcd";
$self->{main_filename} ||= "$self->{obj_dir}/$self->{VM_PREFIX}__main.cpp";
($self->{top_filename} = $self->{pl_filename}) =~ s/\.pl$//;
@@ -633,10 +639,6 @@ sub compile {
$self->skip("Test requires SystemC; ignore error since not installed\n");
return 1;
}
- elsif ($self->{coverage} && !$Have_System_Perl) {
- $self->skip("Test requires SystemPerl; ignore error since not installed\n");
- return 1;
- }
if (!$param{fails} && $param{verilator_make_gcc}
&& $param{make_main}) {
@@ -1143,7 +1145,7 @@ sub _make_main {
if ($self->{coverage}) {
$fh->print("#if VM_COVERAGE\n");
- $fh->print(" SpCoverage::write(\"",$self->{coverage_filename},"\");\n");
+ $fh->print(" VerilatedCov::write(\"",$self->{coverage_filename},"\");\n");
$fh->print("#endif //VM_COVERAGE\n");
}
if ($self->{trace}) {
diff --git a/test_regress/t/t_assert_basic_cover.pl b/test_regress/t/t_assert_basic_cover.pl
index e10bc2e..a14ea16 100755
--- a/test_regress/t/t_assert_basic_cover.pl
+++ b/test_regress/t/t_assert_basic_cover.pl
@@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
top_filename("t/t_assert_basic.v");
compile (
- verilator_flags2 => ['--assert --sp --coverage-user'],
+ verilator_flags2 => ['--assert --cc --coverage-user'],
);
execute (
diff --git a/test_regress/t/t_assert_cover.pl b/test_regress/t/t_assert_cover.pl
index f20a45b..9b33acb 100755
--- a/test_regress/t/t_assert_cover.pl
+++ b/test_regress/t/t_assert_cover.pl
@@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
top_filename("t/t_assert_cover.v");
compile (
- verilator_flags2 => ['--assert --sp --coverage-user'],
+ verilator_flags2 => ['--assert --cc --coverage-user'],
nc_flags2 => ["+nccovoverwrite +nccoverage+all +nccovtest+$Self->{name}"]
);
diff --git a/test_regress/t/t_bitsel_wire_array_bad.pl b/test_regress/t/t_bitsel_wire_array_bad.pl
index b2b725f..3a68ce0 100755
--- a/test_regress/t/t_bitsel_wire_array_bad.pl
+++ b/test_regress/t/t_bitsel_wire_array_bad.pl
@@ -10,13 +10,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Comple time only test
compile (
- verilator_flags2 => ["--lint-only"],
- fails=>1,
-# expect=>
-# TBD better error message, bug509
-#'.*
-#%Error: Exiting due to.*',
- );
+ verilator_flags2 => ["--lint-only"],
+ fails=>1,
+ expect=>
+'.*%Error: t/t_bitsel_wire_array_bad.v:\d+: Illegal assignment of constant to unpacked array
+%Error: Exiting due to.*',
+ );
ok(1);
1;
diff --git a/test_regress/t/t_cover_line.out b/test_regress/t/t_cover_line.out
new file mode 100644
index 0000000..c6840d2
--- /dev/null
+++ b/test_regress/t/t_cover_line.out
@@ -0,0 +1,170 @@
+ // verilator_coverage annotation
+ // DESCRIPTION: Verilator: Verilog Test module
+ //
+ // This file ONLY is placed into the Public Domain, for any use,
+ // without warranty, 2008 by Wilson Snyder.
+
+ module t (/*AUTOARG*/
+ // Inputs
+ clk
+ );
+
+ input clk;
+
+ reg toggle; initial toggle=0;
+
+ integer cyc; initial cyc=1;
+ wire [7:0] cyc_copy = cyc[7:0];
+
+ alpha a1 (/*AUTOINST*/
+ // Inputs
+ .clk (clk),
+ .toggle (toggle));
+ alpha a2 (/*AUTOINST*/
+ // Inputs
+ .clk (clk),
+ .toggle (toggle));
+ beta b1 (/*AUTOINST*/
+ // Inputs
+ .clk (clk),
+ .toggle (toggle));
+ beta b2 (/*AUTOINST*/
+ // Inputs
+ .clk (clk),
+ .toggle (toggle));
+ tsk t1 (/*AUTOINST*/
+ // Inputs
+ .clk (clk),
+ .toggle (toggle));
+ off o1 (/*AUTOINST*/
+ // Inputs
+ .clk (clk),
+ .toggle (toggle));
+
+ always @ (posedge clk) begin
+ 000010 if (cyc!=0) begin
+ cyc <= cyc + 1;
+ toggle <= '0;
+%000001 if (cyc==3) begin
+ toggle <= '1;
+ end
+%000001 else if (cyc==5) begin
+ `ifdef VERILATOR
+ $c("call_task();");
+ `else
+ call_task();
+ `endif
+ end
+%000001 else if (cyc==10) begin
+ $write("*-* All Finished *-*\n");
+ $finish;
+ end
+ end
+ end
+
+ task call_task;
+ /* verilator public */
+ t1.center_task(1'b1);
+ endtask
+
+ endmodule
+
+ module alpha (/*AUTOARG*/
+ // Inputs
+ clk, toggle
+ );
+ input clk;
+ input toggle;
+ always @ (posedge clk) begin
+%000002 if (toggle) begin
+ // CHECK_COVER(-1,"top.v.a*",2)
+ // t.a1 and t.a2 collapse to a count of 2
+ end
+ if (toggle) begin
+ // CHECK_COVER_MISSING(-1)
+ // This doesn't even get added
+ // verilator coverage_block_off
+ $write("");
+ end
+ end
+ endmodule
+
+ module beta (/*AUTOARG*/
+ // Inputs
+ clk, toggle
+ );
+ input clk;
+ input toggle;
+
+ /* verilator public_module */
+
+ always @ (posedge clk) begin
+%000000 if (0) begin
+ // CHECK_COVER(-1,"top.v.b*",0)
+ // Make sure that we don't optimize away zero buckets
+ end
+%000002 if (toggle) begin
+ // CHECK_COVER(-1,"top.v.b*",2)
+ // t.b1 and t.b2 collapse to a count of 2
+ end
+ if (toggle) begin
+ // CHECK_COVER_MISSING(-1)
+ // This doesn't
+ // verilator coverage_block_off
+ $write("");
+ end
+ end
+ endmodule
+
+ module tsk (/*AUTOARG*/
+ // Inputs
+ clk, toggle
+ );
+ input clk;
+ input toggle;
+
+ /* verilator public_module */
+
+ always @ (posedge clk) begin
+ center_task(1'b0);
+ end
+
+ task center_task;
+ input external;
+ begin
+%000001 if (toggle) begin
+ // CHECK_COVER(-1,"top.v.t1",1)
+ end
+%000001 if (external) begin
+ // CHECK_COVER(-1,"top.v.t1",1)
+ $write("[%0t] Got external pulse\n", $time);
+ end
+ end
+ endtask
+
+ endmodule
+
+ module off (/*AUTOARG*/
+ // Inputs
+ clk, toggle
+ );
+ input clk;
+ input toggle;
+
+ // verilator coverage_off
+ always @ (posedge clk) begin
+ if (toggle) begin
+ // CHECK_COVER_MISSING(-1)
+ // because under coverage_module_off
+ end
+ end
+ // verilator coverage_on
+ always @ (posedge clk) begin
+%000001 if (toggle) begin
+ // CHECK_COVER(-1,"top.v.o1",1)
+ // because under coverage_module_off
+ end
+ end
+
+ endmodule
+
diff --git a/test_regress/t/t_cover_line_cc.pl b/test_regress/t/t_cover_line_cc.pl
index 0b803dd..af024c4 100755
--- a/test_regress/t/t_cover_line_cc.pl
+++ b/test_regress/t/t_cover_line_cc.pl
@@ -20,5 +20,12 @@ execute (
# Read the input .v file and do any CHECK_COVER requests
inline_checks();
-ok(1);
+$Self->_run(cmd=>["../bin/verilator_coverage",
+ "--annotate", "$Self->{obj_dir}/annotated",
+ "$Self->{obj_dir}/coverage.dat",
+ ],
+ );
+
+ok(files_identical("$Self->{obj_dir}/annotated/t_cover_line.v", "t/t_cover_line.out"));
+
1;
diff --git a/test_regress/t/t_cover_line_sp.pl b/test_regress/t/t_cover_line_sp.pl
deleted file mode 100755
index 05afc6b..0000000
--- a/test_regress/t/t_cover_line_sp.pl
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/perl
-if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
-# DESCRIPTION: Verilator: Verilog Test driver/expect definition
-#
-# Copyright 2003-2009 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.
-
-top_filename("t/t_cover_line.v");
-
-compile (
- verilator_flags2 => ['--sp --coverage-line'],
- );
-
-execute (
- check_finished=>1,
- );
-
-# Read the input .v file and do any CHECK_COVER requests
-inline_checks();
-
-ok(1);
-1;
diff --git a/test_regress/t/t_cover_sva_notflat.pl b/test_regress/t/t_cover_sva_notflat.pl
index 5d55d60..9ee0511 100755
--- a/test_regress/t/t_cover_sva_notflat.pl
+++ b/test_regress/t/t_cover_sva_notflat.pl
@@ -8,7 +8,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Version 2.0.
compile (
- verilator_flags2 => ['--assert --sp --coverage-user'],
+ verilator_flags2 => ['--assert --cc --coverage-user'],
);
execute (
diff --git a/test_regress/t/t_cover_toggle.pl b/test_regress/t/t_cover_toggle.pl
index 9b68058..2747130 100755
--- a/test_regress/t/t_cover_toggle.pl
+++ b/test_regress/t/t_cover_toggle.pl
@@ -8,7 +8,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Version 2.0.
compile (
- verilator_flags2 => ['--sp --coverage-toggle --stats'],
+ verilator_flags2 => ['--cc --coverage-toggle --stats'],
);
execute (
diff --git a/test_regress/t/t_dist_spdiff.pl b/test_regress/t/t_dist_spdiff.pl
deleted file mode 100755
index ffbae66..0000000
--- a/test_regress/t/t_dist_spdiff.pl
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/perl
-if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
-# DESCRIPTION: Verilator: Verilog Test driver/expect definition
-#
-# Copyright 2010 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.
-
-my $root = "..";
-if (!-r "$root/.git") {
- $Self->skip("Not in a git repository");
-} else {
- my $cmd = "cd $root && nodist/spdiff . $ENV{SYSTEMPERL}";
- my $grep = `$cmd`;
- print "$grep\n";
- if ($grep ne "") {
- $Self->error("Include mismatches SystemPerl src\n");
- }
-}
-
-ok(1);
-1;
diff --git a/test_regress/t/t_sv_enum_type_methods.pl b/test_regress/t/t_enum_name2.pl
similarity index 83%
copy from test_regress/t/t_sv_enum_type_methods.pl
copy to test_regress/t/t_enum_name2.pl
index fda118f..f912897 100755
--- a/test_regress/t/t_sv_enum_type_methods.pl
+++ b/test_regress/t/t_enum_name2.pl
@@ -7,9 +7,6 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
-# Not yet working on Verilator
-$Self->{vlt} and $Self->unsupported("Verilator unsupported");
-
compile (
);
diff --git a/test_regress/t/t_enum_name2.v b/test_regress/t/t_enum_name2.v
new file mode 100644
index 0000000..6e420bd
--- /dev/null
+++ b/test_regress/t/t_enum_name2.v
@@ -0,0 +1,31 @@
+// DESCRIPTION: Verilator: Verilog Test module
+//
+// This file ONLY is placed into the Public Domain, for any use,
+// without warranty, 2014 by Jonathon Donaldson.
+
+package our_pkg;
+ typedef enum logic [8-1:0] {
+ ADC_IN2IN = 8'h99,
+ ADC_IMMED = 8'h88,
+ ADC_INDIR = 8'h86,
+ ADC_INIDX = 8'h97
+ } T_Opcode;
+endpackage : our_pkg
+
+module t ();
+ our our ();
+endmodule
+
+module our
+ import our_pkg::*;
+ ();
+
+ T_Opcode IR = ADC_IN2IN;
+
+ initial begin
+ $write ("%s (%t)\n", IR.name, $realtime);
+ $write("*-* All Finished *-*\n");
+ $finish;
+ end
+
+endmodule
diff --git a/test_regress/t/t_enum_type_methods.v b/test_regress/t/t_enum_type_methods.v
index b05af53..ea2ffae 100644
--- a/test_regress/t/t_enum_type_methods.v
+++ b/test_regress/t/t_enum_type_methods.v
@@ -1,48 +1,10 @@
-// DESCRIPTION: Verilator: System Verilog test of enumerated type methods
+// DESCRIPTION: Verilator: Verilog Test module
//
-// This code instantiates a module that uses a localparam with an enumerated
-// type.
-//
-// This file ONLY is placed into the Public Domain, for any use, without
-// warranty.
-
-// Contributed 2012 by M W Lund, Atmel Corporation and Jeremy Bennett, Embecosm.
-
-
-// **** Pin Identifiers ****
-typedef enum int
-{
- PINID_A0 = 32'd0, // MUST BE ZERO!
- // - Standard Ports -
- PINID_A1, PINID_A2, PINID_A3, PINID_A4, PINID_A5, PINID_A6, PINID_A7,
- PINID_B0, PINID_B1, PINID_B2, PINID_B3, PINID_B4, PINID_B5, PINID_B6, PINID_B7,
- PINID_C0, PINID_C1, PINID_C2, PINID_C3, PINID_C4, PINID_C5, PINID_C6, PINID_C7,
- PINID_D0, PINID_D1, PINID_D2, PINID_D3, PINID_D4, PINID_D5, PINID_D6, PINID_D7,
- PINID_E0, PINID_E1, PINID_E2, PINID_E3, PINID_E4, PINID_E5, PINID_E6, PINID_E7,
- PINID_F0, PINID_F1, PINID_F2, PINID_F3, PINID_F4, PINID_F5, PINID_F6, PINID_F7,
- PINID_G0, PINID_G1, PINID_G2, PINID_G3, PINID_G4, PINID_G5, PINID_G6, PINID_G7,
- PINID_H0, PINID_H1, PINID_H2, PINID_H3, PINID_H4, PINID_H5, PINID_H6, PINID_H7,
-// PINID_I0, PINID_I1, PINID_I2, PINID_I3, PINID_I4, PINID_I5, PINID_I6, PINID_I7,-> DO NOT USE!!!! I == 1
- PINID_J0, PINID_J1, PINID_J2, PINID_J3, PINID_J4, PINID_J5, PINID_J6, PINID_J7,
- PINID_K0, PINID_K1, PINID_K2, PINID_K3, PINID_K4, PINID_K5, PINID_K6, PINID_K7,
- PINID_L0, PINID_L1, PINID_L2, PINID_L3, PINID_L4, PINID_L5, PINID_L6, PINID_L7,
- PINID_M0, PINID_M1, PINID_M2, PINID_M3, PINID_M4, PINID_M5, PINID_M6, PINID_M7,
- PINID_N0, PINID_N1, PINID_N2, PINID_N3, PINID_N4, PINID_N5, PINID_N6, PINID_N7,
-// PINID_O0, PINID_O1, PINID_O2, PINID_O3, PINID_O4, PINID_O5, PINID_O6, PINID_O7,-> DO NOT USE!!!! O == 0
- PINID_P0, PINID_P1, PINID_P2, PINID_P3, PINID_P4, PINID_P5, PINID_P6, PINID_P7,
- PINID_Q0, PINID_Q1, PINID_Q2, PINID_Q3, PINID_Q4, PINID_Q5, PINID_Q6, PINID_Q7,
- PINID_R0, PINID_R1, PINID_R2, PINID_R3, PINID_R4, PINID_R5, PINID_R6, PINID_R7,
- // - AUX Port (Custom) -
- PINID_X0, PINID_X1, PINID_X2, PINID_X3, PINID_X4, PINID_X5, PINID_X6, PINID_X7,
- // - PDI Port -
- PINID_D2W_DAT, PINID_D2W_CLK,
- // - Power Pins -
- PINID_VDD0, PINID_VDD1, PINID_VDD2, PINID_VDD3,
- PINID_GND0, PINID_GND1, PINID_GND2, PINID_GND3,
- // - Maximum number of pins -
- PINID_MAX
- } t_pinid;
+// This file ONLY is placed into the Public Domain, for any use,
+// without warranty, 2014 by Wilson Snyder.
+`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
+`define checks(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='%s' exp='%s'\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
module t (/*AUTOARG*/
// Inputs
@@ -50,26 +12,85 @@ module t (/*AUTOARG*/
);
input clk;
- wire a = clk;
- wire b = 1'b0;
- reg c;
-
- simple_test_1 simple_test_1_i (/*AUTOINST*/
- // Outputs
- .c (c),
- // Inputs
- .a (a),
- .b (b));
+ typedef enum {
+ E01 = 1,
+ E03 = 3,
+ E04 = 4
+ } my_t;
+
+ integer cyc=0;
+ my_t e;
- // This is a compile time only test. Immediately finish
- always @(posedge clk) begin
- $write("*-* All Finished *-*\n");
- $finish;
+ int arrayfits [e.num]; // Check can use as constant
+
+ string all;
+
+ // Check constification
+ initial begin
+ e = E03;
+ `checkh(e.first, E01);
+ `checkh(e.last, E04);
+ `checkh(e.last(), E04);
+ `checkh(e.next, E04);
+ `checkh(e.next(), E04);
+ `checkh(e.next(1), E04);
+ //Unsup: `checkh(e.next(2), E01);
+ `checkh(e.prev, E01);
+ `checkh(e.prev(1), E01);
+ //Unsup: `checkh(e.prev(2), E04);
+ `checkh(e.num, 3);
+ `checks(e.name, "E03");
+ //
+ all = "";
+ for (my_t e = e.first; e != e.last; e = e.next) begin
+ all = {all, e.name};
+ end
+ e = e.last;
+ all = {all, e.name};
+ `checks(all, "E01E03E04");
end
-endmodule
+ // Check runtime
+ always @ (posedge clk) begin
+ cyc <= cyc + 1;
+ if (cyc==0) begin
+ // Setup
+ e <= E01;
+ end
+ else if (cyc==1) begin
+ `checks(e.name, "E01");
+ `checkh(e.next, E03);
+ `checkh(e.next(1), E03);
+ //Unsup: `checkh(e.next(2), E04);
+ `checkh(e.prev, E04);
+ `checkh(e.prev(1), E04);
+ //Unsup: `checkh(e.prev(2), E03);
+ e <= E03;
+ end
+ else if (cyc==2) begin
+ `checks(e.name, "E03");
+ `checkh(e.next, E04);
+ `checkh(e.next(1), E04);
+ //Unsup: `checkh(e.next(2), E01);
+ `checkh(e.prev, E01);
+ `checkh(e.prev(1), E01);
+ //Unsup: `checkh(e.prev(2), E04);
+ e <= E04;
+ end
+ else if (cyc==3) begin
+ `checks(e.name, "E04");
+ `checkh(e.next, E01);
+ `checkh(e.next(1), E01);
+ //Unsup: `checkh(e.next(2), E03);
+ `checkh(e.prev, E03);
+ `checkh(e.prev(1), E03);
+ //Unsup: `checkh(e.prev(2), E01);
+ e <= E01;
+ end
+ else if (cyc==99) begin
+ $write("*-* All Finished *-*\n");
+ $finish;
+ end
+ end
-// **** Simple use of parameters for sizing an array ****
-module simple_test_1 (input a, b, output c);
- int myarray1 [PINID_MAX];
endmodule
diff --git a/test_regress/t/t_sv_enum_type_methods.pl b/test_regress/t/t_enum_type_pins.pl
similarity index 100%
copy from test_regress/t/t_sv_enum_type_methods.pl
copy to test_regress/t/t_enum_type_pins.pl
diff --git a/test_regress/t/t_sv_enum_type_methods.v b/test_regress/t/t_enum_type_pins.v
similarity index 100%
rename from test_regress/t/t_sv_enum_type_methods.v
rename to test_regress/t/t_enum_type_pins.v
diff --git a/test_regress/t/t_sv_enum_type_methods.pl b/test_regress/t/t_flag_stats.pl
similarity index 70%
copy from test_regress/t/t_sv_enum_type_methods.pl
copy to test_regress/t/t_flag_stats.pl
index fda118f..c79b43f 100755
--- a/test_regress/t/t_sv_enum_type_methods.pl
+++ b/test_regress/t/t_flag_stats.pl
@@ -2,15 +2,15 @@
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
+# Copyright 2008 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.
-# Not yet working on Verilator
-$Self->{vlt} and $Self->unsupported("Verilator unsupported");
+$Self->{vlt} or $Self->skip("Verilator only test");
compile (
+ verilator_flags2 => ["--stats --stats-vars"],
);
execute (
diff --git a/test_regress/t/t_flag_stats.v b/test_regress/t/t_flag_stats.v
new file mode 100644
index 0000000..2bd129e
--- /dev/null
+++ b/test_regress/t/t_flag_stats.v
@@ -0,0 +1,13 @@
+// DESCRIPTION: Verilator: Verilog Test module
+//
+// This file ONLY is placed into the Public Domain, for any use,
+// without warranty, 2014 by Wilson Snyder.
+
+module t (b);
+ output reg [31:0] b;
+ initial begin
+ b = 22;
+ $write("*-* All Finished *-*\n");
+ $finish;
+ end
+endmodule
diff --git a/test_regress/t/t_flag_werror_bad2.pl b/test_regress/t/t_flag_werror_bad2.pl
index 41c91e2..c6786b5 100755
--- a/test_regress/t/t_flag_werror_bad2.pl
+++ b/test_regress/t/t_flag_werror_bad2.pl
@@ -12,7 +12,7 @@ top_filename("t/t_flag_werror.v");
compile (
v_flags2 => ["--lint-only"],
fails=>$Self->{v3},
- verilator_flags=> [qw(-sp -Werror-WIDTH)],
+ verilator_flags=> [qw(-cc -Werror-WIDTH)],
expect=>
q{%Error-WIDTH: t/t_flag_werror.v:\d+: Operator ASSIGNW expects 4 bits on the Assign RHS, but Assign RHS.s CONST '6'h2e' generates 6 bits.
%Error: Exiting due to},
diff --git a/test_regress/t/t_help.pl b/test_regress/t/t_help.pl
index ba73b76..5324df1 100755
--- a/test_regress/t/t_help.pl
+++ b/test_regress/t/t_help.pl
@@ -9,14 +9,20 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
$Self->{vlt} or $Self->skip("Verilator only test");
-$Self->_run(fails=>1,
- cmd=>["perl","../bin/verilator",
- "--help"],
- logfile=>"$Self->{obj_dir}/t_help.log",
- tee=>0,
- );
-
-file_grep ("$Self->{obj_dir}/t_help.log", qr/DISTRIBUTION/i);
+foreach my $prog (
+ "../bin/verilator",
+ "../bin/verilator_coverage",
+ "../bin/verilator_difftree",
+ "../bin/verilator_profcfunc",
+ ) {
+ $Self->_run(fails=>1,
+ cmd=>["perl",$prog,
+ "--help"],
+ logfile=>"$Self->{obj_dir}/t_help.log",
+ tee=>0,
+ );
+ file_grep ("$Self->{obj_dir}/t_help.log", qr/DISTRIBUTION/i);
+}
ok(1);
1;
diff --git a/test_regress/t/t_inst_overwide.pl b/test_regress/t/t_inst_overwide.pl
index d5af537..2d0bd83 100755
--- a/test_regress/t/t_inst_overwide.pl
+++ b/test_regress/t/t_inst_overwide.pl
@@ -9,7 +9,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
compile (
make_top_shell=>0,
- verilator_flags2 => [qw(-sp -Wno-WIDTH)],
+ verilator_flags2 => [qw(-sc -Wno-WIDTH)],
verilator_make_gcc=>0,
);
diff --git a/test_regress/t/t_inst_overwide_bad.pl b/test_regress/t/t_inst_overwide_bad.pl
index 4a2e845..6e0b9ae 100755
--- a/test_regress/t/t_inst_overwide_bad.pl
+++ b/test_regress/t/t_inst_overwide_bad.pl
@@ -12,7 +12,7 @@ top_filename("t/t_inst_overwide.v");
compile (
v_flags2 => ["--lint-only"],
make_top_shell=>0,
- verilator_flags=> [qw(-sp)],
+ verilator_flags=> [qw(-cc)],
verilator_make_gcc=>0,
fails=>$Self->{v3},
expect=>
diff --git a/test_regress/t/t_psl_basic_off.pl b/test_regress/t/t_interface_gen4.pl
similarity index 83%
rename from test_regress/t/t_psl_basic_off.pl
rename to test_regress/t/t_interface_gen4.pl
index ba70562..1118f2e 100755
--- a/test_regress/t/t_psl_basic_off.pl
+++ b/test_regress/t/t_interface_gen4.pl
@@ -7,15 +7,12 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
-top_filename("t/t_psl_basic.v");
-
compile (
- v_flags2 => [],
- );
+ );
execute (
- check_finished=>1,
- );
+ check_finished=>1,
+ );
ok(1);
1;
diff --git a/test_regress/t/t_interface_gen4.v b/test_regress/t/t_interface_gen4.v
new file mode 100644
index 0000000..7678ac0
--- /dev/null
+++ b/test_regress/t/t_interface_gen4.v
@@ -0,0 +1,58 @@
+// DESCRIPTION: Verilator: Verilog Test module
+//
+// This file ONLY is placed into the Public Domain, for any use,
+// without warranty, 2013 by Wilson Snyder.
+
+// bug789 generates
+
+module t (/*AUTOARG*/
+ // Inputs
+ clk
+ );
+
+ input clk;
+ integer cyc=1;
+
+ ifc #(1) itopa();
+ ifc #(2) itopb();
+
+ sub #(1) ca (.isub(itopa),
+ .i_value(4));
+ sub #(2) cb (.isub(itopb),
+ .i_value(5));
+
+ always @ (posedge clk) begin
+ cyc <= cyc + 1;
+ if (cyc==1) begin
+ if (itopa.MODE != 1) $stop;
+ if (itopb.MODE != 2) $stop;
+ end
+ if (cyc==20) begin
+ if (itopa.i != 4) $stop;
+ if (itopb.i != 5) $stop;
+ $write("*-* All Finished *-*\n");
+ $finish;
+ end
+ end
+endmodule
+
+module sub
+ #(parameter MODE = 0)
+ (
+ ifc isub,
+ input integer i_value
+ );
+
+ // Commercial unsupported Xmrs into scopes within interfaces
+ generate
+ always_comb isub.i = i_value;
+ endgenerate
+endmodule
+
+interface ifc;
+ parameter MODE = 0;
+ // Commercial unsupported Xmrs into scopes within interfaces
+ generate
+ integer i;
+ endgenerate
+endinterface
diff --git a/test_regress/t/t_math_real.v b/test_regress/t/t_math_real.v
index dcb19a0..a72054b 100644
--- a/test_regress/t/t_math_real.v
+++ b/test_regress/t/t_math_real.v
@@ -24,6 +24,7 @@ module t (/*AUTOARG*/
sub_cast_bug374 sub (.cyc5(cyc[4:0]), .*);
initial begin
+ if (1_00_0.0_1 != 1000.01) $stop;
// rtoi truncates
if ($rtoi(36.7) != 36) $stop;
if ($rtoi(36.5) != 36) $stop;
diff --git a/test_regress/t/t_mem_multidim_trace.pl b/test_regress/t/t_mem_multidim_trace.pl
index 05a9968..b8a0427 100755
--- a/test_regress/t/t_mem_multidim_trace.pl
+++ b/test_regress/t/t_mem_multidim_trace.pl
@@ -10,7 +10,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
top_filename("t/t_mem_multidim.v");
compile (
- verilator_flags2 => ['--sp --trace'],
+ verilator_flags2 => ['--cc --trace'],
);
execute (
diff --git a/test_regress/t/t_preproc_psl.v b/test_regress/t/t_preproc_psl.v
deleted file mode 100644
index c65b796..0000000
--- a/test_regress/t/t_preproc_psl.v
+++ /dev/null
@@ -1,72 +0,0 @@
-// DESCRIPTION: Verilator: Verilog Test module
-//
-//
-// This file ONLY is placed into the Public Domain, for any use,
-// without warranty, 2005 by Wilson Snyder.
-
-// verilator metacomment preserved
-/**/
-/*verilator metacomment also_preserved*/
-
-Hello in t_preproc_psl.v
- // Psl capitalized not relevant
- // Double commented ignored // psl not ok
- // You can't have multiple statements on one // psl line.
- // Inline /*cmt*/ comments not allowed inside psl comments
-
- // psl default clock = (posedge clk);
- // psl fails1: cover {cyc==10};
- // psl assert always cyc!=10;
- // psl assert always cyc==3 -> mask==8'h2;
- // psl failsx: cover {cyc==3 && mask==8'h1};
- /* psl fails2:
- cover {
- cyc==3 && mask==8'h9};
- // Ignore this comment-in-between-statements (however not legal inside a statement)
- fails3: always assert {
- cyc==3 && mask==8'h10 };
- */
- `__LINE__
-
- // Note the PSL statement can be on a unique line
- // There can also be multiple "psl" keywords per line.
- /*
- psl
- fails_ml:
- assert always
- cyc==3 -> mask==8'h21;
- psl
- fails_mlalso: assert always cyc==3 -> mask==8'h21;
- */
- `__LINE__
-
- // psl assert never (cyc==1 && reset_l);
-
- // psl fails3: assert always
- // cyc==3 -> mask==8'h21;
- // syntax_error, not_part_of_above_stmt;
-
-// We need to count { and ( when looking for ; that terminate a PSL expression
- // psl assert always
- // {[*]; cyc==3;
- // cyc==4; cyc==6};
- // syntax_error, not_part_of_above_stmt;
-
-// However /**/ pairs can't be split as above.
-
-`ifdef NEVER
- // psl ifdefs have precedence;
-`endif
-
-// Macros are expanded...
-`define define_sig cyc
- // psl assert always `define_sig!=10;
-
-`ifdef verilator
- `psl
-psl assert always sig!=90;
- `verilog
-`endif
-
-// Did we end up right?
-`__LINE__
diff --git a/test_regress/t/t_preproc_psl_off.out b/test_regress/t/t_preproc_psl_off.out
deleted file mode 100644
index fecd977..0000000
--- a/test_regress/t/t_preproc_psl_off.out
+++ /dev/null
@@ -1,99 +0,0 @@
-`line 1 "t/t_preproc_psl.v" 1
-
-
-
-`line 4 "t/t_preproc_psl.v" 0
-
-
-
-`line 7 "t/t_preproc_psl.v" 0
-/*verilator metacomment preserved*/
-
-/*verilator metacomment also_preserved*/
-
-`line 11 "t/t_preproc_psl.v" 0
-Hello in t_preproc_psl.v
-
-
-
-
-
-`line 17 "t/t_preproc_psl.v" 0
-
-
-
-
-
-
-
-`line 28 "t/t_preproc_psl.v" 0
-
-`line 28 "t/t_preproc_psl.v" 0
-
-`line 28 "t/t_preproc_psl.v" 0
-
-`line 28 "t/t_preproc_psl.v" 0
-
-`line 28 "t/t_preproc_psl.v" 0
-
- 29
-
-`line 31 "t/t_preproc_psl.v" 0
-
-
-
-
-`line 40 "t/t_preproc_psl.v" 0
-
-`line 40 "t/t_preproc_psl.v" 0
-
-`line 40 "t/t_preproc_psl.v" 0
-
-`line 40 "t/t_preproc_psl.v" 0
-
-`line 40 "t/t_preproc_psl.v" 0
-
-`line 40 "t/t_preproc_psl.v" 0
-
- 41
-
-`line 43 "t/t_preproc_psl.v" 0
-
-
-`line 45 "t/t_preproc_psl.v" 0
-
-
-
-
-`line 49 "t/t_preproc_psl.v" 0
-
-
-
-
-
-
-`line 55 "t/t_preproc_psl.v" 0
-
-
-`line 57 "t/t_preproc_psl.v" 0
-
-
-
-
-`line 61 "t/t_preproc_psl.v" 0
-
-
-
-
-`line 65 "t/t_preproc_psl.v" 0
-
- `psl
-psl assert always sig!=90;
- `verilog
-
-
-`line 71 "t/t_preproc_psl.v" 0
-
-72
-
-`line 74 "t/t_preproc_psl.v" 2
diff --git a/test_regress/t/t_preproc_psl_on.out b/test_regress/t/t_preproc_psl_on.out
deleted file mode 100644
index bf4bb1e..0000000
--- a/test_regress/t/t_preproc_psl_on.out
+++ /dev/null
@@ -1,88 +0,0 @@
-`line 1 "t/t_preproc_psl.v" 1
-
-
-
-`line 4 "t/t_preproc_psl.v" 0
-
-
-
-`line 7 "t/t_preproc_psl.v" 0
-/*verilator metacomment preserved*/
-
-/*verilator metacomment also_preserved*/
-
-`line 11 "t/t_preproc_psl.v" 0
-Hello in t_preproc_psl.v
-
-
-
-
-
-`line 17 "t/t_preproc_psl.v" 0
- psl default clock = (posedge clk);
- psl fails1: cover {cyc==10};
- psl assert always cyc!=10;
- psl assert always cyc==3 -> mask==8'h2;
- psl failsx: cover {cyc==3 && mask==8'h1};
- psl fails2:
- cover {
- cyc==3 && mask==8'h9};
-
- fails3: always assert {
- cyc==3 && mask==8'h10 };
-
- 29
-
-`line 31 "t/t_preproc_psl.v" 0
-
-
-
- psl
- fails_ml:
- assert always
- cyc==3 -> mask==8'h21;
- psl
- fails_mlalso: assert always cyc==3 -> mask==8'h21;
-
- 41
-
-`line 43 "t/t_preproc_psl.v" 0
- psl assert never (cyc==1 && reset_l);
-
-`line 45 "t/t_preproc_psl.v" 0
- psl fails3: assert always
- psl cyc==3 -> mask==8'h21;
-
-
-`line 49 "t/t_preproc_psl.v" 0
-
- psl assert always
- psl {[*]; cyc==3;
- psl cyc==4; cyc==6};
-
-
-`line 55 "t/t_preproc_psl.v" 0
-
-
-`line 57 "t/t_preproc_psl.v" 0
-
-
-
-
-`line 61 "t/t_preproc_psl.v" 0
-
-
- psl assert always cyc!=10;
-
-`line 65 "t/t_preproc_psl.v" 0
-
- `psl
-psl assert always sig!=90;
- `verilog
-
-
-`line 71 "t/t_preproc_psl.v" 0
-
-72
-
-`line 74 "t/t_preproc_psl.v" 2
diff --git a/test_regress/t/t_psl_basic.v b/test_regress/t/t_psl_basic.v
deleted file mode 100644
index 8fe62c1..0000000
--- a/test_regress/t/t_psl_basic.v
+++ /dev/null
@@ -1,54 +0,0 @@
-// DESCRIPTION: Verilator: Verilog Test module
-//
-// This file ONLY is placed into the Public Domain, for any use,
-// without warranty, 2005 by Wilson Snyder.
-
-module t (/*AUTOARG*/
- // Inputs
- clk
- );
-
- input clk;
-
- reg toggle;
-
- integer cyc; initial cyc=1;
- wire [7:0] cyc_copy = cyc[7:0];
-
- // psl cover {cyc==3 || cyc==4} @ (posedge clk);
- // psl assert {cyc<100} @ (posedge clk) report "AssertionFalse1";
-`ifdef FAILING_ASSERTIONS
- // psl assert {toggle} @ (posedge clk) report "AssertionShouldFail";
-`endif
-
- // psl default clock = negedge clk;
-//FIX // psl assert always {cyc<99};
- // psl cover {cyc==9} report "DefaultClock,expect=1";
-
- // psl assert {(cyc==5)->toggle};
- // psl cover {(cyc==5)->toggle} report "ToggleLogIf,expect=1";
-`ifdef NOT_SUP
- // psl assert {toggle<->cyc[0]};
- // psl cover {toggle<->cyc[0]} report "CycsLogIff,expect=10";
-`endif
-
- // Test {{..}} == Sequence of sequence...
- // psl assert {{true}};
-
- always @ (negedge clk) begin
- //if (!(cyc==5) || toggle) $write("%d: %s\n", cyc, "ToggleLogIf,expect=1");
- //if (toggle&&cyc[0] || ~toggle&&~cyc[0]) $write("%d: %s\n", cyc, "CycsLogIff,expect=10");
- end
-
- always @ (posedge clk) begin
- if (cyc!=0) begin
- cyc <= cyc + 1;
- toggle <= !cyc[0];
- if (cyc==10) begin
- $write("*-* All Finished *-*\n");
- $finish;
- end
- end
- end
-
-endmodule
diff --git a/test_regress/t/t_psl_basic_cover.pl b/test_regress/t/t_psl_basic_cover.pl
deleted file mode 100755
index 700c381..0000000
--- a/test_regress/t/t_psl_basic_cover.pl
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/perl
-if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
-# DESCRIPTION: Verilator: Verilog Test driver/expect definition
-#
-# Copyright 2003-2009 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.
-
-top_filename("t/t_psl_basic.v");
-
-compile (
- verilator_flags2 => ['--psl-deprecated --sp --coverage-user'],
- );
-
-execute (
- check_finished=>1,
- );
-
-# Allow old Perl format dump, or new binary dump
-file_grep ($Self->{coverage_filename}, qr/(,o=>'cover'.*,c=>2\)|o.cover.* 2\n)/);
-file_grep ($Self->{coverage_filename}, qr/(DefaultClock.*,c=>1\)|DefaultClock.* 1\n)/);
-file_grep ($Self->{coverage_filename}, qr/(ToggleLogIf.*,c=>9\)|ToggleLogIf.* 9\n)/);
-
-ok(1);
-1;
diff --git a/test_regress/t/t_savable.v b/test_regress/t/t_savable.v
index 4df08d2..a98c687 100644
--- a/test_regress/t/t_savable.v
+++ b/test_regress/t/t_savable.v
@@ -73,6 +73,7 @@ module sub (/*AUTOARG*/
if (vec[2][1] !== 32'h0201) $stop;
if (vec[2][2] !== 32'h0202) $stop;
if (r != 1.234) $stop;
+ $display("%s",s);
$write("*-* All Finished *-*\n");
$finish;
end
diff --git a/test_regress/t/t_sv_enum_type_methods.pl b/test_regress/t/t_string.pl
similarity index 83%
copy from test_regress/t/t_sv_enum_type_methods.pl
copy to test_regress/t/t_string.pl
index fda118f..f912897 100755
--- a/test_regress/t/t_sv_enum_type_methods.pl
+++ b/test_regress/t/t_string.pl
@@ -7,9 +7,6 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
-# Not yet working on Verilator
-$Self->{vlt} and $Self->unsupported("Verilator unsupported");
-
compile (
);
diff --git a/test_regress/t/t_string.v b/test_regress/t/t_string.v
new file mode 100644
index 0000000..3310728
--- /dev/null
+++ b/test_regress/t/t_string.v
@@ -0,0 +1,91 @@
+// DESCRIPTION: Verilator: Verilog Test module
+//
+// This file ONLY is placed into the Public Domain, for any use,
+// without warranty, 2014 by Wilson Snyder.
+
+`define checkh(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got='h%x exp='h%x\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
+`define checks(gotv,expv) do if ((gotv) !== (expv)) begin $write("%%Error: %s:%0d: got=\"%s\" exp=\"%s\"\n", `__FILE__,`__LINE__, (gotv), (expv)); $stop; end while(0);
+
+module t (/*AUTOARG*/
+ // Inputs
+ clk
+ );
+ input clk;
+
+ integer cyc=0;
+
+ reg [4*8:1] vstr;
+ const string s = "a"; // Check static assignment
+ string s2;
+ string s3;
+ reg eq;
+
+ // Operators == != < <= > >= {a,b} {a{b}} a[b]
+ // a.len, a.putc, a.getc, a.toupper, a.tolower, a.compare, a.icompare, a.substr
+ // a.atoi, a.atohex, a.atooct, a.atobin, a.atoreal,
+ // a.itoa, a.hextoa, a.octoa, a.bintoa, a.realtoa
+
+ initial begin
+ $sformat(vstr, "s=%s", s);
+ `checks(vstr, "s=a");
+ `checks(s, "a");
+ `checks({s,s,s}, "aaa");
+ `checks({4{s}}, "aaaa");
+ // Constification
+ `checkh(s == "a", 1'b1);
+ `checkh(s == "b", 1'b0);
+ `checkh(s != "a", 1'b0);
+ `checkh(s != "b", 1'b1);
+ `checkh(s > " ", 1'b1);
+ `checkh(s > "a", 1'b0);
+ `checkh(s >= "a", 1'b1);
+ `checkh(s >= "b", 1'b0);
+ `checkh(s < "a", 1'b0);
+ `checkh(s < "b", 1'b1);
+ `checkh(s <= " ", 1'b0);
+ `checkh(s <= "a", 1'b1);
+ end
+
+ // Test loop
+ always @ (posedge clk) begin
+ cyc <= cyc + 1;
+ if (cyc==0) begin
+ // Setup
+ s2 = "c0";
+ end
+ else if (cyc==1) begin
+ $sformat(vstr, "s2%s", s2);
+ `checks(vstr, "s2c0");
+ end
+ else if (cyc==2) begin
+ s3 = s2;
+ $sformat(vstr, "s2%s", s3);
+ `checks(vstr, "s2c0");
+ end
+ else if (cyc==3) begin
+ s2 = "a";
+ s3 = "b";
+ end
+ else if (cyc==4) begin
+ `checks({s2,s3}, "ab");
+ `checks({3{s3}}, "bbb");
+ `checkh(s == "a", 1'b1);
+ `checkh(s == "b", 1'b0);
+ `checkh(s != "a", 1'b0);
+ `checkh(s != "b", 1'b1);
+ `checkh(s > " ", 1'b1);
+ `checkh(s > "a", 1'b0);
+ `checkh(s >= "a", 1'b1);
+ `checkh(s >= "b", 1'b0);
+ `checkh(s < "a", 1'b0);
+ `checkh(s < "b", 1'b1);
+ `checkh(s <= " ", 1'b0);
+ `checkh(s <= "a", 1'b1);
+ end
+ else if (cyc==99) begin
+ $write("*-* All Finished *-*\n");
+ $finish;
+ end
+ end
+
+endmodule
diff --git a/test_regress/t/t_sys_sformat.v b/test_regress/t/t_sys_sformat.v
index e2ce550..fbda9b9 100644
--- a/test_regress/t/t_sys_sformat.v
+++ b/test_regress/t/t_sys_sformat.v
@@ -13,6 +13,7 @@ module t;
reg [63:0] q;
reg [16*8:1] wide;
+ reg [8:1] char;
reg [48*8:1] str;
reg [48*8:1] str2;
@@ -48,6 +49,9 @@ module t;
if (str2 !== "mod=top.t") $stop;
`endif
+ $sformat(char,"%s","c");
+ if (char != "c") $stop;
+
$write("*-* All Finished *-*\n");
$finish;
end
diff --git a/test_regress/t/t_trace_ena_sp.pl b/test_regress/t/t_trace_ena_sp.pl
deleted file mode 100755
index 3ff0118..0000000
--- a/test_regress/t/t_trace_ena_sp.pl
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/perl
-if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
-# DESCRIPTION: Verilator: Verilog Test driver/expect definition
-#
-# Copyright 2003-2009 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.
-
-top_filename("t/t_trace_ena.v");
-
-compile (
- verilator_flags2 => ['-trace -sp'],
- );
-
-execute (
- check_finished=>1,
- );
-
-if ($Self->{vlt}) {
- # Note more checks in _cc.pl
- file_grep ("$Self->{obj_dir}/simx.vcd", qr/\$enddefinitions/x);
-}
-
-ok(1);
-1;
diff --git a/test_regress/t/t_trace_off_sp.pl b/test_regress/t/t_trace_off_sp.pl
deleted file mode 100755
index 91b03c8..0000000
--- a/test_regress/t/t_trace_off_sp.pl
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/usr/bin/perl
-if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
-# DESCRIPTION: Verilator: Verilog Test driver/expect definition
-#
-# Copyright 2003-2009 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.
-
-top_filename("t/t_trace_ena.v");
-
-compile (
- verilator_flags2 => ['-notrace -sp'],
- );
-
-execute (
- check_finished=>1,
- );
-
-if ($Self->{vlt}) {
- !-r "$Self->{obj_dir}/simx.vcd" or $Self->error("Tracing should be off\n");
-}
-
-ok(1);
-1;
diff --git a/test_regress/t/t_psl_basic.pl b/test_regress/t/t_trace_scstruct.pl
similarity index 77%
rename from test_regress/t/t_psl_basic.pl
rename to test_regress/t/t_trace_scstruct.pl
index 21301e5..9c08b40 100755
--- a/test_regress/t/t_psl_basic.pl
+++ b/test_regress/t/t_trace_scstruct.pl
@@ -8,12 +8,10 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Version 2.0.
compile (
- v_flags2 => [$Self->{v3}?'--assert --psl-deprecated':($Self->{nc}?'+assert':'')],
- );
+ verilator_flags2 => ['--sc --trace --trace-structs --pins-bv 2'],
+ );
-execute (
- check_finished=>1,
- );
+#execute (); # didn't bother with top shell
ok(1);
1;
diff --git a/test_regress/t/t_trace_scstruct.v b/test_regress/t/t_trace_scstruct.v
new file mode 100644
index 0000000..0993f0f
--- /dev/null
+++ b/test_regress/t/t_trace_scstruct.v
@@ -0,0 +1,26 @@
+// DESCRIPTION: Verilator: Verilog Test module
+//
+// This file ONLY is placed into the Public Domain, for any use,
+// without warranty, 2014 by Wilson Snyder.
+
+// verilator lint_off UNUSED
+// verilator lint_off UNDRIVEN
+
+//bug858
+
+typedef struct packed {
+ logic m_1;
+ logic m_2;
+} struct_t;
+
+typedef struct packed {
+ logic [94:0] m_1;
+ logic m_2;
+} struct96_t;
+
+module t
+ (
+ input struct_t test_input,
+ input struct96_t t96
+ );
+endmodule
diff --git a/test_regress/t/t_var_pins_sc1.pl b/test_regress/t/t_var_pins_sc1.pl
index 871ad5e..cd42fa7 100755
--- a/test_regress/t/t_var_pins_sc1.pl
+++ b/test_regress/t/t_var_pins_sc1.pl
@@ -12,28 +12,28 @@ $Self->{vlt} or $Self->skip("Verilator only test");
top_filename("t/t_var_pinsizes.v");
compile (
- verilator_flags2 => ["-sp -pins-bv 1 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
+ verilator_flags2 => ["-sc -pins-bv 1 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
make_main => 0,
);
if ($Self->{vlt}) {
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<1>\s> \s+ i1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<8>\s> \s+ i8;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ i16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<32>\s> \s+ i32;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<64>\s> \s+ i64;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ i1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<8>\s> \s+ i8;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ i16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<32>\s> \s+ i32;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<64>\s> \s+ i64;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ o1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<8>\s> \s+ o8;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ o16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<32>\s> \s+ o32;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<64>\s> \s+ o64;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ o1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<8>\s> \s+ o8;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ o16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<32>\s> \s+ o32;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<64>\s> \s+ o64;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
}
execute();
diff --git a/test_regress/t/t_var_pins_sc2.pl b/test_regress/t/t_var_pins_sc2.pl
index eb03cbc..9846c71 100755
--- a/test_regress/t/t_var_pins_sc2.pl
+++ b/test_regress/t/t_var_pins_sc2.pl
@@ -12,28 +12,28 @@ $Self->{vlt} or $Self->skip("Verilator only test");
top_filename("t/t_var_pinsizes.v");
compile (
- verilator_flags2 => ["-sp -pins-bv 2 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
+ verilator_flags2 => ["-sc -pins-bv 2 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
make_main => 0,
);
if ($Self->{vlt}) {
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<bool> \s+ i1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<8>\s> \s+ i8;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ i16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<32>\s> \s+ i32;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<64>\s> \s+ i64;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<bool> \s+ i1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<8>\s> \s+ i8;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ i16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<32>\s> \s+ i32;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<64>\s> \s+ i64;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<8>\s> \s+ o8;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ o16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<32>\s> \s+ o32;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<64>\s> \s+ o64;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<bool> \s+ o1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<8>\s> \s+ o8;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ o16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<32>\s> \s+ o32;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<64>\s> \s+ o64;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
}
execute();
diff --git a/test_regress/t/t_var_pins_sc32.pl b/test_regress/t/t_var_pins_sc32.pl
index 329ff94..92976f4 100755
--- a/test_regress/t/t_var_pins_sc32.pl
+++ b/test_regress/t/t_var_pins_sc32.pl
@@ -12,28 +12,28 @@ $Self->{vlt} or $Self->skip("Verilator only test");
top_filename("t/t_var_pinsizes.v");
compile (
- verilator_flags2 => ["-sp -no-pins64 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
+ verilator_flags2 => ["-sc -no-pins64 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
make_main => 0,
);
if ($Self->{vlt}) {
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<bool> \s+ i1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i8;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i32;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<64>\s> \s+ i64;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<bool> \s+ i1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<uint32_t> \s+ i8;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<uint32_t> \s+ i16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<uint32_t> \s+ i32;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<64>\s> \s+ i64;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o8;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o32;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<64>\s> \s+ o64;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<bool> \s+ o1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<uint32_t> \s+ o8;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<uint32_t> \s+ o16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<uint32_t> \s+ o32;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<64>\s> \s+ o64;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
}
execute();
diff --git a/test_regress/t/t_var_pins_sc64.pl b/test_regress/t/t_var_pins_sc64.pl
index 896b740..f5d06e7 100755
--- a/test_regress/t/t_var_pins_sc64.pl
+++ b/test_regress/t/t_var_pins_sc64.pl
@@ -12,28 +12,28 @@ $Self->{vlt} or $Self->skip("Verilator only test");
top_filename("t/t_var_pinsizes.v");
compile (
- verilator_flags2 => ["-sp -pins64 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
+ verilator_flags2 => ["-sc -pins64 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
make_main => 0,
);
if ($Self->{vlt}) {
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<bool> \s+ i1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i8;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i32;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<vluint64_t> \s+ i64;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<bool> \s+ i1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<uint32_t> \s+ i8;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<uint32_t> \s+ i16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<uint32_t> \s+ i32;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<vluint64_t> \s+ i64;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o8;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o32;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<vluint64_t> \s+ o64;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<bool> \s+ o1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<uint32_t> \s+ o8;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<uint32_t> \s+ o16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<uint32_t> \s+ o32;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<vluint64_t> \s+ o64;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
}
execute();
diff --git a/test_regress/t/t_var_pins_sc_biguint.pl b/test_regress/t/t_var_pins_sc_biguint.pl
index 9a4584b..439abd8 100755
--- a/test_regress/t/t_var_pins_sc_biguint.pl
+++ b/test_regress/t/t_var_pins_sc_biguint.pl
@@ -12,32 +12,32 @@ $Self->{vlt} or $Self->skip("Verilator only test");
top_filename("t/t_var_pinsizes.v");
compile (
- verilator_flags2 => ["-sp --pins-sc-biguint --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
+ verilator_flags2 => ["-sc --pins-sc-biguint --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
make_main => 0,
);
if ($Self->{vlt}) {
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<bool> \s+ i1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i8;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i32;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<vluint64_t> \s+ i64;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_biguint<65>\s> \s+ i65;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_biguint<128>\s> \s+ i128;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<513>\s> \s+ i513;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<bool> \s+ i1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<uint32_t> \s+ i8;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<uint32_t> \s+ i16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<uint32_t> \s+ i32;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<vluint64_t> \s+ i64;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_biguint<65>\s> \s+ i65;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_biguint<128>\s> \s+ i128;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<513>\s> \s+ i513;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o8;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o32;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<vluint64_t> \s+ o64;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_biguint<65>\s> \s+ o65;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_biguint<128>\s> \s+ o128;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<513>\s> \s+ o513;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<bool> \s+ o1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<uint32_t> \s+ o8;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<uint32_t> \s+ o16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<uint32_t> \s+ o32;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<vluint64_t> \s+ o64;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_biguint<65>\s> \s+ o65;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_biguint<128>\s> \s+ o128;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<513>\s> \s+ o513;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
}
execute();
diff --git a/test_regress/t/t_var_pins_sc_uint.pl b/test_regress/t/t_var_pins_sc_uint.pl
index 3d1bedd..9c81467 100755
--- a/test_regress/t/t_var_pins_sc_uint.pl
+++ b/test_regress/t/t_var_pins_sc_uint.pl
@@ -12,32 +12,32 @@ $Self->{vlt} or $Self->skip("Verilator only test");
top_filename("t/t_var_pinsizes.v");
compile (
- verilator_flags2 => ["-sp --pins-sc-uint --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
+ verilator_flags2 => ["-sc --pins-sc-uint --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
make_main => 0,
);
if ($Self->{vlt}) {
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<bool> \s+ i1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_uint<8>\s> \s+ i8;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_uint<16>\s> \s+ i16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_uint<32>\s> \s+ i32;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_uint<64>\s> \s+ i64;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<128>\s> \s+ i128;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<513>\s> \s+ i513;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<bool> \s+ i1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_uint<8>\s> \s+ i8;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_uint<16>\s> \s+ i16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_uint<32>\s> \s+ i32;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_uint<64>\s> \s+ i64;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<128>\s> \s+ i128;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<513>\s> \s+ i513;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_uint<8>\s> \s+ o8;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_uint<16>\s> \s+ o16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_uint<32>\s> \s+ o32;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_uint<64>\s> \s+ o64;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<128>\s> \s+ o128;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<513>\s> \s+ o513;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<bool> \s+ o1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_uint<8>\s> \s+ o8;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_uint<16>\s> \s+ o16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_uint<32>\s> \s+ o32;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_uint<64>\s> \s+ o64;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<128>\s> \s+ o128;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<513>\s> \s+ o513;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
}
execute();
diff --git a/test_regress/t/t_var_pins_sc_uint_biguint.pl b/test_regress/t/t_var_pins_sc_uint_biguint.pl
index 9bc5234..258f3ba 100755
--- a/test_regress/t/t_var_pins_sc_uint_biguint.pl
+++ b/test_regress/t/t_var_pins_sc_uint_biguint.pl
@@ -12,32 +12,32 @@ $Self->{vlt} or $Self->skip("Verilator only test");
top_filename("t/t_var_pinsizes.v");
compile (
- verilator_flags2 => ["-sp --pins-sc-uint --pins-sc-biguint --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
+ verilator_flags2 => ["-sc --pins-sc-uint --pins-sc-biguint --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
make_main => 0,
);
if ($Self->{vlt}) {
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<bool> \s+ i1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_uint<8>\s> \s+ i8;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_uint<16>\s> \s+ i16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_uint<32>\s> \s+ i32;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_uint<64>\s> \s+ i64;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_biguint<65>\s> \s+ i65;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_biguint<128>\s> \s+ i128;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<513>\s> \s+ i513;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<bool> \s+ i1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_uint<8>\s> \s+ i8;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_uint<16>\s> \s+ i16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_uint<32>\s> \s+ i32;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_uint<64>\s> \s+ i64;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_biguint<65>\s> \s+ i65;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_biguint<128>\s> \s+ i128;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<513>\s> \s+ i513;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_uint<8>\s> \s+ o8;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_uint<16>\s> \s+ o16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_uint<32>\s> \s+ o32;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_uint<64>\s> \s+ o64;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_biguint<65>\s> \s+ o65;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_biguint<128>\s> \s+ o128;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<513>\s> \s+ o513;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<bool> \s+ o1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_uint<8>\s> \s+ o8;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_uint<16>\s> \s+ o16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_uint<32>\s> \s+ o32;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_uint<64>\s> \s+ o64;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_biguint<65>\s> \s+ o65;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_biguint<128>\s> \s+ o128;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<513>\s> \s+ o513;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
}
execute();
diff --git a/test_regress/t/t_var_pins_scui.pl b/test_regress/t/t_var_pins_scui.pl
index 5c2fddf..3c54085 100755
--- a/test_regress/t/t_var_pins_scui.pl
+++ b/test_regress/t/t_var_pins_scui.pl
@@ -12,28 +12,28 @@ $Self->{vlt} or $Self->skip("Verilator only test");
top_filename("t/t_var_pinsizes.v");
compile (
- verilator_flags2 => ["-sp -pins-uint8 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
+ verilator_flags2 => ["-sc -pins-uint8 --trace --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
make_main => 0,
);
if ($Self->{vlt}) {
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<bool> \s+ i1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint8_t> \s+ i8;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint16_t> \s+ i16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i32;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<vluint64_t> \s+ i64;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<bool> \s+ i1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<uint8_t> \s+ i8;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<uint16_t> \s+ i16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<uint32_t> \s+ i32;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<vluint64_t> \s+ i64;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<1>\s> \s+ ibv1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_in<sc_bv<16>\s> \s+ ibv16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint8_t> \s+ o8;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint16_t> \s+ o16;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o32;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<vluint64_t> \s+ o64;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
- file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<bool> \s+ o1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<uint8_t> \s+ o8;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<uint16_t> \s+ o16;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<uint32_t> \s+ o32;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<vluint64_t> \s+ o64;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<1>\s> \s+ obv1;/x);
+ file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.h", qr/sc_out<sc_bv<16>\s> \s+ obv16;/x);
}
execute();
diff --git a/test_regress/t/t_sv_enum_type_methods.pl b/test_regress/t/t_var_static.pl
similarity index 83%
rename from test_regress/t/t_sv_enum_type_methods.pl
rename to test_regress/t/t_var_static.pl
index fda118f..823ae5c 100755
--- a/test_regress/t/t_sv_enum_type_methods.pl
+++ b/test_regress/t/t_var_static.pl
@@ -7,8 +7,7 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
-# Not yet working on Verilator
-$Self->{vlt} and $Self->unsupported("Verilator unsupported");
+$Self->{vlt} and $Self->unsupported("Verilator unsupported, bug546");
compile (
);
diff --git a/test_regress/t/t_var_static.v b/test_regress/t/t_var_static.v
new file mode 100644
index 0000000..2e38c75
--- /dev/null
+++ b/test_regress/t/t_var_static.v
@@ -0,0 +1,69 @@
+// DESCRIPTION: Verilator: Verilog Test module
+//
+// This file ONLY is placed into the Public Domain, for any use,
+// without warranty, 2014 by Wilson Snyder.
+
+module t (/*AUTOARG*/
+ // Inputs
+ clk
+ );
+
+ input clk;
+
+ function int f_no_no ();
+ int st = 2; st++; return st;
+ endfunction
+ function int f_no_st ();
+ static int st = 2; st++; return st;
+ endfunction
+ function int f_no_au ();
+ automatic int st = 2; st++; return st;
+ endfunction
+
+ function static int f_st_no ();
+ int st = 2; st++; return st;
+ endfunction
+ function static int f_st_st ();
+ static int st = 2; st++; return st;
+ endfunction
+ function static int f_st_au ();
+ automatic int st = 2; st++; return st;
+ endfunction
+
+ function automatic int f_au_no ();
+ int st = 2; st++; return st;
+ endfunction
+ function automatic int f_au_st ();
+ static int st = 2; st++; return st;
+ endfunction
+ function automatic int f_au_au ();
+ automatic int st = 2; st++; return st;
+ endfunction
+
+ initial begin
+ if (f_no_no() != 3) $stop;
+ if (f_no_no() != 4) $stop;
+ if (f_no_st() != 3) $stop;
+ if (f_no_st() != 4) $stop;
+ if (f_no_au() != 3) $stop;
+ if (f_no_au() != 3) $stop;
+ //
+ if (f_st_no() != 3) $stop;
+ if (f_st_no() != 4) $stop;
+ if (f_st_st() != 3) $stop;
+ if (f_st_st() != 4) $stop;
+ if (f_st_au() != 3) $stop;
+ if (f_st_au() != 3) $stop;
+ //
+ if (f_au_no() != 3) $stop;
+ if (f_au_no() != 3) $stop;
+ if (f_au_st() != 3) $stop;
+ if (f_au_st() != 4) $stop;
+ if (f_au_au() != 3) $stop;
+ if (f_au_au() != 3) $stop;
+ //
+ $write("*-* All Finished *-*\n");
+ $finish;
+ end
+
+endmodule
diff --git a/test_regress/t/t_vlcov_data_a.dat b/test_regress/t/t_vlcov_data_a.dat
new file mode 100644
index 0000000..5acd5df
--- /dev/null
+++ b/test_regress/t/t_vlcov_data_a.dat
@@ -0,0 +1,5 @@
+# SystemC::Coverage-3
+C 'CoverPoint0ffile1.sphl159' 0
+C 'CoverPoint1ffile1.sphl159' 1
+C 'CoverPoint2ffile1.sphl159' 10
+C 'CoverPoint3ffile1.sphl159' 0
diff --git a/test_regress/t/t_vlcov_data_b.dat b/test_regress/t/t_vlcov_data_b.dat
new file mode 100644
index 0000000..d06b129
--- /dev/null
+++ b/test_regress/t/t_vlcov_data_b.dat
@@ -0,0 +1,5 @@
+# SystemC::Coverage-3
+C 'CoverPoint2ffile1.sphl159' 10
+C 'CoverPoint3ffile1.sphl159' 0
+C 'CoverPoint4ffile1.sphl159' 1
+C 'CoverPoint5ffile1.sphl159' 9
diff --git a/test_regress/t/t_vlcov_data_c.dat b/test_regress/t/t_vlcov_data_c.dat
new file mode 100644
index 0000000..73f5bb1
--- /dev/null
+++ b/test_regress/t/t_vlcov_data_c.dat
@@ -0,0 +1,2 @@
+# SystemC::Coverage-3
+C 'CoverPoint6ffile1.sphl159' 10
diff --git a/test_regress/t/t_vlcov_data_d.dat b/test_regress/t/t_vlcov_data_d.dat
new file mode 100644
index 0000000..d9e06d0
--- /dev/null
+++ b/test_regress/t/t_vlcov_data_d.dat
@@ -0,0 +1,2 @@
+# SystemC::Coverage-3
+C 'CoverPoint6ffile1.sphl159' 12
diff --git a/test_regress/t/t_vlcov_merge.out b/test_regress/t/t_vlcov_merge.out
new file mode 100644
index 0000000..7ac2cab
--- /dev/null
+++ b/test_regress/t/t_vlcov_merge.out
@@ -0,0 +1,8 @@
+# SystemC::Coverage-3
+C 'CoverPoint0ffile1.sphl159' 0
+C 'CoverPoint1ffile1.sphl159' 1
+C 'CoverPoint2ffile1.sphl159' 20
+C 'CoverPoint3ffile1.sphl159' 0
+C 'CoverPoint4ffile1.sphl159' 1
+C 'CoverPoint5ffile1.sphl159' 9
+C 'CoverPoint6ffile1.sphl159' 22
diff --git a/test_regress/t/t_preproc_psl_off.pl b/test_regress/t/t_vlcov_merge.pl
similarity index 61%
copy from test_regress/t/t_preproc_psl_off.pl
copy to test_regress/t/t_vlcov_merge.pl
index 0bea790..e7143ab 100755
--- a/test_regress/t/t_preproc_psl_off.pl
+++ b/test_regress/t/t_vlcov_merge.pl
@@ -9,16 +9,13 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
$Self->{vlt} or $Self->skip("Verilator only test");
-my $stdout_filename = "$Self->{obj_dir}/$Self->{name}__test.vpp";
-
-top_filename("t/t_preproc_psl.v");
-
-compile (
- verilator_flags2 => ['-E'],
- verilator_make_gcc=>0,
- stdout_filename => $stdout_filename,
+$Self->_run(cmd=>["../bin/verilator_coverage",
+ "--write", "$Self->{obj_dir}/coverage.dat",
+ "t/t_vlcov_data_a.dat",
+ "t/t_vlcov_data_b.dat",
+ "t/t_vlcov_data_c.dat",
+ "t/t_vlcov_data_d.dat",
+ ],
);
-
-ok(files_identical($stdout_filename, "t/$Self->{name}.out"));
-
+ok(files_identical("$Self->{obj_dir}/coverage.dat", "t/$Self->{name}.out"));
1;
diff --git a/test_regress/t/t_vlcov_rank.out b/test_regress/t/t_vlcov_rank.out
new file mode 100644
index 0000000..4439fcb
--- /dev/null
+++ b/test_regress/t/t_vlcov_rank.out
@@ -0,0 +1,6 @@
+Tests:
+ Covered, Rank, RankPts, Filename
+ 2, 2, 1, "t/t_vlcov_data_a.dat"
+ 3, 1, 3, "t/t_vlcov_data_b.dat"
+ 1, 3, 1, "t/t_vlcov_data_c.dat"
+ 1, 0, 0, "t/t_vlcov_data_d.dat"
diff --git a/test_regress/t/t_preproc_psl_on.pl b/test_regress/t/t_vlcov_rank.pl
similarity index 59%
rename from test_regress/t/t_preproc_psl_on.pl
rename to test_regress/t/t_vlcov_rank.pl
index fd818a9..febe59c 100755
--- a/test_regress/t/t_preproc_psl_on.pl
+++ b/test_regress/t/t_vlcov_rank.pl
@@ -9,16 +9,15 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
$Self->{vlt} or $Self->skip("Verilator only test");
-my $stdout_filename = "$Self->{obj_dir}/$Self->{name}__test.vpp";
-
-top_filename("t/t_preproc_psl.v");
-
-compile (
- verilator_flags2 => ['-psl-deprecated -E'],
- verilator_make_gcc=>0,
- stdout_filename => $stdout_filename,
+$Self->_run(cmd=>["../bin/verilator_coverage",
+ "--rank",
+ "t/t_vlcov_data_a.dat",
+ "t/t_vlcov_data_b.dat",
+ "t/t_vlcov_data_c.dat",
+ "t/t_vlcov_data_d.dat",
+ ],
+ logfile=>"$Self->{obj_dir}/vlcov.log",
+ tee => 0,
);
-
-ok(files_identical($stdout_filename, "t/$Self->{name}.out"));
-
+ok(files_identical("$Self->{obj_dir}/vlcov.log", "t/$Self->{name}.out"));
1;
diff --git a/test_regress/t/t_preproc_psl_off.pl b/test_regress/t/t_vlcov_rewrite.pl
similarity index 55%
rename from test_regress/t/t_preproc_psl_off.pl
rename to test_regress/t/t_vlcov_rewrite.pl
index 0bea790..c538a94 100755
--- a/test_regress/t/t_preproc_psl_off.pl
+++ b/test_regress/t/t_vlcov_rewrite.pl
@@ -9,16 +9,17 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
$Self->{vlt} or $Self->skip("Verilator only test");
-my $stdout_filename = "$Self->{obj_dir}/$Self->{name}__test.vpp";
-
-top_filename("t/t_preproc_psl.v");
-
-compile (
- verilator_flags2 => ['-E'],
- verilator_make_gcc=>0,
- stdout_filename => $stdout_filename,
- );
-
-ok(files_identical($stdout_filename, "t/$Self->{name}.out"));
-
+foreach my $basename ("t_vlcov_data_a.dat",
+ "t_vlcov_data_b.dat",
+ "t_vlcov_data_c.dat",
+ "t_vlcov_data_d.dat",
+ ) {
+ $Self->_run(cmd=>["../bin/verilator_coverage",
+ "t/${basename}",
+ "--write", "$Self->{obj_dir}/${basename}"
+ ],
+ tee=>0,
+ );
+ ok(files_identical("$Self->{obj_dir}/${basename}", "t/${basename}"));
+}
1;
diff --git a/test_sc/Makefile b/test_sc/Makefile
index 60a850b..e97196c 100644
--- a/test_sc/Makefile
+++ b/test_sc/Makefile
@@ -26,8 +26,8 @@ SYSTEMC_TESTING ?= $(SYSTEMC)$(SYSTEMC_INCLUDE)
######################################################################
ifneq ($(SYSTEMC_TESTING),)
-test_default: precopy prep preproc compile run
-test_debug: precopy prep_dbg preproc compile run
+test_default: precopy prep compile run
+test_debug: precopy prep_dbg compile run
else
test_default: nosc
test_debug: nosc
@@ -44,9 +44,6 @@ prep:
prep_dbg:
$(PERL) $(VERILATOR_ROOT)/bin/verilator $(DEBUG_ON) $(VERILATOR_FLAGS)
-preproc:
- cd obj_dir ; $(MAKE) -j 1 -f ../Makefile_obj preproc
-
compile:
cd obj_dir ; $(MAKE) -j 3 -f ../Makefile_obj
diff --git a/test_sc/sc_main.cpp b/test_sc/sc_main.cpp
index ba6be6a..d878152 100644
--- a/test_sc/sc_main.cpp
+++ b/test_sc/sc_main.cpp
@@ -12,15 +12,8 @@
#include <sys/times.h>
#include <sys/stat.h>
-#ifdef SYSTEMPERL
-# include "systemperl.h" // SystemC + SystemPerl global header
-# include "sp_log.h" // Logging cout to files
-# include "SpTraceVcd.h"
-# include "SpCoverage.h"
-#else
-# include "systemc.h" // SystemC global header
-# include "verilated_vcd_sc.h" // Tracing
-#endif
+#include "systemc.h" // SystemC global header
+#include "verilated_vcd_sc.h" // Tracing
#include "Vtop.h" // Top level header, generated from verilog
@@ -33,10 +26,6 @@ int sc_main(int argc, char* argv[]) {
// General logfile
ios::sync_with_stdio();
-#ifdef SYSTEMPERL
- sp_log_file simlog ("sim.log");
- simlog.redirect_cout();
-#endif
// Defaults
#if (SYSTEMC_VERSION>20011000)
@@ -70,19 +59,6 @@ int sc_main(int argc, char* argv[]) {
//==========
// Part under test
-#ifdef SYSTEMPERL
- SP_CELL (top, Vtop);
- SP_PIN (top, clk, clk);
- SP_PIN (top, fastclk, fastclk);
- SP_PIN (top, reset_l, reset_l);
- SP_PIN (top, passed, passed);
- SP_PIN (top, in_small, in_small);
- SP_PIN (top, in_quad, in_quad);
- SP_PIN (top, in_wide, in_wide);
- SP_PIN (top, out_small, out_small);
- SP_PIN (top, out_quad, out_quad);
- SP_PIN (top, out_wide, out_wide);
-#else
Vtop* top = new Vtop("top");
top->clk (clk);
top->fastclk (fastclk);
@@ -94,7 +70,6 @@ int sc_main(int argc, char* argv[]) {
top->out_small (out_small);
top->out_quad (out_quad);
top->out_wide (out_wide);
-#endif
//==========
// Waves
@@ -119,11 +94,7 @@ int sc_main(int argc, char* argv[]) {
#if VM_TRACE
cout << "Enabling waves...\n";
-# ifdef SYSTEMPERL
- SpTraceFile* tfp = new SpTraceFile;
-# else
VerilatedVcdSc* tfp = new VerilatedVcdSc;
-# endif
top->trace (tfp, 99);
tfp->open ("vlt_dump.vcd");
#endif
@@ -134,10 +105,10 @@ int sc_main(int argc, char* argv[]) {
cout <<("Test beginning...\n");
reset_l = 1;
- while (VL_TIME_Q() < 60 && !passed && !Verilated::gotFinish()) {
+ while (VL_TIME_Q() < 60 && !Verilated::gotFinish()) {
#if VM_TRACE
// Flush the wave files each cycle so we can immediately see the output
- // Don't do this in "real" programs, do it in a abort() handler instead
+ // Don't do this in "real" programs, do it in an abort() handler instead
if (tfp) tfp->flush();
#endif
if (VL_TIME_Q() > 10) {
diff --git a/test_sp/.gitignore b/test_sp/.gitignore
deleted file mode 100644
index b491e81..0000000
--- a/test_sp/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-*.old
-*.dmp
-*.log
-*.csrc
-*.vcd
-obj_*
-logs
-project
diff --git a/test_sp/Makefile b/test_sp/Makefile
deleted file mode 100644
index 78dbffb..0000000
--- a/test_sp/Makefile
+++ /dev/null
@@ -1,86 +0,0 @@
-#*****************************************************************************
-#
-# DESCRIPTION: Verilator Example: Makefile for inside source directory
-#
-# This calls the object directory makefile. That allows the objects to
-# be placed in the "current directory" which simplifies the Makefile.
-#
-# Copyright 2003-2014 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.
-#
-#****************************************************************************/
-
-default: test_default
-
-# This must point to the root of the VERILATOR kit
-VERILATOR_ROOT := $(shell pwd)/..
-export VERILATOR_ROOT
-
-# Pick up PERL and other variable settings
-include $(VERILATOR_ROOT)/include/verilated.mk
-
-DEBUG_ON = --debug --trace-dups
-
-######################################################################
-ifneq ($(SYSTEMPERL),)
-test_default: precopy prep preproc compile run coverage
-test_debug: precopy prep_dbg preproc compile_dbg run coverage
-test_nopublic: precopy prep_dbg_np preproc compile_dbg run coverage
-else
-test_default: nosp
-test_debug: nosp
-test_nopublic: nosp
-endif
-
-V_FLAGS = -f $(VERILATOR_ROOT)/test_v/input.vc
-
-# Note the --public --output-split-cfunc is here for testing only,
-# Avoid using these settings in real application Makefiles!
-VERILATOR_FLAGS = --public --output-split-cfuncs 1000 --output-split 1000 \
- --sp --coverage --stats --trace $(V_FLAGS) top.v
-
-precopy: obj_dir obj_dir/sc_main.cpp
-obj_dir/sc_main.cpp: ../test_sc/sc_main.cpp
- mkdir -p obj_dir
- cp $^ $@
-
-prep:
- $(PERL) $(VERILATOR_ROOT)/bin/verilator $(VERILATOR_FLAGS)
-prep_dbg:
- $(PERL) $(VERILATOR_ROOT)/bin/verilator $(DEBUG_ON) $(VERILATOR_FLAGS)
-prep_dbg_np:
- $(PERL) $(VERILATOR_ROOT)/bin/verilator $(DEBUG_ON) $(VERILATOR_FLAGS) --nopublic
-
-preproc:
- cd obj_dir ; $(MAKE) -j 1 -f ../Makefile_obj preproc
-
-compile:
- cd obj_dir ; $(MAKE) -j 3 -f ../Makefile_obj
-
-compile_dbg:
- cd obj_dir ; $(MAKE) OPT=-g -j 3 -f ../Makefile_obj
-
-run:
- obj_dir/simx
-
-coverage:
- vcoverage $(V_FLAGS)
-
-######################################################################
-
-obj_dir:
- mkdir $@
-
-nosp:
- @echo
- @echo %Skip: SYSTEMPERL not in environment
- @echo
-
-######################################################################
-
-maintainer-copy::
-clean mostlyclean distclean maintainer-clean::
- -rm -rf obj_dir *.log *.dmp *.vpd *.vcd core logs
-
diff --git a/test_sp/Makefile_obj b/test_sp/Makefile_obj
deleted file mode 100644
index 9386bb5..0000000
--- a/test_sp/Makefile_obj
+++ /dev/null
@@ -1,37 +0,0 @@
-# -*- Makefile -*-
-#*****************************************************************************
-#
-# DESCRIPTION: Verilator Example: Makefile for inside object directory
-#
-# This is executed in the object directory, and called by ../Makefile
-#
-# Copyright 2003-2014 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.
-#
-#*****************************************************************************
-
-default: simx
-include Vtop.mk
-
-#######################################################################
-# Use sp_log.cpp, so we can get output in sim.log
-
-CPPFLAGS += -DUTIL_PRINTF=sp_log_printf
-CPPFLAGS += -Wno-deprecated
-CPPFLAGS += $(SYSTEMC_CXX_FLAGS)
-CPPFLAGS += $(OPT)
-
-LDFLAGS += $(SYSTEMC_CXX_FLAGS)
-
-#######################################################################
-# Linking final exe -- presumes have a sim_main.cpp
-
-SC_LIB = $(SYSTEMC_LIBDIR)/libsystemc.a
-
-simx: sc_main.o $(VK_GLOBAL_OBJS) \
- $(VM_PREFIX)__ALL.a $(SC_LIB)
- $(LINK) $(LDFLAGS) -g $^ $(LOADLIBES) $(LDLIBS) -o $@ $(SC_LIBS) $(LIBS) 2>&1 | c++filt
-
-sc_main.o: sc_main.cpp $(VM_PREFIX).h
diff --git a/test_vcs/.gitignore b/test_vcs/.gitignore
deleted file mode 100644
index 485ec44..0000000
--- a/test_vcs/.gitignore
+++ /dev/null
@@ -1,13 +0,0 @@
-*.old
-*.dmp
-*.log
-*.csrc
-*.vcd
-csrc
-vcs.key
-ucli.key
-*.daidir
-simv
-obj_*
-project
-INCA_libs
diff --git a/test_vcs/Makefile b/test_vcs/Makefile
deleted file mode 100644
index 1619183..0000000
--- a/test_vcs/Makefile
+++ /dev/null
@@ -1,76 +0,0 @@
-#*****************************************************************************
-#
-# DESCRIPTION: Verilator Example: Makefile for inside source directory
-#
-# This calls the object directory makefile. That allows the objects to
-# be placed in the "current directory" which simplifies the Makefile.
-#
-# Copyright 2003-2014 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.
-#
-#****************************************************************************/
-
-default: test
-
-# This must point to the root of the VERILATOR kit
-VERILATOR_ROOT := $(shell pwd)/..
-export VERILATOR_ROOT
-
-# Pick up PERL and other variable settings
-include $(VERILATOR_ROOT)/include/verilated.mk
-
-######################################################################
-
-V_FILES := $(wildcard *.v ../test_v/*.v)
-
-######################################################################
-
-ifneq ($(VCS_HOME),)
-test:: vcs
-else
-test:: novcs
-endif
-
-ifneq ($(NC_ROOT),)
-test:: nc
-else
-test:: nonc
-endif
-
-######################################################################
-
-novcs:
- @echo "No VCS simulator installed."
- @echo "Not running VCS regression test."
-
-vcs: vcs_passed.log
-
-simv: $(V_FILES) ../test_v/input.vc
- vcs +cli -I -sverilog +define+VCS+1 -f ../test_v/input.vc -q bench.v
-
-vcs_passed.log : simv
- -rm -f test_passed.log
- ./simv -l sim.log
- grep -q Finished sim.log && grep Finished sim.log > vcs_passed.log
-
-######################################################################
-
-nonc:
- @echo "No NC-Verilog simulator installed."
- @echo "Not running NC-Verilog regression test."
-
-nc: nc_passed.log
-
-nc_passed.log: $(V_FILES) ../test_v/input.vc
- ncverilog +define+ncverilog=1 +licqueue -f ../test_v/input.vc -q bench.v
- -rm -f nc_passed.log
- grep -q Finished ncverilog.log && grep Finished ncverilog.log > nc_passed.log
-
-######################################################################
-
-maintainer-copy::
-clean mostlyclean distclean maintainer-clean::
- -rm -rf obj_dir *.log *.dmp *.vpd simv* *.key csrc INCA_libs
-
diff --git a/test_vcs/bench.v b/test_vcs/bench.v
deleted file mode 100644
index 0139014..0000000
--- a/test_vcs/bench.v
+++ /dev/null
@@ -1,81 +0,0 @@
-// DESCRIPTION: Verilator Test: Top level testbench for VCS or other fully Verilog compliant simulators
-//
-// This file ONLY is placed into the Public Domain, for any use,
-// without warranty, 2003 by Wilson Snyder.
-
-`timescale 1 ns / 1ns
-
-module bench;
-
- /*AUTOWIRE*/
- // Beginning of automatic wires (for undeclared instantiated-module outputs)
- wire [39:0] out_quad; // From top of top.v
- wire [1:0] out_small; // From top of top.v
- wire [69:0] out_wide; // From top of top.v
- wire passed; // From top of top.v
- // End of automatics
-
- reg clk;
- reg fastclk;
- reg reset_l;
- reg [1:0] in_small;
- reg [39:0] in_quad;
- reg [69:0] in_wide;
-
- // Test cases
- top top (/*AUTOINST*/
- // Outputs
- .passed (passed),
- .out_small (out_small[1:0]),
- .out_quad (out_quad[39:0]),
- .out_wide (out_wide[69:0]),
- // Inputs
- .clk (clk),
- .fastclk (fastclk),
- .reset_l (reset_l),
- .in_small (in_small[1:0]),
- .in_quad (in_quad[39:0]),
- .in_wide (in_wide[69:0]));
-
- //surefire lint_off STMINI
- //surefire lint_off STMFVR
- //surefire lint_off DLYONE
-
- integer fh;
-
- // surefire lint_off CWECBB
- initial begin
- reset_l = 1'b1; // Want to catch negedge
- fastclk = 0;
- clk = 0;
- forever begin
- in_small = 0;
- in_wide = 0;
- $write("[%0t] %x %x %x %x %x\n", $time, clk, reset_l, passed, out_small, out_wide);
- if (($time % 10) == 3) clk = 1'b1;
- if (($time % 10) == 8) clk = 1'b0;
- if ($time>10) reset_l = 1'b1;
- else if ($time > 1) reset_l = 1'b0;
- if ($time>60 || passed === 1'b1) begin
- if (passed !== 1'b1) begin
- $write("A Test failed!!!\n");
- $stop;
- end
- else begin
- $write("*-* All Finished *-*\n"); // Magic if using perl's Log::Detect
- fh = $fopen("test_passed.log");
- $fclose(fh);
- end
- $finish;
- end
- #1;
- fastclk = !fastclk;
- end
- end
-
-endmodule
-
-// Local Variables:
-// verilog-library-directories:("." "../test_v")
-// compile-command: "vlint --brief -f ../test_v/input.vc bench.v"
-// End:
diff --git a/verilator.1 b/verilator.1
index 0a29938..feabb43 100644
--- a/verilator.1
+++ b/verilator.1
@@ -124,7 +124,7 @@
.\" ========================================================================
.\"
.IX Title "VERILATOR 1"
-.TH VERILATOR 1 "2014-11-13" "perl v5.14.2" "User Contributed Perl Documentation"
+.TH VERILATOR 1 "2014-12-20" "perl v5.14.2" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
@@ -143,17 +143,13 @@ Verilator \- Convert Verilog code to C++/SystemC
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
Verilator converts synthesizable (not behavioral) Verilog code, plus some
-Synthesis, SystemVerilog and a small subset of Verilog \s-1AMS\s0
-assertions, into \*(C+, SystemC or SystemPerl code. It is not a complete
-simulator, just a compiler.
+Synthesis, SystemVerilog and a small subset of Verilog \s-1AMS\s0 assertions, into
+\&\*(C+ or SystemC code. It is not a complete simulator, but a compiler.
.PP
Verilator is invoked with parameters similar to \s-1GCC\s0, Cadence
Verilog\-XL/NC\-Verilog, or Synopsys's \s-1VCS\s0. It reads the specified Verilog
code, lints it, and optionally adds coverage and waveform tracing code.
-For \*(C+ and SystemC formats, it outputs .cpp and .h files. For SystemPerl
-format, it outputs .sp files for the SystemPerl preprocessor, which greatly
-simplifies writing SystemC code and is available at
-<http://www.veripool.org>.
+For \*(C+ and SystemC formats, it outputs .cpp and .h files.
.PP
The files created by Verilator are then compiled with \*(C+. The user writes
a little \*(C+ wrapper file, which instantiates the top level module, and
@@ -249,8 +245,8 @@ descriptions in the next sections for more information.
\& \-\-report\-unoptflat Extra diagnostics for UNOPTFLAT
\& \-\-savable Enable model save\-restore
\& \-\-sc Create SystemC output
-\& \-\-sp Create SystemPerl output
\& \-\-stats Create statistics file
+\& \-\-stats\-vars Provide statistics on variables
\& \-sv Enable SystemVerilog parsing
\& +systemverilogext+<ext> Synonym for +1800\-2012ext+<ext>
\& \-\-top\-module <topname> Name of top level input module
@@ -376,7 +372,7 @@ run on the generated makefile these will be passed to the \*(C+ compiler
(gcc/g++/msvc++).
.IP "\-\-cc" 4
.IX Item "--cc"
-Specifies \*(C+ without SystemC output mode; see also \-\-sc and \-\-sp.
+Specifies \*(C+ without SystemC output mode; see also \-\-sc.
.IP "\-\-cdc" 4
.IX Item "--cdc"
Experimental. Perform some clock domain crossing checks and issue related
@@ -838,13 +834,15 @@ other data the process needs saved/restored. For example:
.Ve
.IP "\-\-sc" 4
.IX Item "--sc"
-Specifies SystemC output mode; see also \-\-cc and \-sp.
-.IP "\-\-sp" 4
-.IX Item "--sp"
-Specifies SystemPerl output mode; see also \-\-cc and \-sc.
+Specifies SystemC output mode; see also \-\-cc.
.IP "\-\-stats" 4
.IX Item "--stats"
Creates a dump file with statistics on the design in {prefix}_\|_stats.txt.
+.IP "\-\-stats\-vars" 4
+.IX Item "--stats-vars"
+Creates more detailed statistics including a list of all the variables by
+size (plain \-\-stats just gives a count). See \-\-stats, which is implied by
+this.
.IP "\-sv" 4
.IX Item "-sv"
Specifies SystemVerilog language features should be enabled; equivalent to
@@ -1141,7 +1139,7 @@ when your source changes it will automatically run all of these steps. See
the test_c directory in the distribution for an example.
.SH "EXAMPLE SYSTEMC EXECUTION"
.IX Header "EXAMPLE SYSTEMC EXECUTION"
-This is an example similar to the above, but using SystemPerl.
+This is an example similar to the above, but using SystemC.
.PP
.Vb 2
\& mkdir test_our_sc
@@ -1181,21 +1179,9 @@ your operating system (as an \s-1RPM\s0), first you need to point to the kit:
Now we run Verilator on our little example.
.PP
.Vb 1
-\& verilator \-Wall \-\-sp our.v
+\& verilator \-Wall \-\-sc our.v
.Ve
.PP
-Then we convert the SystemPerl output to SystemC.
-.PP
-.Vb 3
-\& cd obj_dir
-\& export SYSTEMPERL=/path/to/where/systemperl/kit/came/from
-\& $SYSTEMPERL/sp_preproc \-\-preproc *.sp
-.Ve
-.PP
-(You can also skip the above sp_preproc by getting pure SystemC from
-Verilator by replacing the verilator \-\-sp flag in the previous step with
-\&\-sc.)
-.PP
We then can compile it
.PP
.Vb 2
@@ -1231,7 +1217,7 @@ And we get the same output as the \*(C+ example:
.PP
Really, you're better off using a Makefile to do all this for you. Then,
when your source changes it will automatically run all of these steps. See
-the test_sp directory in the distribution for an example.
+the test_sc directory in the distribution for an example.
.SH "BENCHMARKING & OPTIMIZATION"
.IX Header "BENCHMARKING & OPTIMIZATION"
For best performance, run Verilator with the \*(L"\-O3 \-\-x\-assign=fast
@@ -1289,6 +1275,10 @@ especially if you link in \s-1DPI\s0 code. To enable \s-1LTO\s0 on \s-1GCC\s0,
both compilation and link. Note \s-1LTO\s0 may cause excessive compile times on
large designs.
.PP
+If you are using your own makefiles, you may want to compile the Verilated
+code with \-DVL_INLINE_OPT=inline. This will inline functions, however this
+requires that all cpp files be compiled in a single compiler run.
+.PP
You may uncover further tuning possibilities by profiling the Verilog code.
Use Verilator's \-\-profile\-cfuncs, then \s-1GCC\s0's \-g \-pg. You can then run
either oprofile or gprof to see where in the \*(C+ code the time is spent.
@@ -1318,13 +1308,6 @@ For \-cc and \-sc mode, it also creates:
\& {prefix}{each_verilog_module}.h // Lower level internal header files
.Ve
.PP
-For \-sp mode, instead of .cpp and .h it creates:
-.PP
-.Vb 2
-\& {prefix}.sp // Top level SystemC file
-\& {prefix}{each_verilog_module}.sp // Lower level internal SC files
-.Ve
-.PP
In certain optimization modes, it also creates:
.PP
.Vb 8
@@ -1395,19 +1378,6 @@ If set, specifies the directory containing the libsystemc.a library. If not
specified, it will come from a default optionally specified at configure
time (before Verilator was compiled), or computed from
SYSTEMC/lib\-SYSTEMC_ARCH.
-.IP "\s-1SYSTEMPERL\s0" 4
-.IX Item "SYSTEMPERL"
-Specifies the directory containing the SystemPerl distribution kit. This
-is used to find the SystemPerl library and include files. If not
-specified, it will come from a default optionally specified at configure
-time (before Verilator was compiled). See also \s-1SYSTEMPERL_INCLUDE\s0.
-.IP "\s-1SYSTEMPERL_INCLUDE\s0" 4
-.IX Item "SYSTEMPERL_INCLUDE"
-Specifies the directory containing the Verilog-Perl include .cpp files,
-from the src/ directory of the SystemPerl kit. If not specified, it will
-be computed from the \s-1SYSTEMPERL\s0 environment variable if it is set, and if
-\&\s-1SYSTEMPERL\s0 is not set \s-1SYSTEMPERL_INCLUDE\s0 will come from a default
-optionally specified at configure time (before Verilator was compiled).
.IP "\s-1VCS_HOME\s0" 4
.IX Item "VCS_HOME"
If set, specifies the directory containing the Synopsys \s-1VCS\s0 distribution.
@@ -2022,8 +1992,8 @@ Specifies the module the comment appears in may be inlined into any modules
that use this module. This is useful to speed up simulation time with some
small loss of trace visibility and modularity. Note signals under inlined
submodules will be named \fIsubmodule\fR_\|_DOT_\|_\fIsubsignal\fR as \*(C+ does not
-allow \*(L".\*(R" in signal names. SystemPerl when tracing such signals will
-replace the _\|_DOT_\|_ with the period.
+allow \*(L".\*(R" in signal names. When tracing such signals the tracing routines
+will replace the _\|_DOT_\|_ with the period.
.IP "/*verilator isolate_assignments*/" 4
.IX Item "/*verilator isolate_assignments*/"
Used after a signal declaration to indicate the assignments to this signal
@@ -2427,8 +2397,9 @@ full nor unique.
All specify blocks and timing checks are ignored.
.IP "string" 4
.IX Item "string"
-String is supported only to the point that they can be passed to \s-1DPI\s0
-imports.
+String is supported only to the point that they can be assigned,
+concatenated, compared, and passed to \s-1DPI\s0 imports. Standard method calls
+on strings are not supported.
.IP "timeunit, timeprecision" 4
.IX Item "timeunit, timeprecision"
All timing control statements are ignored.
@@ -3226,10 +3197,6 @@ flag.
Note you can also call \->trace on multiple Verilated objects with the same
trace file if you want all data to land in the same output file.
.Sp
-Note also older versions of Verilator used the SystemPerl package and
-SpTraceVcdC class. This still works, but is depreciated as it requires
-strong coupling between the Verilator and SystemPerl versions.
-.Sp
.Vb 10
\& #include "verilated_vcd_c.h"
\& ...
@@ -3253,7 +3220,7 @@ Add the \-\-trace switch to Verilator, and in your top level C sc_main code,
include verilated_vcd_sc.h. Then call Verilated::traceEverOn(true). Then
create a VerilatedVcdSc object as you would create a normal SystemC trace
file. For an example, see the call to VerilatedVcdSc in the
-test_sp/sc_main.cpp file of the distribution, and below.
+test_sc/sc_main.cpp file of the distribution, and below.
.Sp
Alternatively you may use the \*(C+ trace mechanism described in the previous
question, however the timescale and timeprecision will not inherited from
@@ -3304,22 +3271,21 @@ network disk. Network disks are generally far slower.
.IP "How do I do coverage analysis?" 4
.IX Item "How do I do coverage analysis?"
Verilator supports both block (line) coverage and user inserted functional
-coverage. Both require the SystemPerl package to be installed but do not
-require use of the SystemPerl output mode.
+coverage.
.Sp
First, run verilator with the \-\-coverage option. If you're using your own
-makefile, compile the model with the \s-1GCC\s0 flag \-DSP_COVERAGE (if using
+makefile, compile the model with the \s-1GCC\s0 flag \-DVM_COVERAGE (if using
Verilator's, it will do this for you.)
.Sp
Run your tests in different directories. Each test will create a
logs/coverage.pl file.
.Sp
-After running all of your tests, the vcoverage utility (from the SystemPerl
-package) is executed. Vcoverage reads the logs/coverage.pl file(s), and
-creates an annotated source code listing showing code coverage details.
+After running all of your tests, verilator_coverage is executed.
+Verilator_coverage reads the logs/coverage.pl file(s), and creates an
+annotated source code listing showing code coverage details.
.Sp
For an example, after running 'make test' in the Verilator distribution,
-see the test_sp/logs/coverage_source directory. Grep for lines starting
+see the test_sc/logs directory. Grep for lines starting
with '%' to see what lines Verilator believes need more coverage.
.IP "Where is the translate_off command? (How do I ignore a construct?)" 4
.IX Item "Where is the translate_off command? (How do I ignore a construct?)"
@@ -3607,7 +3573,7 @@ Wilson Snyder <wsnyder at wsnyder.org>
Major concepts by Paul Wasson and Duane Galbi.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
-verilator_profcfunc, systemperl, vcoverage, make,
+verilator_coverage, verilator_profcfunc, make,
.PP
\&\*(L"verilator \-\-help\*(R" which is the source for this document,
.PP
diff --git a/verilator.html b/verilator.html
index 02007a4..551b3d7 100644
--- a/verilator.html
+++ b/verilator.html
@@ -121,16 +121,12 @@
<hr />
<h1><a name="description">DESCRIPTION</a></h1>
<p>Verilator converts synthesizable (not behavioral) Verilog code, plus some
-Synthesis, SystemVerilog and a small subset of Verilog AMS
-assertions, into C++, SystemC or SystemPerl code. It is not a complete
-simulator, just a compiler.</p>
+Synthesis, SystemVerilog and a small subset of Verilog AMS assertions, into
+C++ or SystemC code. It is not a complete simulator, but a compiler.</p>
<p>Verilator is invoked with parameters similar to GCC, Cadence
Verilog-XL/NC-Verilog, or Synopsys's VCS. It reads the specified Verilog
code, lints it, and optionally adds coverage and waveform tracing code.
-For C++ and SystemC formats, it outputs .cpp and .h files. For SystemPerl
-format, it outputs .sp files for the SystemPerl preprocessor, which greatly
-simplifies writing SystemC code and is available at
-<a href="http://www.veripool.org">http://www.veripool.org</a>.</p>
+For C++ and SystemC formats, it outputs .cpp and .h files.</p>
<p>The files created by Verilator are then compiled with C++. The user writes
a little C++ wrapper file, which instantiates the top level module, and
passes this filename on the command line. These C files are compiled in
@@ -224,8 +220,8 @@ descriptions in the next sections for more information.</p>
--report-unoptflat Extra diagnostics for UNOPTFLAT
--savable Enable model save-restore
--sc Create SystemC output
- --sp Create SystemPerl output
--stats Create statistics file
+ --stats-vars Provide statistics on variables
-sv Enable SystemVerilog parsing
+systemverilogext+<ext> Synonym for +1800-2012ext+<ext>
--top-module <topname> Name of top level input module
@@ -364,7 +360,7 @@ run on the generated makefile these will be passed to the C++ compiler
<dt><strong><a name="cc" class="item">--cc</a></strong></dt>
<dd>
-<p>Specifies C++ without SystemC output mode; see also --sc and --sp.</p>
+<p>Specifies C++ without SystemC output mode; see also --sc.</p>
</dd>
<dt><strong><a name="cdc" class="item">--cdc</a></strong></dt>
@@ -920,17 +916,19 @@ other data the process needs saved/restored. For example:</p>
<dt><strong><a name="sc" class="item">--sc</a></strong></dt>
<dd>
-<p>Specifies SystemC output mode; see also --cc and -sp.</p>
+<p>Specifies SystemC output mode; see also --cc.</p>
</dd>
-<dt><strong><a name="sp" class="item">--sp</a></strong></dt>
+<dt><strong><a name="stats" class="item">--stats</a></strong></dt>
<dd>
-<p>Specifies SystemPerl output mode; see also --cc and -sc.</p>
+<p>Creates a dump file with statistics on the design in {prefix}__stats.txt.</p>
</dd>
-<dt><strong><a name="stats" class="item">--stats</a></strong></dt>
+<dt><strong><a name="stats_vars" class="item">--stats-vars</a></strong></dt>
<dd>
-<p>Creates a dump file with statistics on the design in {prefix}__stats.txt.</p>
+<p>Creates more detailed statistics including a list of all the variables by
+size (plain --stats just gives a count). See --stats, which is implied by
+this.</p>
</dd>
<dt><strong><a name="sv" class="item">-sv</a></strong></dt>
@@ -1256,7 +1254,7 @@ the test_c directory in the distribution for an example.</p>
</p>
<hr />
<h1><a name="example_systemc_execution">EXAMPLE SYSTEMC EXECUTION</a></h1>
-<p>This is an example similar to the above, but using SystemPerl.</p>
+<p>This is an example similar to the above, but using SystemC.</p>
<pre>
mkdir test_our_sc
cd test_our_sc</pre>
@@ -1289,15 +1287,7 @@ your operating system (as an RPM), first you need to point to the kit:</p>
export PATH=$VERILATOR_ROOT/bin:$PATH</pre>
<p>Now we run Verilator on our little example.</p>
<pre>
- verilator -Wall --sp our.v</pre>
-<p>Then we convert the SystemPerl output to SystemC.</p>
-<pre>
- cd obj_dir
- export SYSTEMPERL=/path/to/where/systemperl/kit/came/from
- $SYSTEMPERL/sp_preproc --preproc *.sp</pre>
-<p>(You can also skip the above sp_preproc by getting pure SystemC from
-Verilator by replacing the verilator --sp flag in the previous step with
--sc.)</p>
+ verilator -Wall --sc our.v</pre>
<p>We then can compile it</p>
<pre>
make -j -f Vour.mk Vour__ALL.a
@@ -1321,7 +1311,7 @@ depending on the operating system.</p>
- our.v:2: Verilog $finish</pre>
<p>Really, you're better off using a Makefile to do all this for you. Then,
when your source changes it will automatically run all of these steps. See
-the test_sp directory in the distribution for an example.</p>
+the test_sc directory in the distribution for an example.</p>
<p>
</p>
<hr />
@@ -1370,6 +1360,9 @@ feedback driven compilation. With GCC, using -fprofile-arcs, then
especially if you link in DPI code. To enable LTO on GCC, pass "-flto" in
both compilation and link. Note LTO may cause excessive compile times on
large designs.</p>
+<p>If you are using your own makefiles, you may want to compile the Verilated
+code with -DVL_INLINE_OPT=inline. This will inline functions, however this
+requires that all cpp files be compiled in a single compiler run.</p>
<p>You may uncover further tuning possibilities by profiling the Verilog code.
Use Verilator's --profile-cfuncs, then GCC's -g -pg. You can then run
either oprofile or gprof to see where in the C++ code the time is spent.
@@ -1393,10 +1386,6 @@ how Verilator compares, and may be able to suggest additional improvements.</p>
{prefix}.h // Top level header
{prefix}{each_verilog_module}.cpp // Lower level internal C++ files
{prefix}{each_verilog_module}.h // Lower level internal header files</pre>
-<p>For -sp mode, instead of .cpp and .h it creates:</p>
-<pre>
- {prefix}.sp // Top level SystemC file
- {prefix}{each_verilog_module}.sp // Lower level internal SC files</pre>
<p>In certain optimization modes, it also creates:</p>
<pre>
{prefix}__Dpi.h // DPI import and export declarations
@@ -1474,23 +1463,6 @@ specified, it will come from a default optionally specified at configure
time (before Verilator was compiled), or computed from
SYSTEMC/lib-SYSTEMC_ARCH.</p>
</dd>
-<dt><strong><a name="systemperl" class="item">SYSTEMPERL</a></strong></dt>
-
-<dd>
-<p>Specifies the directory containing the SystemPerl distribution kit. This
-is used to find the SystemPerl library and include files. If not
-specified, it will come from a default optionally specified at configure
-time (before Verilator was compiled). See also SYSTEMPERL_INCLUDE.</p>
-</dd>
-<dt><strong><a name="systemperl_include" class="item">SYSTEMPERL_INCLUDE</a></strong></dt>
-
-<dd>
-<p>Specifies the directory containing the Verilog-Perl include .cpp files,
-from the src/ directory of the SystemPerl kit. If not specified, it will
-be computed from the SYSTEMPERL environment variable if it is set, and if
-SYSTEMPERL is not set SYSTEMPERL_INCLUDE will come from a default
-optionally specified at configure time (before Verilator was compiled).</p>
-</dd>
<dt><strong><a name="vcs_home" class="item">VCS_HOME</a></strong></dt>
<dd>
@@ -2108,8 +2080,8 @@ appropriate --coverage flags are passed) after being disabled earlier with
that use this module. This is useful to speed up simulation time with some
small loss of trace visibility and modularity. Note signals under inlined
submodules will be named <em>submodule</em>__DOT__<em>subsignal</em> as C++ does not
-allow "." in signal names. SystemPerl when tracing such signals will
-replace the __DOT__ with the period.</p>
+allow "." in signal names. When tracing such signals the tracing routines
+will replace the __DOT__ with the period.</p>
</dd>
<dt><strong><a name="verilator_isolate_assignments" class="item">/*verilator isolate_assignments*/</a></strong></dt>
@@ -2566,8 +2538,9 @@ full nor unique.</p>
<dt><strong><a name="string" class="item">string</a></strong></dt>
<dd>
-<p>String is supported only to the point that they can be passed to DPI
-imports.</p>
+<p>String is supported only to the point that they can be assigned,
+concatenated, compared, and passed to DPI imports. Standard method calls
+on strings are not supported.</p>
</dd>
<dt><strong><a name="timeunit_timeprecision" class="item">timeunit, timeprecision</a></strong></dt>
@@ -3372,9 +3345,6 @@ Makefile's link rule. This is done for you if using the Verilator --exe
flag.</p>
<p>Note you can also call ->trace on multiple Verilated objects with the same
trace file if you want all data to land in the same output file.</p>
-<p>Note also older versions of Verilator used the SystemPerl package and
-SpTraceVcdC class. This still works, but is depreciated as it requires
-strong coupling between the Verilator and SystemPerl versions.</p>
<pre>
#include "verilated_vcd_c.h"
...
@@ -3399,7 +3369,7 @@ strong coupling between the Verilator and SystemPerl versions.</p>
include verilated_vcd_sc.h. Then call Verilated::traceEverOn(true). Then
create a VerilatedVcdSc object as you would create a normal SystemC trace
file. For an example, see the call to VerilatedVcdSc in the
-test_sp/sc_main.cpp file of the distribution, and below.</p>
+test_sc/sc_main.cpp file of the distribution, and below.</p>
<p>Alternatively you may use the C++ trace mechanism described in the previous
question, however the timescale and timeprecision will not inherited from
your SystemC settings.</p>
@@ -3449,18 +3419,17 @@ network disk. Network disks are generally far slower.</p>
<dd>
<p>Verilator supports both block (line) coverage and user inserted functional
-coverage. Both require the SystemPerl package to be installed but do not
-require use of the SystemPerl output mode.</p>
+coverage.</p>
<p>First, run verilator with the --coverage option. If you're using your own
-makefile, compile the model with the GCC flag -DSP_COVERAGE (if using
+makefile, compile the model with the GCC flag -DVM_COVERAGE (if using
Verilator's, it will do this for you.)</p>
<p>Run your tests in different directories. Each test will create a
logs/coverage.pl file.</p>
-<p>After running all of your tests, the vcoverage utility (from the SystemPerl
-package) is executed. Vcoverage reads the logs/coverage.pl file(s), and
-creates an annotated source code listing showing code coverage details.</p>
+<p>After running all of your tests, verilator_coverage is executed.
+Verilator_coverage reads the logs/coverage.pl file(s), and creates an
+annotated source code listing showing code coverage details.</p>
<p>For an example, after running 'make test' in the Verilator distribution,
-see the test_sp/logs/coverage_source directory. Grep for lines starting
+see the test_sc/logs directory. Grep for lines starting
with '%' to see what lines Verilator believes need more coverage.</p>
</dd>
<dt><strong><a name="where_is_the_translate_off_command_how_do_i_ignore_a_construct" class="item">Where is the translate_off command? (How do I ignore a construct?)</a></strong></dt>
@@ -3736,7 +3705,7 @@ License Version 2.0.</p>
</p>
<hr />
<h1><a name="see_also">SEE ALSO</a></h1>
-<p><em>verilator_profcfunc</em>, <em>systemperl</em>, <em>vcoverage</em>, <em>make</em>,</p>
+<p><em>verilator_coverage</em>, <em>verilator_profcfunc</em>, <em>make</em>,</p>
<p><a href="#verilator___help">verilator --help</a> which is the source for this document,</p>
<p>and internals.txt in the distribution.</p>
diff --git a/verilator.pdf b/verilator.pdf
index ada2468..48b2a4a 100644
Binary files a/verilator.pdf and b/verilator.pdf differ
diff --git a/verilator.txt b/verilator.txt
index ed48441..6b3c258 100644
--- a/verilator.txt
+++ b/verilator.txt
@@ -11,16 +11,13 @@ SYNOPSIS
DESCRIPTION
Verilator converts synthesizable (not behavioral) Verilog code, plus
some Synthesis, SystemVerilog and a small subset of Verilog AMS
- assertions, into C++, SystemC or SystemPerl code. It is not a complete
- simulator, just a compiler.
+ assertions, into C++ or SystemC code. It is not a complete simulator,
+ but a compiler.
Verilator is invoked with parameters similar to GCC, Cadence
Verilog-XL/NC-Verilog, or Synopsys's VCS. It reads the specified Verilog
code, lints it, and optionally adds coverage and waveform tracing code.
- For C++ and SystemC formats, it outputs .cpp and .h files. For
- SystemPerl format, it outputs .sp files for the SystemPerl preprocessor,
- which greatly simplifies writing SystemC code and is available at
- <http://www.veripool.org>.
+ For C++ and SystemC formats, it outputs .cpp and .h files.
The files created by Verilator are then compiled with C++. The user
writes a little C++ wrapper file, which instantiates the top level
@@ -115,8 +112,8 @@ ARGUMENT SUMMARY
--report-unoptflat Extra diagnostics for UNOPTFLAT
--savable Enable model save-restore
--sc Create SystemC output
- --sp Create SystemPerl output
--stats Create statistics file
+ --stats-vars Provide statistics on variables
-sv Enable SystemVerilog parsing
+systemverilogext+<ext> Synonym for +1800-2012ext+<ext>
--top-module <topname> Name of top level input module
@@ -235,7 +232,7 @@ ARGUMENTS
compiler (gcc/g++/msvc++).
--cc
- Specifies C++ without SystemC output mode; see also --sc and --sp.
+ Specifies C++ without SystemC output mode; see also --sc.
--cdc
Experimental. Perform some clock domain crossing checks and issue
@@ -704,15 +701,17 @@ ARGUMENTS
}
--sc
- Specifies SystemC output mode; see also --cc and -sp.
-
- --sp
- Specifies SystemPerl output mode; see also --cc and -sc.
+ Specifies SystemC output mode; see also --cc.
--stats
Creates a dump file with statistics on the design in
{prefix}__stats.txt.
+ --stats-vars
+ Creates more detailed statistics including a list of all the
+ variables by size (plain --stats just gives a count). See --stats,
+ which is implied by this.
+
-sv Specifies SystemVerilog language features should be enabled;
equivalent to "--language 1800-2005". This option is selected by
default, it exists for compatibility with other simulators.
@@ -994,7 +993,7 @@ EXAMPLE C++ EXECUTION
steps. See the test_c directory in the distribution for an example.
EXAMPLE SYSTEMC EXECUTION
- This is an example similar to the above, but using SystemPerl.
+ This is an example similar to the above, but using SystemC.
mkdir test_our_sc
cd test_our_sc
@@ -1030,17 +1029,7 @@ EXAMPLE SYSTEMC EXECUTION
Now we run Verilator on our little example.
- verilator -Wall --sp our.v
-
- Then we convert the SystemPerl output to SystemC.
-
- cd obj_dir
- export SYSTEMPERL=/path/to/where/systemperl/kit/came/from
- $SYSTEMPERL/sp_preproc --preproc *.sp
-
- (You can also skip the above sp_preproc by getting pure SystemC from
- Verilator by replacing the verilator --sp flag in the previous step with
- -sc.)
+ verilator -Wall --sc our.v
We then can compile it
@@ -1069,7 +1058,7 @@ EXAMPLE SYSTEMC EXECUTION
Really, you're better off using a Makefile to do all this for you. Then,
when your source changes it will automatically run all of these steps.
- See the test_sp directory in the distribution for an example.
+ See the test_sc directory in the distribution for an example.
BENCHMARKING & OPTIMIZATION
For best performance, run Verilator with the "-O3 --x-assign=fast
@@ -1125,6 +1114,11 @@ BENCHMARKING & OPTIMIZATION
"-flto" in both compilation and link. Note LTO may cause excessive
compile times on large designs.
+ If you are using your own makefiles, you may want to compile the
+ Verilated code with -DVL_INLINE_OPT=inline. This will inline functions,
+ however this requires that all cpp files be compiled in a single
+ compiler run.
+
You may uncover further tuning possibilities by profiling the Verilog
code. Use Verilator's --profile-cfuncs, then GCC's -g -pg. You can then
run either oprofile or gprof to see where in the C++ code the time is
@@ -1151,11 +1145,6 @@ FILES
{prefix}{each_verilog_module}.cpp // Lower level internal C++ files
{prefix}{each_verilog_module}.h // Lower level internal header files
- For -sp mode, instead of .cpp and .h it creates:
-
- {prefix}.sp // Top level SystemC file
- {prefix}{each_verilog_module}.sp // Lower level internal SC files
-
In certain optimization modes, it also creates:
{prefix}__Dpi.h // DPI import and export declarations
@@ -1223,21 +1212,6 @@ ENVIRONMENT
at configure time (before Verilator was compiled), or computed from
SYSTEMC/lib-SYSTEMC_ARCH.
- SYSTEMPERL
- Specifies the directory containing the SystemPerl distribution kit.
- This is used to find the SystemPerl library and include files. If
- not specified, it will come from a default optionally specified at
- configure time (before Verilator was compiled). See also
- SYSTEMPERL_INCLUDE.
-
- SYSTEMPERL_INCLUDE
- Specifies the directory containing the Verilog-Perl include .cpp
- files, from the src/ directory of the SystemPerl kit. If not
- specified, it will be computed from the SYSTEMPERL environment
- variable if it is set, and if SYSTEMPERL is not set
- SYSTEMPERL_INCLUDE will come from a default optionally specified at
- configure time (before Verilator was compiled).
-
VCS_HOME
If set, specifies the directory containing the Synopsys VCS
distribution. When set, a 'make test' in the Verilator distribution
@@ -1815,8 +1789,8 @@ LANGUAGE EXTENSIONS
time with some small loss of trace visibility and modularity. Note
signals under inlined submodules will be named
*submodule*__DOT__*subsignal* as C++ does not allow "." in signal
- names. SystemPerl when tracing such signals will replace the __DOT__
- with the period.
+ names. When tracing such signals the tracing routines will replace
+ the __DOT__ with the period.
/*verilator isolate_assignments*/
Used after a signal declaration to indicate the assignments to this
@@ -2240,8 +2214,9 @@ LANGUAGE LIMITATIONS
All specify blocks and timing checks are ignored.
string
- String is supported only to the point that they can be passed to DPI
- imports.
+ String is supported only to the point that they can be assigned,
+ concatenated, compared, and passed to DPI imports. Standard method
+ calls on strings are not supported.
timeunit, timeprecision
All timing control statements are ignored.
@@ -3021,11 +2996,6 @@ FAQ/FREQUENTLY ASKED QUESTIONS
the same trace file if you want all data to land in the same output
file.
- Note also older versions of Verilator used the SystemPerl package
- and SpTraceVcdC class. This still works, but is depreciated as it
- requires strong coupling between the Verilator and SystemPerl
- versions.
-
#include "verilated_vcd_c.h"
...
int main(int argc, char **argv, char **env) {
@@ -3047,7 +3017,7 @@ FAQ/FREQUENTLY ASKED QUESTIONS
code, include verilated_vcd_sc.h. Then call
Verilated::traceEverOn(true). Then create a VerilatedVcdSc object as
you would create a normal SystemC trace file. For an example, see
- the call to VerilatedVcdSc in the test_sp/sc_main.cpp file of the
+ the call to VerilatedVcdSc in the test_sc/sc_main.cpp file of the
distribution, and below.
Alternatively you may use the C++ trace mechanism described in the
@@ -3099,25 +3069,23 @@ FAQ/FREQUENTLY ASKED QUESTIONS
How do I do coverage analysis?
Verilator supports both block (line) coverage and user inserted
- functional coverage. Both require the SystemPerl package to be
- installed but do not require use of the SystemPerl output mode.
+ functional coverage.
First, run verilator with the --coverage option. If you're using
- your own makefile, compile the model with the GCC flag -DSP_COVERAGE
+ your own makefile, compile the model with the GCC flag -DVM_COVERAGE
(if using Verilator's, it will do this for you.)
Run your tests in different directories. Each test will create a
logs/coverage.pl file.
- After running all of your tests, the vcoverage utility (from the
- SystemPerl package) is executed. Vcoverage reads the
- logs/coverage.pl file(s), and creates an annotated source code
- listing showing code coverage details.
+ After running all of your tests, verilator_coverage is executed.
+ Verilator_coverage reads the logs/coverage.pl file(s), and creates
+ an annotated source code listing showing code coverage details.
For an example, after running 'make test' in the Verilator
- distribution, see the test_sp/logs/coverage_source directory. Grep
- for lines starting with '%' to see what lines Verilator believes
- need more coverage.
+ distribution, see the test_sc/logs directory. Grep for lines
+ starting with '%' to see what lines Verilator believes need more
+ coverage.
Where is the translate_off command? (How do I ignore a construct?)
Translate on/off pragmas are generally a bad idea, as it's easy to
@@ -3396,7 +3364,7 @@ AUTHORS
Major concepts by Paul Wasson and Duane Galbi.
SEE ALSO
- verilator_profcfunc, systemperl, vcoverage, make,
+ verilator_coverage, verilator_profcfunc, make,
"verilator --help" which is the source for this document,
diff --git a/verilator_coverage.1 b/verilator_coverage.1
new file mode 100644
index 0000000..f3ece0f
--- /dev/null
+++ b/verilator_coverage.1
@@ -0,0 +1,238 @@
+.\" Automatically generated by Pod::Man 2.25 (Pod::Simple 3.16)
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings. \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote. \*(C+ will
+.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
+.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
+.\" nothing in troff, for use with C<>.
+.tr \(*W-
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+. ds -- \(*W-
+. ds PI pi
+. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
+. ds L" ""
+. ds R" ""
+. ds C` ""
+. ds C' ""
+'br\}
+.el\{\
+. ds -- \|\(em\|
+. ds PI \(*p
+. ds L" ``
+. ds R" ''
+'br\}
+.\"
+.\" Escape single quotes in literal strings from groff's Unicode transform.
+.ie \n(.g .ds Aq \(aq
+.el .ds Aq '
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
+.\" entries marked with X<> in POD. Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.ie \nF \{\
+. de IX
+. tm Index:\\$1\t\\n%\t"\\$2"
+..
+. nr % 0
+. rr F
+.\}
+.el \{\
+. de IX
+..
+.\}
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear. Run. Save yourself. No user-serviceable parts.
+. \" fudge factors for nroff and troff
+.if n \{\
+. ds #H 0
+. ds #V .8m
+. ds #F .3m
+. ds #[ \f1
+. ds #] \fP
+.\}
+.if t \{\
+. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+. ds #V .6m
+. ds #F 0
+. ds #[ \&
+. ds #] \&
+.\}
+. \" simple accents for nroff and troff
+.if n \{\
+. ds ' \&
+. ds ` \&
+. ds ^ \&
+. ds , \&
+. ds ~ ~
+. ds /
+.\}
+.if t \{\
+. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+. \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+. \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+. \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+. ds : e
+. ds 8 ss
+. ds o a
+. ds d- d\h'-1'\(ga
+. ds D- D\h'-1'\(hy
+. ds th \o'bp'
+. ds Th \o'LP'
+. ds ae ae
+. ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "VERILATOR_COVERAGE 1"
+.TH VERILATOR_COVERAGE 1 "2014-12-19" "perl v5.14.2" "User Contributed Perl Documentation"
+.\" For nroff, turn off justification. Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.if n .ad l
+.nh
+.SH "NAME"
+verilator_coverage \- Verilator coverage analyzer
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+.Vb 2
+\& verilator_coverage \-\-help
+\& verilator_coverage \-\-version
+\&
+\& verilator_coverage \-\-annotate <obj>
+\&
+\& verilator_coverage \-write merged.dat \-read <datafiles>...
+.Ve
+.PP
+Verilator_coverage processes Verilator coverage reports.
+.PP
+With \-\-anotate, it reads the specified data file and generates annotated
+source code with coverage metrics annotated. If multiple coverage points
+exist on the same line, additional lines will be inserted to report the
+additional points.
+.PP
+Additional Verilog-standard arguments specify the search paths necessary to
+find the source code that the coverage analysis was performed on.
+.PP
+To get correct coverage percentages, you may wish to read logs/coverage.pl
+into Emacs and do a M\-x keep-lines to include only those statistics of
+interest.
+.PP
+For Verilog conditions that should never occur, you should add a \f(CW$stop\fR
+statement. This will remove the coverage during the next build.
+.SH "ARGUMENTS"
+.IX Header "ARGUMENTS"
+.IP "\fIfilename\fR" 4
+.IX Item "filename"
+Specify input data file, may be repeated to read multiple inputs. If no
+data file is specified, by default coverage.dat is read.
+.IP "\-\-annotate \fIoutput_directory\fR" 4
+.IX Item "--annotate output_directory"
+Sprcifies the directory name that source files with annotated coverage data
+should be written to.
+.IP "\-\-annotate\-all" 4
+.IX Item "--annotate-all"
+Specifies all files should be shown. By default, only those source files
+which have low coverage are written to the output directory.
+.IP "\-\-annotate\-min \fIcount\fR" 4
+.IX Item "--annotate-min count"
+Specifies the minimum occurrence count that should be flagged if the
+coverage point does not include a specified threshold. Defaults to 10.
+.IP "\-\-help" 4
+.IX Item "--help"
+Displays this message and program version and exits.
+.IP "\-\-rank" 4
+.IX Item "--rank"
+Print an experimental report listing the relative importance of each test
+in covering all of the coverage points. The report shows \*(L"Covered\*(R" which
+indicates the number of points that test covers; a test is considered to
+cover a point if it has a bucket count of at least 1. The \*(L"rank\*(R" column has
+a higher number t indicate the test is more important, and rank 0 means the
+test does not need to be run to cover the points. \*(L"RankPts\*(R" indicates the
+number of coverage points this test will contribute to overall coverage if
+all tests are run in the order of highest to lowest rank.
+.IP "\-\-unlink" 4
+.IX Item "--unlink"
+When using \-\-write to combine coverage data, unlink all input files after
+the output has been created.
+.IP "\-\-version" 4
+.IX Item "--version"
+Displays program version and exits.
+.IP "\-\-write \fIfilename\fR" 4
+.IX Item "--write filename"
+Specifies the aggregate coverage results, summed across all the files,
+should be written to the given filename. This is useful in scripts to
+combine many sequential runs into one master coverage file.
+.SH "VERILOG ARGUMENTS"
+.IX Header "VERILOG ARGUMENTS"
+The following arguments are compatible with \s-1GCC\s0, \s-1VCS\s0 and most Verilog
+programs.
+.IP "+libext+\fIext\fR+\fIext\fR..." 4
+.IX Item "+libext+ext+ext..."
+Defines the extensions for Verilog files.
+.IP "+define+\fIvar\fR+\fIvalue\fR =item \-D\fIvar\fR=\fIvalue\fR" 4
+.IX Item "+define+var+value =item -Dvar=value"
+Defines the given variable.
+.IP "+incdir+\fIdir\fR =item \-I\fIdir\fR" 4
+.IX Item "+incdir+dir =item -Idir"
+Specifies a directory for finding include files.
+.IP "\-f \fIfile\fR" 4
+.IX Item "-f file"
+Specifies a file containing additional command line arguments.
+.IP "\-y \fIdir\fR" 4
+.IX Item "-y dir"
+Specifies a module search directory.
+.SH "DISTRIBUTION"
+.IX Header "DISTRIBUTION"
+The latest version is available from <http://www.veripool.org/>.
+.PP
+Copyright 2003\-2014 by Wilson Snyder. Verilator is free software; you can
+redistribute it and/or modify the Verilator internals under the terms of
+either the \s-1GNU\s0 Lesser General Public License Version 3 or the Perl Artistic
+License Version 2.0.
+.SH "AUTHORS"
+.IX Header "AUTHORS"
+Wilson Snyder <wsnyder at wsnyder.org>
+.SH "SEE ALSO"
+.IX Header "SEE ALSO"
+\&\f(CW\*(C`verilator\*(C'\fR
+.PP
+\&\*(L"verilator_coverage \-\-help\*(R" which is the source for this document.
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-electronics/verilator.git
More information about the Pkg-electronics-commits
mailing list