mirror of
https://github.com/verilator/verilator.git
synced 2026-10-02 16:13:34 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3a2f8224e4 | ||
|
|
15841fe5f6 | ||
|
|
7e5a7b65a0 | ||
|
|
549bf876e4 | ||
|
|
bd60cf12f8 | ||
|
|
61fbab1910 | ||
|
|
957f495314 | ||
|
|
280eb48ba4 | ||
|
|
ebe5711b40 | ||
|
|
a16477d84f | ||
|
|
f6fb2362c6 | ||
|
|
170427bba1 | ||
|
|
93531e520a | ||
|
|
aa2db8fdde | ||
|
|
7c3c2af90b | ||
|
|
6dca9b4ba4 | ||
|
|
ede37bb9d8 | ||
|
|
4a1729eaab | ||
|
|
b1565f5b89 | ||
|
|
4fb8dcfd4e | ||
|
|
16d1f2b835 | ||
|
|
73594e5aa5 | ||
|
|
c0a365bd34 | ||
|
|
45940ff820 | ||
|
|
d545ae242c | ||
|
|
e862aaf2e1 | ||
|
|
30c3540086 |
@@ -3,6 +3,61 @@ 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.661 2008/04/04
|
||||
|
||||
*** The --enable-defenv configure option added in 3.660 is now the default.
|
||||
This hard-codes a default for VERILATOR_ROOT etc in the executables.
|
||||
|
||||
*** Add --language option for supporting older code. [Stefan Thiede]
|
||||
|
||||
*** Add --top-module option to select between multiple tops. [Stefan Thiede]
|
||||
|
||||
*** Unsized concatenates now give WIDTHCONCAT warnings. [Jonathan Kimmitt]
|
||||
Previously they threw fatal errors, which in most cases is correct
|
||||
according to spec, but can be incorrect in presence of parameter values.
|
||||
|
||||
**** Support functions with "input integer". [Johan Wouters]
|
||||
|
||||
**** Ignore delays attached to gate UDPs. [Stefan Thiede]
|
||||
|
||||
**** Fix SystemVerilog parameterized defines with `` expansion,
|
||||
and fix extra whitespace inserted on substitution. [Vladimir Matveyenko]
|
||||
|
||||
**** Fix no-module include files on command line. [Stefan Thiede]
|
||||
|
||||
**** Fix dropping of backslash quoted-quote at end of $display.
|
||||
|
||||
**** Fix task output pin connected to non-variables. [Jonathan Kimmitt]
|
||||
|
||||
**** Fix missing test_v in install datadir. [Holger Waechtler]
|
||||
|
||||
**** Fix internal error after MSB < LSB error reported to user. [Stefan Thiede]
|
||||
|
||||
* Verilator 3.660 2008/03/23
|
||||
|
||||
*** Add support for hard-coding VERILATOR_ROOT etc in the executables,
|
||||
to enable easier use of Verilator RPMs. [Gunter Dannoritzer]
|
||||
|
||||
*** Allow multiple .v files on command line. [Stefan Thiede]
|
||||
|
||||
*** Convert re-defining macro error to warning. [Stefan Thiede]
|
||||
|
||||
*** Add --error-limit option. [Stefan Thiede]
|
||||
|
||||
*** Allow __ in cell names by quoting them in C. [Stefan Thiede]
|
||||
|
||||
**** Fix genvar to be signed, so "< 0" works properly. [Niranjan Prabhu]
|
||||
|
||||
**** Fix assignments to inputs inside functions/tasks. [Patricio Kaplan]
|
||||
|
||||
**** Fix definitions in main file.v, referenced in library. [Stefan Thiede]
|
||||
|
||||
**** Fix undefined assigns to be implicit warnings. [Stefan Thiede]
|
||||
|
||||
* Verilator 3.658 2008/02/25
|
||||
|
||||
**** Fix unistd compile error in 3.657. [Patricio Kaplan, Jonathan Kimmitt]
|
||||
|
||||
* Verilator 3.657 2008/02/20
|
||||
|
||||
**** Fix assignments of {a,b,c} = {c,b,a}. [Jonathan Kimmitt]
|
||||
|
||||
+19
-5
@@ -78,6 +78,7 @@ datadir = @datadir@
|
||||
infodir = @infodir@
|
||||
|
||||
# Directory in which to install package specific files
|
||||
# Generally ${prefix}/share/verilator
|
||||
pkgdatadir = @pkgdatadir@
|
||||
|
||||
#### End of system configuration section. ####
|
||||
@@ -140,6 +141,7 @@ msg_test:
|
||||
@echo "Type 'make test' to test."
|
||||
@echo
|
||||
|
||||
.PHONY:test
|
||||
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
|
||||
test: test_vcs test_c test_sc test_sp test_verilated test_regress
|
||||
else
|
||||
@@ -203,21 +205,32 @@ README: readme.texi
|
||||
$(MAKEINFO) -I$(srcdir) $(srcdir)/readme.texi --output=$@ \
|
||||
--no-headers --no-validate
|
||||
|
||||
installdirs:
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(bindir) $(infodir)
|
||||
|
||||
# See uninstall also
|
||||
VL_INST_BIN_FILES = verilator
|
||||
VL_INST_BIN_FILES = verilator verilator_bin verilator_bin_dbg
|
||||
installbin:
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(bindir)
|
||||
( cd bin ; $(INSTALL_PROGRAM) verilator $(bindir)/verilator )
|
||||
( $(INSTALL_PROGRAM) verilator_bin $(bindir)/verilator_bin )
|
||||
( $(INSTALL_PROGRAM) verilator_bin_dbg $(bindir)/verilator_bin_dbg )
|
||||
|
||||
VL_INST_MAN_FILES = verilator.1
|
||||
installman:
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(mandir)
|
||||
for p in $(VL_INST_MAN_FILES) ; do \
|
||||
$(INSTALL_PROGRAM) $$p $(mandir)/man1/$$p; \
|
||||
done
|
||||
|
||||
install: all_nomsg installdirs installbin installman install-msg
|
||||
installdata:
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(pkgdatadir)/examples
|
||||
cp -r include $(pkgdatadir)
|
||||
cp -r src $(pkgdatadir)
|
||||
cp -r test_c $(pkgdatadir)/examples
|
||||
cp -r test_sc $(pkgdatadir)/examples
|
||||
cp -r test_sp $(pkgdatadir)/examples
|
||||
cp -r test_v $(pkgdatadir)/examples
|
||||
|
||||
VL_INST_DATA_FILES = verilator.1
|
||||
install: all_nomsg installbin installman installdata install-msg
|
||||
|
||||
install-here: installman ftp
|
||||
|
||||
@@ -263,6 +276,7 @@ install-msg:
|
||||
uninstall:
|
||||
-cd $(mandir)/man1 && rm -f $(VL_INST_MAN_FILES)
|
||||
-cd $(bindir) && rm -f $(VL_INST_BIN_FILES)
|
||||
-rm -f $(pkgdatadir)
|
||||
|
||||
# autoheader might not change config_build.h.in, so touch a stamp file.
|
||||
IN_WILD := ${srcdir}/*.in ${srcdir}/*/*.in ${srcdir}/*/*/*.in \
|
||||
|
||||
+102
-70
@@ -34,27 +34,7 @@ use Config;
|
||||
use Cwd qw(abs_path getcwd);
|
||||
|
||||
use strict;
|
||||
use vars qw ($Debug %Vars $Opt $Opt_Make_Dir $Opt_Sp @Opt_Verilator_Sw
|
||||
$Opt_Trace
|
||||
%Modules
|
||||
);
|
||||
|
||||
#######################################################################
|
||||
# Global constants -- Configuration info
|
||||
|
||||
# Where to find real executables
|
||||
# We could find it by using $RealBin, but we require this path
|
||||
# so that when the user runs make, they will have it and not get strange error.
|
||||
$ENV{VERILATOR_ROOT} or die "%Error: verilator: VERILATOR_ROOT needs to be in environment\n";
|
||||
print "export VERILATOR_ROOT=$ENV{VERILATOR_ROOT}\n" if $Debug;
|
||||
|
||||
# Read by verilator for populating makefile
|
||||
if (!defined $ENV{SYSTEMC_ARCH}) {
|
||||
$ENV{SYSTEMC_ARCH} ||= (($Config{osname} =~ /solaris/i && "gccsparcOS5")
|
||||
|| ($Config{osname} =~ /cygwin/i && "cygwin")
|
||||
|| "linux");
|
||||
print "export SYSTEMC_ARCH=$ENV{SYSTEMC_ARCH}\n" if $Debug;
|
||||
}
|
||||
use vars qw ($Debug @Opt_Verilator_Sw);
|
||||
|
||||
#######################################################################
|
||||
#######################################################################
|
||||
@@ -65,7 +45,6 @@ autoflush STDERR 1;
|
||||
|
||||
$Debug = 0;
|
||||
my $opt_gdb;
|
||||
$Opt_Sp = undef;
|
||||
|
||||
# No arguments can't do anything useful. Give help
|
||||
if ($#ARGV < 0) {
|
||||
@@ -84,34 +63,15 @@ if (! GetOptions (
|
||||
# Major operating modes
|
||||
"help" => \&usage,
|
||||
"debug:s" => \&debug,
|
||||
"version!" => \&version,
|
||||
# "version!" => \&version, # Also passthru'ed
|
||||
# Switches
|
||||
"gdb=s" => \$opt_gdb, # Undocumented debugging
|
||||
"trace!" => \$Opt_Trace,
|
||||
"sp!" => sub {$Opt_Sp = 'sp';},
|
||||
"sc!" => sub {$Opt_Sp = 'sc';},
|
||||
"cc!" => sub {$Opt_Sp = 0;},
|
||||
"lint-only!" => sub {$Opt_Sp = 0;},
|
||||
#"ignc!" => ..., # Undocumented debugging, disable $c but don't complain
|
||||
# Additional parameters
|
||||
"<>" => sub {}, # Ignored
|
||||
)) {
|
||||
pod2usage(-exitstatus=>2, -verbose=>0);
|
||||
}
|
||||
|
||||
# Check configuration
|
||||
if ($Opt_Sp) {
|
||||
(defined $ENV{SYSTEMC}) or die "%Error: verilator: Need \$SYSTEMC in environment\nProbably System-C isn't installed, see http://www.systemc.org\n";
|
||||
}
|
||||
if ($Opt_Sp eq 'sp' || $Opt_Trace) {
|
||||
if (!defined $ENV{SYSTEMPERL}) {
|
||||
my $try = "$ENV{W}/hw/utils/perltools/SystemC";
|
||||
$ENV{SYSTEMPERL} = $try if -d $try;
|
||||
}
|
||||
(defined $ENV{SYSTEMPERL}) or die "%Error: verilator: Need \$SYSTEMPERL in environment for --sp or --trace\nProbably System-Perl isn't installed, see http://www.veripool.com/systemperl.html\n";
|
||||
(-d "$ENV{SYSTEMPERL}/src") or die "%Error: verilator: \$SYSTEMPERL environment var doesn't seem to point to System-Perl kit\n";
|
||||
}
|
||||
|
||||
# Determine runtime flags
|
||||
my $vcmd =(($opt_gdb?"$opt_gdb ":"")
|
||||
.verilator_bin()
|
||||
@@ -124,7 +84,6 @@ run ($vcmd);
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub usage {
|
||||
bin_version();
|
||||
print '$Revision$$Date$ ', "\n";
|
||||
pod2usage(-exitstatus=>2, -verbose=>2);
|
||||
}
|
||||
@@ -135,23 +94,16 @@ sub debug {
|
||||
$Debug = $level||3;
|
||||
}
|
||||
|
||||
sub version {
|
||||
bin_version();
|
||||
exit (0);
|
||||
}
|
||||
|
||||
sub bin_version {
|
||||
($ENV{VERILATOR_ROOT}) or print "%Warning: Unknown rev: VERILATOR_ROOT undefined\n";
|
||||
run (verilator_bin()." --version");
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#######################################################################
|
||||
# Builds
|
||||
|
||||
sub verilator_bin {
|
||||
my $bin = "$ENV{VERILATOR_ROOT}/".($ENV{VERILATOR_BIN}||"verilator_bin");
|
||||
if ($Debug && -x "${bin}_dbg") { $bin = "${bin}_dbg"; }
|
||||
my $bin = "";
|
||||
# Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path
|
||||
$bin .= $ENV{VERILATOR_ROOT}."/" if defined($ENV{VERILATOR_ROOT});
|
||||
$bin .= ($ENV{VERILATOR_BIN}||"verilator_bin");
|
||||
if ($Debug) { $bin = "${bin}_dbg"; }
|
||||
return $bin;
|
||||
}
|
||||
|
||||
@@ -166,8 +118,11 @@ sub run {
|
||||
system($command);
|
||||
my $status = $?;
|
||||
if ($status) {
|
||||
if ($! =~ /no such file or directory/i) {
|
||||
warn "%Error: verilator: Misinstalled, or VERILATOR_ROOT might need to be in environment\n";
|
||||
}
|
||||
if ($Debug) { # For easy rerunning
|
||||
warn "%Error: export VERILATOR_ROOT=$ENV{VERILATOR_ROOT}\n";
|
||||
warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n";
|
||||
warn "%Error: $command\n";
|
||||
}
|
||||
die "%Error: Command Failed $command\n";
|
||||
@@ -235,12 +190,14 @@ descriptions in the next sections for more information.
|
||||
--debug-check Enable debugging assertions
|
||||
--dump-tree Enable dumping .tree files
|
||||
-E Preprocess, but do not compile
|
||||
--error-limit <value> Abort after this number of errors
|
||||
--exe Link to create executable
|
||||
-f <file> Parse options from a file
|
||||
--help Display this help.
|
||||
-I<dir> Directory to search for includes
|
||||
--inhibit-sim Create function to turn off sim
|
||||
--inline-mult <value> Tune module inlining
|
||||
--language <lang> Language standard to parse
|
||||
--lint-only Lint, but do not make output
|
||||
--MMD Create .d dependency files
|
||||
--MP Create phony dependency targets
|
||||
@@ -261,6 +218,7 @@ descriptions in the next sections for more information.
|
||||
--sc Create SystemC output
|
||||
--sp Create SystemPerl output
|
||||
--stats Create statistics file
|
||||
--top-module <topname> Name of top level input module
|
||||
--trace Enable waveform creation
|
||||
--trace-depth <levels> Depth of tracing
|
||||
-U<var> Undefine preprocessor define
|
||||
@@ -393,6 +351,11 @@ Preprocess the source code, but do not compile, as with 'gcc -E'. Output
|
||||
is written to standard out. Beware of enabling debugging messages, as they
|
||||
will also go to standard out.
|
||||
|
||||
=item --error-limit <value>
|
||||
|
||||
After this number of errors or warnings are encountered, exit. Defaults to
|
||||
50.
|
||||
|
||||
=item --exe
|
||||
|
||||
Generate a executable. You will also need to pass additional .cpp files on
|
||||
@@ -418,6 +381,14 @@ values, or a value <= 1 will inline everything, will lead to longer compile
|
||||
times, but potentially faster runtimes. This setting is ignored for very
|
||||
small modules; they will always be inlined, if allowed.
|
||||
|
||||
=item --language I<value>
|
||||
|
||||
Select the language to be used when first processing each Verilog file.
|
||||
The language value must be "1364-1995", "1364-2001", "1364-2001",
|
||||
"1364-2005", or "1800-2005". This should only be used for legacy code, as
|
||||
the preferable option is to edit the code to repair new keywords, or add
|
||||
appropriate `begin_keywords.
|
||||
|
||||
=item --lint-only
|
||||
|
||||
Check the files for lint violations only, do not create any other output.
|
||||
@@ -490,8 +461,9 @@ the backward-compatible default of sc_bv's.
|
||||
|
||||
=item --prefix I<topname>
|
||||
|
||||
Specifies the name of the top level class. Defaults to the name of the top
|
||||
level Verilog module.
|
||||
Specifies the name of the top level class and makefile. Defaults to V
|
||||
prepended to the name of the --top-module switch, or V prepended to the
|
||||
first Verilog filename passed on the command line.
|
||||
|
||||
=item --profile-cfuncs
|
||||
|
||||
@@ -537,6 +509,13 @@ Specifies SystemPerl output mode; see also --cc and -sc.
|
||||
|
||||
Creates a dump file with statistics on the design in {prefix}__stats.txt.
|
||||
|
||||
=item --top-module I<topname>
|
||||
|
||||
When the input Verilog contains more than one top level module, specifies
|
||||
the name of the top level Verilog module to become the top, and sets the
|
||||
default for if --prefix is not used. This is not needed with standard
|
||||
designs with only one top.
|
||||
|
||||
=item --trace
|
||||
|
||||
Adds waveform tracing code to the model, this will create additional
|
||||
@@ -872,14 +851,16 @@ After running Make, the C++ compiler should produce the following:
|
||||
|
||||
Required for SystemC output mode. If set, specifies the directory
|
||||
containing the SystemC distribution. This is used to find the SystemC
|
||||
include files.
|
||||
include files. If not specified, it will come from a default optionally
|
||||
specified at configure time (before Verilator was compiled).
|
||||
|
||||
=item SYSTEMC_ARCH
|
||||
|
||||
Specifies the architecture name used by the SystemC kit. This is the part
|
||||
after the dash in the lib-{...} directory name created by a 'make' in the
|
||||
SystemC distribution. If not set, Verilator will try to intuit the proper
|
||||
setting.
|
||||
setting, or use the default optionally specified at configure time (before
|
||||
Verilator was compiled). .
|
||||
|
||||
=item SYSTEMC_CXX_FLAGS
|
||||
|
||||
@@ -889,7 +870,9 @@ building the SystemC model.
|
||||
=item SYSTEMPERL
|
||||
|
||||
Specifies the directory containing the Verilog-Perl distribution kit. This
|
||||
is used to find the Verilog-Perl library and include files.
|
||||
is used to find the Verilog-Perl library and include files. If not
|
||||
specified, it will come from a default optionally specified at configure
|
||||
time (before Verilator was compiled).
|
||||
|
||||
=item VCS_HOME
|
||||
|
||||
@@ -905,7 +888,9 @@ for debugging and selecting between multiple operating system builds.
|
||||
=item VERILATOR_ROOT
|
||||
|
||||
Specifies the directory containing the distribution kit. This is used to
|
||||
find the executable, Perl library, and include files.
|
||||
find the executable, Perl library, and include files. If not specified, it
|
||||
will come from a default optionally specified at configure time (before
|
||||
Verilator was compiled).
|
||||
|
||||
=back
|
||||
|
||||
@@ -1734,6 +1719,23 @@ not really needed. The best solution is to insure that each module is in a
|
||||
unique file by the same name. Otherwise, make sure all library files are
|
||||
read in as libraries with -v, instead of automatically with -y.
|
||||
|
||||
=item REDEFMACRO
|
||||
|
||||
Warns that you have redefined the same macro with a different value, for
|
||||
example:
|
||||
|
||||
`define MACRO def1
|
||||
//...
|
||||
`define MACRO otherdef
|
||||
|
||||
The best solution is to use a different name for the second macro. If this
|
||||
is not possible, add a undef to indicate the code is overriding the value:
|
||||
|
||||
`define MACRO def1
|
||||
//...
|
||||
`undef MACRO
|
||||
`define MACRO otherdef
|
||||
|
||||
=item STMTDLY
|
||||
|
||||
Warns that you have a statement with a delayed time in front of it, for
|
||||
@@ -1891,6 +1893,24 @@ The best fix, which clarifies intent and will also make all tools happy is:
|
||||
Ignoring this warning will only suppress the lint check, it will simulate
|
||||
correctly.
|
||||
|
||||
=item WIDTHCONCAT
|
||||
|
||||
Warns that based on width rules of Verilog, a concatenate or replication
|
||||
has a undeterminate width. In most cases this violates the Verilog rule
|
||||
that widths inside concatenates and replicates must be sized, and should be
|
||||
fixed in the code.
|
||||
|
||||
wire [63:0] concat = {1,2};
|
||||
|
||||
An example where this is technically legal (though still bad form) is:
|
||||
|
||||
parameter PAR = 1;
|
||||
wire [63:0] concat = {PAR,PAR};
|
||||
|
||||
The correct fix is to either size the 1 ("32'h1"), or add the width to the
|
||||
parameter definition ("parameter [31:0]"), or add the width to the
|
||||
parameter usage ("{PAR[31:0],PAR[31:0]}".
|
||||
|
||||
=back
|
||||
|
||||
The following describes the less obvious errors:
|
||||
@@ -1944,11 +1964,14 @@ Visual C++ Version 7 or newer, but this is not tested by the author.
|
||||
|
||||
=item Can you provide binaries?
|
||||
|
||||
At this time I'd prefer to get patches out quickly than have to generate
|
||||
myriad binaries for many different OS flavors. People have generally
|
||||
requested binaries when they are having problems with their C++
|
||||
compiler. Alas, binaries won't help this, as in the end a fully working C++
|
||||
compiler is required to compile the output of Verilator.
|
||||
Verilator is available as a RPM for SuSE and perhaps other systems; this is
|
||||
done by porters and may slightly lag the primary distribution. If there
|
||||
isn't a binary build for your distribution, how about you set one up?
|
||||
Please contact the authors for assistance.
|
||||
|
||||
Note people sometimes request binaries when they are having problems with
|
||||
their C++ compiler. Alas, binaries won't help this, as in the end a fully
|
||||
working C++ compiler is required to compile the output of Verilator.
|
||||
|
||||
=item How can it be faster than (name-the-simulator)?
|
||||
|
||||
@@ -2031,15 +2054,24 @@ the "verilator" define for you, so just wrap the code in a ifndef region:
|
||||
|
||||
=item Why do I get "unexpected `do'" or "unexpected `bit'" errors?
|
||||
|
||||
Do, bit, ref, and other words are now SystemVerilog keywords. You should
|
||||
change your code to not use them to insure it works with newer tools.
|
||||
Alternatively, surround them by the Verilog 2005/SystemVerilog
|
||||
Do, bit, ref, return, and other words are now SystemVerilog keywords. You
|
||||
should change your code to not use them to insure it works with newer
|
||||
tools. Alternatively, surround them by the Verilog 2005/SystemVerilog
|
||||
begin_keywords pragma to indicate Verilog 2001 code.
|
||||
|
||||
`begin_keywords "1364-2001"
|
||||
integer bit; initial bit = 1;
|
||||
`end_keywords
|
||||
|
||||
If you want the whole file to be parsed as Verilog 2001, just create a
|
||||
file with
|
||||
|
||||
`begin_keywords "1364-2001"
|
||||
|
||||
and add it before other Verilog files on the command line. (Note this will
|
||||
also change the default for --prefix, so if you're not using --prefix, you
|
||||
will now need to.)
|
||||
|
||||
=item How do I prevent my assertions from firing during reset?
|
||||
|
||||
Call Verilated::assertOn(false) before you first call the model, then turn
|
||||
|
||||
@@ -9,6 +9,11 @@ AC_INIT(src/Verilator.cpp)
|
||||
AC_CONFIG_HEADER(src/config_build.h)
|
||||
|
||||
dnl Special Substitutions
|
||||
AC_ARG_ENABLE(defenv,
|
||||
[AS_HELP_STRING([--disable-defenv], [disable hardcoded default environment variables])],
|
||||
CFG_WITH_DEFENV=$enableval,
|
||||
CFG_WITH_DEFENV=1)
|
||||
AC_SUBST(CFG_WITH_DEFENV)
|
||||
|
||||
dnl Checks for programs.
|
||||
CXX=g++
|
||||
|
||||
@@ -126,6 +126,12 @@ do a @code{make sc_patch}.
|
||||
@item
|
||||
Type @samp{./configure} to configure Verilator for your system.
|
||||
|
||||
If you are configuring Verilator to be part of a RPM or other
|
||||
distribution package system, you may want to use the --enable-defenv
|
||||
configure flag. This will take the current value of VERILATOR_ROOT,
|
||||
SYSTEMC, SYSTEMC_ARCH, and SYSTEMPERL and build them as defaults into
|
||||
the executable.
|
||||
|
||||
@item
|
||||
Type @samp{make} to compile Verilator.
|
||||
|
||||
|
||||
@@ -30,6 +30,14 @@ LINK = @CXX@
|
||||
|
||||
LDFLAGS += @LDFLAGS@
|
||||
|
||||
CFG_WITH_DEFENV = @CFG_WITH_DEFENV@
|
||||
|
||||
prefix = @prefix@
|
||||
|
||||
# Directory in which to install package specific files
|
||||
# Generally ${prefix}/share/verilator
|
||||
pkgdatadir = @pkgdatadir@
|
||||
|
||||
#### End of system configuration section. ####
|
||||
|
||||
VPATH += . $(srcdir)
|
||||
@@ -70,6 +78,19 @@ CPPFLAGS += -W -Wall -Wno-unused-parameter -Wno-char-subscripts -Werror
|
||||
#CPPFLAGS += -pedantic-errors
|
||||
endif
|
||||
|
||||
# Allow RPM builds to specify hardcoded data directories
|
||||
# To do this:
|
||||
ifeq ($(CFG_WITH_DEFENV),yes)
|
||||
CPPFLAGS += -DDEFENV_SYSTEMC=\"$(SYSTEMC)\"
|
||||
CPPFLAGS += -DDEFENV_SYSTEMC_ARCH=\"$(SYSTEMC_ARCH)\"
|
||||
CPPFLAGS += -DDEFENV_SYSTEMPERL=\"$(SYSTEMPERL)\"
|
||||
ifeq ($(VERILATOR_ROOT),) # Use what we're given, or intuit
|
||||
CPPFLAGS += -DDEFENV_VERILATOR_ROOT=\"$(pkgdatadir)\"
|
||||
else
|
||||
CPPFLAGS += -DDEFENV_VERILATOR_ROOT=\"$(VERILATOR_ROOT)\"
|
||||
endif
|
||||
endif
|
||||
|
||||
HEADERS = $(wildcard V*.h v*.h)
|
||||
|
||||
ASTGEN = $(srcdir)/astgen
|
||||
|
||||
@@ -83,6 +83,20 @@ void AstNode::init() {
|
||||
m_user5Cnt = 0;
|
||||
}
|
||||
|
||||
string AstNode::encodeName(const string& namein) {
|
||||
string name2 = namein;
|
||||
string out;
|
||||
for (string::iterator pos = name2.begin(); pos != name2.end(); pos++) {
|
||||
if (pos[0]=='_' && pos[1]=='_') {
|
||||
out += "__ULUL_";
|
||||
pos++;
|
||||
} else {
|
||||
out += pos[0];
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
string AstNode::shortName() const {
|
||||
string pretty = name();
|
||||
string::size_type pos;
|
||||
@@ -114,6 +128,9 @@ string AstNode::prettyName(const string& namein) {
|
||||
while ((pos=pretty.find("__PVT__")) != string::npos) {
|
||||
pretty.replace(pos, 7, "");
|
||||
}
|
||||
while ((pos=pretty.find("__ULUL_")) != string::npos) {
|
||||
pretty.replace(pos, 7, "");
|
||||
}
|
||||
return AstNode::dedotName(pretty);
|
||||
}
|
||||
|
||||
|
||||
@@ -558,6 +558,7 @@ public:
|
||||
string shortName() const; // Name with __PVT__ removed for concatenating scopes
|
||||
static string dedotName(const string& namein); // Name with dots removed
|
||||
static string prettyName(const string& namein); // Name for printing out to the user
|
||||
static string encodeName(const string& namein); // Encode user name into internal C representation
|
||||
string prettyName() const { return prettyName(name()); }
|
||||
FileLine* fileline() const { return m_fileline; }
|
||||
int width() const { return m_width; }
|
||||
|
||||
@@ -304,6 +304,10 @@ void AstCellInline::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
str<<" -> "<<origModName();
|
||||
}
|
||||
void AstDisplay::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
//str<<" "<<displayType().ascii();
|
||||
}
|
||||
void AstPin::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
if (modVarp()) { str<<" -> "; modVarp()->dump(str); }
|
||||
|
||||
@@ -1254,6 +1254,7 @@ public:
|
||||
virtual AstType type() const { return AstType::DISPLAY;}
|
||||
virtual AstNode* clone() { return new AstDisplay(*this); }
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void dump(ostream& str);
|
||||
virtual string verilogKwd() const { return (filep() ? (string)"$f"+(string)displayType().ascii()
|
||||
: (string)"$"+(string)displayType().ascii()); }
|
||||
virtual bool isGateOptimizable() const { return false; }
|
||||
|
||||
@@ -1027,10 +1027,8 @@ void EmitCStmts::visit(AstDisplay* nodep, AstNUser*) {
|
||||
emitDispState.clear();
|
||||
string fmt = "";
|
||||
string::iterator pos = vformat.begin();
|
||||
if (*pos == '"') pos++;
|
||||
bool inPct = false;
|
||||
for (; pos != vformat.end(); ++pos) {
|
||||
if (pos[0]=='"' && (pos+1)==vformat.end()) break;
|
||||
if (inPct && pos[0]=='%') {
|
||||
emitDispState.pushFormat("%%"); // We're printf'ing it, so need to quote the %
|
||||
inPct = false;
|
||||
|
||||
+4
-4
@@ -79,16 +79,16 @@ public:
|
||||
of.puts("default: "+v3Global.opt.prefix()+"__ALL.a\n");
|
||||
}
|
||||
of.puts("\n# Constants...\n");
|
||||
of.puts("PERL = "+V3Options::getenvStr("PERL","perl")+"\n");
|
||||
of.puts("VERILATOR_ROOT = "+V3Options::getenvStr("VERILATOR_ROOT","")+"\n");
|
||||
of.puts("SYSTEMPERL = "+V3Options::getenvStr("SYSTEMPERL","")+"\n");
|
||||
of.puts("PERL = "+V3Options::getenvPERL()+"\n");
|
||||
of.puts("VERILATOR_ROOT = "+V3Options::getenvVERILATOR_ROOT()+"\n");
|
||||
of.puts("SYSTEMPERL = "+V3Options::getenvSYSTEMPERL()+"\n");
|
||||
|
||||
of.puts("\n# Switches...\n");
|
||||
of.puts(string("VM_SP = ")+(v3Global.opt.systemPerl()?"1":"0")+"\n");
|
||||
of.puts(string("VM_SC = ")+((v3Global.opt.systemC()&&!v3Global.opt.systemPerl())?"1":"0")+"\n");
|
||||
of.puts(string("VM_SP_OR_SC = ")+(v3Global.opt.systemC()?"1":"0")+"\n");
|
||||
of.puts(string("VM_PCLI = ")+(v3Global.opt.systemC()?"0":"1")+"\n");
|
||||
of.puts(string("VM_SC_TARGET_ARCH = ")+V3Options::getenvStr("SYSTEMC_ARCH","")+"\n");
|
||||
of.puts(string("VM_SC_TARGET_ARCH = ")+V3Options::getenvSYSTEMC_ARCH()+"\n");
|
||||
|
||||
of.puts("\n# Vars...\n");
|
||||
of.puts(string("VM_PREFIX = ")+v3Global.opt.prefix()+"\n");
|
||||
|
||||
+2
-2
@@ -243,8 +243,8 @@ void V3Error::incWarnings() {
|
||||
|
||||
void V3Error::incErrors() {
|
||||
s_errCount++;
|
||||
if (errorCount() == MAX_ERRORS) { // Not >= as would otherwise recurse
|
||||
v3fatal ("Exiting due to too many errors encountered\n");
|
||||
if (errorCount() == v3Global.opt.errorLimit()) { // Not >= as would otherwise recurse
|
||||
v3fatal ("Exiting due to too many errors encountered; --error-limit="<<errorCount()<<endl);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -53,6 +53,7 @@ public:
|
||||
IMPLICIT, // Implicit wire
|
||||
IMPURE, // Impure function not being inlined
|
||||
MULTIDRIVEN, // Driven from multiple blocks
|
||||
REDEFMACRO, // Redefining existing define macro
|
||||
UNDRIVEN, // No drivers
|
||||
UNOPT, // Unoptimizable block
|
||||
UNOPTFLAT, // Unoptimizable block after flattening
|
||||
@@ -60,6 +61,7 @@ public:
|
||||
UNUSED, // No receivers
|
||||
VARHIDDEN, // Hiding variable
|
||||
WIDTH, // Width mismatch
|
||||
WIDTHCONCAT, // Unsized numbers/parameters in concatenations
|
||||
MAX
|
||||
// ***Add new elements below also***
|
||||
};
|
||||
@@ -78,9 +80,9 @@ public:
|
||||
"BLKANDNBLK",
|
||||
"CASEINCOMPLETE", "CASEOVERLAP", "CASEX", "CMPCONST",
|
||||
"COMBDLY", "STMTDLY", "GENCLK", "IMPLICIT", "IMPURE",
|
||||
"MULTIDRIVEN",
|
||||
"MULTIDRIVEN", "REDEFMACRO",
|
||||
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED",
|
||||
"VARHIDDEN", "WIDTH",
|
||||
"VARHIDDEN", "WIDTH", "WIDTHCONCAT",
|
||||
" MAX"
|
||||
};
|
||||
return names[m_e];
|
||||
|
||||
@@ -480,3 +480,97 @@ public:
|
||||
void DfaGraph::dfaReduce() {
|
||||
DfaGraphReduce (this, &V3GraphEdge::followAlwaysTrue);
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
//######################################################################
|
||||
// Algorithms - complement a DFA
|
||||
//
|
||||
// The traditional algorithm is to make a rejecting state, add edges to
|
||||
// reject from all missing values, then swap accept and reject. Rather
|
||||
// than swap at the end, it's faster if we swap up front, then do the edge
|
||||
// changes.
|
||||
//
|
||||
// 1. Since we didn't log rejecting states, make a temp state (this will be
|
||||
// the old accept, and new reject).
|
||||
//
|
||||
// 2. All vertexes except start/accept get edges to NEW accept for any
|
||||
// non-existing case. Weedely we don't have a nice way of representing
|
||||
// this so we just create a edge for each case and mark it "complemented."
|
||||
//
|
||||
// 3. Delete temp vertex (old accept/new reject) and related edges.
|
||||
// The user's old accept is now the new accept. This is imporant as
|
||||
// we want the virtual type of it to be intact.
|
||||
|
||||
class DfaGraphComplement : GraphAlg {
|
||||
private:
|
||||
// MEMBERS
|
||||
DfaVertex* m_tempNewerReject;
|
||||
|
||||
// METHODS
|
||||
int debug() { return 9; }
|
||||
DfaGraph* graphp() { return static_cast<DfaGraph*>(m_graphp); }
|
||||
|
||||
void add_complement_edges() {
|
||||
// Find accepting vertex
|
||||
DfaVertex* acceptp = NULL;
|
||||
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
|
||||
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
|
||||
if (vvertexp->accepting()) {
|
||||
acceptp = vvertexp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!acceptp) v3fatalSrc("No accepting vertex in DFA\n");
|
||||
|
||||
// Remap edges
|
||||
for (V3GraphVertex* vertexp = m_graphp->verticesBeginp(); vertexp; vertexp=vertexp->verticesNextp()) {
|
||||
if (DfaVertex* vvertexp = dynamic_cast<DfaVertex*>(vertexp)) {
|
||||
//UINFO(9, " on vertex "<<vvertexp->name()<<endl);
|
||||
if (!vvertexp->accepting() && vvertexp != m_tempNewerReject) {
|
||||
for (V3GraphEdge* nextp, *edgep = vertexp->outBeginp(); edgep; edgep=nextp) {
|
||||
nextp = edgep->outNextp();
|
||||
if (!edgep->user()) { // Not processed
|
||||
// Old edges to accept now go to new reject
|
||||
DfaEdge* vedgep = static_cast<DfaEdge*>(edgep);
|
||||
DfaVertex* tovertexp = static_cast<DfaVertex*>(edgep->top());
|
||||
if (tovertexp->accepting()) {
|
||||
new DfaEdge(graphp(), vvertexp, m_tempNewerReject, vedgep);
|
||||
edgep->unlinkDelete(); edgep=NULL;
|
||||
}
|
||||
|
||||
// NOT of all values goes to accept
|
||||
// We make a edge for each value to OR, IE
|
||||
// edge(complemented,a) edge(complemented,b) means !(a | b)
|
||||
if (!tovertexp->accepting()) { // Note we must include edges moved above to reject
|
||||
DfaEdge* newp = new DfaEdge (graphp(), vvertexp, acceptp, vedgep);
|
||||
newp->complement(!newp->complement());
|
||||
newp->user(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public:
|
||||
DfaGraphComplement(V3Graph* dfagraphp, V3EdgeFuncP edgeFuncp)
|
||||
: GraphAlg(dfagraphp, edgeFuncp) {
|
||||
if (debug()>=6) m_graphp->dumpDotFilePrefixed("comp_in");
|
||||
|
||||
// Vertex::m_user begin: 1 indicates new edge, no more processing
|
||||
m_graphp->userClearEdges();
|
||||
|
||||
m_tempNewerReject = new DfaVertex(graphp());
|
||||
add_complement_edges();
|
||||
if (debug()>=6) m_graphp->dumpDotFilePrefixed("comp_preswap");
|
||||
|
||||
m_tempNewerReject->unlinkDelete(graphp()); m_tempNewerReject=NULL;
|
||||
if (debug()>=6) m_graphp->dumpDotFilePrefixed("comp_out");
|
||||
}
|
||||
~DfaGraphComplement() {}
|
||||
};
|
||||
|
||||
void DfaGraph::dfaComplement() {
|
||||
DfaGraphComplement (this, &V3GraphEdge::followAlwaysTrue);
|
||||
}
|
||||
|
||||
+24
-6
@@ -43,7 +43,9 @@ class DfaEdge;
|
||||
/// or epsilon, represented as a empty list of inputs.
|
||||
///
|
||||
/// We're only looking for matches, so the only accepting states are
|
||||
/// at the end of the transformations.
|
||||
/// at the end of the transformations. (If we want the complement, we
|
||||
/// call complement and the algorithm makes a REJECT state, then flips
|
||||
/// accept and reject for you.)
|
||||
///
|
||||
/// Common transforms:
|
||||
///
|
||||
@@ -51,8 +53,8 @@ class DfaEdge;
|
||||
///
|
||||
/// "L": ...->[ON_L]-->DfaVtx-->[epsilon]-->DfaVtx(ACCEPT)
|
||||
///
|
||||
/// "LR": ...->[ON_L]-->DfaVtx-->[epsilon]-->DfaVtx()
|
||||
/// ->[ON_R]-->DfaVtx-->[epsilon]-->DfaVtx(ACCEPT)
|
||||
/// "LR": ...->[ON_L]-->DfaVtx-->[epsilon]-->DfaVtx(ACCEPT)
|
||||
/// ->[ON_R]-->DfaVtx-->[epsilon]-/
|
||||
///
|
||||
/// "L|R": ...->DfaVtx-->[epsilon]-->DfaVtx-->[ON_L]-->DfaVtx()->[epsilon]-->DfaVtx(ACCEPT)
|
||||
/// \->[epsilon]-->DfaVtx-->[ON_R]-->DfaVtx()->[epsilon]-/
|
||||
@@ -76,6 +78,9 @@ public:
|
||||
|
||||
/// Simplify a DFA automata
|
||||
void dfaReduce();
|
||||
|
||||
/// Complement result (must already be dfa)
|
||||
void dfaComplement();
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
@@ -113,20 +118,33 @@ typedef AstNUser* DfaInput;
|
||||
|
||||
class DfaEdge : public V3GraphEdge {
|
||||
DfaInput m_input;
|
||||
bool m_complement; // Invert value when doing compare
|
||||
public:
|
||||
static DfaInput EPSILON() { return NULL; }
|
||||
static DfaInput NA() { return AstNUser::fromInt(1); } // as in not-applicable
|
||||
// CONSTRUCTORS
|
||||
DfaEdge(DfaGraph* graphp, DfaVertex* fromp, DfaVertex* top, DfaInput input)
|
||||
: V3GraphEdge(graphp, fromp, top, 1)
|
||||
, m_input(input) {}
|
||||
, m_input(input), m_complement(false) {}
|
||||
DfaEdge(DfaGraph* graphp, DfaVertex* fromp, DfaVertex* top, const DfaEdge* copyfrom)
|
||||
: V3GraphEdge(graphp, fromp, top, copyfrom->weight())
|
||||
, m_input(copyfrom->input()), m_complement(copyfrom->complement()) {}
|
||||
virtual ~DfaEdge() {}
|
||||
// METHODS
|
||||
virtual string dotColor() const { return na()?"yellow":epsilon()?"green":"black"; }
|
||||
virtual string dotLabel() const { return na()?"":epsilon()?"e":cvtToStr((void*)(input())); }
|
||||
virtual string dotColor() const {
|
||||
return (na() ? "yellow"
|
||||
: epsilon() ? "green"
|
||||
: "black"); }
|
||||
virtual string dotLabel() const {
|
||||
return (na() ? ""
|
||||
: epsilon() ? "e"
|
||||
: complement() ? ("not "+cvtToStr((void*)(input())))
|
||||
: cvtToStr((void*)(input()))); }
|
||||
virtual string dotStyle() const { return (na()||cutable())?"dashed":""; }
|
||||
bool epsilon() const { return input()==EPSILON(); }
|
||||
bool na() const { return input()==NA(); }
|
||||
bool complement() const { return m_complement; }
|
||||
void complement(bool value) { m_complement=value; }
|
||||
DfaInput input() const { return m_input; }
|
||||
};
|
||||
|
||||
|
||||
@@ -309,6 +309,12 @@ public:
|
||||
gp->nfaToDfa();
|
||||
dump();
|
||||
gp->dfaReduce();
|
||||
dump();
|
||||
|
||||
gp->dfaComplement();
|
||||
dump();
|
||||
gp->dfaReduce();
|
||||
dump();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+4
-4
@@ -381,10 +381,10 @@ private:
|
||||
|
||||
virtual void visit(AstAssignW* nodep, AstNUser*) {
|
||||
// Deal with implicit definitions
|
||||
if (nodep->allowImplicit()) {
|
||||
if (AstVarRef* forrefp = nodep->lhsp()->castVarRef()) {
|
||||
createImplicitVar(forrefp, false);
|
||||
}
|
||||
// We used to nodep->allowImplicit() here, but it turns out
|
||||
// normal "assigns" can also make implicit wires. Yuk.
|
||||
if (AstVarRef* forrefp = nodep->lhsp()->castVarRef()) {
|
||||
createImplicitVar(forrefp, false);
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
|
||||
@@ -127,9 +127,6 @@ private:
|
||||
// Module: Pick up modnames, so we can resolve cells later
|
||||
m_modp = nodep;
|
||||
UINFO(2,"Link Module: "<<nodep<<endl);
|
||||
if (nodep->name().find("__") != string::npos) {
|
||||
nodep->v3error("Unsupported: Double underscores (__) in module names reserved for internal use: "<<nodep->prettyName());
|
||||
}
|
||||
if (nodep->inLibrary()) {
|
||||
if (!m_libVertexp) m_libVertexp = new LibraryVertex(&m_graph);
|
||||
new V3GraphEdge(&m_graph, m_libVertexp, vertex(nodep), 1, false);
|
||||
|
||||
+13
-10
@@ -379,17 +379,20 @@ private:
|
||||
// This may not be the module with isTop() set, as early in the steps,
|
||||
// wrapTop may have not been created yet.
|
||||
AstModule* topmodp = nodep->modulesp();
|
||||
if (!topmodp) nodep->v3fatalSrc("No top level module");
|
||||
UINFO(8,"Top Module: "<<topmodp<<endl);
|
||||
m_scope = "TOP";
|
||||
m_cellVxp = m_statep->insertTopCell(topmodp, m_scope);
|
||||
m_inlineVxp = m_cellVxp;
|
||||
{
|
||||
topmodp->accept(*this);
|
||||
if (!topmodp) {
|
||||
nodep->v3error("No top level module found");
|
||||
} else {
|
||||
UINFO(8,"Top Module: "<<topmodp<<endl);
|
||||
m_scope = "TOP";
|
||||
m_cellVxp = m_statep->insertTopCell(topmodp, m_scope);
|
||||
m_inlineVxp = m_cellVxp;
|
||||
{
|
||||
topmodp->accept(*this);
|
||||
}
|
||||
m_scope = "";
|
||||
m_cellVxp = NULL;
|
||||
m_inlineVxp = m_cellVxp;
|
||||
}
|
||||
m_scope = "";
|
||||
m_cellVxp = NULL;
|
||||
m_inlineVxp = m_cellVxp;
|
||||
}
|
||||
virtual void visit(AstModule* nodep, AstNUser*) {
|
||||
UINFO(8," "<<nodep<<endl);
|
||||
|
||||
+20
-5
@@ -45,6 +45,7 @@ private:
|
||||
|
||||
// STATE
|
||||
bool m_setRefLvalue; // Set VarRefs to lvalues for pin assignments
|
||||
AstNodeFTask* m_ftaskp; // Function or task we're inside
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
@@ -59,7 +60,9 @@ private:
|
||||
}
|
||||
if (nodep->varp()) {
|
||||
if (nodep->lvalue() && nodep->varp()->isInOnly()) {
|
||||
nodep->v3error("Assigning to input variable: "<<nodep->prettyName());
|
||||
if (!m_ftaskp) {
|
||||
nodep->v3error("Assigning to input variable: "<<nodep->prettyName());
|
||||
}
|
||||
}
|
||||
}
|
||||
nodep->iterateChildren(*this);
|
||||
@@ -150,6 +153,11 @@ private:
|
||||
}
|
||||
m_setRefLvalue = last_setRefLvalue;
|
||||
}
|
||||
virtual void visit(AstNodeFTask* nodep, AstNUser*) {
|
||||
m_ftaskp = nodep;
|
||||
nodep->iterateChildren(*this);
|
||||
m_ftaskp = NULL;
|
||||
}
|
||||
|
||||
virtual void visit(AstNode* nodep, AstNUser*) {
|
||||
// Default: Just iterate
|
||||
@@ -158,9 +166,10 @@ private:
|
||||
|
||||
public:
|
||||
// CONSTUCTORS
|
||||
LinkLValueVisitor(AstNetlist* rootp) {
|
||||
m_setRefLvalue = false;
|
||||
rootp->accept(*this);
|
||||
LinkLValueVisitor(AstNode* nodep, bool start) {
|
||||
m_setRefLvalue = start;
|
||||
m_ftaskp = NULL;
|
||||
nodep->accept(*this);
|
||||
}
|
||||
virtual ~LinkLValueVisitor() {}
|
||||
};
|
||||
@@ -170,5 +179,11 @@ public:
|
||||
|
||||
void V3LinkLValue::linkLValue(AstNetlist* rootp) {
|
||||
UINFO(4,__FUNCTION__<<": "<<endl);
|
||||
LinkLValueVisitor visitor(rootp);
|
||||
LinkLValueVisitor visitor(rootp, false);
|
||||
}
|
||||
void V3LinkLValue::linkLValueSet(AstNode* nodep) {
|
||||
// Called by later link functions when it is known a node needs
|
||||
// to be converted to a lvalue.
|
||||
UINFO(9,__FUNCTION__<<": "<<endl);
|
||||
LinkLValueVisitor visitor(nodep, true);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
class V3LinkLValue {
|
||||
public:
|
||||
static void linkLValue(AstNetlist* nodep);
|
||||
static void linkLValueSet(AstNode* nodep);
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
|
||||
+20
-2
@@ -85,6 +85,21 @@ void V3LinkLevel::modSortByLevel() {
|
||||
// Sort modules by levels, root down to lowest children
|
||||
// Calculate levels again in case we added modules
|
||||
UINFO(2,"modSortByLevel()\n");
|
||||
|
||||
if (v3Global.opt.topModule()!="") {
|
||||
bool hit = false;
|
||||
for (AstModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castModule()) {
|
||||
if (nodep->name() == v3Global.opt.topModule()) {
|
||||
hit = true;
|
||||
} else {
|
||||
nodep->level(3);
|
||||
}
|
||||
}
|
||||
if (!hit) {
|
||||
v3error("Specified --top-module '"<<v3Global.opt.topModule()<<"' was not found in design.");
|
||||
}
|
||||
}
|
||||
|
||||
LinkLevelVisitor visitor;
|
||||
visitor.main(v3Global.rootp());
|
||||
|
||||
@@ -92,8 +107,11 @@ void V3LinkLevel::modSortByLevel() {
|
||||
AstModule* topp = NULL;
|
||||
for (AstModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castModule()) {
|
||||
if (nodep->level()<=2) {
|
||||
if (topp) nodep->v3warn(MULTITOP, "Unsupported: Multiple top level modules: "
|
||||
<<nodep->prettyName()<<" and "<<topp->prettyName());
|
||||
if (topp) {
|
||||
nodep->v3warn(MULTITOP, "Unsupported: Multiple top level modules: "
|
||||
<<nodep->prettyName()<<" and "<<topp->prettyName());
|
||||
nodep->v3warn(MULTITOP, "Fix, or use --top-module option to select which you want.");
|
||||
}
|
||||
topp = nodep;
|
||||
}
|
||||
vec.push_back(nodep);
|
||||
|
||||
+6
-3
@@ -698,8 +698,10 @@ V3Number& V3Number::opXnor (const V3Number& lhs, const V3Number& rhs) {
|
||||
|
||||
V3Number& V3Number::opConcat (const V3Number& lhs, const V3Number& rhs) {
|
||||
setZero();
|
||||
if (!lhs.sized()) m_fileline->v3error("Unsized constants not allowed in concatenations: "<<lhs);
|
||||
if (!rhs.sized()) m_fileline->v3error("Unsized constants not allowed in concatenations: "<<rhs);
|
||||
// See also error in V3Width
|
||||
if (!lhs.sized() || !rhs.sized()) {
|
||||
m_fileline->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in concatenations.");
|
||||
}
|
||||
int obit = 0;
|
||||
for(int bit=0; bit<rhs.width(); bit++) {
|
||||
setBit(obit,rhs.bitIs(bit));
|
||||
@@ -714,7 +716,8 @@ V3Number& V3Number::opConcat (const V3Number& lhs, const V3Number& rhs) {
|
||||
|
||||
V3Number& V3Number::opRepl (const V3Number& lhs, const V3Number& rhs) { // rhs is # of times to replicate
|
||||
// Hopefully the using routine has a error check too.
|
||||
if (!lhs.sized()) m_fileline->v3error("Unsized constants not allowed in concatenations: "<<lhs);
|
||||
// See also error in V3Width
|
||||
if (!lhs.sized()) m_fileline->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in replications.");
|
||||
return opRepl(lhs, rhs.asInt());
|
||||
}
|
||||
|
||||
|
||||
+158
-11
@@ -23,7 +23,10 @@
|
||||
#include "verilatedos.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/utsname.h>
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <unistd.h>
|
||||
#include <set>
|
||||
#include <list>
|
||||
#include <map>
|
||||
@@ -97,6 +100,11 @@ void V3Options::addLibraryFile(const string& filename) {
|
||||
m_libraryFiles.insert(filename);
|
||||
}
|
||||
}
|
||||
void V3Options::addVFile(const string& filename) {
|
||||
if (m_vFiles.find(filename) == m_vFiles.end()) {
|
||||
m_vFiles.insert(filename);
|
||||
}
|
||||
}
|
||||
void V3Options::addArg(const string& arg) {
|
||||
m_impp->m_allArgs.push_back(arg);
|
||||
}
|
||||
@@ -110,6 +118,20 @@ string V3Options::allArgsString() {
|
||||
return out;
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
// Language class
|
||||
|
||||
V3LangCode::V3LangCode (const char* textp) {
|
||||
// Return code for given string, or ERROR, which is a bad code
|
||||
for (int codei=V3LangCode::ERROR; codei<V3LangCode::MAX; codei++) {
|
||||
V3LangCode code = (V3LangCode)codei;
|
||||
if (0==strcasecmp(textp,code.ascii())) {
|
||||
m_e = code; return;
|
||||
}
|
||||
}
|
||||
m_e = V3LangCode::ERROR;
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
// File searching
|
||||
|
||||
@@ -146,6 +168,14 @@ string V3Options::filenameNonExt (const string& filename) {
|
||||
return base;
|
||||
}
|
||||
|
||||
bool V3Options::fileStatDir(const string& filename) {
|
||||
struct stat m_stat; // Stat information
|
||||
int err = stat(filename.c_str(), &m_stat);
|
||||
if (err!=0) return false;
|
||||
if (!S_ISDIR(m_stat.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);
|
||||
@@ -238,6 +268,96 @@ void V3Options::unlinkRegexp(const string& dir, const string& regexp) {
|
||||
}
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
// Environment
|
||||
|
||||
string V3Options::getenvStr(const char* envvar, const char* defaultValue) {
|
||||
if (const char* envvalue = getenv(envvar)) {
|
||||
return envvalue;
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
string V3Options::getenvSYSTEMC() {
|
||||
string var = getenvStr("SYSTEMC","");
|
||||
if (var == "" && string(DEFENV_SYSTEMC) != "") {
|
||||
var = DEFENV_SYSTEMC;
|
||||
UINFO(1,"export SYSTEMC="<<var<<" # Hardcoded at build time"<<endl);
|
||||
setenv("SYSTEMC", var.c_str(), false);
|
||||
}
|
||||
// Only correct or check it if we really need the value
|
||||
if ((v3Global.opt.systemPerl() || v3Global.opt.systemC())
|
||||
&& !v3Global.opt.lintOnly()) {
|
||||
if (var == "") {
|
||||
v3fatal("Need $SYSTEMC in environment\n"
|
||||
"Probably System-C isn't installed, see http://www.systemc.org\n");
|
||||
}
|
||||
}
|
||||
return var;
|
||||
}
|
||||
string V3Options::getenvSYSTEMC_ARCH() {
|
||||
string var = getenvStr("SYSTEMC_ARCH","");
|
||||
if (var == "" && string(DEFENV_SYSTEMC_ARCH) != "") {
|
||||
var = DEFENV_SYSTEMC_ARCH;
|
||||
UINFO(1,"export SYSTEMC_ARCH="<<var<<" # Hardcoded at build time"<<endl);
|
||||
setenv("SYSTEMC_ARCH", var.c_str(), false);
|
||||
}
|
||||
if (var == "") {
|
||||
struct utsname uts;
|
||||
uname(&uts);
|
||||
string sysname = downcase(uts.sysname); // aka 'uname -s'
|
||||
if (wildmatch(sysname.c_str(), "*solaris*")) { var = "gccsparcOS5"; }
|
||||
else if (wildmatch(sysname.c_str(), "*cygwin*")) { var ="cygwin"; }
|
||||
else { var = "linux"; }
|
||||
UINFO(1,"export SYSTEMC_ARCH="<<var<<" # From sysname '"<<sysname<<"'"<<endl);
|
||||
setenv("SYSTEMC_ARCH", var.c_str(), false);
|
||||
}
|
||||
return var;
|
||||
}
|
||||
string V3Options::getenvSYSTEMPERL() {
|
||||
string var = getenvStr("SYSTEMPERL","");
|
||||
if (var == "" && string(DEFENV_SYSTEMPERL) != "") {
|
||||
var = DEFENV_SYSTEMPERL;
|
||||
UINFO(1,"export SYSTEMPERL="<<var<<" # Hardcoded at build time"<<endl);
|
||||
setenv("SYSTEMC_PERL", var.c_str(), false);
|
||||
}
|
||||
// Only correct or check it if we really need the value
|
||||
if ((v3Global.opt.systemPerl() || v3Global.opt.trace()) && !v3Global.opt.lintOnly()) {
|
||||
if (var == "") {
|
||||
string testdir = V3Options::getenvW() + "/hw/utils/perltools/SystemC"; // Hack for internal testing
|
||||
if (V3Options::fileStatDir(testdir)) {
|
||||
var = testdir;
|
||||
UINFO(1,"export SYSTEMPERL="<<var<<endl);
|
||||
setenv ("SYSTEMPERL", var.c_str(), false);
|
||||
}
|
||||
}
|
||||
if (var == "") {
|
||||
v3fatal("Need $SYSTEMPERL in environment for --sp or --trace\n"
|
||||
"Probably System-Perl isn't installed, see http://www.veripool.com/systemperl.html\n");
|
||||
}
|
||||
if (var != ""
|
||||
&& !V3Options::fileStatNormal(var+"/src/systemperl.h")) {
|
||||
v3fatal("$SYSTEMPERL environment var doesn't seem to point to System-Perl kit\n");
|
||||
}
|
||||
}
|
||||
return var;
|
||||
}
|
||||
string V3Options::getenvVERILATOR_ROOT() {
|
||||
string var = getenvStr("VERILATOR_ROOT","");
|
||||
if (var == "" && string(DEFENV_VERILATOR_ROOT) != "") {
|
||||
var = DEFENV_VERILATOR_ROOT;
|
||||
UINFO(1,"export VERILATOR_ROOT="<<var<<" # Hardcoded at build time"<<endl);
|
||||
setenv("VERILATOR_ROOT", var.c_str(), false);
|
||||
}
|
||||
if (var == "") {
|
||||
v3fatal("$VERILATOR_ROOT needs to be in environment\n");
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
// Wildcard
|
||||
|
||||
// Double procedures, inlined, unrolls loop much better
|
||||
inline bool V3Options::wildmatchi(const char* s, const char* p) {
|
||||
for ( ; *p; s++, p++) {
|
||||
@@ -275,6 +395,14 @@ bool V3Options::wildmatch(const char* s, const char* p) {
|
||||
return(*s == '\0' || *s == '[');
|
||||
}
|
||||
|
||||
string V3Options::downcase(const string& str) {
|
||||
string out = str;
|
||||
for (string::iterator pos = out.begin(); pos != out.end(); pos++) {
|
||||
*pos = tolower(*pos);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
// V3 Options accessors
|
||||
|
||||
@@ -310,12 +438,13 @@ void V3Options::parseOpts (FileLine* fl, int argc, char** argv) {
|
||||
|
||||
// Default certain options and error check
|
||||
// Detailed error, since this is what we often get when run with minimal arguments
|
||||
if (top()=="") {
|
||||
if (vFiles().empty()) {
|
||||
v3fatal("verilator: No Input Verilog file specified on command line, see verilator --help for more information\n");
|
||||
}
|
||||
|
||||
// Default prefix to the filename
|
||||
if (prefix()=="") m_prefix = string("V")+filenameNonExt(top());
|
||||
if (prefix()=="" && topModule()!="") m_prefix = string("V")+topModule();
|
||||
if (prefix()=="") m_prefix = string("V")+filenameNonExt(*(vFiles().begin()));
|
||||
if (modPrefix()=="") m_modPrefix = prefix();
|
||||
|
||||
// Find files in makedir
|
||||
@@ -383,19 +512,23 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
||||
shift;
|
||||
setDebugMode(atoi(argv[i]));
|
||||
}
|
||||
else if ( !strcmp (sw, "-v") ) {
|
||||
else if ( !strcmp (sw, "-error-limit") ) {
|
||||
shift;
|
||||
V3Options::addLibraryFile(argv[i]);
|
||||
}
|
||||
else if ( !strcmp (sw, "-version") ) {
|
||||
cout <<version();
|
||||
cout <<endl;
|
||||
exit(0);
|
||||
m_inlineMult = atoi(argv[i]);
|
||||
}
|
||||
else if ( !strcmp (sw, "-inline-mult") ) {
|
||||
shift;
|
||||
m_inlineMult = atoi(argv[i]);
|
||||
}
|
||||
else if ( !strcmp (sw, "-language") ) {
|
||||
shift;
|
||||
V3LangCode optval = V3LangCode(argv[i]);
|
||||
if (optval.legal()) {
|
||||
m_language = optval;
|
||||
} else {
|
||||
fl->v3fatal("Unknown language specified: "<<argv[i]);
|
||||
}
|
||||
}
|
||||
else if ( !strcmp (sw, "-output-split") ) {
|
||||
shift;
|
||||
m_outputSplit = atoi(argv[i]);
|
||||
@@ -416,6 +549,15 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
||||
shift;
|
||||
m_unrollStmts = atoi(argv[i]);
|
||||
}
|
||||
else if ( !strcmp (sw, "-v") ) {
|
||||
shift;
|
||||
V3Options::addLibraryFile(argv[i]);
|
||||
}
|
||||
else if ( !strcmp (sw, "-version") ) {
|
||||
cout <<version();
|
||||
cout <<endl;
|
||||
exit(0);
|
||||
}
|
||||
// Single switches
|
||||
else if ( !strcmp (sw, "-E") ) { m_preprocOnly = true; }
|
||||
else if ( onoff (sw, "-MMD", flag/*ref*/) ) { m_makeDepend = flag; }
|
||||
@@ -536,6 +678,9 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
||||
shift; m_prefix = argv[i];
|
||||
if (m_modPrefix=="") m_modPrefix = m_prefix;
|
||||
}
|
||||
else if ( !strcmp (sw, "-top-module") && (i+1)<argc ) {
|
||||
shift; m_topModule = argv[i];
|
||||
}
|
||||
else if ( !strcmp (sw, "-x-assign") && (i+1)<argc) {
|
||||
shift;
|
||||
if (!strcmp (argv[i], "0")) { m_xAssign="0"; }
|
||||
@@ -562,8 +707,7 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
||||
|| filename.find(".sp") != string::npos) {
|
||||
V3Options::addCppFile(argv[i]);
|
||||
} else {
|
||||
if (m_top!="") fl->v3fatal ("Top filename specified twice: "<<m_top<<" and "<<filename);
|
||||
m_top = filename;
|
||||
V3Options::addVFile(argv[i]);
|
||||
}
|
||||
shift;
|
||||
}
|
||||
@@ -657,6 +801,7 @@ V3Options::V3Options() {
|
||||
m_traceDups = false;
|
||||
m_underlineZero = false;
|
||||
|
||||
m_errorLimit = 50;
|
||||
m_inlineMult = 2000;
|
||||
m_outputSplit = 0;
|
||||
m_outputSplitCFuncs = 0;
|
||||
@@ -672,6 +817,8 @@ V3Options::V3Options() {
|
||||
m_flags = "";
|
||||
m_xAssign = "unique";
|
||||
|
||||
m_language = V3LangCode::mostRecent();
|
||||
|
||||
optimize(true);
|
||||
// Default +libext+
|
||||
addLibExt(""); // So include "filename.v" will find the same file
|
||||
|
||||
+60
-12
@@ -29,6 +29,41 @@
|
||||
|
||||
#include "V3Global.h"
|
||||
|
||||
//######################################################################
|
||||
|
||||
class V3LangCode {
|
||||
public:
|
||||
enum en {
|
||||
ERROR, // Must be first.
|
||||
L1364_1995,
|
||||
L1364_2001,
|
||||
L1364_2005,
|
||||
L1800_2005,
|
||||
// ***Add new elements below also***
|
||||
MAX
|
||||
};
|
||||
const char* ascii() const {
|
||||
const char* names[] = {
|
||||
// These must match the `begin_keywords values.
|
||||
" ERROR",
|
||||
"1364-1995",
|
||||
"1364-2001",
|
||||
"1364-2005",
|
||||
"1800-2005"
|
||||
};
|
||||
return names[m_e];
|
||||
};
|
||||
static V3LangCode mostRecent() { return V3LangCode(L1800_2005); }
|
||||
bool legal() const { return m_e != ERROR; }
|
||||
//
|
||||
enum en m_e;
|
||||
inline V3LangCode () : m_e(ERROR) {};
|
||||
inline V3LangCode (en _e) : m_e(_e) {};
|
||||
V3LangCode (const char* textp); // Return matching code or ERROR
|
||||
explicit inline V3LangCode (int _e) : m_e(static_cast<en>(_e)) {};
|
||||
operator en () const { return m_e; };
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
// V3Options - Command line options
|
||||
|
||||
@@ -41,8 +76,9 @@ class V3Options {
|
||||
// MEMBERS (general options)
|
||||
V3OptionsImp* m_impp; // Slow hidden options
|
||||
|
||||
V3StringSet m_cppFiles; // C++ files to link against
|
||||
V3StringSet m_libraryFiles; // Verilog -v files
|
||||
V3StringSet m_cppFiles; // argument: C++ files to link against
|
||||
V3StringSet m_libraryFiles; // argument: Verilog -v files
|
||||
V3StringSet m_vFiles; // argument: Verilog files to read
|
||||
|
||||
bool m_preprocOnly; // main switch: -E
|
||||
bool m_makeDepend; // main switch: -MMD
|
||||
@@ -70,6 +106,7 @@ class V3Options {
|
||||
bool m_traceDups; // main switch: --trace-dups
|
||||
bool m_underlineZero;// main switch: --underline-zero
|
||||
|
||||
int m_errorLimit; // main switch: --error-limit
|
||||
int m_inlineMult; // main switch: --inline-mult
|
||||
int m_outputSplit; // main switch: --output-split
|
||||
int m_outputSplitCFuncs;// main switch: --output-split-cfuncs
|
||||
@@ -82,11 +119,13 @@ class V3Options {
|
||||
|
||||
string m_bin; // main switch: --bin {binary}
|
||||
string m_flags; // main switch: -f {name}
|
||||
string m_top; // main switch: Top .v file name
|
||||
string m_makeDir; // main switch: -Mdir
|
||||
string m_prefix; // main switch: --prefix
|
||||
string m_modPrefix; // main switch: --mod-prefix
|
||||
string m_xAssign; // main switch: --x-assign
|
||||
string m_topModule; // main switch: --top-module
|
||||
|
||||
V3LangCode m_language; // main switch: --language
|
||||
|
||||
// MEMBERS (optimizations)
|
||||
// // main switch: -Op: --public
|
||||
@@ -116,6 +155,7 @@ class V3Options {
|
||||
void coverage(bool flag) { m_coverageLine = m_coverageUser = flag; }
|
||||
bool onoff(const char* sw, const char* arg, bool& flag);
|
||||
static bool wildmatchi(const char* s, const char* p);
|
||||
static string getenvStr(const char* envvar, const char* defaultValue);
|
||||
|
||||
public:
|
||||
// CREATORS
|
||||
@@ -126,9 +166,9 @@ class V3Options {
|
||||
// METHODS
|
||||
void addCppFile(const string& filename);
|
||||
void addLibraryFile(const string& filename);
|
||||
void addVFile(const string& filename);
|
||||
|
||||
// ACCESSORS (options)
|
||||
const string& top() const { return m_top; }
|
||||
bool preprocOnly() const { return m_preprocOnly; }
|
||||
bool makeDepend() const { return m_makeDepend; }
|
||||
bool makePhony() const { return m_makePhony; }
|
||||
@@ -159,6 +199,7 @@ class V3Options {
|
||||
bool ignc() const { return m_ignc; }
|
||||
bool inhibitSim() const { return m_inhibitSim; }
|
||||
|
||||
int errorLimit() const { return m_errorLimit; }
|
||||
int inlineMult() const { return m_inlineMult; }
|
||||
int outputSplit() const { return m_outputSplit; }
|
||||
int outputSplitCFuncs() const { return m_outputSplitCFuncs; }
|
||||
@@ -172,10 +213,12 @@ class V3Options {
|
||||
string makeDir() const { return m_makeDir; }
|
||||
string prefix() const { return m_prefix; }
|
||||
string modPrefix() const { return m_modPrefix; }
|
||||
string topModule() const { return m_topModule; }
|
||||
string xAssign() const { return m_xAssign; }
|
||||
const V3StringSet& cppFiles() const { return m_cppFiles; }
|
||||
const V3StringSet& libraryFiles() const { return m_libraryFiles; }
|
||||
|
||||
const V3StringSet& vFiles() const { return m_vFiles; }
|
||||
const V3LangCode& language() const { return m_language; }
|
||||
|
||||
// ACCESSORS (optimization options)
|
||||
bool oAcycSimp() const { return m_oAcycSimp; }
|
||||
@@ -206,6 +249,7 @@ class V3Options {
|
||||
|
||||
// METHODS (generic string utilities)
|
||||
static bool wildmatch(const char* s, const char* p);
|
||||
static string downcase(const string& str);
|
||||
|
||||
// METHODS (generic file utilities)
|
||||
static string filenameFromDirBase (const string& dir, const string& basename);
|
||||
@@ -214,17 +258,21 @@ class V3Options {
|
||||
static string filenameNonDirExt (const string& filename) { return filenameNonExt(filenameNonDir(filename)); } ///< Return basename of filename
|
||||
static string filenameDir (const string& filename); ///< Return directory part of filename
|
||||
static void unlinkRegexp(const string& dir, const string& regexp);
|
||||
static string getenvStr(const char* envvar, const char* defaultValue) {
|
||||
if (const char* envvalue = getenv(envvar)) {
|
||||
return envvalue;
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
// METHODS (environment)
|
||||
// Most of these may be built into the executable with --enable-defenv,
|
||||
// see the README. If adding new variables, also see src/Makefile_obj.in
|
||||
static string getenvPERL() { return getenvStr("PERL","perl"); }
|
||||
static string getenvSYSTEMC();
|
||||
static string getenvSYSTEMC_ARCH();
|
||||
static string getenvSYSTEMPERL();
|
||||
static string getenvVERILATOR_ROOT();
|
||||
static string getenvW() { return getenvStr("W",""); }
|
||||
|
||||
// METHODS (file utilities using these options)
|
||||
string fileExists (const string& filename);
|
||||
string filePath (FileLine* fl, const string& modname, const string& errmsg);
|
||||
static bool fileStatDir (const string& filename);
|
||||
static bool fileStatNormal (const string& filename);
|
||||
};
|
||||
|
||||
|
||||
+3
-3
@@ -133,9 +133,9 @@ class V3PreLex {
|
||||
void lineDirective(const char* text);
|
||||
void incLineno() { m_curFilelinep->incLineno(); }
|
||||
// Called by V3PreProc.cpp to inform lexer
|
||||
void setStateDefArg();
|
||||
void setStateDefValue();
|
||||
void setStateIncFilename();
|
||||
void pushStateDefArg();
|
||||
void pushStateDefValue();
|
||||
void pushStateIncFilename();
|
||||
void unputString(const char* textp);
|
||||
};
|
||||
|
||||
|
||||
+20
-9
@@ -140,14 +140,25 @@ psl [p]sl
|
||||
<ARGMODE><<EOF>> { yyerror("EOF in define argument list\n"); yyleng = 0; yyterminate(); }
|
||||
<ARGMODE>{crnl} { linenoInc(); yytext="\n"; yyleng=1; return(VP_WHITE); }
|
||||
<ARGMODE>{quote} { yy_push_state(STRMODE); yymore(); }
|
||||
<ARGMODE>[(] { V3PreLex::s_currentLexp->m_parenLevel++; appendDefValue(yytext,yyleng); }
|
||||
<ARGMODE>[,)] { if (V3PreLex::s_currentLexp->m_parenLevel>1) {
|
||||
<ARGMODE>[(] { V3PreLex::s_currentLexp->m_parenLevel++;
|
||||
if (V3PreLex::s_currentLexp->m_parenLevel>1) {
|
||||
appendDefValue(yytext,yyleng);
|
||||
if (yytext[0]==')') V3PreLex::s_currentLexp->m_parenLevel--;
|
||||
} else {
|
||||
unput(yytext[0]); yy_pop_state(); return (VP_DEFARG);
|
||||
return (VP_TEXT);
|
||||
}}
|
||||
<ARGMODE>[^\/\*\n\r\\(,)\"]+ |
|
||||
<ARGMODE>[)] { V3PreLex::s_currentLexp->m_parenLevel--;
|
||||
if (V3PreLex::s_currentLexp->m_parenLevel>0) {
|
||||
appendDefValue(yytext,yyleng);
|
||||
} else {
|
||||
yy_pop_state(); return (VP_DEFARG);
|
||||
}}
|
||||
<ARGMODE>[,] { if (V3PreLex::s_currentLexp->m_parenLevel>1) {
|
||||
appendDefValue(yytext,yyleng);
|
||||
} else {
|
||||
yy_pop_state(); return (VP_DEFARG);
|
||||
}}
|
||||
<ARGMODE>"`"{symb} { return (VP_DEFREF); } /* defref in defref */
|
||||
<ARGMODE>[^\/\*\n\r\\(,)\"`]+ |
|
||||
<ARGMODE>. { appendDefValue(yytext,yyleng); }
|
||||
|
||||
/* One line comments. */
|
||||
@@ -199,21 +210,21 @@ psl [p]sl
|
||||
<INITIAL,PSLMULM,PSLONEM>. { return (VP_TEXT); }
|
||||
%%
|
||||
|
||||
void V3PreLex::setStateDefArg() {
|
||||
void V3PreLex::pushStateDefArg() {
|
||||
// Enter define substitution argument state
|
||||
yy_push_state(ARGMODE);
|
||||
m_parenLevel = 1;
|
||||
m_parenLevel = 0;
|
||||
m_defValue = "";
|
||||
}
|
||||
|
||||
void V3PreLex::setStateDefValue() {
|
||||
void V3PreLex::pushStateDefValue() {
|
||||
// Enter define value state
|
||||
yy_push_state(DEFMODE);
|
||||
m_parenLevel = 0;
|
||||
m_defValue = "";
|
||||
}
|
||||
|
||||
void V3PreLex::setStateIncFilename() {
|
||||
void V3PreLex::pushStateIncFilename() {
|
||||
// Enter include <> filename state
|
||||
yy_push_state(INCMODE);
|
||||
yymore();
|
||||
|
||||
+99
-53
@@ -61,6 +61,28 @@ public:
|
||||
string params() const { return m_params; }
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
class V3DefineRef {
|
||||
// One for each pending define substitution
|
||||
string m_name; // Define last name being defined
|
||||
string m_params; // Define parameter list for next expansion
|
||||
string m_nextarg; // String being built for next argument
|
||||
int m_parenLevel; // Parenthesis counting inside def args
|
||||
|
||||
vector<string> m_args; // List of define arguments
|
||||
public:
|
||||
string name() const { return m_name; }
|
||||
string params() const { return m_params; }
|
||||
string nextarg() const { return m_nextarg; }
|
||||
void nextarg(const string& value) { m_nextarg = value; }
|
||||
int parenLevel() const { return m_parenLevel; }
|
||||
vector<string>& args() { return m_args; }
|
||||
V3DefineRef(const string& name, const string& params, int pl)
|
||||
: m_name(name), m_params(params), m_parenLevel(pl) {}
|
||||
~V3DefineRef() {}
|
||||
};
|
||||
|
||||
//*************************************************************************
|
||||
// Data for a preprocessor instantiation.
|
||||
|
||||
@@ -88,14 +110,12 @@ struct V3PreProcImp : public V3PreProc {
|
||||
bool m_rawAtBol; ///< Last rawToken left us at beginning of line
|
||||
|
||||
// For defines
|
||||
string m_defName; // Define last name being defined
|
||||
string m_defParams; // Define parameter list for next expansion
|
||||
stack<V3DefineRef> m_defRefs; // Pending definine substitution
|
||||
stack<bool> m_ifdefStack; // Stack of true/false emitting evaluations
|
||||
vector<string> m_defArgs; // List of define arguments
|
||||
unsigned m_defDepth; // How many `defines deep
|
||||
|
||||
// Defines list
|
||||
DefinesMap m_defines; // Map of defines
|
||||
DefinesMap m_defines; // Map of defines
|
||||
|
||||
// For getline()
|
||||
string m_lineChars; // Characters left for next line
|
||||
@@ -113,7 +133,7 @@ struct V3PreProcImp : public V3PreProc {
|
||||
private:
|
||||
// Internal methods
|
||||
void eof();
|
||||
string defineSubst();
|
||||
string defineSubst(V3DefineRef* refp);
|
||||
void addLineComment(int enter_exit_level);
|
||||
|
||||
bool defExists(const string& name);
|
||||
@@ -122,6 +142,7 @@ private:
|
||||
FileLine* defFileline(const string& name);
|
||||
|
||||
bool commentTokenMatch(string& cmdr, const char* strg);
|
||||
string trimWhitespace(const string& strg);
|
||||
|
||||
void parsingOn() {
|
||||
m_off--;
|
||||
@@ -149,7 +170,6 @@ public:
|
||||
V3PreProcImp(FileLine* fl) : V3PreProc(fl) {
|
||||
m_lexp = NULL; // Closed.
|
||||
m_state = ps_TOP;
|
||||
m_defName = "";
|
||||
m_off = 0;
|
||||
m_lineChars = "";
|
||||
m_lastSym = "";
|
||||
@@ -207,8 +227,8 @@ void V3PreProcImp::define(FileLine* fl, const string& name, const string& value,
|
||||
UINFO(4,"DEFINE '"<<name<<"' as '"<<value<<"' params '"<<params<<"'"<<endl);
|
||||
if (defExists(name)) {
|
||||
if (!(defValue(name)==value && defParams(name)==params)) { // Duplicate defs are OK
|
||||
fl->v3error("Define already exists: "<<name);
|
||||
defFileline(name)->v3error("Previous definition is here.");
|
||||
fl->v3warn(REDEFMACRO,"Redefining existing define: "<<name<<", with different value: "<<value<<" "<<params);
|
||||
defFileline(name)->v3warn(REDEFMACRO,"Previous definition is here, with value: "<<defValue(name)<<" "<<defParams(name));
|
||||
}
|
||||
undef(name);
|
||||
}
|
||||
@@ -348,33 +368,43 @@ const char* V3PreProcImp::tokenName(int tok) {
|
||||
}
|
||||
}
|
||||
|
||||
string V3PreProcImp::defineSubst() {
|
||||
string V3PreProcImp::trimWhitespace(const string& strg) {
|
||||
string out = strg;
|
||||
while (out.length()>0 && isspace(out[0])) {
|
||||
out.erase(0,1);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
string V3PreProcImp::defineSubst(V3DefineRef* refp) {
|
||||
// Substitute out defines in a argumented define reference.
|
||||
// We could push the define text back into the lexer, but that's slow
|
||||
// and would make recursive definitions and parameter handling nasty.
|
||||
//
|
||||
// Note we parse the definition parameters and value here. If a
|
||||
// parameterized define is used many, many times, we could cache the
|
||||
// parametrized define is used many, many times, we could cache the
|
||||
// parsed result.
|
||||
UINFO(4,"defineSubstIn `"<<m_defName<<" "<<m_defParams<<endl);
|
||||
for (unsigned i=0; i<m_defArgs.size(); i++) {
|
||||
UINFO(4,"defineArg["<<i<<"] = "<<m_defArgs[i]<<endl);
|
||||
UINFO(4,"defineSubstIn `"<<refp->name()<<" "<<refp->params()<<endl);
|
||||
for (unsigned i=0; i<refp->args().size(); i++) {
|
||||
UINFO(4,"defineArg["<<i<<"] = "<<refp->args()[i]<<endl);
|
||||
}
|
||||
// Grab value
|
||||
string value = defValue(m_defName);
|
||||
UINFO(4,"defineValue `"<<value<<endl);
|
||||
string value = defValue(refp->name());
|
||||
UINFO(4,"defineValue '"<<value<<"'"<<endl);
|
||||
|
||||
map<string,string> argValueByName;
|
||||
{ // Parse argument list into map
|
||||
unsigned numArgs=0;
|
||||
string argName;
|
||||
for (const char* cp=m_defParams.c_str(); *cp; cp++) {
|
||||
for (const char* cp=refp->params().c_str(); *cp; cp++) {
|
||||
if (*cp=='(') {
|
||||
} else if (argName=="" && isspace(*cp)) {
|
||||
} else if (isspace(*cp) || *cp==')' || *cp==',') {
|
||||
if (argName!="") {
|
||||
if (m_defArgs.size() >= numArgs) {
|
||||
argValueByName[argName] = m_defArgs[numArgs];
|
||||
if (refp->args().size() > numArgs) {
|
||||
// A call `def( a ) must be equivelent to `def(a ), so trimWhitespace
|
||||
// Note other sims don't trim trailing whitespace, so we don't either.
|
||||
argValueByName[argName] = trimWhitespace(refp->args()[numArgs]);
|
||||
}
|
||||
numArgs++;
|
||||
//cout << " arg "<<argName<<endl;
|
||||
@@ -385,13 +415,13 @@ string V3PreProcImp::defineSubst() {
|
||||
argName += *cp;
|
||||
}
|
||||
}
|
||||
if (m_defArgs.size() != numArgs) {
|
||||
fileline()->v3error("Define passed wrong number of arguments: "+m_defName+"\n");
|
||||
return " `"+m_defName+" ";
|
||||
if (refp->args().size() != numArgs) {
|
||||
fileline()->v3error("Define passed wrong number of arguments: "+refp->name()+"\n");
|
||||
return " `"+refp->name()+" ";
|
||||
}
|
||||
}
|
||||
|
||||
string out = " ";
|
||||
string out = "";
|
||||
{ // Parse substitution define using arguments
|
||||
string argName;
|
||||
string prev;
|
||||
@@ -447,8 +477,7 @@ string V3PreProcImp::defineSubst() {
|
||||
}
|
||||
}
|
||||
|
||||
out += " ";
|
||||
UINFO(4,"defineSubstOut "<<out<<endl);
|
||||
UINFO(4,"defineSubstOut '"<<out<<"'"<<endl);
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -533,7 +562,7 @@ int V3PreProcImp::getRawToken() {
|
||||
if (m_lineAdd) {
|
||||
m_lineAdd--;
|
||||
m_rawAtBol = true;
|
||||
yytext="\n"; yyleng=1;
|
||||
yytext=(char*)"\n"; yyleng=1;
|
||||
return (VP_TEXT);
|
||||
}
|
||||
if (m_lineCmt!="") {
|
||||
@@ -565,8 +594,9 @@ int V3PreProcImp::getRawToken() {
|
||||
string::size_type pos;
|
||||
while ((pos=buf.find("\n")) != string::npos) { buf.replace(pos, 1, "\\n"); }
|
||||
while ((pos=buf.find("\r")) != string::npos) { buf.replace(pos, 1, "\\r"); }
|
||||
fprintf (stderr, "%d: RAW %d %d: %-10s: %s\n",
|
||||
fileline()->lineno(), m_off, m_state, tokenName(tok), buf.c_str());
|
||||
fprintf (stderr, "%d: RAW %s s%d dr%d: %-10s: %s\n",
|
||||
fileline()->lineno(), m_off?"of":"on", m_state, (int)m_defRefs.size(),
|
||||
tokenName(tok), buf.c_str());
|
||||
}
|
||||
|
||||
// On EOF, try to pop to upper level includes, as needed.
|
||||
@@ -651,7 +681,7 @@ int V3PreProcImp::getToken() {
|
||||
else if (m_stateFor==VP_DEFINE) {
|
||||
// m_lastSym already set.
|
||||
m_state = ps_DEFVALUE;
|
||||
m_lexp->setStateDefValue();
|
||||
m_lexp->pushStateDefValue();
|
||||
}
|
||||
else fileline()->v3fatalSrc("Bad case\n");
|
||||
goto next_tok;
|
||||
@@ -698,7 +728,7 @@ int V3PreProcImp::getToken() {
|
||||
&& isspace(m_lexp->m_defValue[m_lexp->m_defValue.length()-1-trailspace])) trailspace++;
|
||||
if (trailspace) m_lexp->m_defValue.erase(m_lexp->m_defValue.length()-trailspace,trailspace);
|
||||
// Define it
|
||||
UINFO(4,"Define "<<m_lastSym<<" = "<<m_lexp->m_defValue<<endl);
|
||||
UINFO(4,"Define "<<m_lastSym<<" = '"<<m_lexp->m_defValue<<"'"<<endl);
|
||||
define(fileline(), m_lastSym, m_lexp->m_defValue, params);
|
||||
}
|
||||
} else {
|
||||
@@ -712,40 +742,57 @@ int V3PreProcImp::getToken() {
|
||||
}
|
||||
case ps_DEFPAREN: {
|
||||
if (tok==VP_TEXT && yyleng==1 && yytext[0]=='(') {
|
||||
m_defArgs.clear();
|
||||
m_state = ps_DEFARG;
|
||||
m_lexp->setStateDefArg();
|
||||
goto next_tok;
|
||||
} else {
|
||||
m_state = ps_TOP;
|
||||
fileline()->v3error("Expecting ( to begin argument list for define reference `"<<m_defName);
|
||||
if (m_defRefs.empty()) v3fatalSrc("Shouldn't be in DEFPAREN w/o active defref");
|
||||
V3DefineRef* refp = &(m_defRefs.top());
|
||||
fileline()->v3error("Expecting ( to begin argument list for define reference `"<<refp->name());
|
||||
goto next_tok;
|
||||
}
|
||||
}
|
||||
case ps_DEFARG: {
|
||||
if (tok==VP_DEFARG) {
|
||||
UINFO(4," Defarg "<<m_defName<<" arg="<<m_lexp->m_defValue<<endl);
|
||||
goto next_tok; // Next is a , or )
|
||||
} else if (tok==VP_TEXT && yyleng==1 && yytext[0]==',') {
|
||||
m_defArgs.push_back(m_lexp->m_defValue);
|
||||
if (m_defRefs.empty()) v3fatalSrc("Shouldn't be in DEFARG w/o active defref");
|
||||
V3DefineRef* refp = &(m_defRefs.top());
|
||||
refp->nextarg(refp->nextarg()+m_lexp->m_defValue); m_lexp->m_defValue="";
|
||||
if (tok==VP_DEFARG && yyleng==1 && yytext[0]==',') {
|
||||
refp->args().push_back(refp->nextarg());
|
||||
m_state = ps_DEFARG;
|
||||
m_lexp->setStateDefArg();
|
||||
m_lexp->pushStateDefArg();
|
||||
refp->nextarg("");
|
||||
goto next_tok;
|
||||
} else if (tok==VP_TEXT && yyleng==1 && yytext[0]==')') {
|
||||
m_defArgs.push_back(m_lexp->m_defValue);
|
||||
string out = defineSubst();
|
||||
m_lexp->m_parenLevel = 0;
|
||||
} else if (tok==VP_DEFARG && yyleng==1 && yytext[0]==')') {
|
||||
refp->args().push_back(refp->nextarg());
|
||||
string out = defineSubst(refp);
|
||||
// Substitute in and prepare for next action
|
||||
// Similar code in non-parenthesized define (Search for END_OF_DEFARG)
|
||||
m_defRefs.pop();
|
||||
m_lexp->unputString(out.c_str());
|
||||
// Prepare for next action
|
||||
m_defArgs.clear();
|
||||
m_state = ps_TOP;
|
||||
if (m_defRefs.empty()) {
|
||||
m_state = ps_TOP;
|
||||
m_lexp->m_parenLevel = 0;
|
||||
}
|
||||
else { // Finished a defref inside a upper defref
|
||||
refp = &(m_defRefs.top()); // We popped, so new top
|
||||
m_lexp->m_parenLevel = refp->parenLevel();
|
||||
m_state = ps_DEFARG;
|
||||
}
|
||||
goto next_tok;
|
||||
} else if (tok==VP_DEFREF) {
|
||||
// Expand it, then state will come back here
|
||||
// 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) {
|
||||
string rtn; rtn.assign(yytext,yyleng);
|
||||
refp->nextarg(refp->nextarg()+rtn);
|
||||
goto next_tok;
|
||||
} else {
|
||||
fileline()->v3error("Expecting ) or , to end argument list for define reference. Found: "<<tokenName(tok));
|
||||
m_state = ps_TOP;
|
||||
goto next_tok;
|
||||
}
|
||||
goto next_tok;
|
||||
}
|
||||
case ps_INCNAME: {
|
||||
if (tok==VP_STRING) {
|
||||
@@ -763,7 +810,7 @@ int V3PreProcImp::getToken() {
|
||||
else if (tok==VP_TEXT && yyleng==1 && yytext[0]=='<') {
|
||||
// include <filename>
|
||||
m_state = ps_INCNAME; // Still
|
||||
m_lexp->setStateIncFilename();
|
||||
m_lexp->pushStateIncFilename();
|
||||
goto next_tok;
|
||||
}
|
||||
else if (tok==VP_DEFREF) {
|
||||
@@ -844,18 +891,17 @@ int V3PreProcImp::getToken() {
|
||||
else {
|
||||
string params = defParams(name);
|
||||
if (params=="0" || params=="") { // Found, as simple substitution
|
||||
// Pack spaces around the define value, as there must be token boundaries around it.
|
||||
// It also makes it more obvious where defines got substituted.
|
||||
string out = " "+defValue(name)+" ";
|
||||
UINFO(4,"Defref `"<<name<<" => "<<out<<endl);
|
||||
string out = defValue(name);
|
||||
UINFO(4,"Defref `"<<name<<" => '"<<out<<"'"<<endl);
|
||||
// Similar code in parenthesized define (Search for END_OF_DEFARG)
|
||||
m_lexp->unputString(out.c_str());
|
||||
goto next_tok;
|
||||
}
|
||||
else { // Found, with parameters
|
||||
UINFO(4,"Defref `"<<name<<" => parameterized"<<endl);
|
||||
m_defName = name;
|
||||
m_defParams = params;
|
||||
m_defRefs.push(V3DefineRef(name, params, m_lexp->m_parenLevel));
|
||||
m_state = ps_DEFPAREN; m_stateFor = tok;
|
||||
m_lexp->pushStateDefArg();
|
||||
goto next_tok;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +121,13 @@ void V3Read::readFile(FileLine* fileline, const string& modfilename, bool inLibr
|
||||
m_fileline = new FileLine(fileline);
|
||||
m_inLibrary = inLibrary;
|
||||
|
||||
// Set language standard up front
|
||||
if (!v3Global.opt.preprocOnly()) {
|
||||
// Leting lex parse this saves us from having to specially en/decode
|
||||
// from the V3LangCode to the various Lex BEGIN states.
|
||||
ppPushText((string)"`begin_keywords \""+v3Global.opt.language().ascii()+"\"\n");
|
||||
}
|
||||
|
||||
// Preprocess into m_ppBuffer
|
||||
V3PreShell::preproc(fileline, modfilename, this);
|
||||
|
||||
|
||||
+21
-10
@@ -41,6 +41,7 @@
|
||||
#include "V3Ast.h"
|
||||
#include "V3EmitCBase.h"
|
||||
#include "V3Graph.h"
|
||||
#include "V3LinkLValue.h"
|
||||
|
||||
//######################################################################
|
||||
// Graph subclasses
|
||||
@@ -360,11 +361,11 @@ private:
|
||||
else if (portp->isOutput()) {
|
||||
// Make output variables
|
||||
// Correct lvalue; we didn't know when we linked
|
||||
if (AstVarRef* varrefp = pinp->castVarRef()) {
|
||||
varrefp->lvalue(true);
|
||||
} else {
|
||||
pinp->v3warn(TASKNSVAR,"Unsupported: Task output pin connected to non-variable");
|
||||
}
|
||||
// This is slightly scary; are we sure no decisions were made
|
||||
// before here based on this not being a lvalue?
|
||||
// Doesn't seem so; V3Unknown uses it earlier, but works ok.
|
||||
V3LinkLValue::linkLValueSet(pinp);
|
||||
|
||||
// Even if it's referencing a varref, we still make a temporary
|
||||
// Else task(x,x,x) might produce incorrect results
|
||||
AstVarScope* outvscp = createVarScope (portp, namePrefix+"__"+portp->shortName());
|
||||
@@ -445,11 +446,21 @@ private:
|
||||
else if (portp->isOutput()) {
|
||||
// Make output variables
|
||||
// Correct lvalue; we didn't know when we linked
|
||||
if (AstVarRef* varrefp = pinp->castVarRef()) {
|
||||
varrefp->lvalue(true);
|
||||
} else {
|
||||
pinp->v3warn(TASKNSVAR,"Unsupported: Task output pin connected to non-variable");
|
||||
}
|
||||
// This is slightly scary; are we sure no decisions were made
|
||||
// before here based on this not being a lvalue?
|
||||
// Doesn't seem so; V3Unknown uses it earlier, but works ok.
|
||||
V3LinkLValue::linkLValueSet(pinp);
|
||||
|
||||
// Even if it's referencing a varref, we still make a temporary
|
||||
// Else task(x,x,x) might produce incorrect results
|
||||
AstVarScope* outvscp = createVarScope (portp, namePrefix+"__"+portp->shortName());
|
||||
portp->user2p(outvscp);
|
||||
pinp->replaceWith(new AstVarRef(outvscp->fileline(), outvscp, true));
|
||||
AstAssign* assp = new AstAssign (pinp->fileline(),
|
||||
pinp,
|
||||
new AstVarRef(outvscp->fileline(), outvscp, false));
|
||||
// Put assignment BEHIND of all other statements
|
||||
beginp->addNext(assp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+22
-8
@@ -201,7 +201,10 @@ private:
|
||||
nodep->lhsp()->widthMin() + nodep->rhsp()->widthMin());
|
||||
}
|
||||
if (vup->c()->final()) {
|
||||
if (!nodep->widthSized()) nodep->v3error("Concat argument must have specific size. (No unsized numbers/parameters).");
|
||||
if (!nodep->widthSized()) {
|
||||
// See also error in V3Number
|
||||
nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in concatenations.");
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstReplicate* nodep, AstNUser* vup) {
|
||||
@@ -217,7 +220,10 @@ private:
|
||||
(nodep->lhsp()->widthMin() * times));
|
||||
}
|
||||
if (vup->c()->final()) {
|
||||
if (!nodep->widthSized()) nodep->v3error("Replication expression must have specific size.");
|
||||
if (!nodep->widthSized()) {
|
||||
// See also error in V3Number
|
||||
nodep->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in replications.");
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstRange* nodep, AstNUser* vup) {
|
||||
@@ -243,15 +249,11 @@ private:
|
||||
while (huntbackp->backp()->castRange()) huntbackp=huntbackp->backp();
|
||||
if (huntbackp->backp()->castVar()
|
||||
&& huntbackp->backp()->castVar()->arraysp()==huntbackp) {
|
||||
AstNRelinker msbHandle;
|
||||
AstNRelinker lsbHandle;
|
||||
msbConstp->unlinkFrBack(&msbHandle);
|
||||
lsbConstp->unlinkFrBack(&lsbHandle);
|
||||
msbHandle.relink(lsbConstp);
|
||||
lsbHandle.relink(msbConstp);
|
||||
} else {
|
||||
nodep->v3error("Unsupported: MSB < LSB of bit range: "<<msb<<"<"<<lsb);
|
||||
}
|
||||
// Correct it.
|
||||
swap(msbConstp, lsbConstp);
|
||||
int x=msb; msb=lsb; lsb=x;
|
||||
}
|
||||
int width = msb-lsb+1;
|
||||
@@ -275,6 +277,10 @@ private:
|
||||
&& nodep->msbConst() < nodep->lsbConst()) {
|
||||
nodep->v3error("Unsupported: MSB < LSB of bit extract: "
|
||||
<<nodep->msbConst()<<"<"<<nodep->lsbConst());
|
||||
width = (nodep->lsbConst() - nodep->msbConst() + 1);
|
||||
nodep->width(width,width);
|
||||
nodep->widthp()->replaceWith(new AstConst(nodep->widthp()->fileline(),
|
||||
width));
|
||||
nodep->lsbp()->replaceWith(new AstConst(nodep->lsbp()->fileline(), 0));
|
||||
}
|
||||
// We're extracting, so just make sure the expression is at least wide enough.
|
||||
@@ -720,6 +726,14 @@ private:
|
||||
bool fixAutoExtend (AstNode*& nodepr, int expWidth);
|
||||
void fixWidthExtend (AstNode* nodep, int expWidth);
|
||||
void fixWidthReduce (AstNode* nodep, int expWidth);
|
||||
void swap (AstNode* ap, AstNode* bp) {
|
||||
AstNRelinker aHandle;
|
||||
AstNRelinker bHandle;
|
||||
ap->unlinkFrBack(&aHandle);
|
||||
bp->unlinkFrBack(&bHandle);
|
||||
aHandle.relink(bp);
|
||||
bHandle.relink(ap);
|
||||
}
|
||||
|
||||
public:
|
||||
// CONSTUCTORS
|
||||
|
||||
+13
-2
@@ -90,14 +90,21 @@ V3Global v3Global;
|
||||
|
||||
void V3Global::readFiles() {
|
||||
V3Read reader (m_rootp);
|
||||
// Read top module
|
||||
for (V3StringSet::iterator it = v3Global.opt.vFiles().begin();
|
||||
it != v3Global.opt.vFiles().end(); ++it) {
|
||||
string filename = *it;
|
||||
reader.readFile(new FileLine("CommandLine",0), filename, false);
|
||||
}
|
||||
|
||||
// Read libraries
|
||||
// To be compatible with other simulators,
|
||||
// this needs to be done after the top file is read
|
||||
for (V3StringSet::iterator it = v3Global.opt.libraryFiles().begin();
|
||||
it != v3Global.opt.libraryFiles().end(); ++it) {
|
||||
string filename = *it;
|
||||
reader.readFile(new FileLine("CommandLine",0), filename, true);
|
||||
}
|
||||
// Read top module
|
||||
reader.readFile(new FileLine("CommandLine",0), opt.top(), false);
|
||||
V3Error::abortIfErrors();
|
||||
}
|
||||
|
||||
@@ -503,6 +510,10 @@ int main(int argc, char** argv, char** env) {
|
||||
if (!v3Global.opt.outFormatOk() && !v3Global.opt.preprocOnly() && !v3Global.opt.lintOnly()) {
|
||||
v3fatal("verilator: Need --cc, --sc, --sp, --lint-only or --E option");
|
||||
}
|
||||
// Check enviornment
|
||||
V3Options::getenvSYSTEMC();
|
||||
V3Options::getenvSYSTEMC_ARCH();
|
||||
V3Options::getenvSYSTEMPERL();
|
||||
|
||||
V3Error::abortIfErrors();
|
||||
|
||||
|
||||
+21
-1
@@ -24,7 +24,7 @@
|
||||
//**********************************************************************
|
||||
//**** Version and host name
|
||||
|
||||
#define DTVERSION "Verilator 3.657 2008/01/18"
|
||||
#define DTVERSION "Verilator 3.661 2008/04/04"
|
||||
|
||||
//**********************************************************************
|
||||
//**** Functions
|
||||
@@ -57,6 +57,26 @@
|
||||
// Set define if we have header: <inttypes.h>
|
||||
#define HAVE_INTTYPES_H 0
|
||||
|
||||
//**********************************************************************
|
||||
//**** Default environment
|
||||
|
||||
// Set defines to defaults for environment variables
|
||||
// If set to "", this default is ignored and the user is expected
|
||||
// to set them at Verilator runtime.
|
||||
|
||||
#ifndef DEFENV_SYSTEMC
|
||||
# define DEFENV_SYSTEMC ""
|
||||
#endif
|
||||
#ifndef DEFENV_SYSTEMC_ARCH
|
||||
# define DEFENV_SYSTEMC_ARCH ""
|
||||
#endif
|
||||
#ifndef DEFENV_SYSTEMPERL
|
||||
# define DEFENV_SYSTEMPERL ""
|
||||
#endif
|
||||
#ifndef DEFENV_VERILATOR_ROOT
|
||||
# define DEFENV_VERILATOR_ROOT ""
|
||||
#endif
|
||||
|
||||
//**********************************************************************
|
||||
//**** Compile options
|
||||
|
||||
|
||||
+7
-3
@@ -634,14 +634,18 @@ escid \\[^ \t\f\r\n]+
|
||||
if (!isalnum(yytext[i]))
|
||||
yytext[i] = '_';
|
||||
if (isalpha(yytext[1])) {
|
||||
yylval.strp = V3Read::newString(yytext+1); // +1 to skip the backslash
|
||||
yylval.strp = V3Read::newString(
|
||||
AstNode::encodeName(
|
||||
string(yytext+1))); // +1 to skip the backslash
|
||||
} else {
|
||||
yylval.strp = V3Read::newString(yytext); // Need _ as "6..." isn't legal ID
|
||||
yylval.strp = V3Read::newString(
|
||||
AstNode::encodeName(
|
||||
yytext)); // Need _ as "6..." isn't legal ID
|
||||
}
|
||||
return yaID;
|
||||
}
|
||||
|
||||
{id} { yylval.strp = V3Read::newString(yytext);
|
||||
{id} { yylval.strp = V3Read::newString(AstNode::encodeName(string(yytext)));
|
||||
return yaID;
|
||||
}
|
||||
|
||||
|
||||
+29
-23
@@ -382,7 +382,7 @@ class AstSenTree;
|
||||
%type<nodep> modItem modItemList modItemListE modOrGenItem
|
||||
%type<nodep> generateRegion
|
||||
%type<nodep> genItem genItemList genItemBegin genItemBlock genTopBlock genCaseListE genCaseList
|
||||
%type<nodep> dlyTerm
|
||||
%type<nodep> dlyTerm minTypMax
|
||||
%type<fileline> delay
|
||||
%type<varp> sigAndAttr sigId sigIdRange sigList regsig regsigList regSigId
|
||||
%type<varp> netSig netSigList
|
||||
@@ -429,7 +429,7 @@ class AstSenTree;
|
||||
%type<nodep> pslDecl
|
||||
%type<nodep> pslSequence pslSere pslExpr
|
||||
|
||||
%start file
|
||||
%start fileE
|
||||
|
||||
%%
|
||||
//**********************************************************************
|
||||
@@ -445,8 +445,12 @@ statePop: /* empty */ { V3Read::statePop(); }
|
||||
//**********************************************************************
|
||||
// Files
|
||||
|
||||
file: description { }
|
||||
| file description { }
|
||||
fileE: /* empty */ { }
|
||||
| file { }
|
||||
;
|
||||
|
||||
file: description { }
|
||||
| file description { }
|
||||
;
|
||||
|
||||
// IEEE: description
|
||||
@@ -526,8 +530,8 @@ regsigList: regsig { $$ = $1; }
|
||||
| regsigList ',' regsig { $$ = $1;$1->addNext($3); }
|
||||
;
|
||||
|
||||
portV2kDecl: varRESET varInput v2kNetDeclE signingE regrangeE portV2kSig { $$ = $6; }
|
||||
| varRESET varInout v2kNetDeclE signingE regrangeE portV2kSig { $$ = $6; }
|
||||
portV2kDecl: varRESET varInput v2kVarDeclE signingE regrangeE portV2kSig { $$ = $6; }
|
||||
| varRESET varInout v2kVarDeclE signingE regrangeE portV2kSig { $$ = $6; }
|
||||
| varRESET varOutput v2kVarDeclE signingE regrangeE portV2kSig { $$ = $6; }
|
||||
;
|
||||
|
||||
@@ -577,11 +581,8 @@ signingE: /*empty*/ { }
|
||||
| yUNSIGNED { VARSIGNED(false); }
|
||||
;
|
||||
|
||||
v2kNetDeclE: /*empty*/ { }
|
||||
v2kVarDeclE: /*empty*/ { }
|
||||
| varNet { }
|
||||
;
|
||||
|
||||
v2kVarDeclE: v2kNetDeclE { }
|
||||
| varReg { }
|
||||
;
|
||||
|
||||
@@ -692,9 +693,9 @@ delayE: /* empty */ { }
|
||||
;
|
||||
|
||||
delay: '#' dlyTerm { $$ = $1; } /* ignored */
|
||||
| '#' '(' dlyInParen ')' { $$ = $1; } /* ignored */
|
||||
| '#' '(' dlyInParen ',' dlyInParen ')' { $$ = $1; } /* ignored */
|
||||
| '#' '(' dlyInParen ',' dlyInParen ',' dlyInParen ')' { $$ = $1; } /* ignored */
|
||||
| '#' '(' minTypMax ')' { $$ = $1; } /* ignored */
|
||||
| '#' '(' minTypMax ',' minTypMax ')' { $$ = $1; } /* ignored */
|
||||
| '#' '(' minTypMax ',' minTypMax ',' minTypMax ')' { $$ = $1; } /* ignored */
|
||||
;
|
||||
|
||||
dlyTerm: yaID { $$ = NULL; }
|
||||
@@ -702,7 +703,9 @@ dlyTerm: yaID { $$ = NULL; }
|
||||
| yaFLOATNUM { $$ = NULL; }
|
||||
;
|
||||
|
||||
dlyInParen: dlyTerm { } /* ignored */
|
||||
// IEEE: mintypmax_expression and constant_mintypmax_expression
|
||||
minTypMax: dlyTerm { $$ = $1; } /* ignored */
|
||||
| dlyTerm ':' dlyTerm ':' dlyTerm { $$ = $1; } /* ignored */
|
||||
;
|
||||
|
||||
sigAndAttr: sigId sigAttrListE { $$ = $1; }
|
||||
@@ -1118,14 +1121,14 @@ commaEListE: /* empty */ { $$ = NULL; }
|
||||
//************************************************
|
||||
// Gate declarations
|
||||
|
||||
gateDecl: yBUF gateBufList ';' { $$ = $2; }
|
||||
| yNOT gateNotList ';' { $$ = $2; }
|
||||
| yAND gateAndList ';' { $$ = $2; }
|
||||
| yNAND gateNandList ';' { $$ = $2; }
|
||||
| yOR gateOrList ';' { $$ = $2; }
|
||||
| yNOR gateNorList ';' { $$ = $2; }
|
||||
| yXOR gateXorList ';' { $$ = $2; }
|
||||
| yXNOR gateXnorList ';' { $$ = $2; }
|
||||
gateDecl: yBUF delayE gateBufList ';' { $$ = $3; }
|
||||
| yNOT delayE gateNotList ';' { $$ = $3; }
|
||||
| yAND delayE gateAndList ';' { $$ = $3; }
|
||||
| yNAND delayE gateNandList ';' { $$ = $3; }
|
||||
| yOR delayE gateOrList ';' { $$ = $3; }
|
||||
| yNOR delayE gateNorList ';' { $$ = $3; }
|
||||
| yXOR delayE gateXorList ';' { $$ = $3; }
|
||||
| yXNOR delayE gateXnorList ';' { $$ = $3; }
|
||||
;
|
||||
|
||||
gateBufList: gateBuf { $$ = $1; }
|
||||
@@ -1403,7 +1406,10 @@ AstVar* V3Parse::createVariable(FileLine* fileline, string name, AstRange* array
|
||||
rangep->cloneTree(false),
|
||||
arrayp);
|
||||
nodep->isSigned(V3Parse::s_varSigned);
|
||||
if (type == AstVarType::INTEGER || V3Parse::s_varDecl == AstVarType::INTEGER) nodep->isSigned(true);
|
||||
if (type == AstVarType::INTEGER || V3Parse::s_varDecl == AstVarType::INTEGER
|
||||
|| type == AstVarType::GENVAR) {
|
||||
nodep->isSigned(true);
|
||||
}
|
||||
if (V3Parse::s_varDecl != AstVarType::UNKNOWN) nodep->combineType(V3Parse::s_varDecl);
|
||||
if (V3Parse::s_varIO != AstVarType::UNKNOWN) nodep->combineType(V3Parse::s_varIO);
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ endif
|
||||
|
||||
######################################################################
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
$(PERL) driver.pl $(DRIVER_FLAGS) $(PRODUCTS)
|
||||
|
||||
|
||||
@@ -443,7 +443,8 @@ sub sc_or_sp {
|
||||
|
||||
sub _run {
|
||||
my $self = (ref $_[0]? shift : $Last_Self);
|
||||
my %param = (@_);
|
||||
my %param = (tee=>1,
|
||||
@_);
|
||||
my $command = join(' ',@{$param{cmd}});
|
||||
print "\t$command\n";
|
||||
|
||||
@@ -451,7 +452,11 @@ sub _run {
|
||||
open(SAVEOUT, ">&STDOUT") or die "%Error: Can't dup stdout";
|
||||
open(SAVEERR, ">&STDERR") or die "%Error: Can't dup stderr";
|
||||
if (0) {close(SAVEOUT); close(SAVEERR);} # Prevent unused warning
|
||||
open(STDOUT, "|tee $param{logfile}") or die "%Error: Can't redirect stdout";
|
||||
if ($param{tee}) {
|
||||
open(STDOUT, "|tee $param{logfile}") or die "%Error: Can't redirect stdout";
|
||||
} else {
|
||||
open(STDOUT, ">$param{logfile}") or die "%Error: Can't open $param{logfile}";
|
||||
}
|
||||
open(STDERR, ">&STDOUT") or die "%Error: Can't dup stdout";
|
||||
autoflush STDOUT 1;
|
||||
autoflush STDERR 1;
|
||||
|
||||
@@ -18,6 +18,7 @@ execute (
|
||||
[0] In TOP.v.sub.subblock
|
||||
[0] In TOP.v.sub2
|
||||
[0] In TOP.v.sub2.subblock2
|
||||
[0] Back \ Quote "
|
||||
[0] %X=0c %D=12 %0X=c %0O=14 %B=001100
|
||||
[0] %x=0c %d=12 %0x=c %0o=14 %b=001100
|
||||
[0] %x=00abbbbcccc %0x=abbbbcccc %o=00527356746314 %b=00000101010111011101110111100110011001100
|
||||
|
||||
@@ -19,6 +19,9 @@ module t;
|
||||
sub.write_m;
|
||||
sub2.write_m;
|
||||
|
||||
// Escapes
|
||||
$display("[%0t] Back \\ Quote \"", $time); // Old bug when \" last on the line.
|
||||
|
||||
// Display formatting
|
||||
$display("[%0t] %%X=%X %%D=%D %%0X=%0X %%0O=%0O %%B=%B", $time,
|
||||
quad[5:0], quad[5:0], quad[5:0], quad[5:0], quad[5:0]);
|
||||
|
||||
@@ -21,6 +21,7 @@ execute (
|
||||
[0] In TOP.v.sub.subblock
|
||||
[0] In TOP.v.sub2
|
||||
[0] In TOP.v.sub2.subblock2
|
||||
[0] Back \ Quote "
|
||||
[0] %X=0c %D=12 %0X=c %0O=14 %B=001100
|
||||
[0] %x=0c %d=12 %0x=c %0o=14 %b=001100
|
||||
[0] %x=00abbbbcccc %0x=abbbbcccc %o=00527356746314 %b=00000101010111011101110111100110011001100
|
||||
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
|
||||
compile (
|
||||
verilator_flags2 => ['--language 1364-2001'],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,17 @@
|
||||
// $Id$
|
||||
// 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*/);
|
||||
|
||||
// See also t_preproc_kwd.v
|
||||
|
||||
integer bit; initial bit = 1;
|
||||
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# 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
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
v_flags2 => ["--lint-only"],
|
||||
fails=>$Last_Self->{v3},
|
||||
expect=>
|
||||
'%Error: No top level module found
|
||||
%Error: Exiting due to',
|
||||
) if $Last_Self->{v3};
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,7 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2008 by Wilson Snyder.
|
||||
|
||||
`define EMPTY 1
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# 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
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
v_flags2 => ["--top-module b"],
|
||||
) if $Last_Self->{v3};
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
) if $Last_Self->{v3};
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,32 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2008 by Wilson Snyder.
|
||||
|
||||
module a;
|
||||
c c ();
|
||||
initial begin
|
||||
$write("Bad top modules\n");
|
||||
$stop;
|
||||
end
|
||||
endmodule
|
||||
|
||||
module b;
|
||||
d d ();
|
||||
endmodule
|
||||
|
||||
module c;
|
||||
initial begin
|
||||
$write("Bad top modules\n");
|
||||
$stop;
|
||||
end
|
||||
endmodule
|
||||
|
||||
module d;
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# 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
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
top_filename("t/t_flag_topmodule.v");
|
||||
|
||||
compile (
|
||||
fails=>$Last_Self->{v3},
|
||||
nc=>0, # Need to get it not to give the prompt
|
||||
expect=>
|
||||
'%Error-MULTITOP: t/t_flag_topmodule.v:\d+: Unsupported: Multiple top level modules: .*
|
||||
%Error-MULTITOP: t/t_flag_topmodule.v:\d+: Fix, or use --top-module option to select which you want.
|
||||
%Error: Exiting due to.*',
|
||||
) if $Last_Self->{v3};
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Executable
+22
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# 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
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
top_filename("t/t_flag_topmodule.v");
|
||||
|
||||
compile (
|
||||
fails=>$Last_Self->{v3},
|
||||
v_flags2 => ["--top-module notfound"],
|
||||
nc=>0, # Need to get it not to give the prompt
|
||||
expect=>
|
||||
'%Error: Specified --top-module \'notfound\' was not found in design.
|
||||
%Error: Exiting due to.*',
|
||||
) if $Last_Self->{v3};
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
+13
-4
@@ -7,6 +7,7 @@
|
||||
module t;
|
||||
reg [2:0] value;
|
||||
reg [31:0] global;
|
||||
reg [31:0] vec [1:0];
|
||||
|
||||
initial begin
|
||||
global = 1;
|
||||
@@ -32,14 +33,22 @@ module t;
|
||||
nil_task(32'h012,32'h112,global);
|
||||
if (global !== 32'h124) $stop;
|
||||
|
||||
vec[0] = 32'h333;
|
||||
vec[1] = 32'habc;
|
||||
incr(vec[1],vec[0],vec[1]);
|
||||
if (vec[0] != 32'h333) $stop;
|
||||
if (vec[1] != 32'hdef) $stop;
|
||||
|
||||
incr(vec[2],vec[0],vec[2]); // Reading/Writing past end of vector!
|
||||
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
|
||||
function [2:0] add;
|
||||
input [2:0] from;
|
||||
input [2:0] fromv;
|
||||
begin
|
||||
add = from + 3'd1;
|
||||
add = fromv + 3'd1;
|
||||
begin : named
|
||||
reg [31:0] flocal;
|
||||
flocal = 1;
|
||||
@@ -49,13 +58,13 @@ module t;
|
||||
endfunction
|
||||
|
||||
function [3:0] munge4;
|
||||
input [3:0] from; // Different from the 'from' signal above
|
||||
input [3:0] fromv; // Different fromv than the 'fromv' signal above
|
||||
reg one;
|
||||
begin : named
|
||||
reg [1:0] flocal;
|
||||
// Function calling a function
|
||||
one = 1'b1;
|
||||
munge4 = {one, add(from[2:0])};
|
||||
munge4 = {one, add(fromv[2:0])};
|
||||
end
|
||||
endfunction
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ compile (
|
||||
'%Error: t/t_func_bad.v:\d+: Too few arguments in function call
|
||||
%Error: t/t_func_bad.v:\d+: Too many arguments in function call
|
||||
%Error: t/t_func_bad.v:\d+: Too few arguments in function call
|
||||
%Error-TASKNSVAR: t/t_func_bad.v:\d+: Unsupported: Task output pin connected to non-variable
|
||||
%Error: t/t_func_bad.v:\d+: Outputs not allowed in function declarations
|
||||
%Error: Exiting due to',
|
||||
);
|
||||
|
||||
@@ -8,13 +8,11 @@ if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
fails=>$Last_Self->{v3},
|
||||
nc=>0, # Need to get it not to give the prompt
|
||||
expect=>
|
||||
'%Error-MULTITOP: t/t_mod_bad_twotop.v:\d+: Unsupported: Multiple top level modules: t2 and t
|
||||
%Error: Exiting due to.*',
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003-2008 by Wilson Snyder.
|
||||
|
||||
module t (clk);
|
||||
input clk;
|
||||
|
||||
integer cyc; initial cyc=1;
|
||||
integer sum;
|
||||
integer cpre;
|
||||
always @ (posedge clk) begin
|
||||
if (cyc!=0) begin
|
||||
cpre = cyc;
|
||||
cyc <= cyc + 1;
|
||||
if (cyc==1) begin
|
||||
if (mlog2(32'd0) != 32'd0) $stop;
|
||||
if (mlog2(32'd1) != 32'd0) $stop;
|
||||
if (mlog2(32'd3) != 32'd2) $stop;
|
||||
sum <= 32'd0;
|
||||
end
|
||||
else if (cyc<90) begin
|
||||
// (cyc) so if we trash the variable things will get upset.
|
||||
sum <= mlog2(cyc) + sum * 32'd42;
|
||||
if (cpre != cyc) $stop;
|
||||
end
|
||||
else if (cyc==90) begin
|
||||
if (sum !== 32'h0f12bb51) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function integer mlog2;
|
||||
input [31:0] value;
|
||||
integer i;
|
||||
begin
|
||||
if(value < 32'd1) begin
|
||||
mlog2 = 0;
|
||||
end
|
||||
else begin
|
||||
value = value - 32'd1;
|
||||
mlog2 = 0;
|
||||
for(i=0;i<32;i=i+1) begin
|
||||
if(value > 32'd0) begin
|
||||
mlog2 = mlog2 + 1;
|
||||
end
|
||||
value = value >> 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
endmodule
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,97 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
integer cyc=0;
|
||||
reg [63:0] crc;
|
||||
reg [63:0] sum;
|
||||
reg rst_n;
|
||||
|
||||
// Take CRC data and apply to testblock inputs
|
||||
|
||||
/*AUTOWIRE*/
|
||||
// Beginning of automatic wires (for undeclared instantiated-module outputs)
|
||||
wire [2:0] pos; // From test of Test.v
|
||||
// End of automatics
|
||||
|
||||
Test test (
|
||||
// Outputs
|
||||
.pos (pos[2:0]),
|
||||
/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.rst_n (rst_n));
|
||||
|
||||
// Aggregate outputs into a single result vector
|
||||
wire [63:0] result = {61'h0, pos};
|
||||
|
||||
// What checksum will we end up with
|
||||
`define EXPECTED_SUM 64'h039ea4d039c2e70b
|
||||
|
||||
// Test loop
|
||||
always @ (posedge clk) begin
|
||||
`ifdef TEST_VERBOSE
|
||||
$write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result);
|
||||
`endif
|
||||
cyc <= cyc + 1;
|
||||
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
|
||||
sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]};
|
||||
rst_n <= ~1'b0;
|
||||
if (cyc==0) begin
|
||||
// Setup
|
||||
crc <= 64'h5aef0c8d_d70a4497;
|
||||
rst_n <= ~1'b1;
|
||||
end
|
||||
else if (cyc<10) begin
|
||||
sum <= 64'h0;
|
||||
rst_n <= ~1'b1;
|
||||
end
|
||||
else if (cyc<90) begin
|
||||
end
|
||||
else if (cyc==99) begin
|
||||
$write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum);
|
||||
if (crc !== 64'hc77bb9b3784ea091) $stop;
|
||||
if (sum !== `EXPECTED_SUM) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module Test
|
||||
#(parameter SAMPLE_WIDTH = 4 )
|
||||
(
|
||||
`ifdef verilator // UNSUPPORTED
|
||||
output reg [2:0] pos,
|
||||
`else
|
||||
output reg [log2(SAMPLE_WIDTH)-1:0] pos,
|
||||
`endif
|
||||
// System
|
||||
input clk,
|
||||
input rst_n
|
||||
);
|
||||
|
||||
function integer log2(input integer arg);
|
||||
begin
|
||||
for(log2=0; arg>0; log2=log2+1)
|
||||
arg = (arg >> 1);
|
||||
end
|
||||
endfunction
|
||||
|
||||
always @ (posedge clk or negedge rst_n)
|
||||
if (!rst_n) begin
|
||||
pos <= 0;
|
||||
end
|
||||
else begin
|
||||
pos <= pos + 1;
|
||||
end
|
||||
endmodule
|
||||
@@ -20,8 +20,8 @@ module t (/*AUTOARG*/
|
||||
|
||||
// verilator lint_off IMPLICIT
|
||||
not NT0 (nt0, a[0]);
|
||||
and AN0 (an0, a[0], b[0]);
|
||||
nand ND0 (nd0, a[0], b[0], b[1]);
|
||||
and #1 AN0 (an0, a[0], b[0]);
|
||||
nand #(2,3,4) ND0 (nd0, a[0], b[0], b[1]);
|
||||
or OR0 (or0, a[0], b[0]);
|
||||
nor NR0 (nr0, a[0], b[0], b[2]);
|
||||
xor (xo0, a[0], b[0]);
|
||||
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,85 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2007 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
wire b;
|
||||
reg reset;
|
||||
integer cyc=0;
|
||||
|
||||
Testit testit (/*AUTOINST*/
|
||||
// Outputs
|
||||
.b (b),
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.reset (reset));
|
||||
|
||||
always @ (posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
if (cyc==0) begin
|
||||
reset <= 1'b0;
|
||||
end
|
||||
else if (cyc<10) begin
|
||||
reset <= 1'b1;
|
||||
end
|
||||
else if (cyc<90) begin
|
||||
reset <= 1'b0;
|
||||
end
|
||||
else if (cyc==99) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module Testit (clk, reset, b);
|
||||
input clk;
|
||||
input reset;
|
||||
output b;
|
||||
|
||||
wire [0:0] c;
|
||||
wire my_sig;
|
||||
wire [0:0] d;
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for(i = 0; i >= 0; i = i-1) begin: fnxtclk1
|
||||
fnxtclk fnxtclk1
|
||||
(.u(c[i]),
|
||||
.reset(reset),
|
||||
.clk(clk),
|
||||
.w(d[i]) );
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign b = d[0];
|
||||
assign c[0] = my_sig;
|
||||
assign my_sig = 1'b1;
|
||||
|
||||
endmodule
|
||||
|
||||
module fnxtclk (u, reset, clk, w );
|
||||
input u;
|
||||
input reset;
|
||||
input clk;
|
||||
output reg w;
|
||||
|
||||
always @ (posedge clk or posedge reset) begin
|
||||
if (reset == 1'b1) begin
|
||||
w <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
w <= u;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
$Last_Self->_run(fails=>1,
|
||||
cmd=>["perl","../bin/verilator",
|
||||
"--help"],
|
||||
logfile=>"obj_dir/t_help.log",
|
||||
tee=>0,
|
||||
) if $Last_Self->{v3};
|
||||
|
||||
file_grep ("obj_dir/t_help.log", qr/DISTRIBUTION/i);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
v_flags2 => ["-Wno-IMPLICIT"],
|
||||
) if $Last_Self->{v3};
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// $Id$
|
||||
// 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 (a,z);
|
||||
input a;
|
||||
output z;
|
||||
|
||||
assign b = 1'b1;
|
||||
|
||||
or OR0 (nt0, a, b);
|
||||
|
||||
assign z = nt0;
|
||||
endmodule
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# 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
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
top_filename("t/t_lint_implicit.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ["--lint-only"],
|
||||
fails=>1,
|
||||
expect=>
|
||||
'%Warning-IMPLICIT: t/t_lint_implicit.v:\d+: Signal definition not found, creating implicitly: b
|
||||
%Warning-IMPLICIT: Use .* to disable this message.
|
||||
%Warning-IMPLICIT: t/t_lint_implicit.v:\d+: Signal definition not found, creating implicitly: nt0
|
||||
%Error: Exiting due to.*',
|
||||
) if $Last_Self->{v3};
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
// $Id:$
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003 by Wilson Snyder.
|
||||
|
||||
module t;
|
||||
initial begin
|
||||
$write("Two top modules\n");
|
||||
$stop;
|
||||
end
|
||||
endmodule
|
||||
|
||||
module t2;
|
||||
initial begin
|
||||
$write("Two top modules\n");
|
||||
$stop;
|
||||
end
|
||||
endmodule
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
verilator_flags2 => ["--Wno-WIDTHCONCAT"],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,28 @@
|
||||
// $Id$
|
||||
// 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;
|
||||
|
||||
parameter UNSIZED = 10;
|
||||
|
||||
integer cyc=1;
|
||||
always @ (posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
if (cyc==1) begin
|
||||
if ({UNSIZED,UNSIZED+1} != {32'd10, 32'd11}) $stop;
|
||||
if ({2{UNSIZED}} != {32'd10, 32'd10}) $stop;
|
||||
end
|
||||
if (cyc==9) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
Executable
+24
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
top_filename("t/t_param_concat.v");
|
||||
|
||||
compile (
|
||||
fails=>1,
|
||||
expect=>
|
||||
'%Warning-WIDTHCONCAT: t/t_param_concat.v:\d+: Unsized numbers/parameters not allowed in concatenations.
|
||||
%Warning-WIDTHCONCAT: Use "/\* verilator lint_off WIDTHCONCAT \*/" and lint_on around source to disable this message.
|
||||
%Warning-WIDTHCONCAT: t/t_param_concat.v:\d+: Unsized numbers/parameters not allowed in replications.
|
||||
%Warning-WIDTHCONCAT: t/t_param_concat.v:\d+: Unsized numbers/parameters not allowed in concatenations.
|
||||
%Warning-WIDTHCONCAT: t/t_param_concat.v:\d+: Unsized numbers/parameters not allowed in replications.
|
||||
%Error: Exiting due to.*',
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Executable
+32
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id: t_delay.pl 965 2007-10-31 20:29:07Z wsnyder $
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
expect=>quotemeta(
|
||||
'pre thrupre thrumid thrupost post: "right side"
|
||||
left side: "right side"
|
||||
left side : "right side "
|
||||
left_side : "left_side "
|
||||
na : "left_side "
|
||||
prep ( midp1 left_side midp2 ( outp ) ) : "left_side "
|
||||
na: "nana"
|
||||
left_side left_side : "left_side left_side "
|
||||
: ""
|
||||
left side: "right side"
|
||||
left side : "right side "
|
||||
twoline: "first second"
|
||||
*-* All Finished *-*
|
||||
'));
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,56 @@
|
||||
// $Id: t_delay.v 965 2007-10-31 20:29:07Z wsnyder $
|
||||
// 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;
|
||||
wire d1 = 1'b1;
|
||||
wire d2 = 1'b1;
|
||||
wire d3 = 1'b1;
|
||||
wire o1,o2,o3;
|
||||
add1 add1 (d1,o1);
|
||||
add2 add2 (d2,o2);
|
||||
|
||||
`define ls left_side
|
||||
`define rs left_side
|
||||
`define noarg na
|
||||
`define thru(x) x
|
||||
`define thruthru `ls `rs // Doesn't expand
|
||||
`define msg(x,y) `"x: `\`"y`\`"`"
|
||||
initial begin
|
||||
//$display(`msg( \`, \`)); // Illegal
|
||||
$display(`msg(pre `thru(thrupre `thru(thrumid) thrupost) post,right side));
|
||||
$display(`msg(left side,right side));
|
||||
$display(`msg( left side , right side ));
|
||||
$display(`msg( `ls , `rs ));
|
||||
$display(`msg( `noarg , `rs ));
|
||||
$display(`msg( prep ( midp1 `ls midp2 ( outp ) ) , `rs ));
|
||||
$display(`msg(`noarg,`noarg`noarg));
|
||||
$display(`msg( `thruthru , `thruthru )); // Results vary between simulators
|
||||
$display(`msg(`thru(),)); // Empty
|
||||
$display(`msg(`thru(left side),`thru(right side)));
|
||||
$display(`msg( `thru( left side ) , `thru( right side ) ));
|
||||
|
||||
`define twoline first \
|
||||
second
|
||||
$display(`msg(twoline, `twoline));
|
||||
|
||||
//$display(`msg(left side, \ right side \ )); // Not sure \{space} is legal.
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
|
||||
`define ADD_UP(a,c) \
|
||||
wire tmp_``a = a; \
|
||||
wire tmp_``c = tmp_``a + 1; \
|
||||
assign c = tmp_``c ;
|
||||
|
||||
module add1 ( input wire d1, output wire o1);
|
||||
`ADD_UP(d1,o1) // expansion is OK
|
||||
endmodule
|
||||
module add2 ( input wire d2, output wire o2);
|
||||
`ADD_UP( d2 , o2 ) // expansion is bad
|
||||
endmodule
|
||||
// `ADD_UP( \d3 , \o3 ) // This really is illegal
|
||||
Executable
+16
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
v_flags2 => ["-Wno-REDEFMACRO"],
|
||||
) if $Last_Self->{v3};
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
// $Id$
|
||||
// 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;
|
||||
|
||||
`define DUP fred
|
||||
`define DUP barney
|
||||
|
||||
`define DUPP paramed(x) (x)
|
||||
`define DUPP paramed(x,z) (x*z)
|
||||
|
||||
initial $stop; // Should have failed
|
||||
|
||||
endmodule
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# 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
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
top_filename("t/t_pp_dupdef.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ["--lint-only"],
|
||||
fails=>1,
|
||||
expect=>
|
||||
'%Warning-REDEFMACRO: t/t_pp_dupdef.v:\d+: Redefining existing define: DUP, with different value: barney
|
||||
%Warning-REDEFMACRO: Use .* to disable this message.
|
||||
%Warning-REDEFMACRO: t/t_pp_dupdef.v:\d+: Previous definition is here, with value: fred
|
||||
%Warning-REDEFMACRO: t/t_pp_dupdef.v:\d+: Redefining existing define: DUPP, with different value: .*
|
||||
%Warning-REDEFMACRO: t/t_pp_dupdef.v:\d+: Previous definition is here, with value: .*
|
||||
%Error: Exiting due to.*',
|
||||
) if $Last_Self->{v3};
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
v_flags2 => ['-v', 't/t_pp_lib_library.v'],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2008 by Wilson Snyder.
|
||||
|
||||
`include "t_pp_lib_inc.v"
|
||||
module t();
|
||||
wire [`WIDTH-1:0] a;
|
||||
library_cell n1(a);
|
||||
endmodule
|
||||
@@ -0,0 +1,7 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2008 by Wilson Snyder.
|
||||
|
||||
`define WIDTH 10
|
||||
@@ -0,0 +1,13 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2008 by Wilson Snyder.
|
||||
|
||||
module library_cell(a);
|
||||
input [`WIDTH-1:0] a;
|
||||
initial begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
At file t/t_preproc_inc2.v line 4
|
||||
|
||||
|
||||
|
||||
`line 6 "t/t_preproc_inc2.v" 0
|
||||
`line 1 "t/t_preproc_inc3.v" 1
|
||||
`line 2 "inc3_a_filename_from_line_directive" 0
|
||||
@@ -41,7 +41,7 @@ At file t/t_preproc_inc2.v line 4
|
||||
|
||||
`line 18 "inc3_a_filename_from_line_directive" 2
|
||||
`line 6 "t/t_preproc_inc2.v" 0
|
||||
|
||||
|
||||
`line 7 "t/t_preproc_inc2.v" 2
|
||||
`line 9 "t/t_preproc.v" 0
|
||||
|
||||
@@ -78,8 +78,8 @@ text.
|
||||
|
||||
|
||||
|
||||
foo bar
|
||||
foobar2
|
||||
foo bar
|
||||
foobar2
|
||||
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ text.
|
||||
|
||||
|
||||
|
||||
first part second part third part
|
||||
first part second part third part
|
||||
Line_Preproc_Check 49
|
||||
|
||||
|
||||
@@ -100,37 +100,46 @@ Line_Preproc_Check 49
|
||||
|
||||
|
||||
|
||||
deep deep
|
||||
deep deep
|
||||
|
||||
|
||||
|
||||
"Inside: `nosubst"
|
||||
"`nosubst"
|
||||
"`nosubst"
|
||||
|
||||
|
||||
x y LLZZ x y
|
||||
p q LLZZ p q r s LLZZ r s LLZZ p q LLZZ p q r s LLZZ r s
|
||||
x y LLZZ x y
|
||||
p q LLZZ p q r s LLZZ r s LLZZ p q LLZZ p q r s LLZZ r s
|
||||
|
||||
|
||||
|
||||
firstline comma","line LLZZ firstline comma","line
|
||||
firstline comma","line LLZZ firstline comma","line
|
||||
|
||||
|
||||
x y LLZZ "a" y
|
||||
x y LLZZ "a" y
|
||||
|
||||
|
||||
(a,b) (a,b)
|
||||
(a,b)(a,b)
|
||||
|
||||
|
||||
$display( "left side: \" right side\"" )
|
||||
$display("left side: \"right side\"")
|
||||
|
||||
|
||||
bar_suffix
|
||||
bar_suffix
|
||||
|
||||
|
||||
|
||||
$c("Zap(\"",bug1,"\");"); ;
|
||||
$c("Zap(\"","bug2","\");"); ;
|
||||
$c("Zap(\"",bug1,"\");");;
|
||||
$c("Zap(\"","bug2","\");");;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
wire tmp_d1 = d1; wire tmp_o1 = tmp_d1 + 1; assign o1 = tmp_o1 ;
|
||||
wire tmp_d2 = d2 ; wire tmp_o2 = tmp_d2 + 1; assign o2 = tmp_o2 ;
|
||||
|
||||
|
||||
|
||||
@@ -139,7 +148,7 @@ $display( "left side: \" right side\"" )
|
||||
|
||||
|
||||
|
||||
`line 95 "t/t_preproc.v" 0
|
||||
`line 104 "t/t_preproc.v" 0
|
||||
|
||||
Line_Preproc_Check 96
|
||||
`line 97 "t/t_preproc.v" 2
|
||||
Line_Preproc_Check 105
|
||||
`line 106 "t/t_preproc.v" 2
|
||||
|
||||
@@ -86,6 +86,15 @@ $display(`msg(left side, right side))
|
||||
`zap(bug1);
|
||||
`zap("bug2");
|
||||
|
||||
// rt.cpan.org bug34429
|
||||
`define ADD_UP(a,c) \
|
||||
wire tmp_``a = a; \
|
||||
wire tmp_``c = tmp_``a + 1; \
|
||||
assign c = tmp_``c ;
|
||||
|
||||
`ADD_UP(d1,o1) // expansion is OK
|
||||
`ADD_UP( d2 , o2 ) // expansion is bad
|
||||
|
||||
//===========================================================================
|
||||
// Ifdef
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ Hello in t_preproc_psl.v
|
||||
|
||||
|
||||
|
||||
psl assert always cyc !=10;
|
||||
psl assert always cyc!=10;
|
||||
|
||||
|
||||
`psl
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# $Id:$
|
||||
# $Id$
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
@@ -10,7 +10,8 @@ if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
compile (
|
||||
fails=>1,
|
||||
expect=>
|
||||
'%Error: t/t_select_bad_msb.v:\d+: Unsupported: MSB < LSB of bit extract.*
|
||||
'%Error: t/t_select_bad_msb.v:\d+: Unsupported: MSB < LSB of bit range: 0<22
|
||||
%Error: t/t_select_bad_msb.v:\d+: Unsupported: MSB < LSB of bit extract: 1<4
|
||||
%Error: Exiting due to.*',
|
||||
) if $Last_Self->{v3};
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ module t (clk);
|
||||
|
||||
reg [43:0] mi;
|
||||
reg [3:0] sel2;
|
||||
reg [0:22] backwd;
|
||||
|
||||
always @ (posedge clk) begin
|
||||
mi = 44'h123;
|
||||
|
||||
Reference in New Issue
Block a user