Compare commits

...
19 Commits
Author SHA1 Message Date
Wilson Snyder 7c3c2af90b Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1006 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-23 13:58:27 +00:00
Wilson Snyder 6dca9b4ba4 Add graph dfa complementing; not used yet.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1005 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-23 13:56:06 +00:00
Wilson Snyder ede37bb9d8 Allow assigns to create implicit wires
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1004 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-20 01:40:22 +00:00
Wilson Snyder 4a1729eaab Allow __ in cell names by quoting them in C.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1003 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-20 01:16:33 +00:00
Wilson Snyder b1565f5b89 Add --error-limit option
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1002 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-20 00:14:26 +00:00
Wilson Snyder 4fb8dcfd4e Convert re-defining macro error to warning.
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1001 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-19 15:05:08 +00:00
Wilson Snyder 16d1f2b835 Allow multiple .v files on command line. [Stefan Thiede]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@1000 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-19 14:22:05 +00:00
Wilson Snyder 73594e5aa5 Fix definitions in main file.v, referenced in library. [Stefan Thiede]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@999 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-19 00:44:54 +00:00
Wilson Snyder c0a365bd34 With --enable-defenv, support for hard-coding VERILATOR_ROOT etc in the executables
git-svn-id: file://localhost/svn/verilator/trunk/verilator@998 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-18 20:26:37 +00:00
Wilson Snyder 45940ff820 Move most env vars from wrapper to verilator_bin, and wrap in accessor
functions.  The functionallity should be mostly the same as before, except
allow verilator_bin to be in the search-path and VERILATOR_ROOT not set.


git-svn-id: file://localhost/svn/verilator/trunk/verilator@997 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-18 15:21:13 +00:00
Wilson Snyder d545ae242c Fix assignments to inputs inside functions/tasks. [Patricio Kaplan]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@996 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-18 12:41:59 +00:00
Wilson Snyder e862aaf2e1 Fix genvar to be signed, so "< 0" works properly. [Niranjan Prabhu]
git-svn-id: file://localhost/svn/verilator/trunk/verilator@995 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-03-17 20:58:43 +00:00
Wilson Snyder 30c3540086 Fix compile error in some oses
git-svn-id: file://localhost/svn/verilator/trunk/verilator@992 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-02-25 13:55:06 +00:00
Wilson Snyder 663a084ca4 Version bump
git-svn-id: file://localhost/svn/verilator/trunk/verilator@989 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-02-20 16:55:43 +00:00
Wilson Snyder b4d9ccd9af Fix assignments of {a,b,c} = {c,b,a}
git-svn-id: file://localhost/svn/verilator/trunk/verilator@988 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-02-20 16:54:41 +00:00
Wilson Snyder 98fff6a4ce Fix parsing of always @(*)
git-svn-id: file://localhost/svn/verilator/trunk/verilator@987 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-02-14 02:08:10 +00:00
Wilson Snyder 4977a5e1d9 Fix parse error on output reg signed
git-svn-id: file://localhost/svn/verilator/trunk/verilator@986 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-02-08 18:38:47 +00:00
Wilson Snyder e4297486ef Avoid creating obj_dir with --lint-only
git-svn-id: file://localhost/svn/verilator/trunk/verilator@985 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-01-31 14:49:27 +00:00
Wilson Snyder ad591767c9 Make obj_dir only when needed, and use OS calls rather than system to clean up
git-svn-id: file://localhost/svn/verilator/trunk/verilator@984 77ca24e4-aefa-0310-84f0-b9a241c72d87
2008-01-31 13:50:06 +00:00
55 changed files with 1348 additions and 210 deletions
+35
View File
@@ -3,6 +3,41 @@ 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.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]
**** Fix Perl warning with --lint-only. [by Ding Xiaoliang]
**** Avoid creating obj_dir with --lint-only. [Ding Xiaoliang]
**** Fix parsing of always @(*). [Patricio Kaplan]
* Verilator 3.656 2008/01/18
**** Wide VL_CONST_W_#X functions are now made automatically. [Bernard Deadman]
+18 -5
View File
@@ -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,31 @@ 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
VL_INST_DATA_FILES = verilator.1
install: all_nomsg installbin installman installdata install-msg
install-here: installman ftp
@@ -263,6 +275,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 \
+4
View File
@@ -52,6 +52,10 @@ Usability:
Better reporting of unopt problems, including what lines of code
Report more errors (all of them?) before exiting [Eugene Weber]
Internal Code:
Eliminate the AstNUser* passed to all visitors; its only needed in V3Width,
and removing it will speed up and simplify all the other code.
Performance:
Constant propagation
Extra cleaning AND: 1 & ((VARREF >> 1) | ((&VARREF >> 1) & VARREF))
+67 -70
View File
@@ -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,33 +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;},
#"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()
@@ -123,7 +84,6 @@ run ($vcmd);
#----------------------------------------------------------------------
sub usage {
bin_version();
print '$Revision$$Date$ ', "\n";
pod2usage(-exitstatus=>2, -verbose=>2);
}
@@ -134,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;
}
@@ -165,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";
@@ -234,6 +190,7 @@ 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.
@@ -392,6 +349,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
@@ -434,7 +396,7 @@ to gcc -MP option.
=item --Mdir I<directory>
Specifies the name of the Make object directory. All generated files will
be placed in this directory.
be placed in this directory. If not specified, "obj_dir" is used.
=item --mod-prefix I<topname>
@@ -489,8 +451,8 @@ 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. Defaults to the name of the first
Verilog file passed on the command line.
=item --profile-cfuncs
@@ -871,14 +833,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
@@ -888,7 +852,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
@@ -904,7 +870,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
@@ -1733,6 +1701,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
@@ -1943,11 +1928,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)?
@@ -2030,15 +2018,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
+4
View File
@@ -9,6 +9,10 @@ AC_INIT(src/Verilator.cpp)
AC_CONFIG_HEADER(src/config_build.h)
dnl Special Substitutions
AC_ARG_ENABLE(defenv,
[AS_HELP_STRING([--enable-defenv], [hardcode default environment variables])],
CFG_WITH_DEFENV=1,)
AC_SUBST(CFG_WITH_DEFENV)
dnl Checks for programs.
CXX=g++
+6
View File
@@ -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.
+21
View File
@@ -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:
ifneq ($(CFG_WITH_DEFENV),)
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
+17
View File
@@ -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);
}
+1
View File
@@ -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; }
+115 -11
View File
@@ -39,11 +39,63 @@
#include "V3Width.h"
#include "V3Signed.h"
//######################################################################
// Utilities
class ConstVarMarkVisitor : public AstNVisitor {
// NODE STATE
// AstVar::userp -> bool, Var marked, 0=not set yet
private:
// VISITORS
virtual void visit(AstVarRef* nodep, AstNUser*) {
if (nodep->varp()) nodep->varp()->user(1);
}
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
public:
// CONSTUCTORS
ConstVarMarkVisitor(AstNode* nodep) {
AstNode::userClearTree();
nodep->iterateAndNext(*this, NULL);
}
virtual ~ConstVarMarkVisitor() {}
};
class ConstVarFindVisitor : public AstNVisitor {
// NODE STATE
// AstVar::userp -> bool, input from ConstVarMarkVisitor
// MEMBERS
bool m_found;
private:
// VISITORS
virtual void visit(AstVarRef* nodep, AstNUser*) {
if (nodep->varp() && nodep->varp()->user()) m_found = true;
}
virtual void visit(AstNode* nodep, AstNUser*) {
nodep->iterateChildren(*this);
}
public:
// CONSTUCTORS
ConstVarFindVisitor(AstNode* nodep) {
m_found = false;
nodep->iterateAndNext(*this, NULL);
}
virtual ~ConstVarFindVisitor() {}
// METHODS
bool found() const { return m_found; }
};
//######################################################################
// Const state, as a visitor of each AstNode
class ConstVisitor : public AstNVisitor {
private:
// NODE STATE
// ** only when m_warn is set. If state is needed other times,
// ** must track down everywhere V3Const is called and make sure no overlaps.
// AstVar::userp -> Used by ConstVarMarkVisitor/ConstVarFindVisitor
// STATE
bool m_params; // If true, propogate parameterized and true numbers only
bool m_required; // If true, must become a constant
@@ -494,10 +546,26 @@ private:
}
}
else if (!m_cpp && nodep->lhsp()->castConcat()) {
UINFO(4," ASSI "<<nodep<<endl);
bool need_temp = false;
if (m_warn && !nodep->castAssignDly()) { // Is same var on LHS and RHS?
ConstVarMarkVisitor mark(nodep->lhsp());
ConstVarFindVisitor find(nodep->rhsp());
if (find.found()) need_temp = true;
}
if (need_temp) {
// The first time we constify, there may be the same variable on the LHS
// and RHS. In that case, we must use temporaries, or {a,b}={b,a} will break.
UINFO(4," ASSITEMP "<<nodep<<endl);
// ASSIGN(CONCAT(lc1,lc2),rhs) -> ASSIGN(temp1,SEL(rhs,{size})),
// ASSIGN(temp2,SEL(newrhs,{size}))
// ASSIGN(lc1,temp1),
// ASSIGN(lc2,temp2)
} else {
UINFO(4," ASSI "<<nodep<<endl);
// ASSIGN(CONCAT(lc1,lc2),rhs) -> ASSIGN(lc1,SEL(rhs,{size})),
// ASSIGN(lc2,SEL(newrhs,{size}))
}
if (debug()>=9) nodep->dumpTree(cout," Ass_old: ");
// ASSIGN(CONCAT(lc1,lc2),rhs) -> ASSIGN(lc1,SEL(rhs,{size})),
// ASSIGN(lc2,SEL(newrhs,{size}))
// Unlink the stuff
AstNode* lc1p = nodep->lhsp()->castConcat()->lhsp()->unlinkFrBack();
AstNode* lc2p = nodep->lhsp()->castConcat()->rhsp()->unlinkFrBack();
@@ -517,14 +585,50 @@ private:
sel2p->width(msb2-lsb2+1,msb2-lsb2+1);
// Make new assigns of same flavor as old one
//*** Not cloneTree; just one node.
AstNodeAssign* asn1p=nodep->cloneType(lc1p, sel1p)->castNodeAssign();
AstNodeAssign* asn2p=nodep->cloneType(lc2p, sel2p)->castNodeAssign();
asn1p->width(msb1-lsb1+1,msb1-lsb1+1);
asn2p->width(msb2-lsb2+1,msb2-lsb2+1);
nodep->addNextHere(asn1p);
nodep->addNextHere(asn2p);
if (debug()>=9) asn1p->dumpTree(cout," _new: ");
if (debug()>=9) asn2p->dumpTree(cout," _new: ");
AstNode* newp = NULL;
if (!need_temp) {
AstNodeAssign* asn1ap=nodep->cloneType(lc1p, sel1p)->castNodeAssign();
AstNodeAssign* asn2ap=nodep->cloneType(lc2p, sel2p)->castNodeAssign();
asn1ap->width(msb1-lsb1+1,msb1-lsb1+1);
asn2ap->width(msb2-lsb2+1,msb2-lsb2+1);
newp = newp->addNext(asn1ap);
newp = newp->addNext(asn2ap);
} else {
if (!m_modp) nodep->v3fatalSrc("Not under module");
// We could create just one temp variable, but we'll get better optimization
// if we make one per term.
string name1 = ((string)"__Vconcswap__"+cvtToStr(m_modp->varNumGetInc()));
string name2 = ((string)"__Vconcswap__"+cvtToStr(m_modp->varNumGetInc()));
AstVar* temp1p = new AstVar(sel1p->fileline(), AstVarType::BLOCKTEMP, name1,
new AstRange(sel1p->fileline(), msb1-lsb1, 0));
AstVar* temp2p = new AstVar(sel2p->fileline(), AstVarType::BLOCKTEMP, name2,
new AstRange(sel2p->fileline(), msb2-lsb2, 0));
m_modp->addStmtp(temp1p);
m_modp->addStmtp(temp2p);
AstNodeAssign* asn1ap=nodep->cloneType
(new AstVarRef(sel1p->fileline(), temp1p, true),
sel1p)->castNodeAssign();
AstNodeAssign* asn2ap=nodep->cloneType
(new AstVarRef(sel2p->fileline(), temp2p, true),
sel2p)->castNodeAssign();
AstNodeAssign* asn1bp=nodep->cloneType
(lc1p, new AstVarRef(sel1p->fileline(), temp1p, false))
->castNodeAssign();
AstNodeAssign* asn2bp=nodep->cloneType
(lc2p, new AstVarRef(sel2p->fileline(), temp2p, false))
->castNodeAssign();
asn1ap->width(msb1-lsb1+1,msb1-lsb1+1);
asn1bp->width(msb1-lsb1+1,msb1-lsb1+1);
asn2ap->width(msb2-lsb2+1,msb2-lsb2+1);
asn2bp->width(msb2-lsb2+1,msb2-lsb2+1);
// This order matters
newp = newp->addNext(asn1ap);
newp = newp->addNext(asn2ap);
newp = newp->addNext(asn1bp);
newp = newp->addNext(asn2bp);
}
if (debug()>=9) newp->dumpTreeAndNext(cout," _new: ");
nodep->addNextHere(newp);
// Cleanup
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
conp->deleteTree(); conp=NULL;
+4 -4
View File
@@ -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
View File
@@ -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);
}
}
+2 -1
View File
@@ -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
@@ -78,7 +79,7 @@ public:
"BLKANDNBLK",
"CASEINCOMPLETE", "CASEOVERLAP", "CASEX", "CMPCONST",
"COMBDLY", "STMTDLY", "GENCLK", "IMPLICIT", "IMPURE",
"MULTIDRIVEN",
"MULTIDRIVEN", "REDEFMACRO",
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED",
"VARHIDDEN", "WIDTH",
" MAX"
+9
View File
@@ -23,6 +23,7 @@
#include "verilatedos.h"
#include <stdarg.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <iomanip>
#include <memory>
@@ -232,6 +233,14 @@ bool V3File::checkTimes(const string& filename, const string& cmdline) {
return dependImp.checkTimes(filename, cmdline);
}
void V3File::createMakeDir() {
static bool created = false;
if (!created) {
created = true;
mkdir(v3Global.opt.makeDir().c_str(), 0777);
}
}
//######################################################################
// V3OutFile: A class for printing to a file, with automatic indentation of C++ code.
+6
View File
@@ -46,6 +46,7 @@ public:
return new_ofstream_nodepend (filename, append);
}
static ofstream* new_ofstream_nodepend(const string& filename, bool append=false) {
if (filename != "/dev/null") createMakeDir();
if (append) {
return new ofstream(filename.c_str(), ios::app);
} else {
@@ -53,15 +54,20 @@ public:
}
}
static FILE* new_fopen_w(const string& filename) {
if (filename != "/dev/null") createMakeDir();
addTgtDepend(filename);
return fopen(filename.c_str(),"w");
}
// Dependencies
static void addSrcDepend(const string& filename);
static void addTgtDepend(const string& filename);
static void writeDepend(const string& filename);
static void writeTimes(const string& filename, const string& cmdline);
static bool checkTimes(const string& filename, const string& cmdline);
// Directory utilities
static void createMakeDir();
};
//============================================================================
+94
View File
@@ -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
View File
@@ -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; }
};
+6
View File
@@ -309,6 +309,12 @@ public:
gp->nfaToDfa();
dump();
gp->dfaReduce();
dump();
gp->dfaComplement();
dump();
gp->dfaReduce();
dump();
}
};
+4 -4
View File
@@ -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);
}
-3
View File
@@ -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);
+10 -1
View File
@@ -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
@@ -160,6 +168,7 @@ public:
// CONSTUCTORS
LinkLValueVisitor(AstNetlist* rootp) {
m_setRefLvalue = false;
m_ftaskp = NULL;
rootp->accept(*this);
}
virtual ~LinkLValueVisitor() {}
+171 -4
View File
@@ -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);
}
@@ -146,6 +154,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);
@@ -226,6 +242,153 @@ string V3Options::filePath (FileLine* fl, const string& modname, const string& e
return "";
}
void V3Options::unlinkRegexp(const string& dir, const string& regexp) {
if (DIR* dirp = opendir(dir.c_str())) {
while (struct dirent* direntp = readdir(dirp)) {
if (wildmatch(direntp->d_name, regexp.c_str())) {
string fullname = dir + "/" + string(direntp->d_name);
unlink (fullname.c_str());
}
}
closedir(dirp);
}
}
//######################################################################
// 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++) {
if (*p!='*') {
if (((*s)!=(*p)) && *p != '?')
return false;
}
else {
// Trailing star matches everything.
if (!*++p) return true;
while (wildmatch(s, p) == false)
if (*++s == '\0')
return false;
return true;
}
}
return(*s == '\0' || *s == '[');
}
bool V3Options::wildmatch(const char* s, const char* p) {
for ( ; *p; s++, p++) {
if (*p!='*') {
if (((*s)!=(*p)) && *p != '?')
return false;
}
else {
// Trailing star matches everything.
if (!*++p) return true;
while (wildmatchi(s, p) == false)
if (*++s == '\0')
return false;
return true;
}
}
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
@@ -261,12 +424,12 @@ 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()=="") m_prefix = string("V")+filenameNonExt(*(vFiles().begin()));
if (modPrefix()=="") m_modPrefix = prefix();
// Find files in makedir
@@ -343,6 +506,10 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
cout <<endl;
exit(0);
}
else if ( !strcmp (sw, "-error-limit") ) {
shift;
m_inlineMult = atoi(argv[i]);
}
else if ( !strcmp (sw, "-inline-mult") ) {
shift;
m_inlineMult = atoi(argv[i]);
@@ -513,8 +680,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;
}
@@ -608,6 +774,7 @@ V3Options::V3Options() {
m_traceDups = false;
m_underlineZero = false;
m_errorLimit = 50;
m_inlineMult = 2000;
m_outputSplit = 0;
m_outputSplitCFuncs = 0;
+25 -11
View File
@@ -41,8 +41,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 +71,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,7 +84,6 @@ 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
@@ -115,6 +116,8 @@ class V3Options {
void optimize(int level);
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
@@ -125,9 +128,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; }
@@ -158,6 +161,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; }
@@ -174,6 +178,7 @@ class V3Options {
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; }
// ACCESSORS (optimization options)
@@ -203,23 +208,32 @@ class V3Options {
void parseOptsList (FileLine* fl, int argc, char** argv);
void parseOptsFile (FileLine* fl, const string& filename);
// 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);
static string filenameNonDir (const string& filename); ///< Return non-directory part of filename
static string filenameNonExt (const string& filename); ///< Return non-extensioned (no .) part of filename
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 string getenvStr(const char* envvar, const char* defaultValue) {
if (const char* envvalue = getenv(envvar)) {
return envvalue;
} else {
return defaultValue;
}
}
static void unlinkRegexp(const string& dir, const string& regexp);
// 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);
};
+2 -2
View File
@@ -207,8 +207,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);
}
+5 -27
View File
@@ -33,6 +33,7 @@
#include "V3PreShell.h"
#include "V3PreProc.h"
#include "V3File.h"
#include "V3Read.h"
//######################################################################
@@ -64,38 +65,15 @@ protected:
}
}
void preproc (FileLine* fl, const string& modname, const string& vppFilename) {
void preproc (FileLine* fl, const string& modname, V3Read* readerp) {
// Preprocess the given module, putting output in vppFilename
unlink(vppFilename.c_str());
UINFONL(1," Preprocessing "<<modname<<endl);
// Open
ofstream* ofp = NULL;
ostream* osp;
if (v3Global.opt.preprocOnly()) {
osp = &cout;
} else if (!v3Global.opt.keepTempFiles()) { // Must match unlink rule in V3Read.cpp
osp = ofp = V3File::new_ofstream_nodepend(vppFilename);
} else {
osp = ofp = V3File::new_ofstream(vppFilename);
}
if (osp->fail()) {
fl->v3error("Cannot write preprocessor output: "+vppFilename);
return;
}
// Preprocess
preprocOpen(fl, modname, "Cannot find file containing module: ");
while (!s_preprocp->isEof()) {
string line = s_preprocp->getline();
*osp << line;
}
// Close
if (ofp) {
ofp->close();
delete ofp;
osp = ofp = NULL;
readerp->ppPushText(line);
}
}
@@ -129,8 +107,8 @@ V3PreProc* V3PreShellImp::s_preprocp = NULL;
void V3PreShell::boot(char** env) {
V3PreShellImp::s_preImp.boot(env);
}
void V3PreShell::preproc(FileLine* fl, const string& modname, const string& vppFilename) {
V3PreShellImp::s_preImp.preproc(fl, modname, vppFilename);
void V3PreShell::preproc(FileLine* fl, const string& modname, V3Read* readerp) {
V3PreShellImp::s_preImp.preproc(fl, modname, readerp);
}
void V3PreShell::preprocInclude(FileLine* fl, const string& modname) {
V3PreShellImp::s_preImp.preprocInclude(fl, modname);
+3 -1
View File
@@ -26,13 +26,15 @@
#include "verilatedos.h"
#include "V3Error.h"
class V3Read;
//============================================================================
class V3PreShell {
// Static class for calling preprocessor
public:
static void boot(char** env);
static void preproc(FileLine* fileline, const string& module, const string& vppFilename);
static void preproc(FileLine* fileline, const string& module, V3Read* readerp);
static void preprocInclude(FileLine* fileline, const string& module);
static string dependFiles() { return ""; } // Perl only
static void define(const string& name, const string& value);
+55 -22
View File
@@ -57,7 +57,7 @@ extern int yydebug;
class V3Lexer : public V3LexerBase {
public:
// CONSTRUCTORS
V3Lexer(std::istream* arg_yyin) : V3LexerBase(arg_yyin) {}
V3Lexer() : V3LexerBase(NULL) {}
~V3Lexer() {}
// METHODS
void stateExitPsl() {
@@ -91,6 +91,29 @@ V3Read::~V3Read() {
parserClear();
}
int V3Read::ppInputToLex(char* buf, int max_size) {
int got = 0;
while (got < max_size // Haven't got enough
&& !m_ppBuffers.empty()) { // And something buffered
string front = m_ppBuffers.front(); m_ppBuffers.pop_front();
int len = front.length();
if (len > (max_size-got)) { // Front string too big
string remainder = front.substr(max_size-got);
front = front.substr(0, max_size-got);
m_ppBuffers.push_front(remainder); // Put back remainder for next time
len = (max_size-got);
}
strncpy(buf+got, front.c_str(), len);
got += len;
}
if (debug()>=9) {
string out = string(buf,got);
cout<<" inputToLex got="<<got<<" '"<<out<<"'"<<endl;
}
// Note returns 0 at EOF
return got;
}
void V3Read::readFile(FileLine* fileline, const string& modfilename, bool inLibrary) {
string modname = V3Options::filenameNonExt(modfilename);
@@ -98,42 +121,52 @@ void V3Read::readFile(FileLine* fileline, const string& modfilename, bool inLibr
m_fileline = new FileLine(fileline);
m_inLibrary = inLibrary;
// Read it
string vppfilename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"_"+modname+".vpp";
V3PreShell::preproc(fileline, modfilename, vppfilename);
// Preprocess into m_ppBuffer
V3PreShell::preproc(fileline, modfilename, this);
if (!v3Global.opt.preprocOnly()) {
lexFile (vppfilename, modfilename);
if (v3Global.opt.preprocOnly() || v3Global.opt.keepTempFiles()) {
// Create output file with all the preprocessor output we buffered up
string vppfilename = v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"_"+modname+".vpp";
ofstream* ofp = NULL;
ostream* osp;
if (v3Global.opt.preprocOnly()) {
osp = &cout;
} else {
osp = ofp = V3File::new_ofstream(vppfilename);
}
if (osp->fail()) {
fileline->v3error("Cannot write preprocessor output: "+vppfilename);
return;
} else {
for (deque<string>::iterator it = m_ppBuffers.begin(); it!=m_ppBuffers.end(); ++it) {
*osp << *it;
}
if (ofp) {
ofp->close();
delete ofp; ofp = NULL;
}
}
}
if (!v3Global.opt.keepTempFiles()) { // Must match new_ofstream_nodepend rule in V3PreShell.cpp
unlink (vppfilename.c_str());
// Parse it
if (!v3Global.opt.preprocOnly()) {
lexFile (modfilename);
}
}
void V3Read::lexFile(const string& vppfilename, const string& modname) {
// Open the preprocess output
// Don't track a input dependency, as we created the file ourselves
ifstream* fsp = V3File::new_ifstream_nodepend(vppfilename);
if (fsp->fail()) {
m_fileline->v3fatal("Module "<<modname<<" isn't found, or preprocessor errors in "<<vppfilename);
}
void V3Read::lexFile(const string& modname) {
// Prepare for lexing
UINFO(3,"Lexing "<<vppfilename<<endl);
UINFO(3,"Lexing "<<modname<<endl);
V3Read::s_readp = this;
V3Read::fileline()->warnResetDefault(); // Reenable warnings on each file
if (m_lexerp) delete m_lexerp; // Restart from clean slate.
m_lexerp = new V3Lexer(fsp);
m_lexerp = new V3Lexer();
// if (debug()) { m_lexerp->set_debug(~0); }
// if (debug()) yydebug = 1;
UINFO(4,"Lexing Done "<<vppfilename<<endl);
UINFO(4,"Lexing Done "<<modname<<endl);
// Lex it
if (yyparse()) v3fatal("Cannot continue\n");
// Cleanup
fsp->close(); delete fsp; fsp = NULL;
}
//======================================================================
+7 -1
View File
@@ -45,6 +45,7 @@ class V3Read {
deque<string*> m_stringps; // Created strings for later cleanup
deque<V3Number*> m_numberps; // Created numbers for later cleanup
deque<FileLine> m_lintState; // Current lint state for save/restore
deque<string> m_ppBuffers; // Preprocessor->lex buffer of characters to process
//int debug() { return 9; }
protected:
@@ -52,6 +53,7 @@ protected:
friend class V3Lexer;
friend class V3LexerBase;
friend class FileLine;
friend class V3PreShellImp;
int yylexThis();
static bool optPsl();
static void ppline (const char* text);
@@ -64,6 +66,9 @@ protected:
static bool popBeginKeywords() { if (s_readp->m_inBeginKwd) { s_readp->m_inBeginKwd--; return true; } else return false; }
static int lastVerilogState() { return s_readp->m_lastVerilogState; }
void ppPushText(const string& text) { m_ppBuffers.push_back(text); }
int ppInputToLex(char* buf, int max_size);
public: // But for internal use only
static string* newString(const string& text) {
// Allocate a string, remembering it so we can reclaim storage at lex end
@@ -100,6 +105,7 @@ public: // But for internal use only
static void statePushVlg(); // Parser -> lexer communication
static void statePop(); // Parser -> lexer communication
static int stateVerilogRecent(); // Parser -> lexer communication
static int flexPpInputToLex(char* buf, int max_size) { return s_readp->ppInputToLex(buf,max_size); }
public:
// CREATORS
@@ -118,7 +124,7 @@ public:
void readFile(FileLine* fileline, const string& modname, bool inLibrary);
private:
void lexFile(const string& vppfilename, const string& modname);
void lexFile(const string& modname);
};
#endif // Guard
+17 -9
View File
@@ -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();
}
@@ -464,6 +471,7 @@ void process () {
V3EmitC::emitcSyms();
V3EmitC::emitcTrace();
}
// Unfortunately we have some lint checks in emitc.
V3EmitC::emitc();
// Statistics
@@ -502,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();
@@ -521,13 +533,9 @@ int main(int argc, char** argv, char** env) {
//--FRONTEND------------------
// Cleanup
mkdir(v3Global.opt.makeDir().c_str(), 0777);
string cleanFilename = "/bin/rm -rf "+v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"_*.tree";
system(cleanFilename.c_str());
cleanFilename = "/bin/rm -rf "+v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"_*.dot";
system(cleanFilename.c_str());
cleanFilename = "/bin/rm -rf "+v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+"_*.txt";
system(cleanFilename.c_str());
V3Options::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.tree");
V3Options::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.dot");
V3Options::unlinkRegexp(v3Global.opt.makeDir(), v3Global.opt.prefix()+"_*.txt");
// Read first filename
v3Global.readFiles();
+21 -1
View File
@@ -24,7 +24,7 @@
//**********************************************************************
//**** Version and host name
#define DTVERSION "Verilator 3.656 2008/01/18"
#define DTVERSION "Verilator 3.660 2008/03/23"
//**********************************************************************
//**** 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
+11 -4
View File
@@ -33,6 +33,9 @@ extern void yyerrorf(const char* format, ...);
#define STATE_VERILOG_RECENT S05 // State name for most recent Verilog Version
#define YY_INPUT(buf,result,max_size) \
result = V3Read::flexPpInputToLex(buf,max_size);
//======================================================================
#define NEXTLINE() {V3Read::incLineno();}
@@ -631,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;
}
@@ -698,7 +705,7 @@ escid \\[^ \t\f\r\n]+
/************************************************************************/
/* Attributes */
<V95,V01,V05,S05>{
"(*" { yymore(); yy_push_state(ATTRMODE); }
"(*"/{ws}*[^)] { yymore(); yy_push_state(ATTRMODE); } // Doesn't match (*)
}
/************************************************************************/
+11 -8
View File
@@ -526,15 +526,15 @@ regsigList: regsig { $$ = $1; }
| regsigList ',' regsig { $$ = $1;$1->addNext($3); }
;
portV2kDecl: varRESET varInput signingE v2kNetDeclE regrangeE portV2kSig { $$ = $6; }
| varRESET varInout signingE v2kNetDeclE regrangeE portV2kSig { $$ = $6; }
| varRESET varOutput signingE v2kVarDeclE regrangeE portV2kSig { $$ = $6; }
portV2kDecl: varRESET varInput v2kNetDeclE signingE regrangeE portV2kSig { $$ = $6; }
| varRESET varInout v2kNetDeclE signingE regrangeE portV2kSig { $$ = $6; }
| varRESET varOutput v2kVarDeclE signingE regrangeE portV2kSig { $$ = $6; }
;
// IEEE: port_declaration - plus ';'
portDecl: varRESET varInput signingE v2kVarDeclE regrangeE sigList ';' { $$ = $6; }
| varRESET varInout signingE v2kVarDeclE regrangeE sigList ';' { $$ = $6; }
| varRESET varOutput signingE v2kVarDeclE regrangeE sigList ';' { $$ = $6; }
portDecl: varRESET varInput v2kVarDeclE signingE regrangeE sigList ';' { $$ = $6; }
| varRESET varInout v2kVarDeclE signingE regrangeE sigList ';' { $$ = $6; }
| varRESET varOutput v2kVarDeclE signingE regrangeE sigList ';' { $$ = $6; }
;
varDecl: varRESET varReg signingE regrangeE regsigList ';' { $$ = $5; }
@@ -838,7 +838,7 @@ eventControlE: /* empty */ { $$ = NULL; }
// IEEE: event_control
eventControl: '@' '(' senList ')' { $$ = new AstSenTree($1,$3); }
| '@' senitemVar { $$ = new AstSenTree($1,$2); } /* For events only */
| '@' '(' '*' ')' { $$ = NULL; $2->v3error("Use @*. always @ (*) to be depreciated in Verilog 2005.\n"); }
| '@' '(' '*' ')' { $$ = NULL; } /* Verilog 2001 */
| '@' '*' { $$ = NULL; } /* Verilog 2001 */
;
@@ -1403,7 +1403,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);
+1
View File
@@ -39,6 +39,7 @@ endif
######################################################################
.PHONY: test
test:
$(PERL) driver.pl $(DRIVER_FLAGS) $(PRODUCTS)
+7 -2
View File
@@ -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;
+1 -1
View File
@@ -14,7 +14,7 @@
// please note it here, otherwise:**
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2007 by Wilson Snyder.
// without warranty, 2008 by Wilson Snyder.
module t (/*AUTOARG*/
// Inputs
+2 -2
View File
@@ -1,4 +1,4 @@
// $Id:$
// $Id$
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
@@ -14,7 +14,7 @@ module t (/*AUTOARG*/
reg [31:0] a, b, c;
always @ (/*AS*/a or b) begin
always @ (*) begin // Test Verilog 2001 (*)
// verilator lint_off COMBDLY
c <= a | b;
// verilator lint_on COMBDLY
+18
View File
@@ -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;
+56
View File
@@ -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
+18
View File
@@ -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;
+85
View File
@@ -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
+20
View File
@@ -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;
+16
View File
@@ -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;
+16
View File
@@ -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
+24
View File
@@ -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;
+12 -7
View File
@@ -15,21 +15,24 @@ module t (/*AUTOARG*/
reg [63:0] crc;
reg [63:0] sum;
reg [31:0] out1;
sub sub (.in1(crc[15:0]), .in2(crc[31:16]), .out1(out1));
wire [31:0] out1;
wire [31:0] out2;
sub sub (.in1(crc[15:0]), .in2(crc[31:16]), .out1(out1), .out2);
always @ (posedge clk) begin
//$write("[%0t] cyc==%0d crc=%x sum=%x out=%x\n",$time, cyc, crc, sum, out1);
`ifdef TEST_VERBOSE
$write("[%0t] cyc==%0d crc=%x sum=%x out=%x %x\n",$time, cyc, crc, sum, out1, out2);
`endif
cyc <= cyc + 1;
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
sum <= {sum[62:0], sum[63]^sum[2]^sum[0]} ^ {32'h0,out1};
sum <= {sum[62:0], sum[63]^sum[2]^sum[0]} ^ {out2,out1};
if (cyc==1) begin
// Setup
crc <= 64'h00000000_00000097;
sum <= 64'h0;
end
else if (cyc==90) begin
if (sum !== 64'hc1f743ad62c2c04d) $stop;
if (sum !== 64'he396068aba3898a2) $stop;
end
else if (cyc==91) begin
end
@@ -49,18 +52,20 @@ endmodule
module sub (/*AUTOARG*/
// Outputs
out1,
out1, out2,
// Inputs
in1, in2
);
input [15:0] in1;
input [15:0] in2;
output reg [31:0] out1;
output reg signed [31:0] out1;
output reg unsigned [31:0] out2;
always @* begin
// verilator lint_off WIDTH
out1 = $signed(in1) * $signed(in2);
out2 = $unsigned(in1) * $unsigned(in2);
// verilator lint_on WIDTH
end
+18
View File
@@ -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;
+165
View File
@@ -0,0 +1,165 @@
// $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*/
// Inputs
clk
);
input clk;
integer cyc=0;
reg [63:0] crc;
reg [63:0] sum;
// Take CRC data and apply to testblock inputs
wire [31:0] Operand1 = crc[31:0];
wire [15:0] Operand2 = crc[47:32];
wire Unsigned = crc[48];
reg rst;
parameter wl = 16;
/*AUTOWIRE*/
// Beginning of automatic wires (for undeclared instantiated-module outputs)
wire [wl-1:0] Quotient; // From test of Test.v
wire [wl-1:0] Remainder; // From test of Test.v
// End of automatics
Test test (/*AUTOINST*/
// Outputs
.Quotient (Quotient[wl-1:0]),
.Remainder (Remainder[wl-1:0]),
// Inputs
.Operand1 (Operand1[wl*2-1:0]),
.Operand2 (Operand2[wl-1:0]),
.clk (clk),
.rst (rst),
.Unsigned (Unsigned));
// Aggregate outputs into a single result vector
wire [63:0] result = {32'h0, Quotient, Remainder};
// What checksum will we end up with
`define EXPECTED_SUM 64'h98d41f89a8be5693
// Test loop
always @ (posedge clk) begin
`ifdef TEST_VERBOSE
$write("[%0t] cyc==%0d crc=%x result=%x it=%x\n",$time, cyc, crc, result, test.Iteration);
`endif
cyc <= cyc + 1;
if (cyc < 20 || test.Iteration==4'd15) begin
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
end
sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]};
if (cyc==0) begin
// Setup
crc <= 64'h5aef0c8d_d70a4497;
rst <= 1'b1;
end
else if (cyc<20) begin
sum <= 64'h0;
rst <= 1'b0;
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'h8dd70a44972ad809) $stop;
if (sum !== `EXPECTED_SUM) $stop;
$write("*-* All Finished *-*\n");
$finish;
end
end
endmodule
module Test(clk, rst, Operand1, Operand2, Unsigned, Quotient, Remainder);
parameter wl = 16;
input [wl*2-1:0] Operand1;
input [wl-1:0] Operand2;
input clk, rst, Unsigned;
output [wl-1:0] Quotient, Remainder;
reg Cy, Overflow, Sign1, Sign2, Zero, Negative;
reg [wl-1:0] ah,al,Quotient, Remainder;
reg [3:0] Iteration;
reg [wl-1:0] sub_quot,op;
reg ah_ext;
reg [1:0] a,b,c,d,e;
always @(posedge clk) begin
if (!rst) begin
{a,b,c,d,e} = Operand1[9:0];
{a,b,c,d,e} = {e,d,c,b,a};
if (a != Operand1[1:0]) $stop;
if (b != Operand1[3:2]) $stop;
if (c != Operand1[5:4]) $stop;
if (d != Operand1[7:6]) $stop;
if (e != Operand1[9:8]) $stop;
end
end
always @(posedge clk) begin
if (rst) begin
Iteration <= 0;
Quotient <= 0;
Remainder <= 0;
end
else begin
if (Iteration == 0) begin
{ah,al} = Operand1;
op = Operand2;
Cy = 0;
Overflow = 0;
Sign1 = (~Unsigned)&ah[wl-1];
Sign2 = (~Unsigned)&(ah[wl-1]^op[wl-1]);
if (Sign1) {ah,al} = -{ah,al};
end
`define BUG1
`ifdef BUG1
{ah_ext,ah,al} = {ah,al,Cy};
`else
ah_ext = ah[15];
ah[15:1] = ah[14:0];
ah[0] = al[15];
al[15:1] = al[14:0];
al[0] = Cy;
`endif
`ifdef TEST_VERBOSE
$display("%x %x %x %x %x %x %x %x %x",
Iteration, ah, al, Quotient, Remainder, Overflow, ah_ext, sub_quot, Cy);
`endif
{Cy,sub_quot} = (~Unsigned)&op[wl-1]? {ah_ext,ah}+op : {ah_ext,ah} - {1'b1,op};
if (Cy)
begin
{ah_ext,ah} = {1'b0,sub_quot};
end
if (Iteration != 15 )
begin
if (ah_ext) Overflow = 1;
end
else
begin
if (al[14] && ~Unsigned) Overflow = 1;
Quotient <= Sign2 ? -{al[14:0],Cy} : {al[14:0],Cy};
Remainder <= Sign1 ? -ah : ah;
if (Overflow)
begin
Quotient <= Sign2 ? 16'h8001 : {Unsigned,{15{1'b1}}};
Remainder <= Unsigned ? 16'hffff : 16'h8000;
Zero = 1;
Negative = 1;
end
end
Iteration <= Iteration + 1; // Count number of times this instruction is repeated
end
end
endmodule
+16
View File
@@ -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;
+17
View File
@@ -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
+26
View File
@@ -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;
+20
View File
@@ -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;
+11
View File
@@ -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
+7
View File
@@ -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
+13
View File
@@ -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
+2 -1
View File
@@ -8,7 +8,7 @@ if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
# General Public License or the Perl Artistic License.
compile (
v_flags2 => ["--lint-only"],
v_flags2 => ["--lint-only --Mdir obj_lint_only"],
fails=>1,
expect=>
'%Error: t/t_var_in_assign_bad.v:\d+: Assigning to input variable: value
@@ -16,5 +16,6 @@ compile (
%Error: Exiting due to.*',
) if $Last_Self->{v3};
(!-d "obj_lint_only") or $Last_Self->error("%Error: lint-only shouldn't make output directory");
ok(1);
1;