mirror of
https://github.com/verilator/verilator.git
synced 2026-10-03 00:23:35 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb072da81c | ||
|
|
38669d0a10 | ||
|
|
202a8bc3bb | ||
|
|
45e8ed6b49 | ||
|
|
96692e8a5b | ||
|
|
ecb08b0cf3 | ||
|
|
71bdfd9710 | ||
|
|
193dcf38f4 | ||
|
|
09091781cf | ||
|
|
023519c8f6 | ||
|
|
d60d0a60c7 | ||
|
|
8fe0c3dd84 | ||
|
|
85419f01a9 | ||
|
|
a199f4a849 | ||
|
|
290795a76b | ||
|
|
c2cf2bc0ba | ||
|
|
2224918730 | ||
|
|
c4e69daecd | ||
|
|
9162e68d82 | ||
|
|
08f736ae33 | ||
|
|
81092edab4 | ||
|
|
21b5a4e9e4 | ||
|
|
057928b079 | ||
|
|
4beaa45199 | ||
|
|
8f88fa45f1 | ||
|
|
13e8176884 |
@@ -3,12 +3,36 @@ 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.702 2009/03/28
|
||||
|
||||
*** Add --pins-bv option to use sc_bv for all ports. [Brian Small]
|
||||
|
||||
*** Add SYSTEMPERL_INCLUDE envvar to assist RPM builds. [Chitlesh Goorah]
|
||||
|
||||
**** Report errors when duplicate labels are used, bug72. [Vasu Kandadi]
|
||||
|
||||
**** Fix the SC_MODULE name() to not include __PVT__. [Bob Fredieu]
|
||||
|
||||
* Verilator 3.701 2009/02/26
|
||||
|
||||
** Support repeat and forever statements. [Jeremy Bennett]
|
||||
|
||||
*** Add --debugi-<srcfile> option, for internal debugging. [Dennis Muhlestein]
|
||||
|
||||
**** Fix compile issues with GCC 4.3, bug47. [Lane Brooks]
|
||||
|
||||
**** Fix VL_RANDom to better randomize bits. [Art Stamness]
|
||||
|
||||
**** Fix error messages to consistently go to stderr. [Jeremy Bennett]
|
||||
|
||||
**** Fix left associativity for ?: operators.
|
||||
|
||||
* Verilator 3.700 2009/01/08
|
||||
|
||||
** Add limited support for tristate inouts. Written by Lane Brooks.
|
||||
This allows common pad ring and tristate-mux structures to be
|
||||
Verilated. See the documentation for more information on supported
|
||||
constructs.
|
||||
** Add limited support for tristate inouts. Written by Lane Brooks,
|
||||
under support by Ubixum Inc. This allows common pad ring and
|
||||
tristate-mux structures to be Verilated. See the documentation for
|
||||
more information on supported constructs.
|
||||
|
||||
** Add --coverage_toggle for toggle coverage analysis.
|
||||
Running coverage now requires SystemPerl 1.301 or newer.
|
||||
|
||||
+52
-14
@@ -188,6 +188,8 @@ descriptions in the next sections for more information.
|
||||
-D<var>[=<value>] Set preprocessor define
|
||||
--debug Enable debugging
|
||||
--debug-check Enable debugging assertions
|
||||
--debugi <level> Enable debugging at a specified level
|
||||
--debugi-<srcfile> <level> Enable debugging a source file at a level
|
||||
--dump-tree Enable dumping .tree files
|
||||
-E Preprocess, but do not compile
|
||||
--error-limit <value> Abort after this number of errors
|
||||
@@ -210,6 +212,7 @@ descriptions in the next sections for more information.
|
||||
-O<optimization-letter> Selectable optimizations
|
||||
--output-split <bytes> Split .cpp files into pieces
|
||||
--output-split-cfuncs <statements> Split .ccp functions
|
||||
--pins-bv <bits> Specify types for top level ports
|
||||
--prefix <topname> Name of top level class
|
||||
--profile-cfuncs Name functions for profiling
|
||||
--private Debugging; see docs
|
||||
@@ -375,6 +378,12 @@ internal assertions, debugging messages, and intermediate form dump files.
|
||||
Rarely needed. Enable internal debugging assertion checks, without
|
||||
changing debug verbosity. Enabled automatically when --debug specified.
|
||||
|
||||
=item --debugi <level>
|
||||
=item --debugi-<srcfile> <level>
|
||||
|
||||
Rarely needed - for developer use. Set internal debugging level globally
|
||||
or on the specified source file to the specified level.
|
||||
|
||||
=item --dump-tree
|
||||
|
||||
Rarely needed. Enable writing .tree debug files. This is enabled with
|
||||
@@ -451,9 +460,7 @@ the same as --prefix.
|
||||
|
||||
=item --no-pins64
|
||||
|
||||
Specifies SystemC outputs of 33-64 bits wide should use sc_bv's instead of
|
||||
uint64_t's. Uint64's are faster, but sc_bvs were the default until
|
||||
Verilator 3.671.
|
||||
Backward compatible alias for "--pins-bv 33".
|
||||
|
||||
=item --no-skip-identical
|
||||
|
||||
@@ -499,6 +506,17 @@ worse with decreasing split values. Note that this option is stronger than
|
||||
--output-split in the sense that --output-split will not split inside a
|
||||
function.
|
||||
|
||||
=item --pins64
|
||||
|
||||
Backward compatible alias for "--pins-bv 65". Note that's a 65, not a 64.
|
||||
|
||||
=item --pins-bv I<width>
|
||||
|
||||
Specifies SystemC outputs of greater than or equal to I<width> bits wide
|
||||
should use sc_bv's instead of uint32/uint64_t's. The default is "--pins-bv
|
||||
65". Versions before Verilator 3.671 defaulted to "--pins-bv 33". The
|
||||
more sc_bv is used, the worse for performance.
|
||||
|
||||
=item --prefix I<topname>
|
||||
|
||||
Specifies the name of the top level class and makefile. Defaults to V
|
||||
@@ -633,6 +651,12 @@ will call a function to determine the value, this allows randomization of
|
||||
all Xs to find reset bugs and is the slowest, but safest for finding reset
|
||||
bugs in code.
|
||||
|
||||
If using -x-assign unique, you may want to seed your random number
|
||||
generator such that each regression run gets a different randomization
|
||||
sequence. Use the system's srand48() or for Windows srand() function to do
|
||||
this. You'll probably also want to print any seeds selected, and code to
|
||||
enable rerunning with that same seed so you can reproduce bugs.
|
||||
|
||||
=back
|
||||
|
||||
=head1 VERILOG ARGUMENTS
|
||||
@@ -929,10 +953,18 @@ 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. If not
|
||||
Specifies the directory containing the SystemPerl distribution kit. This
|
||||
is used to find the SystemPerl library and include files. If not
|
||||
specified, it will come from a default optionally specified at configure
|
||||
time (before Verilator was compiled).
|
||||
time (before Verilator was compiled). See also SYSTEMPERL_INCLUDE.
|
||||
|
||||
=item SYSTEMPERL_INCLUDE
|
||||
|
||||
Specifies the directory containing the Verilog-Perl include .cpp files,
|
||||
from the src/ directory of the SystemPerl kit. If not specified, it will
|
||||
be computed from the SYSTEMPERL environment variable if it is set, and if
|
||||
SYSTEMPERL is not set SYSTEMPERL_INCLUDE will come from a default
|
||||
optionally specified at configure time (before Verilator was compiled).
|
||||
|
||||
=item VCS_HOME
|
||||
|
||||
@@ -1249,11 +1281,11 @@ The Verilog code returns to the last language mode specified with
|
||||
|
||||
=item /*verilator clock_enable*/
|
||||
|
||||
Experimental use only. Used after a signal declaration to indicate the
|
||||
signal is used to gate a clock, and the user takes responsibility for
|
||||
insuring there are no races related to it. (Typically by adding a latch,
|
||||
and running static timing analysis.) This will cause the clock gate to be
|
||||
ignored in the scheduling algorithm, improving performance.
|
||||
Used after a signal declaration to indicate the signal is used to gate a
|
||||
clock, and the user takes responsibility for insuring there are no races
|
||||
related to it. (Typically by adding a latch, and running static timing
|
||||
analysis.) This will cause the clock gate to be ignored in the scheduling
|
||||
algorithm, improving performance.
|
||||
|
||||
=item /*verilator coverage_block_off*/
|
||||
|
||||
@@ -1290,6 +1322,7 @@ this to the signal causing a false loop may clear up the problem.
|
||||
IE, with the following
|
||||
|
||||
reg splitme /* verilator isolate_assignments*/;
|
||||
// Note the placement of the semicolon above
|
||||
always @* begin
|
||||
if (....) begin
|
||||
splitme = ....;
|
||||
@@ -2143,7 +2176,7 @@ using --debug), see if your machine is paging; most likely you need to run
|
||||
it on a machine with more memory. Verilator is a full 64 bit application
|
||||
and may use more than 4GB, but about 1GB is the maximum typically needed.
|
||||
|
||||
=item How do I generate waveforms (traces) in C++ or SystemC?
|
||||
=item How do I generate waveforms (traces) in C++?
|
||||
|
||||
See the next question for tracing in SystemPerl mode.
|
||||
|
||||
@@ -2162,7 +2195,7 @@ distribution.
|
||||
You also need to compile SpTraceVcdC.cpp and add it to your link. This is
|
||||
done for you if using the Verilator --exe flag.
|
||||
|
||||
=item How do I generate waveforms (traces) in SystemPerl?
|
||||
=item How do I generate waveforms (traces) in SystemC/SystemPerl?
|
||||
|
||||
Add the --trace switch to Verilator, and make sure the SystemPerl package
|
||||
is installed.
|
||||
@@ -2172,6 +2205,10 @@ create a SpTraceFile object as you would create a normal SystemC trace
|
||||
file. For an example, see the call to SpTraceFile in the
|
||||
test_sp/sc_main.cpp file of the distribution.
|
||||
|
||||
Alternatively you may use the C++ trace mechanism described in the previous
|
||||
question, however the timescale and timeprecision will not inherited from
|
||||
your SystemC settings.
|
||||
|
||||
=item How do I view waveforms (traces)?
|
||||
|
||||
Verilator makes standard VCD (Value Change Dump) files. They are viewable
|
||||
@@ -2349,7 +2386,8 @@ strips array bound checks where it believes them to be unnecessary.)
|
||||
|
||||
In the SYSTEMC example above, if you had in our.v:
|
||||
|
||||
input clk /*verilator public*/;
|
||||
input clk /*verilator public*/;
|
||||
// Note the placement of the semicolon above
|
||||
|
||||
From the sc_main.cpp file, you'd then:
|
||||
|
||||
|
||||
@@ -73,9 +73,9 @@ void vl_fatal (const char* filename, int linenum, const char* hier, const char*
|
||||
IData VL_RAND32() {
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
// Windows doesn't have lrand48(), although Cygwin does.
|
||||
return (rand()<<16) | rand();
|
||||
return (rand()<<16) ^ rand();
|
||||
#else
|
||||
return (lrand48()<<16) | lrand48();
|
||||
return (lrand48()<<16) ^ lrand48();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+26
-16
@@ -359,35 +359,45 @@ static inline void VL_ASSIGNBIT_WO(int, int bit, WDataOutP owp, IData) {
|
||||
|
||||
//===================================================================
|
||||
// SYSTEMC OPERATORS
|
||||
// Copying verilog format to/from systemc integers and bit vectors.
|
||||
|
||||
#define VL_ASSIGN_IS(obits,vvar,svar) { (vvar) = VL_CLEAN_II((obits),(obits),(svar).read()); }
|
||||
#define VL_ASSIGN_SI(obits,svar,vvar) { (svar).write(vvar); }
|
||||
// Copying verilog format to systemc integers and bit vectors.
|
||||
|
||||
#define VL_ASSIGN_ISI(obits,vvar,svar) { (vvar) = VL_CLEAN_II((obits),(obits),(svar).read()); }
|
||||
#define VL_ASSIGN_QSQ(obits,vvar,svar) { (vvar) = VL_CLEAN_QQ((obits),(obits),(svar).read()); }
|
||||
|
||||
#define VL_ASSIGN_ISW(obits,od,svar) { \
|
||||
od = (svar.read().get_word(0)) & VL_MASK_I(obits); \
|
||||
}
|
||||
#define VL_ASSIGN_QSW(obits,od,svar) { \
|
||||
od = (((QData)svar.read().get_word(1))<<VL_WORDSIZE | svar.read().get_word(0)) \
|
||||
& VL_MASK_Q(obits); \
|
||||
}
|
||||
#define VL_ASSIGN_WSW(obits,owp,svar) { \
|
||||
int words = VL_WORDS_I(obits); \
|
||||
for (int i=0; i < words; i++) owp[i] = svar.read().get_word(i); \
|
||||
owp[words-1] &= VL_MASK_I(obits); \
|
||||
}
|
||||
|
||||
// Copying verilog format from systemc integers and bit vectors.
|
||||
|
||||
#define VL_ASSIGN_SII(obits,svar,vvar) { (svar).write(vvar); }
|
||||
#define VL_ASSIGN_SQQ(obits,svar,vvar) { (svar).write(vvar); }
|
||||
|
||||
#define VL_ASSIGN_SQ(obits,svar,rd) { \
|
||||
#define VL_ASSIGN_SWI(obits,svar,rd) { \
|
||||
sc_bv<obits> _bvtemp; \
|
||||
_bvtemp.set_word(0,rd); \
|
||||
svar.write(_bvtemp); \
|
||||
}
|
||||
#define VL_ASSIGN_SWQ(obits,svar,rd) { \
|
||||
sc_bv<obits> _bvtemp; \
|
||||
_bvtemp.set_word(0,rd); \
|
||||
_bvtemp.set_word(1,rd>>VL_WORDSIZE); \
|
||||
svar.write(_bvtemp); \
|
||||
}
|
||||
#define VL_ASSIGN_QS(obits,od,svar) { \
|
||||
od = (((QData)svar.read().get_word(1))<<VL_WORDSIZE | svar.read().get_word(0)) \
|
||||
& VL_MASK_Q(obits); \
|
||||
}
|
||||
|
||||
#define VL_ASSIGN_SW(obits,svar,rwp) { \
|
||||
#define VL_ASSIGN_SWW(obits,svar,rwp) { \
|
||||
sc_bv<obits> _bvtemp; \
|
||||
for (int i=0; i < VL_WORDS_I(obits); i++) _bvtemp.set_word(i,rwp[i]); \
|
||||
svar.write(_bvtemp); \
|
||||
}
|
||||
#define VL_ASSIGN_WS(obits,owp,svar) { \
|
||||
int words = VL_WORDS_I(obits); \
|
||||
for (int i=0; i < words; i++) owp[i] = svar.read().get_word(i); \
|
||||
owp[words-1] &= VL_MASK_I(obits); \
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
// Extending sizes
|
||||
|
||||
@@ -89,8 +89,8 @@ endif
|
||||
##### SystemPerl builds
|
||||
|
||||
ifeq ($(VM_SP),1)
|
||||
CPPFLAGS += -I$(SYSTEMPERL)/src -DSYSTEMPERL
|
||||
VPATH += $(SYSTEMPERL)/src
|
||||
CPPFLAGS += -I$(SYSTEMPERL_INCLUDE) -DSYSTEMPERL
|
||||
VPATH += $(SYSTEMPERL_INCLUDE)
|
||||
LIBS += -lm -lstdc++
|
||||
|
||||
VK_CLASSES_SP = $(addsuffix .sp, $(VM_CLASSES))
|
||||
@@ -110,8 +110,8 @@ endif
|
||||
ifeq ($(VM_SC),1)
|
||||
LIBS += -lm -lstdc++
|
||||
ifeq ($(VM_TRACE),1)
|
||||
CPPFLAGS += -I$(SYSTEMPERL)/src
|
||||
VPATH += $(SYSTEMPERL)/src
|
||||
CPPFLAGS += -I$(SYSTEMPERL_INCLUDE)
|
||||
VPATH += $(SYSTEMPERL_INCLUDE)
|
||||
endif
|
||||
endif
|
||||
|
||||
@@ -121,8 +121,8 @@ endif
|
||||
ifeq ($(VM_PCLI),1)
|
||||
LIBS += -lm -lstdc++
|
||||
ifeq ($(VM_TRACE),1)
|
||||
CPPFLAGS += -I$(SYSTEMPERL)/src
|
||||
VPATH += $(SYSTEMPERL)/src
|
||||
CPPFLAGS += -I$(SYSTEMPERL_INCLUDE)
|
||||
VPATH += $(SYSTEMPERL_INCLUDE)
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
Executable
+73
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/perl -w
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2007-2009 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.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the Perl Artistic License
|
||||
# along with this module; see the file COPYING. If not, see
|
||||
# www.cpan.org
|
||||
#
|
||||
######################################################################
|
||||
|
||||
# DESCRIPTION: Diff bison files
|
||||
|
||||
use IO::File;
|
||||
use strict;
|
||||
|
||||
my $Debug;
|
||||
|
||||
diff($ARGV[0],$ARGV[1]);
|
||||
|
||||
sub diff {
|
||||
my $a=shift;
|
||||
my $b=shift;
|
||||
|
||||
my $ta = "/tmp/bisondiff.$$.a";
|
||||
my $tb = "/tmp/bisondiff.$$.b";
|
||||
|
||||
prep($a,$ta);
|
||||
prep($b,$tb);
|
||||
|
||||
system("diff -u -w $ta $tb");
|
||||
}
|
||||
|
||||
sub prep {
|
||||
my $filename = shift;
|
||||
my $wfilename = shift;
|
||||
|
||||
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename";
|
||||
my $fho = IO::File->new(">$wfilename") or die "%Error: $! writing $wfilename";
|
||||
|
||||
my %declared;
|
||||
my %used;
|
||||
|
||||
my $body = 0;
|
||||
my $rule = "";
|
||||
my $skip = 1;
|
||||
while (defined(my $line = $fh->getline)) {
|
||||
if ($skip == 1) {
|
||||
next if $line !~ /%token/;
|
||||
$skip = 2;
|
||||
}
|
||||
# %type<foo>
|
||||
$line =~ s/^(%\S+)<(\S+)>/$1/;
|
||||
# rule<foo>
|
||||
$line =~ s/^([a-zA-Z0-9_]+)<\S+>:/$1:/;
|
||||
# Productions
|
||||
$line =~ s/[ \t]{[^}]*?}/\t{}/g;
|
||||
$fho->print($line);
|
||||
}
|
||||
}
|
||||
|
||||
# Local Variables:
|
||||
# compile-command: "./bisondiff $WUP/Verilog/Parser/VParseBison.y ../src/verilog.y"
|
||||
# End:
|
||||
+3
-3
@@ -42,8 +42,8 @@ foreach my $line (<STDIN>) {
|
||||
$rule .= $line;
|
||||
if ($line =~ m!^\s*;\s*$!) {
|
||||
#print "Rule: $rule\n";
|
||||
($rule =~ /^([a-zA-Z0-9_]+):(.*)$/) or die "%Error: No rule name: $1\n";
|
||||
my $rulename = $1; my $preaction = $2;
|
||||
($rule =~ /^([a-zA-Z0-9_]+)(<\S+>)?:(.*)$/) or die "%Error: No rule name: $1\n";
|
||||
my $rulename = $1; my $preaction = $3;
|
||||
$declared{$rulename} = $lineno;
|
||||
$preaction =~ s/\{[^\}]*\}/ /g;
|
||||
#print "RULEN $rulename PA $preaction\n" if $Debug;
|
||||
@@ -62,5 +62,5 @@ foreach my $line (<STDIN>) {
|
||||
}
|
||||
|
||||
# Local Variables:
|
||||
# compile-command: "./bisonreader < verilog.y"
|
||||
# compile-command: "./bisonreader < ../src/verilog.y"
|
||||
# End:
|
||||
|
||||
+5
-4
@@ -116,8 +116,9 @@ If you will be using SystemC, download and install Verilog-Perl,
|
||||
If you will be using SystemC, download and install System-Perl,
|
||||
@url{http://search.cpan.org/search?module=SystemC::Netlist}. Note
|
||||
you'll need to set a @samp{SYSTEMPERL} environment variable to point
|
||||
to the downloaded kit (not the installed files.) Also, make sure to
|
||||
do a @code{make sc_patch}.
|
||||
to the downloaded kit. Optionally also set @samp{SYSTEMPERL_INCLUDE}
|
||||
to point to the installed headers. Also, make sure to do a @code{make
|
||||
sc_patch}.
|
||||
|
||||
@item
|
||||
@code{cd} to the Verilator directory containing this README.
|
||||
@@ -128,8 +129,8 @@ 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.
|
||||
SYSTEMC, SYSTEMC_ARCH, SYSTEMPERL, and SYSTEMPERL_INCLUDE and build
|
||||
them as defaults into the executable.
|
||||
|
||||
@item
|
||||
Type @samp{make} to compile Verilator.
|
||||
|
||||
+7
-1
@@ -81,12 +81,19 @@ CPPFLAGS += -W -Wall -Wno-unused-parameter -Wno-char-subscripts -Werror
|
||||
#CPPFLAGS += -pedantic-errors
|
||||
endif
|
||||
|
||||
ifneq ($(SYSTEMPERL),) # Intuit SYSTEMPERL_INCLUDE as it's new
|
||||
SYSTEMPERL_INCLUDE ?= $(SYSTEMPERL)/src
|
||||
#else if set, leave as-is.
|
||||
#else if SYSTEMPERL="" don't set _INCLUDE so source will figure it out
|
||||
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)\"
|
||||
CPPFLAGS += -DDEFENV_SYSTEMPERL_INCLUDE=\"$(SYSTEMPERL_INCLUDE)\"
|
||||
ifeq ($(VERILATOR_ROOT),) # Use what we're given, or intuit
|
||||
CPPFLAGS += -DDEFENV_VERILATOR_ROOT=\"$(pkgdatadir)\"
|
||||
else
|
||||
@@ -280,4 +287,3 @@ DEPS := $(wildcard *.d)
|
||||
ifneq ($(DEPS),)
|
||||
include $(DEPS)
|
||||
endif
|
||||
|
||||
|
||||
+5
-1
@@ -52,7 +52,11 @@
|
||||
|
||||
class ActiveBaseVisitor : public AstNVisitor {
|
||||
protected:
|
||||
//int debug() { return 9; }
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
};
|
||||
|
||||
class ActiveNamer : public ActiveBaseVisitor {
|
||||
|
||||
+7
-1
@@ -56,7 +56,13 @@ private:
|
||||
// STATE
|
||||
AstTopScope* m_topscopep; // Top scope for adding sentrees under
|
||||
SenTreeFinder m_finder; // Find global sentree's and add them
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstTopScope* nodep, AstNUser*) {
|
||||
|
||||
+6
-2
@@ -48,9 +48,13 @@ private:
|
||||
// Reset each assertion:
|
||||
AstNodeSenItem* m_senip; // Last sensitivity
|
||||
|
||||
int debug() { return 0; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
AstSenTree* newSenTree(AstNode* nodep) {
|
||||
// Create sentree based on clocked or default clock
|
||||
// Return NULL for always
|
||||
|
||||
+7
-7
@@ -51,11 +51,11 @@ bool AstVar::isSigPublic() const {
|
||||
}
|
||||
|
||||
bool AstVar::isScQuad() const {
|
||||
return (isSc()&&isQuad()&&v3Global.opt.pins64());
|
||||
return (isSc() && isQuad() && !isScBv());
|
||||
}
|
||||
|
||||
bool AstVar::isScWide() const {
|
||||
return (isWide() || isSc()&&isQuad()&&!v3Global.opt.pins64());
|
||||
bool AstVar::isScBv() const {
|
||||
return (isSc() && width() >= v3Global.opt.pinsBv());
|
||||
}
|
||||
|
||||
void AstVar::combineType(AstVarType type) {
|
||||
@@ -108,7 +108,7 @@ string AstVar::cType() const {
|
||||
return "bool";
|
||||
} else if (widthMin() <= VL_WORDSIZE) {
|
||||
return "uint32_t";
|
||||
} else if (isScWide()) {
|
||||
} else if (isWide()) {
|
||||
return "uint32_t"; // []'s added later
|
||||
} else {
|
||||
return "uint64_t";
|
||||
@@ -116,12 +116,12 @@ string AstVar::cType() const {
|
||||
}
|
||||
|
||||
string AstVar::scType() const {
|
||||
if (widthMin() == 1) {
|
||||
if (isScBv()) {
|
||||
return (string("sc_bv<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >>
|
||||
} else if (widthMin() == 1) {
|
||||
return "bool";
|
||||
} else if (widthMin() <= VL_WORDSIZE) {
|
||||
return "uint32_t";
|
||||
} else if (isScWide()) {
|
||||
return (string("sc_bv<")+cvtToStr(widthMin())+"> "); // Keep the space so don't get >>
|
||||
} else {
|
||||
return "uint64_t";
|
||||
}
|
||||
|
||||
+16
-1
@@ -341,7 +341,7 @@ public:
|
||||
bool isUsedParam() const { return m_usedParam; }
|
||||
bool isSc() const { return m_sc; }
|
||||
bool isScQuad() const;
|
||||
bool isScWide() const;
|
||||
bool isScBv() const;
|
||||
bool isScSensitive() const { return m_scSensitive; }
|
||||
bool isSigPublic() const;
|
||||
bool isSigModPublic() const { return m_sigModPublic; }
|
||||
@@ -1408,6 +1408,21 @@ struct AstFor : public AstNodeFor {
|
||||
ASTNODE_NODE_FUNCS(For, FOR)
|
||||
};
|
||||
|
||||
struct AstRepeat : public AstNodeStmt {
|
||||
AstRepeat(FileLine* fileline, AstNode* countp, AstNode* bodysp)
|
||||
: AstNodeStmt(fileline) {
|
||||
setOp2p(countp); addNOp3p(bodysp);
|
||||
}
|
||||
ASTNODE_NODE_FUNCS(Repeat, REPEAT)
|
||||
AstNode* countp() const { return op2p()->castNode(); } // op2= condition to continue
|
||||
AstNode* bodysp() const { return op3p()->castNode(); } // op3= body of loop
|
||||
virtual bool isGateOptimizable() const { return false; }
|
||||
virtual bool isPredictOptimizable() const { return false; }
|
||||
virtual int instrCount() const { return instrCountBranch(); }
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(AstNode* samep) const { return true; }
|
||||
};
|
||||
|
||||
struct AstWhile : public AstNodeStmt {
|
||||
AstWhile(FileLine* fileline, AstNode* condp, AstNode* bodysp)
|
||||
: AstNodeStmt(fileline) {
|
||||
|
||||
+42
-1
@@ -47,11 +47,19 @@ private:
|
||||
AstModule* m_modp; // Current module
|
||||
AstNodeFTask* m_ftaskp; // Current function/task
|
||||
string m_beginScope; // Name of begin blocks above us
|
||||
//int debug() { return 9; }
|
||||
int m_repeatNum; // Repeat counter
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstModule* nodep, AstNUser*) {
|
||||
m_modp = nodep;
|
||||
m_repeatNum = 0;
|
||||
nodep->iterateChildren(*this);
|
||||
m_modp = NULL;
|
||||
}
|
||||
@@ -130,6 +138,38 @@ private:
|
||||
nodep->replaceWith(newp);
|
||||
nodep->deleteTree(); nodep=NULL;
|
||||
}
|
||||
virtual void visit(AstRepeat* nodep, AstNUser*) {
|
||||
// So later optimizations don't need to deal with them,
|
||||
// REPEAT(count,body) -> loop=count,WHILE(loop>0) { body, loop-- }
|
||||
// Note var can be signed or unsigned based on original number.
|
||||
AstNode* countp = nodep->countp()->unlinkFrBackWithNext();
|
||||
string name = string("__Vrepeat")+cvtToStr(m_repeatNum++);
|
||||
AstVar* varp = new AstVar(nodep->fileline(), AstVarType::BLOCKTEMP, name,
|
||||
new AstRange(nodep->fileline(), countp->width()-1, 0));
|
||||
m_modp->addStmtp(varp);
|
||||
AstNode* initsp = new AstAssign(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, true),
|
||||
countp);
|
||||
AstNode* decp = new AstAssign(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, true),
|
||||
new AstSub(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, false),
|
||||
new AstConst(nodep->fileline(), 1)));
|
||||
AstNode* condp;
|
||||
if (countp->isSigned()) {
|
||||
condp = new AstGtS(nodep->fileline(), new AstVarRef(nodep->fileline(), varp, false),
|
||||
new AstConst(nodep->fileline(), 0));
|
||||
} else {
|
||||
condp = new AstGt (nodep->fileline(), new AstVarRef(nodep->fileline(), varp, false),
|
||||
new AstConst(nodep->fileline(), 0));
|
||||
}
|
||||
AstNode* bodysp = nodep->bodysp(); if (bodysp) bodysp->unlinkFrBackWithNext();
|
||||
bodysp = bodysp->addNext(decp);
|
||||
AstNode* newp = new AstWhile(nodep->fileline(),
|
||||
condp,
|
||||
bodysp);
|
||||
initsp = initsp->addNext(newp);
|
||||
newp = initsp;
|
||||
nodep->replaceWith(newp);
|
||||
nodep->deleteTree(); nodep=NULL;
|
||||
}
|
||||
virtual void visit(AstScopeName* nodep, AstNUser*) {
|
||||
// If there's a %m in the display text, we add a special node that will contain the name()
|
||||
// Similar code in V3Inline
|
||||
@@ -155,6 +195,7 @@ public:
|
||||
BeginVisitor(AstNetlist* nodep) {
|
||||
m_modp = NULL;
|
||||
m_ftaskp = NULL;
|
||||
m_repeatNum = 0;
|
||||
nodep->accept(*this);
|
||||
}
|
||||
virtual ~BeginVisitor() {}
|
||||
|
||||
+6
-1
@@ -43,9 +43,14 @@ private:
|
||||
// STATE
|
||||
int m_likely; // Excuses for branch likely taken
|
||||
int m_unlikely; // Excuses for branch likely not taken
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
m_likely = false;
|
||||
m_unlikely = false;
|
||||
|
||||
+3
-3
@@ -129,9 +129,9 @@ public:
|
||||
// Use only AstNode::dump instead of the virtual one, as there
|
||||
// may be varp() and other cross links that are bad.
|
||||
if (debug()) {
|
||||
cout<<"%Error: LeakedNode"<<(it->first->backp()?"Back: ":": ");
|
||||
((AstNode*)(it->first))->AstNode::dump(cout);
|
||||
cout<<endl;
|
||||
cerr<<"%Error: LeakedNode"<<(it->first->backp()?"Back: ":": ");
|
||||
((AstNode*)(it->first))->AstNode::dump(cerr);
|
||||
cerr<<endl;
|
||||
V3Error::incErrors();
|
||||
}
|
||||
it->second |= FLAG_LEAKED;
|
||||
|
||||
+12
-3
@@ -58,7 +58,12 @@
|
||||
class CaseLintVisitor : public AstNVisitor {
|
||||
private:
|
||||
AstNodeCase* m_caseExprp; // Under a CASE value node, if so the relevant case statement
|
||||
//int debug() { return 9; }
|
||||
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeCase* nodep, AstNUser*) {
|
||||
// Detect multiple defaults
|
||||
@@ -130,9 +135,13 @@ private:
|
||||
int m_caseNoOverlapsAllCovered; // Proven to be synopsys parallel_case compliant
|
||||
AstNode* m_valueItem[1<<CASE_OVERLAP_WIDTH]; // For each possible value, the case branch we need
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
bool isCaseTreeFast(AstCase* nodep) {
|
||||
int width = 0;
|
||||
m_caseItems = 0;
|
||||
|
||||
+6
-1
@@ -63,9 +63,14 @@ private:
|
||||
AstUser1InUse m_inuser1;
|
||||
|
||||
// STATE
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
void insertCast(AstNode* nodep, int needsize) { // We'll insert ABOVE passed node
|
||||
UINFO(4," NeedCast "<<nodep<<endl);
|
||||
AstNRelinker relinkHandle;
|
||||
|
||||
+6
-1
@@ -57,9 +57,14 @@ private:
|
||||
AstModule* m_topModp; // Top module
|
||||
AstScope* m_scopetopp; // Scope under TOPSCOPE
|
||||
AstCFunc* m_chgFuncp; // Change function we're building
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
void genChangeDet(AstVarScope* vscp) {
|
||||
#ifdef NEW_ORDERING
|
||||
vscp->v3fatalSrc("Not applicable\n");
|
||||
|
||||
+10
-5
@@ -50,14 +50,19 @@ private:
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
|
||||
// STATE
|
||||
AstModule* m_modp;
|
||||
//int debug() { return 9; }
|
||||
|
||||
// ENUMS
|
||||
// TYPES
|
||||
enum CleanState { UNKNOWN, CLEAN, DIRTY };
|
||||
|
||||
// STATE
|
||||
AstModule* m_modp;
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// Width resetting
|
||||
int cppWidth(AstNode* nodep) {
|
||||
if (nodep->width()<=VL_WORDSIZE) return VL_WORDSIZE;
|
||||
|
||||
+5
-1
@@ -52,7 +52,11 @@
|
||||
|
||||
class GaterBaseVisitor : public AstNVisitor {
|
||||
protected:
|
||||
//int debug() { return 9; }
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
||||
+6
-1
@@ -71,9 +71,14 @@ private:
|
||||
AstSenTree* m_lastSenp; // Last sensitivity match, so we can detect duplicates.
|
||||
AstIf* m_lastIfp; // Last sensitivity if active to add more under
|
||||
int m_stableNum; // Number of each untilstable
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
AstVarScope* getCreateLastClk(AstVarScope* vscp) {
|
||||
if (vscp->user1p()) return ((AstVarScope*)vscp->user1p());
|
||||
AstVar* varp = vscp->varp();
|
||||
|
||||
+7
-1
@@ -58,8 +58,14 @@
|
||||
class CombBaseVisitor : public AstNVisitor {
|
||||
protected:
|
||||
// STATE
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
virtual ~CombBaseVisitor() {}
|
||||
|
||||
//***** optimization levels
|
||||
|
||||
+7
-1
@@ -30,6 +30,7 @@
|
||||
#include <cstdarg>
|
||||
#include <unistd.h>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
#include "V3Global.h"
|
||||
#include "V3Const.h"
|
||||
@@ -104,9 +105,14 @@ private:
|
||||
bool m_expensive; // Enable computationally expensive optimizations
|
||||
AstModule* m_modp; // Current module
|
||||
AstNode* m_scopep; // Current scope
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
bool operandConst (AstNode* nodep) {
|
||||
return (nodep->castConst());
|
||||
}
|
||||
|
||||
+6
-2
@@ -54,9 +54,13 @@ private:
|
||||
FileMap m_fileps; // Column counts for each fileline
|
||||
string m_beginHier; // AstBegin hier name for user coverage points
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
const char* varIgnoreToggle(AstVar* nodep) {
|
||||
// Return true if this shouldn't be traced
|
||||
// See also similar rule in V3TraceDecl::varIgnoreTrace
|
||||
|
||||
@@ -53,9 +53,13 @@ private:
|
||||
|
||||
V3Double0 m_statToggleJoins; // Statistic tracking
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
void detectDuplicates() {
|
||||
UINFO(9,"Finding duplicates\n");
|
||||
// Note uses user4
|
||||
|
||||
+5
-1
@@ -81,9 +81,13 @@ private:
|
||||
AssignMap m_assignMap; // List of all simple assignments for each variable
|
||||
bool m_elimUserVars; // Allow removal of user's vars
|
||||
bool m_sideEffect; // Side effects discovered in assign RHS
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstCell* nodep, AstNUser*) {
|
||||
|
||||
+7
-2
@@ -101,9 +101,14 @@ private:
|
||||
VarMap m_modVarMap; // Table of new var names created under module
|
||||
V3Double0 m_statSharedSet;// Statistic tracking
|
||||
|
||||
//static int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
void markVarUsage(AstVar* nodep, uint32_t flags) {
|
||||
//UINFO(4," MVU "<<flags<<" "<<nodep<<endl);
|
||||
nodep->user1( nodep->user1() | flags );
|
||||
@@ -417,7 +422,7 @@ private:
|
||||
}
|
||||
|
||||
virtual void visit(AstNodeFor* nodep, AstNUser*) {
|
||||
nodep->v3fatalSrc("For statements should have been converted to while statements in V3Unroll\n");
|
||||
nodep->v3fatalSrc("For statements should have been converted to while statements in V3Begin\n");
|
||||
}
|
||||
virtual void visit(AstWhile* nodep, AstNUser*) {
|
||||
bool oldloop = m_inLoop;
|
||||
|
||||
+6
-2
@@ -51,9 +51,13 @@ private:
|
||||
int m_depth; // How deep in an expression
|
||||
int m_maxdepth; // Maximum depth in an expression
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
void createDeepTemp(AstNode* nodep) {
|
||||
UINFO(6," Deep "<<nodep<<endl);
|
||||
//if (debug()>=9) nodep->dumpTree(cout,"deep:");
|
||||
|
||||
@@ -48,9 +48,13 @@ private:
|
||||
int m_depth; // How deep in an expression
|
||||
int m_deepNum; // How many functions made
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
AstCFunc* createDeepFunc(AstNode* nodep) {
|
||||
AstNRelinker relinkHandle;
|
||||
nodep->unlinkFrBack(&relinkHandle);
|
||||
|
||||
+6
-1
@@ -55,9 +55,14 @@ private:
|
||||
AstScope* m_scopep; // Current scope
|
||||
bool m_needThis; // Add thisp to function
|
||||
FuncMmap m_modFuncs; // Name of public functions added
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
string descopedName(AstScope* scopep, bool& hierThisr, AstVar* varp=NULL) {
|
||||
UASSERT(scopep, "Var/Func not scoped\n");
|
||||
hierThisr = true;
|
||||
|
||||
+21
-14
@@ -44,8 +44,14 @@ private:
|
||||
vector<AstVar*> m_ctorVarsVec; // All variables in constructor order
|
||||
int m_splitSize; // # of cfunc nodes placed into output file
|
||||
int m_splitFilenum; // File number being created, 0 = primary
|
||||
|
||||
public:
|
||||
//int debug() { return 9; }
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// ACCESSORS
|
||||
int splitFilenum() { return m_splitFilenum; }
|
||||
@@ -69,6 +75,9 @@ public:
|
||||
void emitIQW(AstNode* nodep) {
|
||||
puts (nodep->isWide()?"W":(nodep->isQuad()?"Q":"I"));
|
||||
}
|
||||
void emitScIQW(AstVar* nodep) {
|
||||
puts (nodep->isScBv()?"SW":(nodep->isScQuad()?"SQ":"SI"));
|
||||
}
|
||||
void emitOpName(AstNode* nodep, const string& format,
|
||||
AstNode* lhsp, AstNode* rhsp, AstNode* thsp);
|
||||
|
||||
@@ -124,8 +133,7 @@ public:
|
||||
} else if (nodep->lhsp()->castVarRef()
|
||||
&& nodep->lhsp()->castVarRef()->varp()->isSc()) {
|
||||
putbs("VL_ASSIGN_"); // Set a systemC variable
|
||||
if (nodep->lhsp()->castVarRef()->varp()->isScQuad()) puts("SQ");
|
||||
else puts("S");
|
||||
emitScIQW(nodep->lhsp()->castVarRef()->varp());
|
||||
emitIQW(nodep);
|
||||
puts("(");
|
||||
puts(cvtToStr(nodep->widthMin())+",");
|
||||
@@ -134,8 +142,8 @@ public:
|
||||
&& nodep->rhsp()->castVarRef()->varp()->isSc()) {
|
||||
putbs("VL_ASSIGN_"); // Get a systemC variable
|
||||
emitIQW(nodep);
|
||||
if (nodep->rhsp()->castVarRef()->varp()->isScQuad()) puts("SQ(");
|
||||
else puts("S(");
|
||||
emitScIQW(nodep->rhsp()->castVarRef()->varp());
|
||||
puts("(");
|
||||
puts(cvtToStr(nodep->widthMin())+",");
|
||||
nodep->lhsp()->iterateAndNext(*this); puts(", ");
|
||||
} else if (nodep->isWide()
|
||||
@@ -1406,7 +1414,7 @@ void EmitCStmts::emitVarList(AstNode* firstp, EisWhich which, const string& pref
|
||||
int sigbytes = varp->widthAlignBytes();
|
||||
if (varp->isUsedClock() && varp->widthMin()==1) sigbytes = 0;
|
||||
else if (varp->arraysp()) sigbytes=7;
|
||||
else if (varp->isScWide()) sigbytes=6;
|
||||
else if (varp->isScBv()) sigbytes=6;
|
||||
else if (sigbytes==8) sigbytes=5;
|
||||
else if (sigbytes==4) sigbytes=4;
|
||||
else if (sigbytes==2) sigbytes=2;
|
||||
@@ -1538,7 +1546,7 @@ void EmitCImp::emitInt(AstModule* modp) {
|
||||
if (!varp->initp()) nodep->v3fatalSrc("No init for a param?");
|
||||
// These should be static const values, however microsloth VC++ doesn't
|
||||
// support them. They also cause problems with GDB under GCC2.95.
|
||||
if (varp->isScWide()) { // Unsupported for output
|
||||
if (varp->isWide()) { // Unsupported for output
|
||||
puts("// enum WData "+varp->name()+" //wide");
|
||||
} else if (!varp->initp()->castConst()) { // Unsupported for output
|
||||
puts("// enum IData "+varp->name()+" //not simple value");
|
||||
@@ -1680,8 +1688,7 @@ void EmitCImp::main(AstModule* modp, bool slow, bool fast) {
|
||||
string filenameNoExt = v3Global.opt.makeDir()+"/"+ modClassName(modp)+(m_fast ? "" : "__Slow");
|
||||
|
||||
if (debug()>=5) {
|
||||
for (int i=0;i<modp->level();i++) { cout<<" "; }
|
||||
UINFONL(0," Emitting "<<modClassName(modp)<<endl);
|
||||
UINFO(0," Emitting "<<modClassName(modp)<<endl);
|
||||
}
|
||||
|
||||
if (optSystemPerl()) {
|
||||
@@ -1811,11 +1818,11 @@ class EmitCTrace : EmitCStmts {
|
||||
puts("\n//======================\n\n");
|
||||
}
|
||||
|
||||
bool emitTraceIsScWide(AstTraceInc* nodep) {
|
||||
bool emitTraceIsScBv(AstTraceInc* nodep) {
|
||||
AstVarRef* varrefp = nodep->valuep()->castVarRef();
|
||||
if (!varrefp) return false;
|
||||
AstVar* varp = varrefp->varp();
|
||||
return varp->isSc() && varp->isScWide();
|
||||
return varp->isSc() && varp->isScBv();
|
||||
}
|
||||
void emitTraceInitOne(AstTraceDecl* nodep) {
|
||||
if (nodep->isWide()) {
|
||||
@@ -1846,7 +1853,7 @@ class EmitCTrace : EmitCStmts {
|
||||
string full = ((m_funcp->funcType() == AstCFuncType::TRACE_FULL
|
||||
|| m_funcp->funcType() == AstCFuncType::TRACE_FULL_SUB)
|
||||
? "full":"chg");
|
||||
if (nodep->isWide() || emitTraceIsScWide(nodep)) {
|
||||
if (nodep->isWide() || emitTraceIsScBv(nodep)) {
|
||||
puts("vcdp->"+full+"Array");
|
||||
} else if (nodep->isQuad()) {
|
||||
puts("vcdp->"+full+"Quad ");
|
||||
@@ -1868,7 +1875,7 @@ class EmitCTrace : EmitCStmts {
|
||||
if (nodep->valuep()->castVarRef()) {
|
||||
AstVarRef* varrefp = nodep->valuep()->castVarRef();
|
||||
AstVar* varp = varrefp->varp();
|
||||
if (emitTraceIsScWide(nodep)) puts("(uint32_t*)");
|
||||
if (emitTraceIsScBv(nodep)) puts("(uint32_t*)");
|
||||
puts("(");
|
||||
varrefp->iterate(*this); // Put var name out
|
||||
if (varp->arraysp()) {
|
||||
@@ -1877,7 +1884,7 @@ class EmitCTrace : EmitCStmts {
|
||||
else puts("["+cvtToStr(arrayindex)+"]");
|
||||
}
|
||||
if (varp->isSc()) puts(".read()");
|
||||
if (emitTraceIsScWide(nodep)) puts(".get_datap()");
|
||||
if (emitTraceIsScBv(nodep)) puts(".get_datap()");
|
||||
puts(")");
|
||||
} else {
|
||||
puts("(");
|
||||
|
||||
+1
-3
@@ -207,11 +207,9 @@ void EmitCSyms::emitImp() {
|
||||
AstScope* scopep = it->first; AstModule* modp = it->second;
|
||||
if (modp->isTop()) {
|
||||
} else {
|
||||
string arrow = scopep->name();
|
||||
if (arrow.substr(0,4) == "TOP.") arrow.replace(0,4,".");
|
||||
ofp()->printf("\t%c %-30s ", comma, scopep->nameDotless().c_str());
|
||||
puts("(Verilated::catName(topp->name(),\"");
|
||||
puts(arrow);
|
||||
puts("."+scopep->prettyName());
|
||||
puts("\"))\n");
|
||||
comma=',';
|
||||
}
|
||||
|
||||
+7
-1
@@ -37,9 +37,14 @@
|
||||
|
||||
class EmitMkVisitor : public EmitCBaseVisitor {
|
||||
public:
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
void emitClassMake() {
|
||||
// Generate the makefile
|
||||
V3OutMkFile of (v3Global.opt.makeDir()+"/"+ v3Global.opt.prefix() + "_classes.mk");
|
||||
@@ -82,6 +87,7 @@ public:
|
||||
of.puts("PERL = "+V3Options::getenvPERL()+"\n");
|
||||
of.puts("VERILATOR_ROOT = "+V3Options::getenvVERILATOR_ROOT()+"\n");
|
||||
of.puts("SYSTEMPERL = "+V3Options::getenvSYSTEMPERL()+"\n");
|
||||
of.puts("SYSTEMPERL_INCLUDE = "+V3Options::getenvSYSTEMPERL_INCLUDE()+"\n");
|
||||
|
||||
of.puts("\n# Switches...\n");
|
||||
of.puts(string("VM_SP = ")+(v3Global.opt.systemPerl()?"1":"0")+"\n");
|
||||
|
||||
+13
-1
@@ -38,9 +38,14 @@
|
||||
class EmitVBaseVisitor : public EmitCBaseVisitor {
|
||||
// MEMBERS
|
||||
bool m_suppressSemi;
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
virtual void puts(const string& str) = 0;
|
||||
virtual void putbs(const string& str) = 0;
|
||||
virtual void putsNoTracking(const string& str) = 0;
|
||||
@@ -234,6 +239,13 @@ class EmitVBaseVisitor : public EmitCBaseVisitor {
|
||||
nodep->bodysp()->iterateAndNext(*this);
|
||||
puts("}\n");
|
||||
}
|
||||
virtual void visit(AstRepeat* nodep, AstNUser*) {
|
||||
puts("repeat (");
|
||||
nodep->countp()->iterateAndNext(*this);
|
||||
puts(") {\n");
|
||||
nodep->bodysp()->iterateAndNext(*this);
|
||||
puts("}\n");
|
||||
}
|
||||
virtual void visit(AstWhile* nodep, AstNUser*) {
|
||||
nodep->precondsp()->iterateAndNext(*this);
|
||||
puts("while (");
|
||||
|
||||
+6
-2
@@ -50,9 +50,13 @@ private:
|
||||
// STATE
|
||||
AstNode* m_stmtp; // Current statement
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
int longOrQuadWidth (AstNode* nodep) {
|
||||
// Return 32 or 64...
|
||||
return (nodep->width()+(VL_WORDSIZE-1)) & ~(VL_WORDSIZE-1);
|
||||
|
||||
+6
-2
@@ -48,7 +48,11 @@ typedef list<AstNodeVarRef*> GateVarRefList;
|
||||
|
||||
class GateBaseVisitor : public AstNVisitor {
|
||||
public:
|
||||
//int debug() { return 9; }
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
@@ -578,7 +582,7 @@ void GateVisitor::replaceAssigns() {
|
||||
//if (debug()>9) {vscp->dumpTree(cout, "-vscDone: "); cout<<endl;}
|
||||
if (!vscp->valuep()->castNodeMath()
|
||||
|| vscp->valuep()->nextp()) {
|
||||
vscp->dumpTree(cout, "vscStrange: ");
|
||||
vscp->dumpTree(cerr, "vscStrange: ");
|
||||
vscp->v3fatalSrc("Value of varscope not mathematical\n");
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -38,7 +38,11 @@
|
||||
|
||||
class GenClkBaseVisitor : public AstNVisitor {
|
||||
protected:
|
||||
//static int debug() { return 9; }
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
||||
+1
-1
@@ -228,7 +228,7 @@ void V3Graph::clearColors() {
|
||||
|
||||
void V3Graph::loopsVertexCb(V3GraphVertex* vertexp) {
|
||||
// Needed here as V3GraphVertex<< isn't defined until later in header
|
||||
cout<<"-Info-Loop: "<<(void*)(vertexp)<<" "<<vertexp<<endl;
|
||||
cerr<<"-Info-Loop: "<<(void*)(vertexp)<<" "<<vertexp<<endl;
|
||||
}
|
||||
|
||||
void V3Graph::dump(ostream& os) {
|
||||
|
||||
+1
-1
@@ -106,7 +106,7 @@ private:
|
||||
V3EdgeFuncP m_origEdgeFuncp; // Function that says we follow this edge (in original graph)
|
||||
uint32_t m_placeStep; // Number that user() must be equal to to indicate processing
|
||||
|
||||
int debug() { return V3Graph::debug(); }
|
||||
static int debug() { return V3Graph::debug(); }
|
||||
|
||||
// METHODS
|
||||
void buildGraph (V3Graph* origGraphp);
|
||||
|
||||
+6
-2
@@ -35,8 +35,12 @@
|
||||
class V3GraphTest {
|
||||
public:
|
||||
// ***These tests only run with DEBUG ON***
|
||||
//static int debug() { return 9; }
|
||||
static int debug() { return 0; }
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
// Note setting just --debug will not enable this, as we exit when we run the test
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__, 0);
|
||||
return level;
|
||||
}
|
||||
|
||||
protected:
|
||||
// MEMBERS
|
||||
|
||||
+5
-1
@@ -53,7 +53,11 @@ private:
|
||||
// STATE
|
||||
V3Hash m_lowerHash; // Hash of the statement we're building
|
||||
|
||||
//int debug() { return 9; }
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// METHODS
|
||||
void hashNodeIterate(AstNode* nodep) {
|
||||
|
||||
+7
-1
@@ -42,7 +42,7 @@ public:
|
||||
private:
|
||||
// MEMBERS
|
||||
HashMmap m_hashMmap; // hashvalue -> nodes with that hash
|
||||
int debug() { return 0; }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
V3Hashed();
|
||||
@@ -51,7 +51,13 @@ public:
|
||||
HashMmap& mmap() { return m_hashMmap; } // Return map for iteration
|
||||
HashMmap::iterator begin() { return m_hashMmap.begin(); }
|
||||
HashMmap::iterator end() { return m_hashMmap.end(); }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
void clear() { m_hashMmap.clear(); }
|
||||
void hashAndInsert(AstNode* nodep); // Hash the node, and insert into map
|
||||
bool sameNodes(AstNode* node1p, AstNode* node2p); // After hashing, and tell if identical
|
||||
|
||||
+5
-1
@@ -62,7 +62,11 @@ private:
|
||||
AstCell* m_cellp; // Cell being cloned
|
||||
V3Double0 m_statCells; // Statistic tracking
|
||||
|
||||
//int debug() { return 9; }
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
|
||||
+10
-2
@@ -53,7 +53,11 @@ private:
|
||||
AstModule* m_modp; // Current module
|
||||
AstCell* m_cellp; // Current cell
|
||||
|
||||
//int debug() { return 8; }
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
//int m_debug; int debug() { return m_debug; }
|
||||
|
||||
// VISITORS
|
||||
@@ -147,7 +151,11 @@ private:
|
||||
int m_instNum; // Current instantiation number
|
||||
int m_instLsb; // Current instantiation number
|
||||
|
||||
//int debug() { return 9; }
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstCell* nodep, AstNUser*) {
|
||||
|
||||
+6
-1
@@ -270,7 +270,6 @@ private:
|
||||
// STATE
|
||||
LifeState* m_statep; // Current state
|
||||
bool m_sideEffect; // Side effects discovered in assign RHS
|
||||
//static int debug() { return 9; }
|
||||
|
||||
// LIFE MAP
|
||||
// For each basic block, we'll make a new map of what variables that if/else is changing
|
||||
@@ -278,6 +277,12 @@ private:
|
||||
LifeBlock* m_lifep; // Current active lifetime map for current scope
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
// Consumption/generation of a variable,
|
||||
|
||||
+5
-1
@@ -44,7 +44,11 @@
|
||||
|
||||
class LifePostBaseVisitor : public AstNVisitor {
|
||||
protected:
|
||||
// static int debug() { return 9; }
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
||||
+103
-59
@@ -29,6 +29,7 @@
|
||||
#include "verilatedos.h"
|
||||
#include <cstdio>
|
||||
#include <cstdarg>
|
||||
#include <cctype>
|
||||
#include <unistd.h>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
@@ -49,10 +50,11 @@ private:
|
||||
// AstModule::user1p() // V3SymTable* Module's Symbol table
|
||||
// AstNodeFTask::user1p() // V3SymTable* Local Symbol table
|
||||
// AstBegin::user1p() // V3SymTable* Local Symbol table
|
||||
// AstVar::user1p() // V3SymTable* Table used to create this variable
|
||||
// AstVar::user2p() // bool True if port set for this variable
|
||||
// AstVar/Module::user3p() // V3SymTable* Table used to create this variable
|
||||
AstUser1InUse m_inuser1;
|
||||
AstUser2InUse m_inuser2;
|
||||
AstUser3InUse m_inuser3;
|
||||
|
||||
// ENUMS
|
||||
enum IdState { // Which loop through the tree
|
||||
@@ -69,27 +71,84 @@ private:
|
||||
V3SymTable* m_curVarsp; // Symbol table of variables and tasks under table we're inserting into
|
||||
V3SymTable* m_cellVarsp; // Symbol table of variables under cell's module
|
||||
int m_beginNum; // Begin block number, 0=none seen
|
||||
bool m_inGenerate; // Inside a generate
|
||||
vector<V3SymTable*> m_delSymps; // Symbol tables to delete
|
||||
|
||||
//int debug() { return 9; }
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// METHODS
|
||||
V3SymTable* symsFindNew(AstNode* nodep, V3SymTable* upperVarsp) {
|
||||
// Find or create symbol table for this node
|
||||
if (V3SymTable* symsp = nodep->user1p()->castSymTable()) {
|
||||
return symsp;
|
||||
} else {
|
||||
V3SymTable* symsp = new V3SymTable(upperVarsp);
|
||||
m_delSymps.push_back(symsp);
|
||||
nodep->user1p(symsp);
|
||||
return symsp;
|
||||
}
|
||||
}
|
||||
|
||||
void symsInsert(const string& name, AstNode* nodep) {
|
||||
// Insert into symbol table, and remember what table the node is in
|
||||
m_curVarsp->insert(name, nodep);
|
||||
nodep->user3p(m_curVarsp);
|
||||
}
|
||||
|
||||
void linkVarName (AstVarRef* nodep) {
|
||||
if (!nodep->varp()) {
|
||||
AstVar* varp = m_curVarsp->findIdName(nodep->name())->castVar();
|
||||
AstVar* varp = m_curVarsp->findIdUpward(nodep->name())->castVar();
|
||||
nodep->varp(varp);
|
||||
}
|
||||
}
|
||||
|
||||
const char* varTextType(AstNode* nodep) {
|
||||
const char* nodeTextType(AstNode* nodep) {
|
||||
const char* what = "node";
|
||||
if (nodep->castVar()) what = "variable";
|
||||
else if (nodep->castCell()) what = "cell";
|
||||
else if (nodep->castTask()) what = "task";
|
||||
else if (nodep->castFunc()) what = "function";
|
||||
else if (nodep->castBegin()) what = "block";
|
||||
return what;
|
||||
}
|
||||
|
||||
string ucfirst(const string& text) {
|
||||
string out = text;
|
||||
out[0] = toupper(out[0]);
|
||||
return out;
|
||||
}
|
||||
|
||||
void findAndInsertAndCheck(AstNode* nodep, const string& name) {
|
||||
// Lookup the given name under current symbol table
|
||||
// Insert if not found
|
||||
// Report error if there's a duplicate
|
||||
//
|
||||
// Note we only check for conflicts at the same level; it's ok if one block hides another
|
||||
// We also wouldn't want to not insert it even though it's lower down
|
||||
AstNode* foundp = m_curVarsp->findIdFlat(name);
|
||||
if (!foundp) {
|
||||
symsInsert(nodep->name(), nodep);
|
||||
foundp = nodep;
|
||||
} else if (nodep==foundp) { // Already inserted.
|
||||
// Good.
|
||||
} else if ((nodep->castBegin() || foundp->castBegin())
|
||||
&& m_inGenerate) {
|
||||
// Begin: ... blocks often replicate under genif/genfor, so simply suppress duplicate checks
|
||||
// See t_gen_forif.v for an example.
|
||||
} else if (nodep->type() == foundp->type()) {
|
||||
nodep->v3error("Duplicate declaration of "<<nodeTextType(foundp)<<": "<<nodep->prettyName());
|
||||
foundp->v3error("... Location of original declaration");
|
||||
} else {
|
||||
nodep->v3error("Unsupported in C: "<<ucfirst(nodeTextType(nodep))<<" has the same name as "
|
||||
<<nodeTextType(foundp)<<": "<<nodep->prettyName());
|
||||
foundp->v3error("... Location of original declaration");
|
||||
}
|
||||
}
|
||||
|
||||
void createImplicitVar (AstVarRef* forrefp, bool noWarn) {
|
||||
// Create implicit after warning
|
||||
linkVarName(forrefp);
|
||||
@@ -111,9 +170,7 @@ private:
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
// Look at all modules, and store pointers to all module names
|
||||
for (AstModule* modp = v3Global.rootp()->modulesp(); modp; modp=modp->nextp()->castModule()) {
|
||||
V3SymTable* symp = new V3SymTable(NULL);
|
||||
m_delSymps.push_back(symp);
|
||||
modp->user1p(symp);
|
||||
symsFindNew(modp, NULL);
|
||||
}
|
||||
// And recurse...
|
||||
m_idState = ID_FIND;
|
||||
@@ -130,7 +187,7 @@ private:
|
||||
UINFO(2,"Link Module: "<<nodep<<endl);
|
||||
m_modp = nodep;
|
||||
// This state must be save/restored in the cell visitor function
|
||||
m_curVarsp = nodep->user1p()->castSymTable();
|
||||
m_curVarsp = symsFindNew(nodep, NULL);
|
||||
if (!m_curVarsp) nodep->v3fatalSrc("NULL");
|
||||
m_cellVarsp = NULL;
|
||||
m_paramNum = 0;
|
||||
@@ -140,6 +197,18 @@ private:
|
||||
m_curVarsp = NULL;
|
||||
m_modp = NULL;
|
||||
}
|
||||
|
||||
virtual void visit(AstGenerate* nodep, AstNUser*) {
|
||||
// Begin: ... blocks often replicate under genif/genfor, so simply suppress duplicate checks
|
||||
// See t_gen_forif.v for an example.
|
||||
bool lastInGen = m_inGenerate;
|
||||
{
|
||||
m_inGenerate = true;
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
m_inGenerate = lastInGen;
|
||||
}
|
||||
|
||||
virtual void visit(AstVar* nodep, AstNUser*) {
|
||||
// Var: Remember its name for later resolution
|
||||
if (!m_curVarsp) nodep->v3fatalSrc("Var not under module??\n");
|
||||
@@ -153,17 +222,17 @@ private:
|
||||
nodep->trace(false);
|
||||
}
|
||||
// Find under either a task or the module's vars
|
||||
AstNode* findidp = m_curVarsp->findIdName(nodep->name());
|
||||
AstVar* findvarp = findidp->castVar();
|
||||
AstNode* foundp = m_curVarsp->findIdUpward(nodep->name());
|
||||
AstVar* findvarp = foundp->castVar();
|
||||
bool ins=false;
|
||||
if (!findidp) {
|
||||
if (!foundp) {
|
||||
ins=true;
|
||||
} else if (!findvarp) {
|
||||
nodep->v3error("Unsupported in C: Variable has same name as "
|
||||
<<varTextType(findidp)<<": "<<nodep->prettyName());
|
||||
<<nodeTextType(foundp)<<": "<<nodep->prettyName());
|
||||
} else if (findvarp != nodep) {
|
||||
UINFO(4,"DupVar: "<<nodep<<" ;; "<<findvarp<<endl);
|
||||
if (findvarp->user1p() == m_curVarsp) { // Only when on same level
|
||||
if (findvarp->user3p() == m_curVarsp) { // Only when on same level
|
||||
if ((findvarp->isIO() && nodep->isSignal())
|
||||
|| (findvarp->isSignal() && nodep->isIO())) {
|
||||
findvarp->combineType(nodep);
|
||||
@@ -184,11 +253,10 @@ private:
|
||||
}
|
||||
}
|
||||
if (ins) {
|
||||
m_curVarsp->insert(nodep->name(), nodep);
|
||||
nodep->user1p(m_curVarsp);
|
||||
symsInsert(nodep->name(), nodep);
|
||||
if (nodep->isGParam()) {
|
||||
m_paramNum++;
|
||||
m_curVarsp->insert("__paramNumber"+cvtToStr(m_paramNum), nodep);
|
||||
symsInsert("__paramNumber"+cvtToStr(m_paramNum), nodep);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,13 +288,8 @@ private:
|
||||
V3SymTable* upperVarsp = m_curVarsp;
|
||||
{
|
||||
// Create symbol table for the task's vars
|
||||
if (V3SymTable* localVarsp = nodep->user1p()->castSymTable()) {
|
||||
m_curVarsp = localVarsp;
|
||||
} else {
|
||||
m_curVarsp = new V3SymTable(upperVarsp);
|
||||
m_delSymps.push_back(m_curVarsp);
|
||||
nodep->user1p(m_curVarsp);
|
||||
}
|
||||
m_curVarsp = symsFindNew(nodep, upperVarsp);
|
||||
|
||||
// Convert the func's range to the output variable
|
||||
// This should probably be done in the Parser instead, as then we could
|
||||
// just attact normal signal attributes to it.
|
||||
@@ -241,7 +304,7 @@ private:
|
||||
newvarp->attrIsolateAssign(funcp->attrIsolateAssign());
|
||||
funcp->addFvarp(newvarp);
|
||||
// Explicit insert required, as the var name shadows the upper level's task name
|
||||
m_curVarsp->insert(newvarp->name(), newvarp);
|
||||
symsInsert(newvarp->name(), newvarp);
|
||||
}
|
||||
}
|
||||
m_ftaskp = nodep;
|
||||
@@ -250,16 +313,7 @@ private:
|
||||
}
|
||||
m_curVarsp = upperVarsp;
|
||||
if (m_idState==ID_FIND) {
|
||||
AstNode* findidp = m_curVarsp->findIdName(nodep->name());
|
||||
AstNodeFTask* findtaskp = findidp->castNodeFTask();
|
||||
if (!findidp) {
|
||||
m_curVarsp->insert(nodep->name(), nodep);
|
||||
} else if (!findtaskp) {
|
||||
nodep->v3error("Unsupported in C: Task/function has same name as "
|
||||
<<varTextType(findidp)<<": "<<nodep->prettyName());
|
||||
} else if (findtaskp!=nodep) {
|
||||
nodep->v3error("Duplicate declaration of task/function: "<<nodep->prettyName());
|
||||
}
|
||||
findAndInsertAndCheck(nodep, nodep->name());
|
||||
}
|
||||
}
|
||||
virtual void visit(AstBegin* nodep, AstNUser*) {
|
||||
@@ -273,18 +327,16 @@ private:
|
||||
++m_beginNum;
|
||||
nodep->name(nodep->name()+cvtToStr(m_beginNum));
|
||||
}
|
||||
// Check naming (we don't really care, but some tools do, so better to warn)
|
||||
if (m_idState==ID_FIND) {
|
||||
findAndInsertAndCheck(nodep, nodep->name());
|
||||
}
|
||||
// Recurse
|
||||
int oldNum = m_beginNum;
|
||||
m_beginNum = 0;
|
||||
{
|
||||
// Create symbol table for the task's vars
|
||||
if (V3SymTable* localVarsp = nodep->user1p()->castSymTable()) {
|
||||
m_curVarsp = localVarsp;
|
||||
} else {
|
||||
m_curVarsp = new V3SymTable(upperVarsp);
|
||||
m_delSymps.push_back(m_curVarsp);
|
||||
nodep->user1p(m_curVarsp);
|
||||
}
|
||||
m_curVarsp = symsFindNew(nodep, upperVarsp);
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
m_curVarsp = upperVarsp;
|
||||
@@ -294,7 +346,7 @@ private:
|
||||
// NodeFTaskRef: Resolve its reference
|
||||
if (m_idState==ID_RESOLVE && !nodep->taskp()) {
|
||||
if (nodep->dotted() == "") {
|
||||
AstNodeFTask* taskp = m_curVarsp->findIdName(nodep->name())->castNodeFTask();
|
||||
AstNodeFTask* taskp = m_curVarsp->findIdUpward(nodep->name())->castNodeFTask();
|
||||
if (!taskp) { nodep->v3error("Can't find definition of task/function: "<<nodep->prettyName()); }
|
||||
nodep->taskp(taskp);
|
||||
}
|
||||
@@ -306,16 +358,7 @@ private:
|
||||
// Cell: Resolve its filename. If necessary, parse it.
|
||||
if (m_idState==ID_FIND) {
|
||||
// Add to list of all cells, for error checking and defparam's
|
||||
AstNode* findidp = m_curVarsp->findIdName(nodep->name());
|
||||
AstCell* findcellp = findidp->castCell();
|
||||
if (!findidp) {
|
||||
m_curVarsp->insert(nodep->name(), nodep);
|
||||
} else if (!findcellp) {
|
||||
nodep->v3error("Unsupported in C: Cell has same name as "
|
||||
<<varTextType(findidp)<<": "<<nodep->prettyName());
|
||||
} else if (findcellp != nodep) {
|
||||
nodep->v3error("Duplicate name of cell: "<<nodep->prettyName());
|
||||
}
|
||||
findAndInsertAndCheck(nodep, nodep->name());
|
||||
}
|
||||
if (!nodep->modp()) {
|
||||
nodep->v3fatalSrc("Cell has unlinked module"); // V3LinkCell should have errored out
|
||||
@@ -339,13 +382,13 @@ private:
|
||||
if (m_idState==ID_PARAM) {
|
||||
// Need to set pin numbers after varnames are created
|
||||
// But before we do the final resolution based on names
|
||||
AstVar* refp = m_curVarsp->findIdName(nodep->name())->castVar();
|
||||
AstVar* refp = m_curVarsp->findIdFlat(nodep->name())->castVar();
|
||||
if (!refp) {
|
||||
nodep->v3error("Input/output/inout declaration not found for port: "<<nodep->prettyName());
|
||||
} else if (!refp->isIO()) {
|
||||
nodep->v3error("Pin is not a in/out/inout: "<<nodep->prettyName());
|
||||
nodep->v3error("Pin is not an in/out/inout: "<<nodep->prettyName());
|
||||
} else {
|
||||
m_curVarsp->insert("__pinNumber"+cvtToStr(nodep->pinNum()), refp);
|
||||
symsInsert("__pinNumber"+cvtToStr(nodep->pinNum()), refp);
|
||||
refp->user2(true);
|
||||
}
|
||||
// Ports not needed any more
|
||||
@@ -373,11 +416,11 @@ private:
|
||||
// Pin: Link to submodule's pin
|
||||
if (!m_cellVarsp) nodep->v3fatalSrc("Pin not under cell?\n");
|
||||
if (m_idState==ID_RESOLVE && !nodep->modVarp()) {
|
||||
AstVar* refp = m_cellVarsp->findIdName(nodep->name())->castVar();
|
||||
AstVar* refp = m_cellVarsp->findIdFlat(nodep->name())->castVar();
|
||||
if (!refp) {
|
||||
nodep->v3error("Pin not found: "<<nodep->prettyName());
|
||||
} else if (!refp->isIO() && !refp->isParam()) {
|
||||
nodep->v3error("Pin is not a in/out/inout/param: "<<nodep->prettyName());
|
||||
nodep->v3error("Pin is not an in/out/inout/param: "<<nodep->prettyName());
|
||||
} else {
|
||||
nodep->modVarp(refp);
|
||||
}
|
||||
@@ -403,8 +446,8 @@ private:
|
||||
virtual void visit(AstDefParam* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_idState==ID_PARAM) {
|
||||
AstNode* findidp = m_curVarsp->findIdName(nodep->path());
|
||||
AstCell* cellp = findidp->castCell();
|
||||
AstNode* foundp = m_curVarsp->findIdUpward(nodep->path());
|
||||
AstCell* cellp = foundp->castCell();
|
||||
if (!cellp) {
|
||||
nodep->v3error("In defparam, cell "<<nodep->path()<<" never declared");
|
||||
} else {
|
||||
@@ -436,6 +479,7 @@ public:
|
||||
m_ftaskp = NULL;
|
||||
m_paramNum = 0;
|
||||
m_beginNum = 0;
|
||||
m_inGenerate = false;
|
||||
//
|
||||
rootp->accept(*this);
|
||||
}
|
||||
|
||||
+12
-6
@@ -96,7 +96,11 @@ private:
|
||||
LinkCellsGraph m_graph; // Linked graph of all cell interconnects
|
||||
LibraryVertex* m_libVertexp; // Vertex at root of all libraries
|
||||
|
||||
//int debug() { return 9; }
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// METHODS
|
||||
V3GraphVertex* vertex(AstModule* nodep) {
|
||||
@@ -140,7 +144,9 @@ private:
|
||||
// Cell: Resolve its filename. If necessary, parse it.
|
||||
if (!nodep->modp()) {
|
||||
UINFO(4,"Link Cell: "<<nodep<<endl);
|
||||
AstModule* modp = m_mods.findIdName(nodep->modName())->castModule();
|
||||
// Use findIdUpward instead of findIdFlat; it doesn't matter for now
|
||||
// but we might support modules-under-modules someday.
|
||||
AstModule* modp = m_mods.findIdUpward(nodep->modName())->castModule();
|
||||
if (!modp) {
|
||||
// Read-subfile
|
||||
V3Read reader (v3Global.rootp());
|
||||
@@ -149,7 +155,7 @@ private:
|
||||
// We've read new modules, grab new pointers to their names
|
||||
readModNames();
|
||||
// Check again
|
||||
modp = m_mods.findIdName(nodep->modName())->castModule();
|
||||
modp = m_mods.findIdUpward(nodep->modName())->castModule();
|
||||
if (!modp) {
|
||||
nodep->v3error("Can't resolve module reference: "<<nodep->modName());
|
||||
}
|
||||
@@ -167,7 +173,7 @@ private:
|
||||
V3SymTable ports; // Symbol table of all connected port names
|
||||
for (AstPin* pinp = nodep->pinsp(); pinp; pinp=pinp->nextp()->castPin()) {
|
||||
if (pinp->name()=="") pinp->v3error("Connect by position is illegal in .* connected cells");
|
||||
if (!ports.findIdName(pinp->name())) {
|
||||
if (!ports.findIdFlat(pinp->name())) {
|
||||
ports.insert(pinp->name(), pinp);
|
||||
}
|
||||
}
|
||||
@@ -175,7 +181,7 @@ private:
|
||||
// and it's easier to do it now than in V3Link when we'd need to repeat steps.
|
||||
for (AstNode* portnodep = nodep->modp()->stmtsp(); portnodep; portnodep=portnodep->nextp()) {
|
||||
if (AstPort* portp = portnodep->castPort()) {
|
||||
if (!ports.findIdName(portp->name())) {
|
||||
if (!ports.findIdFlat(portp->name())) {
|
||||
UINFO(9," need PORT "<<portp<<endl);
|
||||
// Create any not already connected
|
||||
AstPin* newp = new AstPin(nodep->fileline(),0,portp->name(),
|
||||
@@ -210,7 +216,7 @@ private:
|
||||
void readModNames() {
|
||||
// Look at all modules, and store pointers to all module names
|
||||
for (AstModule* nodep = v3Global.rootp()->modulesp(); nodep; nodep=nodep->nextp()->castModule()) {
|
||||
AstNode* foundp = m_mods.findIdName(nodep->name());
|
||||
AstNode* foundp = m_mods.findIdUpward(nodep->name());
|
||||
if (foundp && foundp != nodep) {
|
||||
nodep->v3error("Duplicate declaration of module: "<<nodep->prettyName());
|
||||
foundp->v3error("... Location of original declaration");
|
||||
|
||||
+10
-3
@@ -186,8 +186,12 @@ private:
|
||||
bool m_forPrearray; // Compress cell__[array] refs
|
||||
bool m_forScopeCreation; // Remove VarXRefs for V3Scope
|
||||
public:
|
||||
static int debug() { return V3Error::debugDefault(); }
|
||||
// static int debug() { return 9; }
|
||||
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// CONSTRUCTORS
|
||||
LinkDotState(bool forPrearray, bool forScopeCreation) {
|
||||
@@ -356,7 +360,7 @@ public:
|
||||
<<((cellVxp->symPrefix()=="") ? "" : cellVxp->symPrefix()+dotname)
|
||||
<<" at "<<cellVxp
|
||||
<<endl);
|
||||
AstNode* nodep = cellVxp->syms().findIdName(cellVxp->symPrefix() + dotname); // Might be NULL
|
||||
AstNode* nodep = cellVxp->syms().findIdFlat(cellVxp->symPrefix() + dotname); // Might be NULL
|
||||
if (!nodep) baddot = dotname;
|
||||
return nodep;
|
||||
}
|
||||
@@ -372,6 +376,7 @@ private:
|
||||
LinkDotBaseVertex* m_inlineVxp; // Vertex for current module, possibly a fake inlined one
|
||||
string m_scope; // Scope text
|
||||
AstBegin* m_beginp; // Current Begin/end block
|
||||
|
||||
int debug() { return LinkDotState::debug(); }
|
||||
|
||||
// VISITs
|
||||
@@ -518,6 +523,7 @@ private:
|
||||
// STATE
|
||||
LinkDotState* m_statep; // State to pass between visitors, including symbol table
|
||||
LinkDotCellVertex* m_cellVxp; // Vertex for current module
|
||||
|
||||
int debug() { return LinkDotState::debug(); }
|
||||
|
||||
// VISITs
|
||||
@@ -580,6 +586,7 @@ private:
|
||||
// STATE
|
||||
LinkDotState* m_statep; // State, including dotted symbol table
|
||||
LinkDotCellVertex* m_cellVxp; // Vertex for current module
|
||||
|
||||
int debug() { return LinkDotState::debug(); }
|
||||
|
||||
// METHODS
|
||||
|
||||
@@ -46,9 +46,12 @@ private:
|
||||
bool m_setRefLvalue; // Set VarRefs to lvalues for pin assignments
|
||||
AstNodeFTask* m_ftaskp; // Function or task we're inside
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// VISITs
|
||||
// Result handing
|
||||
|
||||
+6
-2
@@ -55,9 +55,13 @@ private:
|
||||
AstParseRefExp m_exp; // Type of data we're looking for
|
||||
AstText* m_baseTextp; // Lowest TEXT node that needs replacement with varref
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
void checkExpected(AstNode* nodep) {
|
||||
if (m_exp != AstParseRefExp::NONE) {
|
||||
nodep->v3fatalSrc("Tree syntax error: Not expecting "<<nodep->type()<<" under a "<<nodep->backp()->type());
|
||||
|
||||
+13
-3
@@ -58,9 +58,13 @@ private:
|
||||
AstVAssert* m_assertp; // Current assertion
|
||||
int m_senitemCvtNum; // Temporary signal counter
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// VISITs
|
||||
virtual void visit(AstModule* nodep, AstNUser*) {
|
||||
// Module: Create sim table for entire module and iterate
|
||||
@@ -484,7 +488,13 @@ class LinkBotupVisitor : public AstNVisitor {
|
||||
private:
|
||||
// STATE
|
||||
AstModule* m_modp; // Current module
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// VISITs
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
|
||||
+6
-1
@@ -49,7 +49,12 @@ protected:
|
||||
// AstVar::user2() -> VarFlags. Flag state
|
||||
// AstVar::user4() -> AstVarRef*. First place signal set; must be first assignment
|
||||
|
||||
//int debug() { return 9; }
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// TYPES
|
||||
union VarFlags {
|
||||
|
||||
+6
-1
@@ -53,7 +53,12 @@ private:
|
||||
// STATE
|
||||
AstModule* m_modp;
|
||||
|
||||
//int debug() { return 9; }
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstModule* nodep, AstNUser*) {
|
||||
|
||||
+89
-23
@@ -303,23 +303,31 @@ 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)) {
|
||||
string V3Options::getenvStr(const string& envvar, const string& defaultValue) {
|
||||
if (const char* envvalue = getenv(envvar.c_str())) {
|
||||
return envvalue;
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
void V3Options::setenvStr(const string& envvar, const string& value, const string& why) {
|
||||
if (why != "") {
|
||||
UINFO(1,"export "<<envvar<<"="<<value<<" # "<<why<<endl);
|
||||
} else {
|
||||
UINFO(1,"export "<<envvar<<"="<<value<<endl);
|
||||
}
|
||||
setenv(envvar.c_str(),value.c_str(),true);
|
||||
}
|
||||
|
||||
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);
|
||||
setenvStr("SYSTEMC", var, "Hardcoded at build time");
|
||||
}
|
||||
// Only correct or check it if we really need the value
|
||||
if ((v3Global.opt.systemPerl() || v3Global.opt.systemC())
|
||||
&& !v3Global.opt.lintOnly()) {
|
||||
if (v3Global.opt.usingSystemCLibs()) {
|
||||
if (var == "") {
|
||||
v3fatal("Need $SYSTEMC in environment\n"
|
||||
"Probably System-C isn't installed, see http://www.systemc.org\n");
|
||||
@@ -327,12 +335,12 @@ string V3Options::getenvSYSTEMC() {
|
||||
}
|
||||
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);
|
||||
setenvStr("SYSTEMC_ARCH", var, "Hardcoded at build time");
|
||||
}
|
||||
if (var == "") {
|
||||
struct utsname uts;
|
||||
@@ -341,45 +349,73 @@ string V3Options::getenvSYSTEMC_ARCH() {
|
||||
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);
|
||||
setenvStr("SYSTEMC_ARCH", var,"From sysname '"+sysname+"'");
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
string V3Options::getenvSYSTEMPERL() {
|
||||
// Must be careful to set SYSTEMPERL_INCLUDE first else we'd setenv
|
||||
// SYSTEMPERL which would override a DEFENVed SYSTEMPERL_INCLUDE.
|
||||
V3Options::getenvSYSTEMPERL_INCLUDE();
|
||||
return V3Options::getenvSYSTEMPERLGuts();
|
||||
}
|
||||
|
||||
string V3Options::getenvSYSTEMPERLGuts() {
|
||||
// Get SYSTEMPERL when SYSTEMPERL_INCLUDE has already been tested
|
||||
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);
|
||||
setenvStr("SYSTEMPERL", var, "Hardcoded at build time");
|
||||
}
|
||||
// Only correct or check it if we really need the value
|
||||
if ((v3Global.opt.systemPerl() || v3Global.opt.trace()) && !v3Global.opt.lintOnly()) {
|
||||
if (v3Global.opt.usingSystemPerlLibs()) {
|
||||
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);
|
||||
setenvStr ("SYSTEMPERL", var, "From W");
|
||||
}
|
||||
}
|
||||
// Test for correctness in SYSTEMPERL_INCLUDE
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
string V3Options::getenvSYSTEMPERL_INCLUDE() {
|
||||
string var = getenvStr("SYSTEMPERL_INCLUDE","");
|
||||
if (var == "" && string(DEFENV_SYSTEMPERL_INCLUDE) != "") {
|
||||
// Note if SYSTEMPERL is DEFENVed, then SYSTEMPERL_INCLUDE is also DEFENVed
|
||||
// So we don't need to sweat testing SYSTEMPERL also
|
||||
var = DEFENV_SYSTEMPERL_INCLUDE;
|
||||
setenvStr("SYSTEMPERL_INCLUDE", var, "Hardcoded at build time");
|
||||
}
|
||||
// Only correct or check it if we really need the value
|
||||
if (v3Global.opt.usingSystemPerlLibs()) {
|
||||
if (var == "") {
|
||||
string sp = V3Options::getenvSYSTEMPERLGuts();
|
||||
var = sp+"/src";
|
||||
setenvStr ("SYSTEMPERL_INCLUDE", var, "From $SYSTEMPERL/src");
|
||||
}
|
||||
// We warn about $SYSTEMPERL instead of _INCLUDE since that's more likely
|
||||
// what users will want to set.
|
||||
if (var == "") {
|
||||
v3fatal("Need $SYSTEMPERL in environment for --sp or --trace\n"
|
||||
"Probably System-Perl isn't installed, see http://www.veripool.org/systemperl\n");
|
||||
}
|
||||
if (var != ""
|
||||
&& !V3Options::fileStatNormal(var+"/src/systemperl.h")) {
|
||||
v3fatal("$SYSTEMPERL environment var doesn't seem to point to System-Perl kit\n");
|
||||
&& !V3Options::fileStatNormal(var+"/systemperl.h")) {
|
||||
v3fatal("Neither $SYSTEMPERL nor $SYSTEMPERL_INCLUDE environment vars to point to System-Perl kit: "<<var<<endl);
|
||||
}
|
||||
}
|
||||
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);
|
||||
setenvStr("VERILATOR_ROOT", var.c_str(), "Hardcoded at build time");
|
||||
}
|
||||
if (var == "") {
|
||||
v3fatal("$VERILATOR_ROOT needs to be in environment\n");
|
||||
@@ -532,7 +568,7 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
||||
shift;
|
||||
} // + options
|
||||
else if (argv[i][0]=='-') {
|
||||
char *sw = argv[i];
|
||||
const char *sw = argv[i];
|
||||
bool flag = true;
|
||||
// Allow gnu -- switches
|
||||
if (sw[0]=='-' && sw[1]=='-') ++sw;
|
||||
@@ -544,6 +580,11 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
||||
shift;
|
||||
setDebugMode(atoi(argv[i]));
|
||||
}
|
||||
else if ( !strncmp (sw, "-debugi-", strlen("-debugi-"))) {
|
||||
const char* src = sw+strlen("-debugi-");
|
||||
shift;
|
||||
setDebugSrcLevel(src, atoi(argv[i]));
|
||||
}
|
||||
else if ( !strcmp (sw, "-error-limit") ) {
|
||||
shift;
|
||||
m_inlineMult = atoi(argv[i]);
|
||||
@@ -617,7 +658,8 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
||||
else if ( onoff (sw, "-inhibit-sim", flag/*ref*/)){ m_inhibitSim = flag; }
|
||||
else if ( onoff (sw, "-l2name", flag/*ref*/) ) { m_l2Name = flag; }
|
||||
else if ( onoff (sw, "-lint-only", flag/*ref*/) ) { m_lintOnly = flag; }
|
||||
else if ( onoff (sw, "-pins64", flag/*ref*/) ) { m_pins64 = flag; }
|
||||
else if ( !strcmp (sw, "-no-pins64") ) { m_pinsBv = 33; }
|
||||
else if ( !strcmp (sw, "-pins64") ) { m_pinsBv = 65; }
|
||||
else if ( !strcmp (sw, "-private") ) { m_public = false; }
|
||||
else if ( onoff (sw, "-profile-cfuncs", flag/*ref*/) ) { m_profileCFuncs = flag; }
|
||||
else if ( onoff (sw, "-psl", flag/*ref*/) ) { m_psl = flag; }
|
||||
@@ -631,7 +673,7 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
||||
else if ( onoff (sw, "-underline-zero", flag/*ref*/) ) { m_underlineZero = flag; }
|
||||
// Optimization
|
||||
else if ( !strncmp (sw, "-O", 2) ) {
|
||||
for (char* cp=sw+strlen("-O"); *cp; ++cp) {
|
||||
for (const char* cp=sw+strlen("-O"); *cp; ++cp) {
|
||||
flag = isupper(*cp);
|
||||
switch (tolower(*cp)) {
|
||||
case '0': optimize(0); break; // 0=all off
|
||||
@@ -735,6 +777,9 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
||||
else if ( !strcmp (sw, "-mod-prefix") && (i+1)<argc ) {
|
||||
shift; m_modPrefix = argv[i];
|
||||
}
|
||||
else if ( !strcmp (sw, "-pins-bv") && (i+1)<argc ) {
|
||||
shift; m_pinsBv = atoi(argv[i]);
|
||||
}
|
||||
else if ( !strcmp (sw, "-prefix") && (i+1)<argc ) {
|
||||
shift; m_prefix = argv[i];
|
||||
if (m_modPrefix=="") m_modPrefix = m_prefix;
|
||||
@@ -867,7 +912,7 @@ V3Options::V3Options() {
|
||||
m_makeDepend = true;
|
||||
m_makePhony = false;
|
||||
m_outFormatOk = false;
|
||||
m_pins64 = true;
|
||||
m_pinsBv = 65;
|
||||
m_profileCFuncs = false;
|
||||
m_preprocOnly = false;
|
||||
m_psl = false;
|
||||
@@ -919,6 +964,27 @@ void V3Options::setDebugMode(int level) {
|
||||
cout << "Starting "<<version()<<endl;
|
||||
}
|
||||
|
||||
void V3Options::setDebugSrcLevel(const string& srcfile, int level) {
|
||||
DebugSrcMap::iterator iter = m_debugSrcs.find(srcfile);
|
||||
if (iter!=m_debugSrcs.end()) {
|
||||
iter->second = level;
|
||||
} else {
|
||||
m_debugSrcs.insert(make_pair(srcfile,level));
|
||||
}
|
||||
}
|
||||
|
||||
int V3Options::debugSrcLevel(const string& srcfile_path, int default_level) {
|
||||
// For simplicity, calling functions can just use __FILE__ for srcfile.
|
||||
// That means though we need to cleanup the filename from ../Foo.cpp -> Foo
|
||||
string srcfile = V3Options::filenameNonDirExt(srcfile_path);
|
||||
DebugSrcMap::iterator iter = m_debugSrcs.find(srcfile);
|
||||
if (iter!=m_debugSrcs.end()) {
|
||||
return iter->second;
|
||||
} else {
|
||||
return default_level;
|
||||
}
|
||||
}
|
||||
|
||||
void V3Options::optimize(int level) {
|
||||
// Set all optimizations to on/off
|
||||
bool flag = level > 0;
|
||||
|
||||
+16
-4
@@ -26,6 +26,7 @@
|
||||
#include "verilatedos.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include "V3Global.h"
|
||||
@@ -75,6 +76,9 @@ typedef vector<string> V3StringList;
|
||||
typedef set<string> V3StringSet;
|
||||
|
||||
class V3Options {
|
||||
// TYPES
|
||||
typedef map<string,int> DebugSrcMap;
|
||||
|
||||
// MEMBERS (general options)
|
||||
V3OptionsImp* m_impp; // Slow hidden options
|
||||
|
||||
@@ -82,6 +86,7 @@ class V3Options {
|
||||
V3StringSet m_futures; // argument: -Wfuture- list
|
||||
V3StringSet m_libraryFiles; // argument: Verilog -v files
|
||||
V3StringList m_vFiles; // argument: Verilog files to read
|
||||
DebugSrcMap m_debugSrcs; // argument: --debugi-<srcfile>=<level>
|
||||
|
||||
bool m_preprocOnly; // main switch: -E
|
||||
bool m_makeDepend; // main switch: -MMD
|
||||
@@ -99,7 +104,6 @@ class V3Options {
|
||||
bool m_l2Name; // main switch: --l2name
|
||||
bool m_lintOnly; // main switch: --lint-only
|
||||
bool m_outFormatOk; // main switch: --cc, --sc or --sp was specified
|
||||
bool m_pins64; // main switch: --pins64
|
||||
bool m_profileCFuncs;// main switch: --profile-cfuncs
|
||||
bool m_psl; // main switch: --psl
|
||||
bool m_public; // main switch: --public
|
||||
@@ -116,6 +120,7 @@ class V3Options {
|
||||
int m_outputSplit; // main switch: --output-split
|
||||
int m_outputSplitCFuncs;// main switch: --output-split-cfuncs
|
||||
int m_outputSplitCTrace;// main switch: --output-split-ctrace
|
||||
int m_pinsBv; // main switch: --pins-bv
|
||||
int m_traceDepth; // main switch: --trace-depth
|
||||
int m_unrollCount; // main switch: --unroll-count
|
||||
int m_unrollStmts; // main switch: --unroll-stmts
|
||||
@@ -163,13 +168,17 @@ class V3Options {
|
||||
void coverage(bool flag) { m_coverageLine = m_coverageToggle = 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);
|
||||
static string getenvStr(const string& envvar, const string& defaultValue);
|
||||
static void setenvStr(const string& envvar, const string& value, const string& why);
|
||||
static string getenvSYSTEMPERLGuts();
|
||||
|
||||
public:
|
||||
// CREATORS
|
||||
V3Options();
|
||||
~V3Options();
|
||||
void setDebugMode(int level);
|
||||
void setDebugSrcLevel(const string& srcfile, int level);
|
||||
int debugSrcLevel(const string& srcfile, int default_level=V3Error::debugDefault());
|
||||
|
||||
// METHODS
|
||||
void addCppFile(const string& filename);
|
||||
@@ -185,9 +194,11 @@ class V3Options {
|
||||
string flags() const { return m_flags; }
|
||||
bool systemC() const { return m_systemC; }
|
||||
bool systemPerl() const { return m_systemPerl; }
|
||||
bool usingSystemCLibs() const { return !lintOnly() && (systemPerl() || systemC()); }
|
||||
bool usingSystemPerlLibs() const { return !lintOnly() && (systemPerl() || trace()); }
|
||||
bool skipIdentical() const { return m_skipIdentical; }
|
||||
bool stats() const { return m_stats; }
|
||||
bool assertOn() const { return m_assert; } // assertOn as "assert" may be defined
|
||||
bool assertOn() const { return m_assert; } // assertOn as __FILE__ may be defined
|
||||
bool autoflush() const { return m_autoflush; }
|
||||
bool coverage() const { return m_coverageLine || m_coverageToggle || m_coverageUser; }
|
||||
bool coverageLine() const { return m_coverageLine; }
|
||||
@@ -200,7 +211,6 @@ class V3Options {
|
||||
bool traceDups() const { return m_traceDups; }
|
||||
bool outFormatOk() const { return m_outFormatOk; }
|
||||
bool keepTempFiles() const { return (V3Error::debugDefault()!=0); }
|
||||
bool pins64() const { return m_pins64; }
|
||||
bool profileCFuncs() const { return m_profileCFuncs; }
|
||||
bool psl() const { return m_psl; }
|
||||
bool allPublic() const { return m_public; }
|
||||
@@ -214,6 +224,7 @@ class V3Options {
|
||||
int outputSplit() const { return m_outputSplit; }
|
||||
int outputSplitCFuncs() const { return m_outputSplitCFuncs; }
|
||||
int outputSplitCTrace() const { return m_outputSplitCTrace; }
|
||||
int pinsBv() const { return m_pinsBv; }
|
||||
int traceDepth() const { return m_traceDepth; }
|
||||
int unrollCount() const { return m_unrollCount; }
|
||||
int unrollStmts() const { return m_unrollStmts; }
|
||||
@@ -282,6 +293,7 @@ class V3Options {
|
||||
static string getenvSYSTEMC();
|
||||
static string getenvSYSTEMC_ARCH();
|
||||
static string getenvSYSTEMPERL();
|
||||
static string getenvSYSTEMPERL_INCLUDE();
|
||||
static string getenvVERILATOR_ROOT();
|
||||
static string getenvW() { return getenvStr("W",""); }
|
||||
|
||||
|
||||
+8
-4
@@ -121,10 +121,10 @@ class OrderMoveDomScope;
|
||||
void OrderGraph::loopsVertexCb(V3GraphVertex* vertexp) {
|
||||
if (debug()) cout<<"-Info-Loop: "<<vertexp<<" "<<endl;
|
||||
if (OrderLogicVertex* vvertexp = dynamic_cast<OrderLogicVertex*>(vertexp)) {
|
||||
cout<<V3Error::msgPrefix()<<" Example path: "<<vvertexp->nodep()->fileline()<<" "<<vvertexp->nodep()->typeName()<<endl;
|
||||
cerr<<V3Error::msgPrefix()<<" Example path: "<<vvertexp->nodep()->fileline()<<" "<<vvertexp->nodep()->typeName()<<endl;
|
||||
}
|
||||
if (OrderVarVertex* vvertexp = dynamic_cast<OrderVarVertex*>(vertexp)) {
|
||||
cout<<V3Error::msgPrefix()<<" Example path: "<<vvertexp->varScp()->fileline()<<" "<<vvertexp->varScp()->prettyName()<<endl;
|
||||
cerr<<V3Error::msgPrefix()<<" Example path: "<<vvertexp->varScp()->fileline()<<" "<<vvertexp->varScp()->prettyName()<<endl;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -254,8 +254,6 @@ private:
|
||||
AstUser3InUse m_inuser3;
|
||||
//AstUser4InUse m_inuser4; // Used only when building tree, so below
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
// STATE
|
||||
OrderGraph m_graph; // Scoreboard of var usages/dependencies
|
||||
SenTreeFinder m_finder; // Find global sentree's and add them
|
||||
@@ -296,6 +294,12 @@ private:
|
||||
enum VarUsage { VU_NONE=0, VU_CON=1, VU_GEN=2 };
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
void iterateNewStmt(AstNode* nodep) {
|
||||
if (m_scopep) {
|
||||
UINFO(4," STMT "<<nodep<<endl);
|
||||
|
||||
+7
-3
@@ -70,9 +70,13 @@ private:
|
||||
LongMap m_longMap; // Hash of very long names to unique identity number
|
||||
int m_longId;
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
void makeSmallNames(AstModule* modp) {
|
||||
vector<int> usedLetter; usedLetter.resize(256);
|
||||
// Pass 1, assign first letter to each gparam's name
|
||||
@@ -229,7 +233,7 @@ public:
|
||||
|
||||
void ParamVisitor::visit(AstCell* nodep, AstNUser*) {
|
||||
// Cell: Check for parameters in the instantiation.
|
||||
if (!nodep->modp()) { nodep->dumpTree(cout,"error:"); nodep->v3fatalSrc("Not linked?"); }
|
||||
if (!nodep->modp()) { nodep->dumpTree(cerr,"error:"); nodep->v3fatalSrc("Not linked?"); }
|
||||
if (nodep->paramsp()) {
|
||||
UINFO(4,"De-parameterize: "<<nodep<<endl);
|
||||
// Create new module name with _'s between the constants
|
||||
|
||||
+6
-2
@@ -43,11 +43,15 @@ protected:
|
||||
static V3PreShellImp s_preImp;
|
||||
static V3PreProc* s_preprocp;
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
//---------------------------------------
|
||||
// METHODS
|
||||
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
void boot(char** env) {
|
||||
// Create the implementation pointer
|
||||
if (env) {}
|
||||
|
||||
+6
-2
@@ -60,9 +60,13 @@ private:
|
||||
AstTraceInc* m_inTracep; // Inside while loop, special statement additions
|
||||
bool m_assignLhs; // Inside assignment lhs, don't breakup extracts
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
bool assignNoTemp(AstNodeAssign* nodep) {
|
||||
return (nodep->lhsp()->castVarRef()
|
||||
&& !nodep->lhsp()->castVarRef()->varp()->isSc()
|
||||
|
||||
@@ -51,6 +51,8 @@ class V3Read {
|
||||
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
|
||||
|
||||
// Options isn't visible, so not using debugSrcLevel
|
||||
//int debug() { return 9; }
|
||||
|
||||
protected:
|
||||
|
||||
+12
-3
@@ -56,7 +56,12 @@ private:
|
||||
AstCell* m_aboveCellp; // Cell that instantiates this module
|
||||
AstScope* m_aboveScopep; // Scope that instantiates this scope
|
||||
|
||||
//int debug() { return 9; }
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
@@ -250,9 +255,13 @@ private:
|
||||
// STATE
|
||||
AstScope* m_scopep; // Current scope we are building
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstScope* nodep, AstNUser*) {
|
||||
// Want to ignore blocks under it
|
||||
|
||||
+7
-1
@@ -55,8 +55,14 @@ private:
|
||||
// STATE
|
||||
AstTopScope* m_topscopep; // Top scope to add statement to
|
||||
vector<AstSenTree*> m_treesp; // List of sensitive blocks, for folding
|
||||
//int debug() { return 9; }
|
||||
|
||||
// VISITORS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
virtual void visit(AstModule* nodep, AstNUser*) {
|
||||
// Only do the top
|
||||
if (nodep->isTop()) {
|
||||
|
||||
+6
-2
@@ -235,9 +235,13 @@ private:
|
||||
uint32_t m_stepNum; // Step number we need to ignore a edge in
|
||||
V3Double0 m_statSplits; // Statistic tracking
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
void scoreboardClear() {
|
||||
//VV***** We reset user1p() and user2p on each block!!!
|
||||
m_inDly = false;
|
||||
|
||||
+5
-1
@@ -44,7 +44,11 @@
|
||||
class SplitAsBaseVisitor : public AstNVisitor {
|
||||
public:
|
||||
// METHODS
|
||||
//int debug() { return 9; }
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
||||
+6
-2
@@ -45,8 +45,11 @@
|
||||
|
||||
class SubstBaseVisitor : public AstNVisitor {
|
||||
public:
|
||||
static int debug() { return V3Error::debugDefault(); }
|
||||
// static int debug() { return 9; }
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
@@ -80,6 +83,7 @@ class SubstVarEntry {
|
||||
SubstVarWord m_whole; // Data for whole vector used at once
|
||||
vector<SubstVarWord> m_words; // Data for every word, if multi word variable
|
||||
int debug() { return SubstBaseVisitor::debug(); }
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
SubstVarEntry (AstVar* varp) { // Construction for when a var is used
|
||||
|
||||
+10
-2
@@ -1,3 +1,4 @@
|
||||
// -*- C++ -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: Symbol table
|
||||
//
|
||||
@@ -55,13 +56,20 @@ class V3SymTable : public AstNUser {
|
||||
m_idNameMap.insert(make_pair(name, nodep));
|
||||
}
|
||||
}
|
||||
AstNode* findIdName(const string& name) {
|
||||
AstNode* findIdFlat(const string& name) {
|
||||
// Find identifier without looking upward through symbol hierarchy
|
||||
//UINFO(9, " SymFind "<<this<<" '"<<name<<"' "<<endl);
|
||||
// First, scan this begin/end block or module for the name
|
||||
IdNameMap::iterator iter = m_idNameMap.find(name);
|
||||
if (iter != m_idNameMap.end()) return (iter->second);
|
||||
return NULL;
|
||||
}
|
||||
AstNode* findIdUpward(const string& name) {
|
||||
// Find identifier looking upward through symbol hierarchy
|
||||
// First, scan this begin/end block or module for the name
|
||||
if (AstNode* nodep = findIdFlat(name)) return nodep;
|
||||
// Then scan the upper begin/end block or module for the name
|
||||
if (m_upperp) return m_upperp->findIdName(name);
|
||||
if (m_upperp) return m_upperp->findIdUpward(name);
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
|
||||
+5
-2
@@ -54,8 +54,11 @@ class TableVisitor;
|
||||
class TableBaseVisitor : public AstNVisitor {
|
||||
public:
|
||||
// Note level 8&9 include debugging each simulation value
|
||||
// int debug() { return 7; }
|
||||
// int debug() { return 9; }
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
||||
+6
-1
@@ -314,9 +314,14 @@ private:
|
||||
InsertMode m_insMode; // How to insert
|
||||
AstNode* m_insStmtp; // Where to insert statement
|
||||
int m_modNCalls; // Incrementing func # for making symbols
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
AstVarScope* createVarScope(AstVar* invarp, const string& name) {
|
||||
// We could create under either the ref's scope or the ftask's scope.
|
||||
// It shouldn't matter, as they are only local variables.
|
||||
|
||||
+6
-2
@@ -189,9 +189,13 @@ private:
|
||||
V3Double0 m_statUniqSigs; // Statistic tracking
|
||||
V3Double0 m_statUniqCodes;// Statistic tracking
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
void detectDuplicates() {
|
||||
UINFO(9,"Finding duplicates\n");
|
||||
// Note uses user4
|
||||
|
||||
+6
-1
@@ -54,9 +54,14 @@ private:
|
||||
|
||||
V3Double0 m_statSigs; // Statistic tracking
|
||||
V3Double0 m_statIgnSigs; // Statistic tracking
|
||||
//int debug() { return 9; }
|
||||
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
const char* varIgnoreTrace(AstVar* nodep) {
|
||||
// Return true if this shouldn't be traced
|
||||
// See also similar rule in V3Coverage::varIgnoreToggle
|
||||
|
||||
+5
-1
@@ -68,7 +68,11 @@ typedef std::map<AstVar*, RefVec*> VarMap;
|
||||
|
||||
class TristateBaseVisitor : public AstNVisitor {
|
||||
public:
|
||||
//int debug() { return 9; }
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
};
|
||||
|
||||
//######################################################################
|
||||
|
||||
+6
-1
@@ -58,7 +58,12 @@ private:
|
||||
bool m_constXCvt; // Convert X's
|
||||
V3Double0 m_statUnkVars; // Statistic tracking
|
||||
|
||||
//int debug() { return 9; }
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstModule* nodep, AstNUser*) {
|
||||
|
||||
+7
-2
@@ -59,7 +59,12 @@ private:
|
||||
V3Double0 m_statLoops; // Statistic tracking
|
||||
V3Double0 m_statIters; // Statistic tracking
|
||||
|
||||
//int debug() { return 9; }
|
||||
// METHODS
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
virtual void visit(AstModule* nodep, AstNUser*) {
|
||||
@@ -339,7 +344,7 @@ private:
|
||||
if (m_generate) { // Ignore for's when expanding genfor's
|
||||
nodep->iterateChildren(*this);
|
||||
} else {
|
||||
nodep->v3error("V3Task should have removed standard FORs");
|
||||
nodep->v3error("V3Begin should have removed standard FORs");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+18
-11
@@ -81,15 +81,18 @@ private:
|
||||
AstRange* m_cellRangep; // Range for arrayed instantiations, NULL for normal instantiations
|
||||
AstNodeCase* m_casep; // Current case statement CaseItem is under
|
||||
|
||||
//int debug() { return 9; }
|
||||
|
||||
// CLASSES
|
||||
#define ANYSIZE 0
|
||||
|
||||
// METHODS
|
||||
// Naming: width_{output size rule}_{lhs rule}_{rhs rule}
|
||||
static int debug() {
|
||||
static int level = -1;
|
||||
if (VL_UNLIKELY(level < 0)) level = v3Global.opt.debugSrcLevel(__FILE__);
|
||||
return level;
|
||||
}
|
||||
|
||||
// VISITORS
|
||||
// Naming: width_{output size rule}_{lhs rule}_{rhs rule}
|
||||
// Widths: 1 bit out, lhs 1 bit
|
||||
void width_O1_L1(AstNode* nodep, AstNUser* vup);
|
||||
virtual void visit(AstLogNot* nodep, AstNUser* vup) { width_O1_L1(nodep,vup); }
|
||||
@@ -476,9 +479,9 @@ private:
|
||||
nodep->sensesp()->iterateAndNext(*this);
|
||||
if (nodep->disablep()) {
|
||||
nodep->disablep()->iterateAndNext(*this,WidthVP(1,1,BOTH).p());
|
||||
widthCheckReduce(nodep,"Disable",nodep->disablep(),1,1); // it's like a if() condition.
|
||||
widthCheckReduce(nodep,"Disable",nodep->disablep(),1,1); // it's like an if() condition.
|
||||
}
|
||||
widthCheckReduce(nodep,"Property",nodep->propp(),1,1); // it's like a if() condition.
|
||||
widthCheckReduce(nodep,"Property",nodep->propp(),1,1); // it's like an if() condition.
|
||||
nodep->width(1,1);
|
||||
}
|
||||
|
||||
@@ -533,14 +536,18 @@ private:
|
||||
nodep->condp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p());
|
||||
if (!nodep->castGenFor()) nodep->bodysp()->iterateAndNext(*this);
|
||||
nodep->incsp()->iterateAndNext(*this);
|
||||
widthCheckReduce(nodep,"For Test Condition",nodep->condp(),1,1); // it's like a if() condition.
|
||||
widthCheckReduce(nodep,"For Test Condition",nodep->condp(),1,1); // it's like an if() condition.
|
||||
}
|
||||
virtual void visit(AstRepeat* nodep, AstNUser*) {
|
||||
nodep->countp()->iterateAndNext(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
nodep->bodysp()->iterateAndNext(*this);
|
||||
}
|
||||
virtual void visit(AstWhile* nodep, AstNUser*) {
|
||||
// TOP LEVEL NODE
|
||||
nodep->precondsp()->iterateAndNext(*this);
|
||||
nodep->condp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p());
|
||||
nodep->bodysp()->iterateAndNext(*this);
|
||||
widthCheckReduce(nodep,"For Test Condition",nodep->condp(),1,1); // it's like a if() condition.
|
||||
widthCheckReduce(nodep,"For Test Condition",nodep->condp(),1,1); // it's like an if() condition.
|
||||
}
|
||||
virtual void visit(AstNodeIf* nodep, AstNUser*) {
|
||||
// TOP LEVEL NODE
|
||||
@@ -550,7 +557,7 @@ private:
|
||||
nodep->elsesp()->iterateAndNext(*this);
|
||||
}
|
||||
nodep->condp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p());
|
||||
widthCheckReduce(nodep,"If",nodep->condp(),1,1); // it's like a if() condition.
|
||||
widthCheckReduce(nodep,"If",nodep->condp(),1,1); // it's like an if() condition.
|
||||
//if (debug()) nodep->dumpTree(cout," IfPos: ");
|
||||
}
|
||||
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
||||
@@ -651,19 +658,19 @@ private:
|
||||
// TOP LEVEL NODE
|
||||
nodep->propp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p());
|
||||
nodep->stmtsp()->iterateChildren(*this,WidthVP(ANYSIZE,0,BOTH).p());
|
||||
widthCheckReduce(nodep,"Property",nodep->propp(),1,1); // it's like a if() condition.
|
||||
widthCheckReduce(nodep,"Property",nodep->propp(),1,1); // it's like an if() condition.
|
||||
}
|
||||
virtual void visit(AstPslAssert* nodep, AstNUser*) {
|
||||
// TOP LEVEL NODE
|
||||
nodep->propp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p());
|
||||
widthCheckReduce(nodep,"Property",nodep->propp(),1,1); // it's like a if() condition.
|
||||
widthCheckReduce(nodep,"Property",nodep->propp(),1,1); // it's like an if() condition.
|
||||
}
|
||||
virtual void visit(AstVAssert* nodep, AstNUser*) {
|
||||
// TOP LEVEL NODE
|
||||
nodep->propp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p());
|
||||
nodep->passsp()->iterateAndNext(*this);
|
||||
nodep->failsp()->iterateAndNext(*this);
|
||||
widthCheckReduce(nodep,"Property",nodep->propp(),1,1); // it's like a if() condition.
|
||||
widthCheckReduce(nodep,"Property",nodep->propp(),1,1); // it's like an if() condition.
|
||||
}
|
||||
virtual void visit(AstPin* nodep, AstNUser*) {
|
||||
//if (debug()) nodep->dumpTree(cout,"- PinPre: ");
|
||||
|
||||
@@ -538,6 +538,7 @@ int main(int argc, char** argv, char** env) {
|
||||
V3Options::getenvSYSTEMC();
|
||||
V3Options::getenvSYSTEMC_ARCH();
|
||||
V3Options::getenvSYSTEMPERL();
|
||||
V3Options::getenvSYSTEMPERL_INCLUDE();
|
||||
|
||||
V3Error::abortIfErrors();
|
||||
|
||||
|
||||
+52
-10
@@ -9,7 +9,7 @@ use Pod::Usage;
|
||||
use strict;
|
||||
use vars qw ($Debug $VERSION);
|
||||
|
||||
$VERSION = '3.035';
|
||||
$VERSION = '3.101';
|
||||
|
||||
#======================================================================
|
||||
# main
|
||||
@@ -45,8 +45,8 @@ if (! GetOptions (
|
||||
die "%Error: Bad usage, try 'bisonpre --help'\n";
|
||||
}
|
||||
|
||||
$Opt_Input or die "bisonpp: %Error: input file not specified\n";
|
||||
$Opt_Output or die "bisonpp: %Error: --o option is required\n";
|
||||
$Opt_Input or die "bisonpre: %Error: input file not specified\n";
|
||||
$Opt_Output or die "bisonpre: %Error: --o option is required\n";
|
||||
|
||||
process();
|
||||
|
||||
@@ -63,7 +63,7 @@ sub parameter {
|
||||
if (!defined $Opt_Input) {
|
||||
$Opt_Input = $param;
|
||||
} else {
|
||||
die "bisonpp: %Error: Unknown parameter: $param\n";
|
||||
die "bisonpre: %Error: Unknown parameter: $param\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +91,7 @@ sub process {
|
||||
if ($status != 0) {
|
||||
remove_outputs();
|
||||
my $v = bison_version_check();
|
||||
die "bisonpp: %Error: $Opt_Yacc version $v run failed due to errors\n";
|
||||
die "bisonpre: %Error: $Opt_Yacc version $v run failed due to errors\n";
|
||||
}
|
||||
|
||||
clean_output(tmp_prefix().".output",output_prefix().".output");
|
||||
@@ -133,10 +133,10 @@ sub bison_version_check {
|
||||
my $v = `$Opt_Yacc --version`;
|
||||
if ($v && $v =~ /([0-9]+\.[0-9]+)/) {
|
||||
my $v = $1;
|
||||
($v >= 1.875) or die "bisonpp: %Error: '$Opt_Yacc' is version $v; version 1.875 or newer is required\n";
|
||||
($v >= 1.875) or die "bisonpre: %Error: '$Opt_Yacc' is version $v; version 1.875 or newer is required\n";
|
||||
return $v;
|
||||
} else {
|
||||
die "bisonpp: %Error: '$Opt_Yacc' is not installed, or not working\n";
|
||||
die "bisonpre: %Error: '$Opt_Yacc' is not installed, or not working\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,12 +188,50 @@ sub clean_input {
|
||||
my @lines = $fh->getlines;
|
||||
$fh->close;
|
||||
|
||||
# Find "rule<type>:"
|
||||
# Find "%tokens<type>:"
|
||||
my %tokens;
|
||||
foreach my $line (@lines) {
|
||||
if ($line =~ /^%token\s*<(\S+)>\s*(\S+)/) {
|
||||
$tokens{$2} = $1;
|
||||
}
|
||||
}
|
||||
|
||||
# Replace BISONPRE_NOT(type,...) with expanded list
|
||||
{
|
||||
my @linesin = @lines; @lines=(); my $l=0;
|
||||
foreach my $line (@linesin) {
|
||||
if ($line =~ /BISONPRE_NOT/) {
|
||||
($line =~ s/BISONPRE_NOT\((\S+)\)\s*({[^}]+})\s*$//)
|
||||
or die "%Error: $filename:$l: Bad form of BISONPRE_NOT: $line\n";
|
||||
my $endtok = $1; my $action = $2;
|
||||
my @endtoks = split (/,/, $endtok);
|
||||
map { $tokens{$_} or die "%Error: $filename:$l: Can't find definition for token: $_\n"
|
||||
} @endtoks;
|
||||
# Push it all onto one line to avoid error messages changing
|
||||
my $bar = "";
|
||||
tok:
|
||||
foreach my $tok (sort keys %tokens) {
|
||||
foreach (@endtoks) {
|
||||
next tok if $tok eq $_;
|
||||
}
|
||||
if ($endtok ne $tok) {
|
||||
$line .= "\t$bar $tok $action";
|
||||
$bar = "|";
|
||||
}
|
||||
}
|
||||
$line .= "\n";
|
||||
}
|
||||
push @lines, $line;
|
||||
}
|
||||
}
|
||||
|
||||
# Find "rule<type>:" and replace with just "rule:"
|
||||
my %types;
|
||||
{
|
||||
my @linesin = @lines; @lines=(); my $l=0;
|
||||
foreach my $line (@linesin) {
|
||||
if ($line =~ s/^(\S+)<(\S+)>:/$1:/) {
|
||||
# ^/ to prevent comments from matching
|
||||
if ($line =~ s/^([^<\/ \t\n]+)<(\S+)>:/$1:/) {
|
||||
$types{$2}{$1} = 1;
|
||||
}
|
||||
push @lines, $line;
|
||||
@@ -268,7 +306,11 @@ This is expanded into %type declarations.
|
||||
=item rule_label<type>:
|
||||
|
||||
This allows the label declaring a rule to also specify the type of the
|
||||
rule. The type will be inserted where /*BISONPP_TYPES*/ is encountered.
|
||||
rule. The type will be inserted where /*BISONPRE_TYPES*/ is encountered.
|
||||
|
||||
=item BISONPRE_NOT(token[, token...])
|
||||
|
||||
Create a rule that matches every token except for those specified.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
//**********************************************************************
|
||||
//**** Version and host name
|
||||
|
||||
#define DTVERSION "Verilator 3.700 2009/01/08"
|
||||
#define DTVERSION "Verilator 3.702 2009/03/28"
|
||||
|
||||
//**********************************************************************
|
||||
//**** Functions
|
||||
@@ -73,6 +73,9 @@
|
||||
#ifndef DEFENV_SYSTEMPERL
|
||||
# define DEFENV_SYSTEMPERL ""
|
||||
#endif
|
||||
#ifndef DEFENV_SYSTEMPERL_INCLUDE
|
||||
# define DEFENV_SYSTEMPERL_INCLUDE ""
|
||||
#endif
|
||||
#ifndef DEFENV_VERILATOR_ROOT
|
||||
# define DEFENV_VERILATOR_ROOT ""
|
||||
#endif
|
||||
|
||||
+2
-2
@@ -199,6 +199,7 @@ escid \\[^ \t\f\r\n]+
|
||||
"endspecify" {yylval.fileline = CRELINE(); return yENDSPECIFY;}
|
||||
"endtask" {yylval.fileline = CRELINE(); return yENDTASK;}
|
||||
"for" {yylval.fileline = CRELINE(); return yFOR;}
|
||||
"forever" {yylval.fileline = CRELINE(); return yFOREVER;}
|
||||
"function" {yylval.fileline = CRELINE(); return yFUNCTION;}
|
||||
"if" {yylval.fileline = CRELINE(); return yIF;}
|
||||
"initial" {yylval.fileline = CRELINE(); return yINITIAL;}
|
||||
@@ -220,6 +221,7 @@ escid \\[^ \t\f\r\n]+
|
||||
"pulldown" {yylval.fileline = CRELINE(); return yPULLDOWN;}
|
||||
"pullup" {yylval.fileline = CRELINE(); return yPULLUP;}
|
||||
"reg" {yylval.fileline = CRELINE(); return yREG;}
|
||||
"repeat" {yylval.fileline = CRELINE(); return yREPEAT;}
|
||||
"scalared" {yylval.fileline = CRELINE(); return ySCALARED;}
|
||||
"specify" {yylval.fileline = CRELINE(); return ySPECIFY;}
|
||||
"specparam" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
|
||||
@@ -252,7 +254,6 @@ escid \\[^ \t\f\r\n]+
|
||||
"endtable" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
"event" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
"force" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
"forever" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
"fork" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
"highz0" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
"highz1" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
@@ -268,7 +269,6 @@ escid \\[^ \t\f\r\n]+
|
||||
"real" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
"realtime" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
"release" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
"repeat" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
"rnmos" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
"rpmos" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
"rtran" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
|
||||
+286
-271
@@ -129,9 +129,13 @@ class AstSenTree;
|
||||
AstVarRef* varrefp;
|
||||
}
|
||||
|
||||
// When writing Bison patterns we use yTOKEN instead of "token",
|
||||
// so Bison will error out on unknown "token"s.
|
||||
|
||||
// Generic lexer tokens, for example a number
|
||||
// IEEE: real_number
|
||||
%token<cdouble> yaFLOATNUM "FLOATING-POINT NUMBER"
|
||||
|
||||
// IEEE: identifier, class_identifier, class_variable_identifier,
|
||||
// covergroup_variable_identifier, dynamic_array_variable_identifier,
|
||||
// enum_identifier, interface_identifier, interface_instance_identifier,
|
||||
@@ -153,6 +157,33 @@ class AstSenTree;
|
||||
%token<strp> yaSCCTOR "`systemc_implementation BLOCK"
|
||||
%token<strp> yaSCDTOR "`systemc_imp_header BLOCK"
|
||||
|
||||
%token<fileline> '!'
|
||||
%token<fileline> '#'
|
||||
%token<fileline> '%'
|
||||
%token<fileline> '&'
|
||||
%token<fileline> '('
|
||||
%token<fileline> ')'
|
||||
%token<fileline> '*'
|
||||
%token<fileline> '+'
|
||||
%token<fileline> ','
|
||||
%token<fileline> '-'
|
||||
%token<fileline> '.'
|
||||
%token<fileline> '/'
|
||||
%token<fileline> ':'
|
||||
%token<fileline> ';'
|
||||
%token<fileline> '<'
|
||||
%token<fileline> '='
|
||||
%token<fileline> '>'
|
||||
%token<fileline> '?'
|
||||
%token<fileline> '@'
|
||||
%token<fileline> '['
|
||||
%token<fileline> ']'
|
||||
%token<fileline> '^'
|
||||
%token<fileline> '{'
|
||||
%token<fileline> '|'
|
||||
%token<fileline> '}'
|
||||
%token<fileline> '~'
|
||||
|
||||
// Specific keywords
|
||||
// yKEYWORD means match "keyword"
|
||||
// Other cases are yXX_KEYWORD where XX makes it unique,
|
||||
@@ -187,6 +218,7 @@ class AstSenTree;
|
||||
%token<fileline> yENDTASK "endtask"
|
||||
%token<fileline> yFINAL "final"
|
||||
%token<fileline> yFOR "for"
|
||||
%token<fileline> yFOREVER "forever"
|
||||
%token<fileline> yFUNCTION "function"
|
||||
%token<fileline> yGENERATE "generate"
|
||||
%token<fileline> yGENVAR "genvar"
|
||||
@@ -213,6 +245,7 @@ class AstSenTree;
|
||||
%token<fileline> yPULLDOWN "pulldown"
|
||||
%token<fileline> yPULLUP "pullup"
|
||||
%token<fileline> yREG "reg"
|
||||
%token<fileline> yREPEAT "repeat"
|
||||
%token<fileline> ySCALARED "scalared"
|
||||
%token<fileline> ySIGNED "signed"
|
||||
%token<fileline> ySPECIFY "specify"
|
||||
@@ -335,37 +368,9 @@ class AstSenTree;
|
||||
%token<fileline> yPSL_KET "}"
|
||||
%token<fileline> yP_LOGIFF
|
||||
|
||||
%token<fileline> '!'
|
||||
%token<fileline> '#'
|
||||
%token<fileline> '%'
|
||||
%token<fileline> '&'
|
||||
%token<fileline> '('
|
||||
%token<fileline> ')'
|
||||
%token<fileline> '*'
|
||||
%token<fileline> '+'
|
||||
%token<fileline> ','
|
||||
%token<fileline> '-'
|
||||
%token<fileline> '.'
|
||||
%token<fileline> '/'
|
||||
%token<fileline> ':'
|
||||
%token<fileline> ';'
|
||||
%token<fileline> '<'
|
||||
%token<fileline> '='
|
||||
%token<fileline> '>'
|
||||
%token<fileline> '?'
|
||||
%token<fileline> '@'
|
||||
%token<fileline> '['
|
||||
%token<fileline> ']'
|
||||
%token<fileline> '^'
|
||||
%token<fileline> '{'
|
||||
%token<fileline> '|'
|
||||
%token<fileline> '}'
|
||||
%token<fileline> '~'
|
||||
|
||||
// [* is not a operator, as "[ * ]" is legal
|
||||
// [= and [-> could be repitition operators, but to match [* we don't add them.
|
||||
// '( is not a operator, as "' (" is legal
|
||||
// '{ could be an operator. More research needed.
|
||||
|
||||
//********************
|
||||
// PSL op precedence
|
||||
@@ -374,13 +379,11 @@ class AstSenTree;
|
||||
%left<fileline> prPSLCLK
|
||||
|
||||
// Verilog op precedence
|
||||
%left ':'
|
||||
%left '?'
|
||||
%right '?' ':'
|
||||
%left yP_OROR
|
||||
%left yP_ANDAND
|
||||
%left '|' yP_NOR
|
||||
%left '^'
|
||||
%left yP_XNOR
|
||||
%left '^' yP_XNOR
|
||||
%left '&' yP_NAND
|
||||
%left yP_EQUAL yP_NOTEQUAL yP_CASEEQUAL yP_CASENOTEQUAL yP_WILDEQUAL yP_WILDNOTEQUAL
|
||||
%left '>' '<' yP_GTE yP_LTE
|
||||
@@ -388,18 +391,11 @@ class AstSenTree;
|
||||
%left '+' '-'
|
||||
%left '*' '/' '%'
|
||||
%left yP_POW
|
||||
%left '{' '}'
|
||||
%left<fileline> prUNARYARITH
|
||||
%left<fileline> prREDUCTION
|
||||
%left<fileline> prNEGATION
|
||||
%left prUNARYARITH prREDUCTION prNEGATION
|
||||
|
||||
%nonassoc prLOWER_THAN_ELSE
|
||||
%nonassoc yELSE
|
||||
|
||||
// Types are in same order as declarations.
|
||||
// Naming:
|
||||
// Trailing E indicates this type may have empty match
|
||||
|
||||
//BISONPRE_TYPES
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
@@ -419,63 +415,77 @@ class AstSenTree;
|
||||
// Blank lines for type insertion
|
||||
// Blank lines for type insertion
|
||||
|
||||
%start fileE
|
||||
%start source_text
|
||||
|
||||
%%
|
||||
//**********************************************************************
|
||||
// Feedback to the Lexer
|
||||
// Note we read a parenthesis ahead, so this may not change the lexer at the right point.
|
||||
|
||||
stateExitPsl: /* empty */ { V3Read::stateExitPsl(); }
|
||||
stateExitPsl: // For PSL lexing, return from PSL state
|
||||
/* empty */ { V3Read::stateExitPsl(); }
|
||||
;
|
||||
statePushVlg: /* empty */ { V3Read::statePushVlg(); }
|
||||
statePushVlg: // For PSL lexing, escape current state into Verilog state
|
||||
/* empty */ { V3Read::statePushVlg(); }
|
||||
;
|
||||
statePop: /* empty */ { V3Read::statePop(); }
|
||||
statePop: // Return to previous lexing state
|
||||
/* empty */ { V3Read::statePop(); }
|
||||
;
|
||||
|
||||
//**********************************************************************
|
||||
// Files
|
||||
|
||||
fileE: /* empty */ { }
|
||||
| timeunitsDeclE file { }
|
||||
source_text: // ==IEEE: source_text
|
||||
/* empty */ { }
|
||||
| timeunits_declarationE descriptionList { }
|
||||
;
|
||||
|
||||
file: description { }
|
||||
| file description { }
|
||||
descriptionList: // IEEE: part of source_text
|
||||
description { }
|
||||
| descriptionList description { }
|
||||
;
|
||||
|
||||
// IEEE: description
|
||||
description: moduleDecl { }
|
||||
description: // ==IEEE: description
|
||||
module_declaration { }
|
||||
// | interface_declaration { }
|
||||
// | program_declaration { }
|
||||
// | package_declaration { }
|
||||
// | package_item { }
|
||||
// | bind_directive { }
|
||||
// unsupported // IEEE: config_declaration
|
||||
| error { }
|
||||
;
|
||||
|
||||
// IEEE: timeunits_declaration + empty
|
||||
timeunitsDeclE: /*empty*/ { }
|
||||
| yTIMEUNIT yaTIMENUM ';' { }
|
||||
timeunits_declarationE: // IEEE: timeunits_declaration + empty
|
||||
/*empty*/ { }
|
||||
| yTIMEUNIT yaTIMENUM ';' { }
|
||||
| yTIMEPRECISION yaTIMENUM ';' { }
|
||||
| yTIMEUNIT yaTIMENUM ';' yTIMEPRECISION yaTIMENUM ';' { }
|
||||
| yTIMEPRECISION yaTIMENUM ';' yTIMEUNIT yaTIMENUM ';' { }
|
||||
| yTIMEUNIT yaTIMENUM ';' yTIMEPRECISION yaTIMENUM ';' { }
|
||||
| yTIMEPRECISION yaTIMENUM ';' yTIMEUNIT yaTIMENUM ';' { }
|
||||
;
|
||||
|
||||
//**********************************************************************
|
||||
// Module headers
|
||||
|
||||
// IEEE: module_declaration:
|
||||
moduleDecl: modHeader timeunitsDeclE modItemListE yENDMODULE endLabelE
|
||||
module_declaration: // ==IEEE: module_declaration (incomplete)
|
||||
modHeader timeunits_declarationE module_itemListE yENDMODULE endLabelE
|
||||
{ if ($3) $1->addStmtp($3); }
|
||||
;
|
||||
|
||||
modHeader<modulep>:
|
||||
modHdr modParE modPortsE ';'
|
||||
modHeader<modulep>: // IEEE: module_nonansi_header + module_ansi_header
|
||||
modHdr parameter_port_listE modPortsStarE ';'
|
||||
{ $1->modTrace(v3Global.opt.trace() && $1->fileline()->tracingOn()); // Stash for implicit wires, etc
|
||||
if ($2) $1->addStmtp($2); if ($3) $1->addStmtp($3); }
|
||||
;
|
||||
|
||||
modHdr<modulep>:
|
||||
yMODULE yaID { $$ = new AstModule($1,*$2); $$->inLibrary(V3Read::inLibrary()||V3Read::inCellDefine());
|
||||
$$->modTrace(v3Global.opt.trace());
|
||||
V3Read::rootp()->addModulep($$); }
|
||||
yMODULE lifetimeE yaID
|
||||
{ $$ = new AstModule($1,*$3); $$->inLibrary(V3Read::inLibrary()||V3Read::inCellDefine());
|
||||
$$->modTrace(v3Global.opt.trace());
|
||||
V3Read::rootp()->addModulep($$); }
|
||||
;
|
||||
|
||||
modParE<nodep>:
|
||||
parameter_port_listE<nodep>: // IEEE: parameter_port_list + empty == parameter_value_assignment
|
||||
/* empty */ { $$ = NULL; }
|
||||
| '#' '(' ')' { $$ = NULL; }
|
||||
| '#' '(' modParArgs ')' { $$ = $3; }
|
||||
@@ -497,7 +507,7 @@ modParSecond<nodep>:
|
||||
| param { $$ = $1; }
|
||||
;
|
||||
|
||||
modPortsE<nodep>:
|
||||
modPortsStarE<nodep>:
|
||||
/* empty */ { $$ = NULL; }
|
||||
| '(' ')' { $$ = NULL; }
|
||||
| '(' {V3Parse::s_pinNum=1;} portList ')' { $$ = $3; }
|
||||
@@ -553,19 +563,18 @@ regsigList<varp>:
|
||||
;
|
||||
|
||||
portV2kDecl<nodep>:
|
||||
varRESET portDirection v2kVarDeclE signingE regrangeE portV2kInit { $$ = $6; }
|
||||
varRESET port_direction v2kVarDeclE signingE regrangeE portV2kInit { $$ = $6; }
|
||||
;
|
||||
|
||||
// IEEE: port_declaration - plus ';'
|
||||
portDecl<nodep>:
|
||||
varRESET portDirection v2kVarDeclE signingE regrangeE regsigList ';' { $$ = $6; }
|
||||
portDecl<nodep>: // IEEE: port_declaration - plus ';'
|
||||
varRESET port_direction v2kVarDeclE signingE regrangeE regsigList ';' { $$ = $6; }
|
||||
;
|
||||
|
||||
varDecl<nodep>:
|
||||
varRESET varReg signingE regrangeE regsigList ';' { $$ = $5; }
|
||||
| varRESET varGParam signingE regrangeE paramList ';' { $$ = $5; }
|
||||
| varRESET varLParam signingE regrangeE paramList ';' { $$ = $5; }
|
||||
| varRESET varNet signingE delayrange netSigList ';' { $$ = $5; }
|
||||
| varRESET net_type signingE delayrange netSigList ';' { $$ = $5; }
|
||||
| varRESET varGenVar signingE regsigList ';' { $$ = $4; }
|
||||
;
|
||||
|
||||
@@ -573,10 +582,12 @@ modParDecl<nodep>:
|
||||
varRESET varGParam signingE regrangeE param { $$ = $5; }
|
||||
;
|
||||
|
||||
varRESET: /* empty */ { VARRESET(); }
|
||||
varRESET:
|
||||
/* empty */ { VARRESET(); }
|
||||
;
|
||||
|
||||
varNet: ySUPPLY0 { VARDECL(SUPPLY0); }
|
||||
net_type: // ==IEEE: net_type
|
||||
ySUPPLY0 { VARDECL(SUPPLY0); }
|
||||
| ySUPPLY1 { VARDECL(SUPPLY1); }
|
||||
| yWIRE { VARDECL(WIRE); }
|
||||
| yTRI { VARDECL(TRIWIRE); }
|
||||
@@ -591,40 +602,44 @@ varReg: yREG { VARDECL(REG); }
|
||||
| yINTEGER { VARDECL(INTEGER); }
|
||||
;
|
||||
|
||||
//IEEE: port_direction
|
||||
portDirection: yINPUT { VARIO(INPUT); }
|
||||
port_direction: // ==IEEE: port_direction
|
||||
yINPUT { VARIO(INPUT); }
|
||||
| yOUTPUT { VARIO(OUTPUT); }
|
||||
| yINOUT { VARIO(INOUT); }
|
||||
// | yREF { VARIO(REF); }
|
||||
;
|
||||
|
||||
// IEEE: signing - plus empty
|
||||
signingE: /*empty*/ { }
|
||||
signingE: // IEEE: signing - plus empty
|
||||
/*empty*/ { }
|
||||
| ySIGNED { VARSIGNED(true); }
|
||||
| yUNSIGNED { VARSIGNED(false); }
|
||||
;
|
||||
|
||||
v2kVarDeclE: /*empty*/ { }
|
||||
| varNet { }
|
||||
v2kVarDeclE:
|
||||
/*empty*/ { }
|
||||
| net_type { }
|
||||
| varReg { }
|
||||
;
|
||||
|
||||
//************************************************
|
||||
// Module Items
|
||||
|
||||
modItemListE<nodep>:
|
||||
module_itemListE<nodep>: // IEEE: Part of module_declaration
|
||||
/* empty */ { $$ = NULL; }
|
||||
| modItemList { $$ = $1; }
|
||||
| module_itemList { $$ = $1; }
|
||||
;
|
||||
|
||||
modItemList<nodep>:
|
||||
modItem { $$ = $1; }
|
||||
| modItemList modItem { $$ = $1->addNextNull($2); }
|
||||
module_itemList<nodep>: // IEEE: Part of module_declaration
|
||||
module_item { $$ = $1; }
|
||||
| module_itemList module_item { $$ = $1->addNextNull($2); }
|
||||
;
|
||||
|
||||
modItem<nodep>:
|
||||
modOrGenItem { $$ = $1; }
|
||||
| generateRegion { $$ = $1; }
|
||||
module_item<nodep>: // ==IEEE: module_item
|
||||
// // IEEE: non_port_module_item
|
||||
generate_region { $$ = $1; }
|
||||
| module_or_generate_item { $$ = $1; }
|
||||
| specify_block { $$ = $1; }
|
||||
// // Verilator specific
|
||||
| yaSCHDR { $$ = new AstScHdr(CRELINE(),*$1); }
|
||||
| yaSCINT { $$ = new AstScInt(CRELINE(),*$1); }
|
||||
| yaSCIMP { $$ = new AstScImp(CRELINE(),*$1); }
|
||||
@@ -634,38 +649,49 @@ modItem<nodep>:
|
||||
| yVL_INLINE_MODULE { $$ = new AstPragma($1,AstPragmaType::INLINE_MODULE); }
|
||||
| yVL_NO_INLINE_MODULE { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_MODULE); }
|
||||
| yVL_PUBLIC_MODULE { $$ = new AstPragma($1,AstPragmaType::PUBLIC_MODULE); }
|
||||
| ySPECIFY specifyJunkList yENDSPECIFY { $$ = NULL; }
|
||||
| ySPECIFY yENDSPECIFY { $$ = NULL; }
|
||||
;
|
||||
|
||||
// IEEE: generate_region
|
||||
generateRegion<nodep>:
|
||||
generate_region<nodep>: // ==IEEE: generate_region
|
||||
yGENERATE genTopBlock yENDGENERATE { $$ = new AstGenerate($1, $2); }
|
||||
;
|
||||
|
||||
modOrGenItem<nodep>:
|
||||
yALWAYS eventControlE stmtBlock { $$ = new AstAlways($1,$2,$3); }
|
||||
| yFINAL stmtBlock { $$ = new AstFinal($1,$2); }
|
||||
| yINITIAL stmtBlock { $$ = new AstInitial($1,$2); }
|
||||
| yASSIGN delayE assignList ';' { $$ = $3; }
|
||||
| yDEFPARAM defpList ';' { $$ = $2; }
|
||||
// IEEE: module_or_generate_item + module_common_item + parameter_override
|
||||
module_or_generate_item<nodep>:
|
||||
// // IEEE: always_construct
|
||||
yALWAYS event_controlE stmtBlock { $$ = new AstAlways($1,$2,$3); }
|
||||
| continuous_assign { $$ = $1; }
|
||||
| initial_construct { $$ = $1; }
|
||||
| final_construct { $$ = $1; }
|
||||
| yDEFPARAM list_of_defparam_assignments ';' { $$ = $2; }
|
||||
| instDecl { $$ = $1; }
|
||||
| taskDecl { $$ = $1; }
|
||||
| funcDecl { $$ = $1; }
|
||||
| task_declaration { $$ = $1; }
|
||||
| function_declaration { $$ = $1; }
|
||||
| gateDecl { $$ = $1; }
|
||||
| portDecl { $$ = $1; }
|
||||
| varDecl { $$ = $1; }
|
||||
//No: | tableDecl // Unsupported
|
||||
| pslStmt { $$ = $1; }
|
||||
| concurrent_assertion_item { $$ = $1; } // IEEE puts in modItem; seems silly
|
||||
| concurrent_assertion_item { $$ = $1; } // IEEE puts in module_item; seems silly
|
||||
| clocking_declaration { $$ = $1; }
|
||||
;
|
||||
|
||||
continuous_assign<nodep>: // IEEE: continuous_assign
|
||||
yASSIGN delayE assignList ';' { $$ = $3; }
|
||||
;
|
||||
|
||||
initial_construct<nodep>: // IEEE: initial_construct
|
||||
yINITIAL stmtBlock { $$ = new AstInitial($1,$2); }
|
||||
;
|
||||
|
||||
final_construct<nodep>: // IEEE: final_construct
|
||||
yFINAL stmtBlock { $$ = new AstFinal($1,$2); }
|
||||
;
|
||||
|
||||
//************************************************
|
||||
// Generates
|
||||
|
||||
// Because genItemList includes variable declarations, we don't need beginNamed
|
||||
genItemBlock<nodep>:
|
||||
generate_block_or_null<nodep>: // IEEE: generate_block_or_null
|
||||
genItem { $$ = new AstBegin(CRELINE(),"genblk",$1); }
|
||||
| genItemBegin { $$ = $1; }
|
||||
;
|
||||
@@ -675,9 +701,11 @@ genTopBlock<nodep>:
|
||||
| genItemBegin { $$ = $1; }
|
||||
;
|
||||
|
||||
genItemBegin<nodep>:
|
||||
genItemBegin<nodep>: // IEEE: part of generate_block
|
||||
yBEGIN genItemList yEND { $$ = new AstBegin($1,"genblk",$2); }
|
||||
| yBEGIN yEND { $$ = NULL; }
|
||||
| yaID ':' yBEGIN genItemList yEND endLabelE { $$ = new AstBegin($2,*$1,$4); }
|
||||
| yaID ':' yBEGIN yEND endLabelE { $$ = NULL; }
|
||||
| yBEGIN ':' yaID genItemList yEND endLabelE { $$ = new AstBegin($2,*$3,$4); }
|
||||
| yBEGIN ':' yaID yEND endLabelE { $$ = NULL; }
|
||||
;
|
||||
@@ -687,29 +715,39 @@ genItemList<nodep>:
|
||||
| genItemList genItem { $$ = $1->addNextNull($2); }
|
||||
;
|
||||
|
||||
genItem<nodep>:
|
||||
modOrGenItem { $$ = $1; }
|
||||
| yCASE '(' expr ')' genCaseListE yENDCASE { $$ = new AstGenCase($1,$3,$5); }
|
||||
| yIF '(' expr ')' genItemBlock %prec prLOWER_THAN_ELSE { $$ = new AstGenIf($1,$3,$5,NULL); }
|
||||
| yIF '(' expr ')' genItemBlock yELSE genItemBlock { $$ = new AstGenIf($1,$3,$5,$7); }
|
||||
| yFOR '(' varRefBase '=' expr ';' expr ';' varRefBase '=' expr ')' genItemBlock
|
||||
{ $$ = new AstGenFor($1, new AstAssign($4,$3,$5)
|
||||
,$7, new AstAssign($10,$9,$11)
|
||||
,$13);}
|
||||
genItem<nodep>: // IEEE: module_or_interface_or_generate_item (INCOMPLETE)
|
||||
module_or_generate_item { $$ = $1; }
|
||||
| conditional_generate_construct {}
|
||||
| loop_generate_construct {}
|
||||
;
|
||||
|
||||
genCaseListE<nodep>:
|
||||
conditional_generate_construct<nodep>: // ==IEEE: conditional_generate_construct
|
||||
yCASE '(' expr ')' case_generate_itemListE yENDCASE { $$ = new AstGenCase($1,$3,$5); }
|
||||
| yIF '(' expr ')' generate_block_or_null %prec prLOWER_THAN_ELSE { $$ = new AstGenIf($1,$3,$5,NULL); }
|
||||
| yIF '(' expr ')' generate_block_or_null yELSE generate_block_or_null { $$ = new AstGenIf($1,$3,$5,$7); }
|
||||
;
|
||||
|
||||
loop_generate_construct<nodep>: // ==IEEE: loop_generate_construct
|
||||
yFOR '(' varRefBase '=' expr ';' expr ';' varRefBase '=' expr ')' generate_block_or_null
|
||||
{ $$ = new AstGenFor($1, new AstAssign($4,$3,$5)
|
||||
,$7, new AstAssign($10,$9,$11)
|
||||
,$13);}
|
||||
;
|
||||
|
||||
case_generate_itemListE<nodep>: // IEEE: [{ case_generate_itemList }]
|
||||
/* empty */ { $$ = NULL; }
|
||||
| genCaseList { $$ = $1; }
|
||||
| case_generate_itemList { $$ = $1; }
|
||||
;
|
||||
|
||||
genCaseList<nodep>:
|
||||
caseCondList ':' genItemBlock { $$ = new AstCaseItem($2,$1,$3); }
|
||||
| yDEFAULT ':' genItemBlock { $$ = new AstCaseItem($2,NULL,$3); }
|
||||
| yDEFAULT genItemBlock { $$ = new AstCaseItem($1,NULL,$2); }
|
||||
| genCaseList caseCondList ':' genItemBlock { $$ = $1;$1->addNext(new AstCaseItem($3,$2,$4)); }
|
||||
| genCaseList yDEFAULT genItemBlock { $$ = $1;$1->addNext(new AstCaseItem($2,NULL,$3)); }
|
||||
| genCaseList yDEFAULT ':' genItemBlock { $$ = $1;$1->addNext(new AstCaseItem($3,NULL,$4)); }
|
||||
case_generate_itemList<nodep>: // IEEE: { case_generate_itemList }
|
||||
case_generate_item { $$=$1; }
|
||||
| case_generate_itemList case_generate_item { $$=$1; $1->addNext($2); }
|
||||
;
|
||||
|
||||
case_generate_item<nodep>: // ==IEEE: case_generate_item
|
||||
caseCondList ':' generate_block_or_null { $$ = new AstCaseItem($2,$1,$3); }
|
||||
| yDEFAULT ':' generate_block_or_null { $$ = new AstCaseItem($2,NULL,$3); }
|
||||
| yDEFAULT generate_block_or_null { $$ = new AstCaseItem($1,NULL,$2); }
|
||||
;
|
||||
|
||||
//************************************************
|
||||
@@ -722,14 +760,15 @@ assignList<nodep>:
|
||||
|
||||
assignOne<nodep>:
|
||||
varRefDotBit '=' expr { $$ = new AstAssignW($2,$1,$3); }
|
||||
| '{' concIdList '}' '=' expr { $$ = new AstAssignW($1,$2,$5); }
|
||||
| '{' identifier_listLvalue '}' '=' expr { $$ = new AstAssignW($1,$2,$5); }
|
||||
;
|
||||
|
||||
delayE: /* empty */ { }
|
||||
| delay { } /* ignored */
|
||||
delayE:
|
||||
/* empty */ { }
|
||||
| delay_control { } /* ignored */
|
||||
;
|
||||
|
||||
delay<fileline>:
|
||||
delay_control<fileline>: //== IEEE: delay_control
|
||||
'#' dlyTerm { $$ = $1; } /* ignored */
|
||||
| '#' '(' minTypMax ')' { $$ = $1; } /* ignored */
|
||||
| '#' '(' minTypMax ',' minTypMax ')' { $$ = $1; } /* ignored */
|
||||
@@ -743,8 +782,7 @@ dlyTerm<nodep>:
|
||||
| yaTIMENUM { $$ = NULL; }
|
||||
;
|
||||
|
||||
// IEEE: mintypmax_expression and constant_mintypmax_expression
|
||||
minTypMax<nodep>:
|
||||
minTypMax<nodep>: // IEEE: mintypmax_expression and constant_mintypmax_expression
|
||||
dlyTerm { $$ = $1; } /* ignored */
|
||||
| dlyTerm ':' dlyTerm ':' dlyTerm { $$ = $1; } /* ignored */
|
||||
;
|
||||
@@ -774,21 +812,26 @@ regSigId<varp>:
|
||||
$$->addNext(new AstInitial($3,new AstAssign($3, new AstVarRef($3, *$1, true), $4))); }
|
||||
;
|
||||
|
||||
sigId<varp>: yaID { $$ = V3Parse::createVariable(CRELINE(), *$1, NULL); }
|
||||
sigId<varp>:
|
||||
yaID { $$ = V3Parse::createVariable(CRELINE(), *$1, NULL); }
|
||||
;
|
||||
|
||||
regsig<varp>: regSigId sigAttrListE {}
|
||||
regsig<varp>:
|
||||
regSigId sigAttrListE {}
|
||||
;
|
||||
|
||||
sigAttrListE: /* empty */ {}
|
||||
sigAttrListE:
|
||||
/* empty */ {}
|
||||
| sigAttrList {}
|
||||
;
|
||||
|
||||
sigAttrList: sigAttr {}
|
||||
sigAttrList:
|
||||
sigAttr {}
|
||||
| sigAttrList sigAttr {}
|
||||
;
|
||||
|
||||
sigAttr: yVL_CLOCK { V3Parse::s_varAttrp->attrScClocked(true); }
|
||||
sigAttr:
|
||||
yVL_CLOCK { V3Parse::s_varAttrp->attrScClocked(true); }
|
||||
| yVL_CLOCK_ENABLE { V3Parse::s_varAttrp->attrClockEn(true); }
|
||||
| yVL_PUBLIC { V3Parse::s_varAttrp->sigPublic(true); V3Parse::s_varAttrp->sigModPublic(true); }
|
||||
| yVL_PUBLIC_FLAT { V3Parse::s_varAttrp->sigPublic(true); }
|
||||
@@ -800,7 +843,7 @@ rangeListE<rangep>:
|
||||
| rangeList { $$ = $1; }
|
||||
;
|
||||
|
||||
rangeList<rangep>:
|
||||
rangeList<rangep>: // IEEE: packed_dimension + ...
|
||||
anyrange { $$ = $1; }
|
||||
| rangeList anyrange { $$ = $1; $1->addNext($2); }
|
||||
;
|
||||
@@ -838,13 +881,12 @@ paramList<varp>:
|
||||
| paramList ',' param { $$ = $1; $1->addNext($3); }
|
||||
;
|
||||
|
||||
// IEEE: list_of_defparam_assignments
|
||||
defpList<nodep>:
|
||||
defpOne { $$ = $1; }
|
||||
| defpList ',' defpOne { $$ = $1->addNext($3); }
|
||||
list_of_defparam_assignments<nodep>: //== IEEE: list_of_defparam_assignments
|
||||
defparam_assignment { $$ = $1; }
|
||||
| list_of_defparam_assignments ',' defparam_assignment { $$ = $1->addNext($3); }
|
||||
;
|
||||
|
||||
defpOne<nodep>:
|
||||
defparam_assignment<nodep>: // ==IEEE: defparam_assignment
|
||||
yaID '.' yaID '=' expr { $$ = new AstDefParam($4,*$1,*$3,$5); }
|
||||
;
|
||||
|
||||
@@ -853,6 +895,7 @@ defpOne<nodep>:
|
||||
|
||||
instDecl<nodep>:
|
||||
yaID instparamListE {INSTPREP(*$1,$2);} instnameList ';' { $$ = $4; V3Parse::s_impliedDecl=false;}
|
||||
;
|
||||
|
||||
instparamListE<pinp>:
|
||||
/* empty */ { $$ = NULL; }
|
||||
@@ -895,20 +938,19 @@ cellpinItemE<pinp>:
|
||||
//************************************************
|
||||
// EventControl lists
|
||||
|
||||
eventControlE<sentreep>:
|
||||
event_controlE<sentreep>:
|
||||
/* empty */ { $$ = NULL; }
|
||||
| eventControl { $$ = $1; }
|
||||
| event_control { $$ = $1; }
|
||||
;
|
||||
|
||||
// IEEE: event_control
|
||||
eventControl<sentreep>:
|
||||
event_control<sentreep>: // ==IEEE: event_control
|
||||
'@' '(' senList ')' { $$ = new AstSenTree($1,$3); }
|
||||
| '@' senitemVar { $$ = new AstSenTree($1,$2); } /* For events only */
|
||||
| '@' '(' '*' ')' { $$ = NULL; } /* Verilog 2001 */
|
||||
| '@' '(' '*' ')' { $$ = NULL; }
|
||||
| '@' '*' { $$ = NULL; } /* Verilog 2001 */
|
||||
;
|
||||
|
||||
// IEEE: event_expression - split over several
|
||||
senList<senitemp>:
|
||||
senList<senitemp>: // IEEE: event_expression - split over several
|
||||
senitem { $$ = $1; }
|
||||
| senList yOR senitem { $$ = $1;$1->addNext($3); }
|
||||
| senList ',' senitem { $$ = $1;$1->addNext($3); } /* Verilog 2001 */
|
||||
@@ -924,7 +966,7 @@ senitemVar<senitemp>:
|
||||
varRefDotBit { $$ = new AstSenItem(CRELINE(),AstEdgeType::ANYEDGE,$1); }
|
||||
;
|
||||
|
||||
senitemEdge<senitemp>:
|
||||
senitemEdge<senitemp>: // IEEE: part of event_expression
|
||||
yPOSEDGE varRefDotBit { $$ = new AstSenItem($1,AstEdgeType::POSEDGE,$2); }
|
||||
| yNEGEDGE varRefDotBit { $$ = new AstSenItem($1,AstEdgeType::NEGEDGE,$2); }
|
||||
| yPOSEDGE '(' varRefDotBit ')' { $$ = new AstSenItem($1,AstEdgeType::POSEDGE,$3); }
|
||||
@@ -934,7 +976,7 @@ senitemEdge<senitemp>:
|
||||
//************************************************
|
||||
// Statements
|
||||
|
||||
stmtBlock<nodep>:
|
||||
stmtBlock<nodep>: // IEEE: statement + seq_block + par_block
|
||||
stmt { $$ = $1; }
|
||||
| yBEGIN stmtList yEND { $$ = $2; }
|
||||
| yBEGIN yEND { $$ = NULL; }
|
||||
@@ -952,19 +994,42 @@ stmtList<nodep>:
|
||||
| stmtList stmtBlock { $$ = ($2==NULL)?($1):($1->addNext($2)); }
|
||||
;
|
||||
|
||||
// IEEE: statement_or_null (may include more stuff, not analyzed)
|
||||
// == function_statement_or_null
|
||||
stmt<nodep>:
|
||||
// // from _or_null
|
||||
';' { $$ = NULL; }
|
||||
| labeledStmt { $$ = $1; }
|
||||
| yaID ':' labeledStmt { $$ = new AstBegin($2, *$1, $3); } /*S05 block creation rule*/
|
||||
|
||||
| delay stmtBlock { $$ = $2; $1->v3warn(STMTDLY,"Ignoring delay on this delayed statement.\n"); }
|
||||
|
||||
| varRefDotBit yP_LTE delayE expr ';' { $$ = new AstAssignDly($2,$1,$4); }
|
||||
//
|
||||
| delay_control stmtBlock { $$ = $2; $1->v3warn(STMTDLY,"Ignoring delay on this delayed statement.\n"); }
|
||||
//
|
||||
// // IEEE: operator_assignment
|
||||
| varRefDotBit '=' delayE expr ';' { $$ = new AstAssign($2,$1,$4); }
|
||||
| varRefDotBit '=' yD_FOPEN '(' expr ',' expr ')' ';' { $$ = new AstFOpen($3,$1,$5,$7); }
|
||||
| '{' identifier_listLvalue '}' '=' delayE expr ';' { $$ = new AstAssign($4,$2,$6); }
|
||||
//
|
||||
// // IEEE: nonblocking_assignment
|
||||
| varRefDotBit yP_LTE delayE expr ';' { $$ = new AstAssignDly($2,$1,$4); }
|
||||
| '{' identifier_listLvalue '}' yP_LTE delayE expr ';' { $$ = new AstAssignDly($4,$2,$6); }
|
||||
//
|
||||
// // IEEE: procedural_continuous_assignment
|
||||
| yASSIGN varRefDotBit '=' delayE expr ';' { $$ = new AstAssign($1,$2,$5); }
|
||||
| '{' concIdList '}' yP_LTE delayE expr ';' { $$ = new AstAssignDly($4,$2,$6); }
|
||||
| '{' concIdList '}' '=' delayE expr ';' { $$ = new AstAssign($4,$2,$6); }
|
||||
//
|
||||
// // IEEE: case_statement
|
||||
| unique_priorityE caseStart caseAttrE case_itemListE yENDCASE { $$ = $2; if ($4) $2->addItemsp($4);
|
||||
if ($1 == uniq_UNIQUE) $2->parallelPragma(true);
|
||||
if ($1 == uniq_PRIORITY) $2->fullPragma(true); }
|
||||
//
|
||||
// // IEEE: conditional_statement
|
||||
| unique_priorityE yIF '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE
|
||||
{ $$ = new AstIf($2,$4,$6,NULL); }
|
||||
| unique_priorityE yIF '(' expr ')' stmtBlock yELSE stmtBlock
|
||||
{ $$ = new AstIf($2,$4,$6,$8); }
|
||||
//
|
||||
// // IEEE: subroutine_call_statement (INCOMPLETE)
|
||||
| taskRef ';' { $$ = $1; }
|
||||
//
|
||||
| yD_C '(' cStrList ')' ';' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCStmt($1,$3)); }
|
||||
| yD_FCLOSE '(' varRefDotBit ')' ';' { $$ = new AstFClose($1, $3); }
|
||||
| yD_FFLUSH ';' { $1->v3error("Unsupported: $fflush of all handles does not map to C++.\n"); }
|
||||
@@ -975,9 +1040,7 @@ stmt<nodep>:
|
||||
| yD_STOP parenE ';' { $$ = new AstStop($1); }
|
||||
| yD_STOP '(' expr ')' ';' { $$ = new AstStop($1); }
|
||||
| yVL_COVERAGE_BLOCK_OFF { $$ = new AstPragma($1,AstPragmaType::COVERAGE_BLOCK_OFF); }
|
||||
| stateCaseForIf { $$ = $1; }
|
||||
| taskRef ';' { $$ = $1; }
|
||||
|
||||
//
|
||||
| yD_DISPLAY parenE ';' { $$ = new AstDisplay($1,AstDisplayType::DISPLAY,"", NULL,NULL); }
|
||||
| yD_DISPLAY '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::DISPLAY,*$3,NULL,$4); }
|
||||
| yD_WRITE '(' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::WRITE, *$3,NULL,$4); }
|
||||
@@ -992,66 +1055,61 @@ stmt<nodep>:
|
||||
| yD_FATAL parenE ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); }
|
||||
| yD_FATAL '(' expr ')' ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, "", NULL,NULL); $$->addNext(new AstStop($1)); if ($3) $3->deleteTree(); }
|
||||
| yD_FATAL '(' expr ',' yaSTRING commaEListE ')' ';' { $$ = new AstDisplay($1,AstDisplayType::FATAL, *$5,NULL,$6); $$->addNext(new AstStop($1)); if ($3) $3->deleteTree(); }
|
||||
|
||||
//
|
||||
| yD_READMEMB '(' expr ',' varRefMem ')' ';' { $$ = new AstReadMem($1,false,$3,$5,NULL,NULL); }
|
||||
| yD_READMEMB '(' expr ',' varRefMem ',' expr ')' ';' { $$ = new AstReadMem($1,false,$3,$5,$7,NULL); }
|
||||
| yD_READMEMB '(' expr ',' varRefMem ',' expr ',' expr ')' ';' { $$ = new AstReadMem($1,false,$3,$5,$7,$9); }
|
||||
| yD_READMEMH '(' expr ',' varRefMem ')' ';' { $$ = new AstReadMem($1,true, $3,$5,NULL,NULL); }
|
||||
| yD_READMEMH '(' expr ',' varRefMem ',' expr ')' ';' { $$ = new AstReadMem($1,true, $3,$5,$7,NULL); }
|
||||
| yD_READMEMH '(' expr ',' varRefMem ',' expr ',' expr ')' ';' { $$ = new AstReadMem($1,true, $3,$5,$7,$9); }
|
||||
//
|
||||
// // IEEE: loop_statement (INCOMPLETE)
|
||||
| yFOREVER stmtBlock { $$ = new AstWhile($1,new AstConst($1,V3Number($1,1,1)),$2); }
|
||||
| yREPEAT '(' expr ')' stmtBlock { $$ = new AstRepeat($1,$3,$5);}
|
||||
| yWHILE '(' expr ')' stmtBlock { $$ = new AstWhile($1,$3,$5);}
|
||||
| yFOR '(' varRefBase '=' expr ';' expr ';' varRefBase '=' expr ')' stmtBlock
|
||||
{ $$ = new AstFor($1, new AstAssign($4,$3,$5)
|
||||
,$7, new AstAssign($10,$9,$11)
|
||||
,$13);}
|
||||
| yDO stmtBlock yWHILE '(' expr ')' { $$ = $2->cloneTree(true); $$->addNext(new AstWhile($1,$5,$2));}
|
||||
;
|
||||
|
||||
//************************************************
|
||||
// Case/If
|
||||
|
||||
unique_priorityE<uniqstate>:
|
||||
unique_priorityE<uniqstate>: // IEEE: unique_priority + empty
|
||||
/*empty*/ { $$ = uniq_NONE; }
|
||||
| yPRIORITY { $$ = uniq_PRIORITY; }
|
||||
| yUNIQUE { $$ = uniq_UNIQUE; }
|
||||
;
|
||||
|
||||
stateCaseForIf<nodep>:
|
||||
unique_priorityE caseStmt caseAttrE caseListE yENDCASE { $$ = $2; if ($4) $2->addItemsp($4);
|
||||
if ($1 == uniq_UNIQUE) $2->parallelPragma(true);
|
||||
if ($1 == uniq_PRIORITY) $2->fullPragma(true); }
|
||||
| unique_priorityE yIF '(' expr ')' stmtBlock %prec prLOWER_THAN_ELSE
|
||||
{ $$ = new AstIf($2,$4,$6,NULL); }
|
||||
| unique_priorityE yIF '(' expr ')' stmtBlock yELSE stmtBlock
|
||||
{ $$ = new AstIf($2,$4,$6,$8); }
|
||||
| yFOR '(' varRefBase '=' expr ';' expr ';' varRefBase '=' expr ')' stmtBlock
|
||||
{ $$ = new AstFor($1, new AstAssign($4,$3,$5)
|
||||
,$7, new AstAssign($10,$9,$11)
|
||||
,$13);}
|
||||
| yWHILE '(' expr ')' stmtBlock { $$ = new AstWhile($1,$3,$5);}
|
||||
| yDO stmtBlock yWHILE '(' expr ')' { $$ = $2->cloneTree(true); $$->addNext(new AstWhile($1,$5,$2));}
|
||||
;
|
||||
|
||||
caseStmt<casep>:
|
||||
caseStart<casep>: // IEEE: part of case_statement
|
||||
yCASE '(' expr ')' { $$ = V3Parse::s_caseAttrp = new AstCase($1,AstCaseType::CASE,$3,NULL); }
|
||||
| yCASEX '(' expr ')' { $$ = V3Parse::s_caseAttrp = new AstCase($1,AstCaseType::CASEX,$3,NULL); $1->v3warn(CASEX,"Suggest casez (with ?'s) in place of casex (with X's)\n"); }
|
||||
| yCASEZ '(' expr ')' { $$ = V3Parse::s_caseAttrp = new AstCase($1,AstCaseType::CASEZ,$3,NULL); }
|
||||
| yCASEZ '(' expr ')' { $$ = V3Parse::s_caseAttrp = new AstCase($1,AstCaseType::CASEZ,$3,NULL); }
|
||||
;
|
||||
|
||||
caseAttrE: /*empty*/ { }
|
||||
caseAttrE:
|
||||
/*empty*/ { }
|
||||
| caseAttrE yVL_FULL_CASE { V3Parse::s_caseAttrp->fullPragma(true); }
|
||||
| caseAttrE yVL_PARALLEL_CASE { V3Parse::s_caseAttrp->parallelPragma(true); }
|
||||
;
|
||||
|
||||
caseListE<caseitemp>:
|
||||
case_itemListE<caseitemp>: // IEEE: [ { case_item } ]
|
||||
/* empty */ { $$ = NULL; }
|
||||
| caseList { $$ = $1; }
|
||||
| case_itemList { $$ = $1; }
|
||||
;
|
||||
|
||||
caseList<caseitemp>:
|
||||
case_itemList<caseitemp>: // IEEE: { case_item + ... }
|
||||
caseCondList ':' stmtBlock { $$ = new AstCaseItem($2,$1,$3); }
|
||||
| yDEFAULT ':' stmtBlock { $$ = new AstCaseItem($2,NULL,$3); }
|
||||
| yDEFAULT stmtBlock { $$ = new AstCaseItem($1,NULL,$2); }
|
||||
| caseList caseCondList ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,$2,$4)); }
|
||||
| caseList yDEFAULT stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($2,NULL,$3)); }
|
||||
| caseList yDEFAULT ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,NULL,$4)); }
|
||||
| case_itemList caseCondList ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,$2,$4)); }
|
||||
| case_itemList yDEFAULT stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($2,NULL,$3)); }
|
||||
| case_itemList yDEFAULT ':' stmtBlock { $$ = $1;$1->addNext(new AstCaseItem($3,NULL,$4)); }
|
||||
;
|
||||
|
||||
caseCondList<nodep>:
|
||||
caseCondList<nodep>: // IEEE: part of case_item
|
||||
expr { $$ = $1; }
|
||||
| caseCondList ',' expr { $$ = $1;$1->addNext($3); }
|
||||
;
|
||||
@@ -1059,39 +1117,39 @@ caseCondList<nodep>:
|
||||
//************************************************
|
||||
// Functions/tasks
|
||||
|
||||
taskRef<nodep>:
|
||||
taskRef<nodep>: // IEEE: part of tf_call
|
||||
idDotted { $$ = new AstTaskRef(CRELINE(),new AstParseRef($1->fileline(), AstParseRefExp::TASK, $1),NULL);}
|
||||
| idDotted '(' exprList ')' { $$ = new AstTaskRef(CRELINE(),new AstParseRef($1->fileline(), AstParseRefExp::TASK, $1),$3);}
|
||||
;
|
||||
|
||||
funcRef<nodep>:
|
||||
funcRef<nodep>: // IEEE: part of tf_call
|
||||
idDotted '(' exprList ')' { $$ = new AstFuncRef($2,new AstParseRef($1->fileline(), AstParseRefExp::FUNC, $1), $3); }
|
||||
;
|
||||
|
||||
taskDecl<nodep>:
|
||||
yTASK lifetimeE yaID funcGuts yENDTASK endLabelE
|
||||
task_declaration<nodep>: // ==IEEE: task_declaration
|
||||
yTASK lifetimeE yaID tfGuts yENDTASK endLabelE
|
||||
{ $$ = new AstTask ($1,*$3,$4);}
|
||||
;
|
||||
|
||||
funcDecl<funcp>:
|
||||
yFUNCTION lifetimeE funcTypeE yaID funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$4,$5,$3); }
|
||||
| yFUNCTION lifetimeE ySIGNED funcTypeE yaID funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$5,$6,$4); $$->isSigned(true); }
|
||||
| yFUNCTION lifetimeE funcTypeE yaID yVL_ISOLATE_ASSIGNMENTS funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$4,$6,$3); $$->attrIsolateAssign(true);}
|
||||
| yFUNCTION lifetimeE ySIGNED funcTypeE yaID yVL_ISOLATE_ASSIGNMENTS funcGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$5,$7,$4); $$->attrIsolateAssign(true); $$->isSigned(true); }
|
||||
function_declaration<funcp>: // IEEE: function_declaration + function_body_declaration
|
||||
yFUNCTION lifetimeE funcTypeE yaID tfGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$4,$5,$3); }
|
||||
| yFUNCTION lifetimeE ySIGNED funcTypeE yaID tfGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$5,$6,$4); $$->isSigned(true); }
|
||||
| yFUNCTION lifetimeE funcTypeE yaID yVL_ISOLATE_ASSIGNMENTS tfGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$4,$6,$3); $$->attrIsolateAssign(true);}
|
||||
| yFUNCTION lifetimeE ySIGNED funcTypeE yaID yVL_ISOLATE_ASSIGNMENTS tfGuts yENDFUNCTION endLabelE { $$ = new AstFunc ($1,*$5,$7,$4); $$->attrIsolateAssign(true); $$->isSigned(true); }
|
||||
;
|
||||
|
||||
// IEEE: lifetime - plus empty
|
||||
lifetimeE: /* empty */ { }
|
||||
lifetimeE: // IEEE: lifetime - plus empty
|
||||
/* empty */ { }
|
||||
| ySTATIC { $1->v3error("Unsupported: Static in this context\n"); }
|
||||
| yAUTOMATIC { }
|
||||
;
|
||||
|
||||
funcGuts<nodep>:
|
||||
'(' {V3Parse::s_pinNum=1;} portV2kArgs ')' ';' funcBody { $$ = $3->addNextNull($6); }
|
||||
| ';' funcBody { $$ = $2; }
|
||||
tfGuts<nodep>:
|
||||
'(' {V3Parse::s_pinNum=1;} portV2kArgs ')' ';' tfBody { $$ = $3->addNextNull($6); }
|
||||
| ';' tfBody { $$ = $2; }
|
||||
;
|
||||
|
||||
funcBody<nodep>:
|
||||
tfBody<nodep>: // IEEE: part of function_body_declaration/task_body_declaration
|
||||
funcVarList stmtBlock { $$ = $1;$1->addNextNull($2); }
|
||||
| stmtBlock { $$ = $1; }
|
||||
;
|
||||
@@ -1114,7 +1172,8 @@ funcVar<nodep>:
|
||||
| yVL_NO_INLINE_TASK { $$ = new AstPragma($1,AstPragmaType::NO_INLINE_TASK); }
|
||||
;
|
||||
|
||||
parenE: /* empty */ { }
|
||||
parenE:
|
||||
/* empty */ { }
|
||||
| '(' ')' { }
|
||||
;
|
||||
|
||||
@@ -1155,7 +1214,7 @@ exprNoStr<nodep>:
|
||||
| expr yP_POW expr { $$ = new AstPow ($2,$1,$3); }
|
||||
| expr yP_MINUSGT expr { $$ = new AstLogIf ($2,$1,$3); }
|
||||
| expr yP_LOGIFF expr { $$ = new AstLogIff ($2,$1,$3); }
|
||||
|
||||
//
|
||||
| '-' expr %prec prUNARYARITH { $$ = new AstUnaryMin ($1,$2); }
|
||||
| '+' expr %prec prUNARYARITH { $$ = $2; }
|
||||
| '&' expr %prec prREDUCTION { $$ = new AstRedAnd ($1,$2); }
|
||||
@@ -1166,13 +1225,15 @@ exprNoStr<nodep>:
|
||||
| yP_NOR expr %prec prREDUCTION { $$ = new AstNot($1,new AstRedOr ($1,$2)); }
|
||||
| '!' expr %prec prNEGATION { $$ = new AstLogNot ($1,$2); }
|
||||
| '~' expr %prec prNEGATION { $$ = new AstNot ($1,$2); }
|
||||
|
||||
//
|
||||
| expr '?' expr ':' expr { $$ = new AstCond($2,$1,$3,$5); }
|
||||
| '(' expr ')' { $$ = $2; }
|
||||
| '_' '(' statePushVlg expr statePop ')' { $$ = $4; } // Arbitrary Verilog inside PSL
|
||||
//
|
||||
// // IEEE: concatenation/constant_concatenation
|
||||
| '{' cateList '}' { $$ = $2; }
|
||||
| '{' constExpr '{' cateList '}' '}' { $$ = new AstReplicate($1,$4,$2); }
|
||||
|
||||
//
|
||||
| yD_BITS '(' expr ')' { $$ = new AstAttrOf($1,AstAttrType::BITS,$3); }
|
||||
| yD_C '(' cStrList ')' { $$ = (v3Global.opt.ignc() ? NULL : new AstUCFunc($1,$3)); }
|
||||
| yD_CLOG2 '(' expr ')' { $$ = new AstCLog2($1,$3); }
|
||||
@@ -1192,12 +1253,14 @@ exprNoStr<nodep>:
|
||||
| yD_STIME { $$ = new AstSel($1,new AstTime($1),0,32); }
|
||||
| yD_TIME { $$ = new AstTime($1); }
|
||||
| yD_UNSIGNED '(' expr ')' { $$ = new AstUnsigned($1,$3); }
|
||||
|
||||
//
|
||||
| funcRef { $$ = $1; }
|
||||
|
||||
//
|
||||
| yaINTNUM { $$ = new AstConst(CRELINE(),*$1); }
|
||||
|
||||
//
|
||||
| varRefDotBit { $$ = $1; }
|
||||
//
|
||||
| error ';' { $$ = NULL; }
|
||||
;
|
||||
|
||||
// Generic expressions
|
||||
@@ -1354,7 +1417,8 @@ gatePullup<pullp>: gateIdE instRangeE '(' varRefDotBit ')' { $$ = new AstPull ($
|
||||
;
|
||||
gatePulldown<pullp>: gateIdE instRangeE '(' varRefDotBit ')' { $$ = new AstPull ($3, $4, false); }
|
||||
;
|
||||
gateIdE: /*empty*/ {}
|
||||
gateIdE:
|
||||
/*empty*/ {}
|
||||
| yaID {}
|
||||
;
|
||||
|
||||
@@ -1378,71 +1442,19 @@ gateXorPinList<nodep>:
|
||||
//************************************************
|
||||
// Specify
|
||||
|
||||
specifyJunkList: specifyJunk {} /* ignored */
|
||||
| specifyJunkList specifyJunk {} /* ignored */
|
||||
specify_block<nodep>: // ==IEEE: specify_block
|
||||
ySPECIFY specifyJunkList yENDSPECIFY { $$ = NULL; }
|
||||
| ySPECIFY yENDSPECIFY { $$ = NULL; }
|
||||
;
|
||||
|
||||
specifyJunk: dlyTerm {} /* ignored */
|
||||
| ';' {}
|
||||
| '!' {}
|
||||
| '&' {}
|
||||
| '(' {}
|
||||
| ')' {}
|
||||
| '*' {} | '/' {} | '%' {}
|
||||
| '+' {} | '-' {}
|
||||
| ',' {}
|
||||
| ':' {}
|
||||
| '$' {}
|
||||
| '=' {}
|
||||
| '>' {} | '<' {}
|
||||
| '?' {}
|
||||
| '^' {}
|
||||
| '{' {} | '}' {}
|
||||
| '[' {} | ']' {}
|
||||
| '|' {}
|
||||
| '~' {}
|
||||
| '@' {}
|
||||
|
||||
| yIF {}
|
||||
| yNEGEDGE {}
|
||||
| yPOSEDGE {}
|
||||
|
||||
| yaSTRING {}
|
||||
| yaTIMINGSPEC {}
|
||||
|
||||
| yP_ANDAND {} | yP_GTE {} | yP_LTE {}
|
||||
| yP_EQUAL {} | yP_NOTEQUAL {}
|
||||
| yP_CASEEQUAL {} | yP_CASENOTEQUAL {}
|
||||
| yP_WILDEQUAL {} | yP_WILDNOTEQUAL {}
|
||||
| yP_XNOR {} | yP_NOR {} | yP_NAND {}
|
||||
| yP_OROR {}
|
||||
| yP_SLEFT {} | yP_SRIGHT {} | yP_SSRIGHT {}
|
||||
| yP_PLUSCOLON {} | yP_MINUSCOLON {}
|
||||
| yP_POW {}
|
||||
|
||||
| yP_MINUSGT {}
|
||||
| yP_LOGIFF {}
|
||||
| yPSL_BRA {}
|
||||
| yPSL_KET {}
|
||||
| yP_ORMINUSGT {}
|
||||
| yP_OREQGT {}
|
||||
| yP_EQGT {} | yP_ASTGT {}
|
||||
| yP_ANDANDAND {}
|
||||
| yP_MINUSGTGT {}
|
||||
| yP_POUNDPOUND {}
|
||||
| yP_DOTSTAR {}
|
||||
| yP_ATAT {}
|
||||
| yP_COLONCOLON {}
|
||||
| yP_COLONEQ {}
|
||||
| yP_COLONDIV {}
|
||||
|
||||
| yP_PLUSEQ {} | yP_MINUSEQ {}
|
||||
| yP_TIMESEQ {}
|
||||
| yP_DIVEQ {} | yP_MODEQ {}
|
||||
| yP_ANDEQ {} | yP_OREQ {}
|
||||
| yP_XOREQ {}
|
||||
| yP_SLEFTEQ {} | yP_SRIGHTEQ {} | yP_SSRIGHTEQ {}
|
||||
specifyJunkList:
|
||||
specifyJunk { } /* ignored */
|
||||
| specifyJunkList specifyJunk { } /* ignored */
|
||||
;
|
||||
|
||||
specifyJunk:
|
||||
BISONPRE_NOT(ySPECIFY,yENDSPECIFY) { }
|
||||
| ySPECIFY specifyJunk yENDSPECIFY { }
|
||||
| error {}
|
||||
;
|
||||
|
||||
@@ -1469,8 +1481,10 @@ idDotted<nodep>:
|
||||
// we'll assume so and cleanup later.
|
||||
idArrayed<nodep>:
|
||||
yaID { $$ = new AstText(CRELINE(),*$1); }
|
||||
// // IEEE: id + part_select_range/constant_part_select_range
|
||||
| idArrayed '[' expr ']' { $$ = new AstSelBit($2,$1,$3); } // Or AstArraySel, don't know yet.
|
||||
| idArrayed '[' constExpr ':' constExpr ']' { $$ = new AstSelExtract($2,$1,$3,$5); }
|
||||
// // IEEE: id + indexed_range/constant_indexed_range
|
||||
| idArrayed '[' expr yP_PLUSCOLON constExpr ']' { $$ = new AstSelPlus($2,$1,$3,$5); }
|
||||
| idArrayed '[' expr yP_MINUSCOLON constExpr ']' { $$ = new AstSelMinus($2,$1,$3,$5); }
|
||||
;
|
||||
@@ -1488,12 +1502,13 @@ strAsText<nodep>:
|
||||
yaSTRING { $$ = V3Parse::createTextQuoted(CRELINE(),*$1);}
|
||||
;
|
||||
|
||||
concIdList<nodep>:
|
||||
identifier_listLvalue<nodep>: // IEEE: identifier_list for lvalue only
|
||||
varRefDotBit { $$ = $1; }
|
||||
| concIdList ',' varRefDotBit { $$ = new AstConcat($2,$1,$3); }
|
||||
| identifier_listLvalue ',' varRefDotBit { $$ = new AstConcat($2,$1,$3); }
|
||||
;
|
||||
|
||||
endLabelE: /* empty */ { }
|
||||
endLabelE:
|
||||
/* empty */ { }
|
||||
| ':' yaID { }
|
||||
;
|
||||
|
||||
@@ -1509,7 +1524,7 @@ clocking_declaration<nodep>: // IEEE: clocking_declaration (INCOMPLETE)
|
||||
{ $$ = new AstClocking($1, $5, NULL); }
|
||||
;
|
||||
|
||||
concurrent_assertion_item<nodep>: // IEEE: concurrent_assertion_item (complete)
|
||||
concurrent_assertion_item<nodep>: // IEEE: concurrent_assertion_item
|
||||
concurrent_assertion_statement { $$ = $1; }
|
||||
| yaID ':' concurrent_assertion_statement { $$ = new AstBegin($2,*$1,$3); }
|
||||
;
|
||||
@@ -1518,7 +1533,7 @@ concurrent_assertion_statement<nodep>: // IEEE: concurrent_assertion_statement
|
||||
cover_property_statement { $$ = $1; }
|
||||
;
|
||||
|
||||
cover_property_statement<nodep>: // IEEE: cover_property_statement (complete)
|
||||
cover_property_statement<nodep>: // IEEE: cover_property_statement
|
||||
yCOVER yPROPERTY '(' property_spec ')' stmtBlock { $$ = new AstPslCover($1,$4,$6); }
|
||||
;
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ endif
|
||||
# Needed by tracing routines
|
||||
CPPFLAGS += -DVL_DEBUG=1
|
||||
CPPFLAGS += -DVM_PREFIX=$(VM_PREFIX)
|
||||
CPPFLAGS += $(CPPFLAGS_DRIVER)
|
||||
CPPFLAGS += $(CPPFLAGS_ADD)
|
||||
|
||||
#######################################################################
|
||||
|
||||
+35
-19
@@ -1,17 +1,5 @@
|
||||
#!/usr/bin/perl -w
|
||||
######################################################################
|
||||
#
|
||||
# This program is Copyright 2003-2009 by Wilson Snyder.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of either the GNU General Public License or the
|
||||
# Perl Artistic License.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# See copyright, etc in below POD section.
|
||||
######################################################################
|
||||
|
||||
require 5.006_001;
|
||||
@@ -60,6 +48,9 @@ my $opt_gdb;
|
||||
my $opt_jobs = 1;
|
||||
my $opt_verbose;
|
||||
my $Opt_Verilated_Debug;
|
||||
our @Opt_Driver_Verilator_Flags;
|
||||
|
||||
Getopt::Long::config ("pass_through");
|
||||
if (! GetOptions (
|
||||
"help" => \&usage,
|
||||
"debug" => \&debug,
|
||||
@@ -75,7 +66,7 @@ if (! GetOptions (
|
||||
"verbose!" => \$opt_verbose,
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
usage();
|
||||
die "%Error: Bad usage, try '$0 --help'\n";
|
||||
}
|
||||
|
||||
$opt_jobs = calc_jobs() if defined $opt_jobs && $opt_jobs==0;
|
||||
@@ -155,14 +146,28 @@ sub usage {
|
||||
|
||||
sub debug {
|
||||
$Debug = 1;
|
||||
push @Opt_Driver_Verilator_Flags, "--debug";
|
||||
}
|
||||
|
||||
our $_Parameter_Next_Level;
|
||||
|
||||
sub parameter {
|
||||
my $param = shift;
|
||||
if ($param =~ /\.pl/) {
|
||||
if ($_Parameter_Next_Level) {
|
||||
($param =~ /^(\d+)$/)
|
||||
or die "%Error: Expected number following $_Parameter_Next_Level: $param\n";
|
||||
push @Opt_Driver_Verilator_Flags, $param;
|
||||
$_Parameter_Next_Level = undef;
|
||||
}
|
||||
elsif ($param =~ /\.pl/) {
|
||||
push @opt_tests, $param;
|
||||
} else {
|
||||
die "%Error: Unknown parameter: $param\n";
|
||||
}
|
||||
elsif ($param =~ /^--debugi/) {
|
||||
push @Opt_Driver_Verilator_Flags, $param;
|
||||
$_Parameter_Next_Level = $param;
|
||||
}
|
||||
else {
|
||||
warn "%Error: Unknown parameter: $param\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -379,7 +384,7 @@ sub compile {
|
||||
$opt_gdb="gdbrun" if defined $opt_gdb;
|
||||
my @verilator_flags = @{$param{verilator_flags}};
|
||||
unshift @verilator_flags, "--gdb $opt_gdb" if $opt_gdb;
|
||||
unshift @verilator_flags, "--debug" if $::Debug;
|
||||
unshift @verilator_flags, @Opt_Driver_Verilator_Flags;
|
||||
unshift @verilator_flags, "--x-assign unique"; # More likely to be buggy
|
||||
# unshift @verilator_flags, "--trace";
|
||||
if (defined $opt_optimize) {
|
||||
@@ -429,6 +434,7 @@ sub compile {
|
||||
cmd=>["cd $self->{obj_dir} && ",
|
||||
"make", "-f".getcwd()."/Makefile_obj",
|
||||
"VM_PREFIX=$self->{VM_PREFIX}",
|
||||
"CPPFLAGS_DRIVER=-D".uc($self->{name}),
|
||||
($param{make_main}?"":"MAKE_MAIN=0"),
|
||||
($param{benchmark}?"OPT_FAST=-O2":""),
|
||||
"$self->{VM_PREFIX}", # bypass default rule, as we don't need archive
|
||||
@@ -1057,12 +1063,22 @@ Command to use to invoke VCS.
|
||||
|
||||
=back
|
||||
|
||||
=head1 SEE ALSO
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
The latest version is available from L<http://www.veripool.org/>.
|
||||
|
||||
Copyright 2003-2009 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License or the Perl Artistic License.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Wilson Snyder <[email protected]>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<verilator>
|
||||
|
||||
=cut
|
||||
|
||||
######################################################################
|
||||
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
v_flags2 => ["--lint-only"],
|
||||
fails=>1,
|
||||
expect=>
|
||||
'%Error: t/t_assert_dup_bad.v:\d+: Duplicate declaration of block: covlabel
|
||||
%Error: t/t_assert_dup_bad.v:\d+: ... Location of original declaration
|
||||
%Error: Exiting due to.*',
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,19 @@
|
||||
// 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;
|
||||
integer cyc = 0;
|
||||
|
||||
covlabel:
|
||||
cover property (@(posedge clk) cyc==5);
|
||||
covlabel: // Error: Duplicate block_identifier
|
||||
cover property (@(posedge clk) cyc==5);
|
||||
|
||||
endmodule
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2008 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
v_flags2 => [$Self->{v3}?'--assert --sp --coverage-user':''],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
#if ($Self->{nc}) ... # See t_assert_cover.pl for NC version
|
||||
|
||||
# Allow old Perl format dump, or new binary dump
|
||||
# Check that the hierarchy doesn't include __PVT__
|
||||
# Otherwise our coverage reports would look really ugly
|
||||
file_grep ($Self->{coverage_filename}, qr/(TOP\.v\.sub.*.cyc_eq_5)/);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,59 @@
|
||||
// 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;
|
||||
reg toggle;
|
||||
integer cyc; initial cyc=1;
|
||||
|
||||
Test suba (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.toggle (toggle),
|
||||
.cyc (cyc[31:0]));
|
||||
Test subb (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.toggle (toggle),
|
||||
.cyc (cyc[31:0]));
|
||||
Test subc (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.toggle (toggle),
|
||||
.cyc (cyc[31:0]));
|
||||
|
||||
always @ (posedge clk) begin
|
||||
if (cyc!=0) begin
|
||||
cyc <= cyc + 1;
|
||||
toggle <= !cyc[0];
|
||||
if (cyc==9) begin
|
||||
end
|
||||
if (cyc==10) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module Test
|
||||
(
|
||||
input clk,
|
||||
input toggle,
|
||||
input [31:0] cyc
|
||||
);
|
||||
|
||||
// Don't flatten out these modules please:
|
||||
// verilator no_inline_module
|
||||
|
||||
// Labeled cover
|
||||
cyc_eq_5: cover property (@(posedge clk) cyc==5) $display("*COVER: Cyc==5");
|
||||
|
||||
endmodule
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,170 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2009 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
integer cyc=0;
|
||||
reg [63:0] crc;
|
||||
reg [63:0] sum;
|
||||
|
||||
wire [1:0] a = crc[1 +: 2];
|
||||
wire [1:0] b = crc[3 +: 2];
|
||||
wire [1:0] c = crc[5 +: 2];
|
||||
wire [1:0] d = crc[7 +: 2];
|
||||
wire [1:0] e = crc[9 +: 2];
|
||||
wire [1:0] f = crc[11+: 2];
|
||||
wire [1:0] g = crc[13+: 2];
|
||||
|
||||
// left () [] :: .
|
||||
// unary + - ! ~ & ~& | ~| ^ ~^ ^~ ++ -- (unary)
|
||||
// left **
|
||||
// left * / %
|
||||
// left + - (binary)
|
||||
// left << >> <<< >>>
|
||||
// left < <= > >= inside dist
|
||||
// left == != === !== ==? !=?
|
||||
// left & (binary)
|
||||
// left ^ ~^ ^~ (binary)
|
||||
// left | (binary)
|
||||
// left &&
|
||||
// left ||
|
||||
// left ? :
|
||||
// right ->
|
||||
// none = += -= *= /= %= &= ^= |= <<= >>= <<<= >>>= := :/ <=
|
||||
// {} {{}} concatenation
|
||||
|
||||
wire [1:0] bnz = (b==2'b0) ? 2'b11 : b;
|
||||
wire [1:0] cnz = (c==2'b0) ? 2'b11 : c;
|
||||
wire [1:0] dnz = (d==2'b0) ? 2'b11 : d;
|
||||
wire [1:0] enz = (e==2'b0) ? 2'b11 : e;
|
||||
|
||||
// verilator lint_off WIDTH
|
||||
// Do a few in each group
|
||||
wire [1:0] o1 = ~ a; // Can't get more than one reduction to parse
|
||||
wire [1:0] o2 = ^ b; // Can't get more than one reduction to parse
|
||||
`ifdef verilator
|
||||
wire [1:0] o3 = a ** b ** c;
|
||||
`else // A commercial simulator gets this wrong, so calc manually
|
||||
wire [1:0] o3 = pow(pow(a,b),c);
|
||||
`endif
|
||||
|
||||
wire [1:0] o4 = a * b / cnz % dnz * enz;
|
||||
wire [1:0] o5 = a + b - c + d;
|
||||
wire [1:0] o6 = a << b >> c <<< d >>> e <<< f;
|
||||
wire [1:0] o7 = a < b <= c;
|
||||
wire [1:0] o8 = a == b != c === d == e;
|
||||
wire [1:0] o9 = a & b & c;
|
||||
wire [1:0] o10 = a ^ b ~^ c ^~ d ^ a;
|
||||
wire [1:0] o11 = a | b | c;
|
||||
wire [1:0] o12 = a && b && c;
|
||||
wire [1:0] o13 = a || b || c;
|
||||
wire [1:0] o14 = a ? b ? c : d : e;
|
||||
wire [1:0] o15 = a ? b : c ? d : e;
|
||||
|
||||
// Now cross each pair of groups
|
||||
`ifdef verilator
|
||||
wire [1:0] x1 = ~ a ** ~ b ** ~c;
|
||||
wire [1:0] x2 = a ** b * c ** d;
|
||||
`else
|
||||
wire [1:0] x1 = pow(pow(~ a, ~ b), ~c);
|
||||
wire [1:0] x2 = pow(a,b) * pow(c,d);
|
||||
`endif
|
||||
wire [1:0] x3 = a + b * c + d;
|
||||
wire [1:0] x4 = a + b << c + d;
|
||||
wire [1:0] x5 = a == b << c == d;
|
||||
wire [1:0] x6 = a & b << c & d;
|
||||
wire [1:0] x7 = a ^ b & c ^ d;
|
||||
wire [1:0] x8 = a | b ^ c | d;
|
||||
wire [1:0] x9 = a && b | c && d;
|
||||
wire [1:0] x10 = a || b && c || d;
|
||||
wire [1:0] x11 = a ? b || c : d ? e : f;
|
||||
|
||||
// verilator lint_on WIDTH
|
||||
|
||||
function [1:0] pow (input [1:0] x, input [1:0] y);
|
||||
casez ({x,y})
|
||||
4'b00_??: pow = 2'b00;
|
||||
4'b01_00: pow = 2'b01;
|
||||
4'b01_01: pow = 2'b01;
|
||||
4'b01_10: pow = 2'b01;
|
||||
4'b01_11: pow = 2'b01;
|
||||
4'b10_00: pow = 2'b01;
|
||||
4'b10_01: pow = 2'b10;
|
||||
4'b10_10: pow = 2'b00;
|
||||
4'b10_11: pow = 2'b00;
|
||||
4'b11_00: pow = 2'b01;
|
||||
4'b11_01: pow = 2'b11;
|
||||
4'b11_10: pow = 2'b01;
|
||||
4'b11_11: pow = 2'b11;
|
||||
endcase
|
||||
endfunction
|
||||
|
||||
// Aggregate outputs into a single result vector
|
||||
wire [63:0] result = {12'h0,
|
||||
x11,x10,x9,x8,x7,x6,x5,x4,x3,x2,x1,
|
||||
o15,o14,o13,o12,o11,o10,o9,o8,o7,o6,o5,o4,o3,o2,o1};
|
||||
|
||||
// Test loop
|
||||
always @ (posedge clk) begin
|
||||
`ifdef TEST_VERBOSE
|
||||
$write("[%0t] cyc==%0d crc=%x result=%x ",$time, cyc, crc, result);
|
||||
$write(" %b",o1);
|
||||
$write(" %b",o2);
|
||||
$write(" %b",o3);
|
||||
$write(" %b",o4);
|
||||
$write(" %b",o5);
|
||||
$write(" %b",o6);
|
||||
$write(" %b",o7);
|
||||
$write(" %b",o8);
|
||||
$write(" %b",o9);
|
||||
$write(" %b",o10);
|
||||
$write(" %b",o11);
|
||||
$write(" %b",o12);
|
||||
$write(" %b",o13);
|
||||
$write(" %b",o14);
|
||||
$write(" %b",o15);
|
||||
// Now cross each pair of groups
|
||||
$write(" %b",x1);
|
||||
$write(" %b",x2);
|
||||
$write(" %b",x3);
|
||||
$write(" %b",x4);
|
||||
$write(" %b",x5);
|
||||
$write(" %b",x6);
|
||||
$write(" %b",x7);
|
||||
$write(" %b",x8);
|
||||
$write(" %b",x9);
|
||||
$write(" %b",x10);
|
||||
$write(" %b",x11);
|
||||
$write("\n");
|
||||
`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]};
|
||||
if (cyc==0) begin
|
||||
// Setup
|
||||
crc <= 64'h5aef0c8d_d70a4497;
|
||||
sum <= 64'h0;
|
||||
end
|
||||
else if (cyc<10) begin
|
||||
sum <= 64'h0;
|
||||
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;
|
||||
// What checksum will we end up with (above print should match)
|
||||
`define EXPECTED_SUM 64'h34b4e0b25bb03880
|
||||
if (sum !== `EXPECTED_SUM) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,33 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2009 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/);
|
||||
|
||||
reg signed [2:0] negcnt;
|
||||
integer times;
|
||||
integer repeats;
|
||||
initial begin
|
||||
times = 0;
|
||||
repeat (1) begin
|
||||
repeat (0) $stop;
|
||||
repeat (-1) $stop;
|
||||
negcnt = 'sb111;
|
||||
repeat (negcnt) $stop;
|
||||
repeat (5) begin
|
||||
repeat (2) begin
|
||||
times = times + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
if (times != 10) $stop;
|
||||
//
|
||||
repeats = 0;
|
||||
forever begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -9,12 +9,16 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
compile (
|
||||
fails=>1,
|
||||
expect=>
|
||||
'%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Cell has same name as variable: varfirst
|
||||
%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Task/function has same name as variable: varfirst
|
||||
'%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Cell has the same name as variable: varfirst
|
||||
%Error: t/t_var_bad_sameas.v:\d+: ... Location of original declaration
|
||||
%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Task has the same name as variable: varfirst
|
||||
%Error: t/t_var_bad_sameas.v:\d+: ... Location of original declaration
|
||||
%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Variable has same name as cell: cellfirst
|
||||
%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Task/function has same name as cell: cellfirst
|
||||
%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Task has the same name as cell: cellfirst
|
||||
%Error: t/t_var_bad_sameas.v:\d+: ... Location of original declaration
|
||||
%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Variable has same name as task: taskfirst
|
||||
%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Cell has same name as task: taskfirst
|
||||
%Error: t/t_var_bad_sameas.v:\d+: Unsupported in C: Cell has the same name as task: taskfirst
|
||||
%Error: t/t_var_bad_sameas.v:\d+: ... Location of original declaration
|
||||
%Error: Exiting due to.*',
|
||||
);
|
||||
|
||||
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
top_filename("t/t_var_pinsizes.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ["-sp -pins-bv 1 --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
|
||||
make_main => 0,
|
||||
) if $Self->{v3};
|
||||
|
||||
if ($Self->{v3}) {
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<1>\s> \s+ i1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<8>\s> \s+ i8;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ i16;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<32>\s> \s+ i32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<64>\s> \s+ i64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<1>\s> \s+ o1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<8>\s> \s+ o8;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ o16;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<32>\s> \s+ o32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<64>\s> \s+ o64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
}
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
top_filename("t/t_var_pinsizes.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ["-sp -pins-bv 2 --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
|
||||
make_main => 0,
|
||||
) if $Self->{v3};
|
||||
|
||||
if ($Self->{v3}) {
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<bool> \s+ i1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<8>\s> \s+ i8;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<16>\s> \s+ i16;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<32>\s> \s+ i32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<64>\s> \s+ i64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<8>\s> \s+ o8;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<16>\s> \s+ o16;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<32>\s> \s+ o32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<64>\s> \s+ o64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
}
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -9,24 +9,24 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
top_filename("t/t_var_pinsizes.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ['-sp -no-pins64'],
|
||||
verilator_make_gcc => 0,
|
||||
v_flags2 => ["-sp -no-pins64 --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
|
||||
make_main => 0,
|
||||
) if $Self->{v3};
|
||||
|
||||
if ($Self->{v3}) {
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_in<bool> \s+ i1;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_in<uint32_t> \s+ i8;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_in<uint32_t> \s+ i16;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_in<uint32_t> \s+ i32;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_in<sc_bv<64>\s> \s+ i64;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<bool> \s+ i1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i8;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i16;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<64>\s> \s+ i64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_out<bool> \s+ o1;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_out<uint32_t> \s+ o8;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_out<uint32_t> \s+ o16;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_out<uint32_t> \s+ o32;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_out<sc_bv<64>\s> \s+ o64;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc32.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o8;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o16;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<64>\s> \s+ o64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
}
|
||||
|
||||
ok(1);
|
||||
|
||||
@@ -9,24 +9,24 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di
|
||||
top_filename("t/t_var_pinsizes.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => ['-sp -pins64'],
|
||||
verilator_make_gcc => 0,
|
||||
v_flags2 => ["-sp -pins64 --exe $Self->{t_dir}/t_var_pinsizes.cpp"],
|
||||
make_main => 0,
|
||||
) if $Self->{v3};
|
||||
|
||||
if ($Self->{v3}) {
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_in<bool> \s+ i1;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_in<uint32_t> \s+ i8;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_in<uint32_t> \s+ i16;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_in<uint32_t> \s+ i32;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_in<uint64_t> \s+ i64;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<bool> \s+ i1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i8;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i16;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint32_t> \s+ i32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<uint64_t> \s+ i64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_in<sc_bv<65>\s> \s+ i65;/x);
|
||||
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_out<bool> \s+ o1;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_out<uint32_t> \s+ o8;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_out<uint32_t> \s+ o16;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_out<uint32_t> \s+ o32;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_out<uint64_t> \s+ o64;/x);
|
||||
file_grep ("$Self->{obj_dir}/Vt_var_pins_sc64.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<bool> \s+ o1;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o8;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o16;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint32_t> \s+ o32;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<uint64_t> \s+ o64;/x);
|
||||
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}.sp", qr/sc_out<sc_bv<65>\s> \s+ o65;/x);
|
||||
}
|
||||
|
||||
ok(1);
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
#ifdef T_VAR_PINS_CC
|
||||
# include "Vt_var_pins_cc.h"
|
||||
#elif defined(T_VAR_PINS_SC1)
|
||||
# include "Vt_var_pins_sc1.h"
|
||||
#elif defined(T_VAR_PINS_SC2)
|
||||
# include "Vt_var_pins_sc2.h"
|
||||
#elif defined(T_VAR_PINS_SC32)
|
||||
# include "Vt_var_pins_sc32.h"
|
||||
#elif defined(T_VAR_PINS_SC64)
|
||||
# include "Vt_var_pins_sc64.h"
|
||||
#else
|
||||
# error "Unknown test"
|
||||
#endif
|
||||
|
||||
VM_PREFIX* tb = NULL;
|
||||
|
||||
double sc_time_stamp() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main() {
|
||||
Verilated::debug(0);
|
||||
tb = new VM_PREFIX("tb");
|
||||
|
||||
cout << "*-* All Finished *-*" << endl;
|
||||
tb->final();
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user