mirror of
https://github.com/verilator/verilator.git
synced 2026-10-03 00:23:35 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bcc7045fc9 | ||
|
|
3b1929259a | ||
|
|
cdd6ea8e60 | ||
|
|
4b8927af75 | ||
|
|
0fba25c1b3 | ||
|
|
f19ba9d54d | ||
|
|
8e9a0121ac | ||
|
|
bd6e8d808c | ||
|
|
11b9a631d4 | ||
|
|
f197dd29cb | ||
|
|
daf7f42138 | ||
|
|
dd487d4184 | ||
|
|
d90071637d | ||
|
|
d8efae2aba | ||
|
|
22543f3e19 | ||
|
|
6aaef67e73 | ||
|
|
82a934d6fb | ||
|
|
eca6f2ca05 | ||
|
|
ef69f36403 | ||
|
|
99cf981c2f | ||
|
|
fc7a449f6d | ||
|
|
b7fafdafaa | ||
|
|
8e180cfcde | ||
|
|
4770fd39d2 | ||
|
|
df107628c6 | ||
|
|
3463080a71 | ||
|
|
500dc2170f | ||
|
|
a76ae67a81 | ||
|
|
1d091e49e1 | ||
|
|
2b63219cc6 | ||
|
|
f1b7762bef | ||
|
|
043ad86482 | ||
|
|
74ca9578ed | ||
|
|
d499161446 |
@@ -3,6 +3,42 @@ 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.680 2008/10/08
|
||||
|
||||
** Support negative bit indexes. [Stephane Laurent]
|
||||
Tracing negative indexes requires latest Verilog-Perl and SystemPerl.
|
||||
|
||||
*** Suppress width warnings between constant strings and wider vectors.
|
||||
[Rodney Sinclair]
|
||||
|
||||
**** Expand environment variables in -f input files. [Lawrence Butcher]
|
||||
|
||||
**** Report error if port declaration is missing; bug32. [Guy-Armand Kamendje]
|
||||
|
||||
**** Fix genvars causing link error when using --public. [Chris Candler]
|
||||
|
||||
* Verilator 3.671 2008/09/19
|
||||
|
||||
** SystemC uint64_t pins are now the default instead of sc_bv<64>.
|
||||
Use --no-pins64 for backward compatibility.
|
||||
|
||||
*** Support SystemVerilog "cover property" statements.
|
||||
|
||||
*** When warnings are disabled on signals that are flattened out, disable
|
||||
the warnings on the signal(s) that replace it.
|
||||
|
||||
*** Add by-design and by-module subtotals to verilator_profcfunc.
|
||||
|
||||
*** Fix extra evaluation of pure combo blocks in SystemC output.
|
||||
|
||||
**** Add IMPERFECTSCH warning, disabled by default.
|
||||
|
||||
**** Support coverage under SystemPerl 1.285 and newer.
|
||||
|
||||
**** Fix stack overflow on large ? : trees. [John Sanguinetti]
|
||||
|
||||
**** Support arbitrary characters in identifiers. [Stephane Laurent]
|
||||
|
||||
* Verilator 3.670 2008/07/23
|
||||
|
||||
** Add --x-assign=fast option, and make it the default.
|
||||
@@ -10,7 +46,7 @@ indicates the contributor was also the author of the fix; Thanks!
|
||||
|
||||
** Add --autoflush, for flushing streams after $display. [Steve Tong]
|
||||
|
||||
** Add CASEZWITHX lint warning and if disabled fix handling of casez with Xs.
|
||||
** Add CASEWITHX lint warning and if disabled fix handling of casez with Xs.
|
||||
|
||||
*** Add $feof, $fgetc, $fgets, $fflush, $fscanf, $sscanf. [Holger Waechtler]
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
/obj_dbg/
|
||||
/obj_opt/
|
||||
/INCA_libs/
|
||||
/cov_work/
|
||||
/logs/
|
||||
Makefile
|
||||
src/Makefile_obj
|
||||
|
||||
+2
-2
@@ -110,7 +110,7 @@ DISTFILES_INC = $(INFOS) .gitignore COPYING *.in *.ac \
|
||||
include/*.in \
|
||||
include/.*ignore \
|
||||
.*attributes */.*attributes */*/.*attributes \
|
||||
src/.*ignore src/*.in src/*.cpp src/*.[chly] src/astgen src/*fix \
|
||||
src/.*ignore src/*.in src/*.cpp src/*.[chly] src/astgen src/bisonpre src/*fix \
|
||||
src/*.pl \
|
||||
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
|
||||
test_*/*.pl test_*/*.v test_*/*.vc test_*/vlint \
|
||||
@@ -127,6 +127,7 @@ DISTFILES_INC = $(INFOS) .gitignore COPYING *.in *.ac \
|
||||
INST_PROJ_FILES = \
|
||||
bin/verilator \
|
||||
bin/verilator_includer \
|
||||
bin/verilator_profcfunc \
|
||||
include/verilated.[chv]* \
|
||||
include/verilated.mk \
|
||||
include/verilatedos.[chv]* \
|
||||
@@ -245,7 +246,6 @@ installman:
|
||||
installdata:
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(DESTDIR)$(pkgdatadir)/examples
|
||||
cp -r include $(DESTDIR)$(pkgdatadir)
|
||||
cp -r src $(DESTDIR)$(pkgdatadir)
|
||||
cp -r test_c $(DESTDIR)$(pkgdatadir)/examples
|
||||
cp -r test_sc $(DESTDIR)$(pkgdatadir)/examples
|
||||
cp -r test_sp $(DESTDIR)$(pkgdatadir)/examples
|
||||
|
||||
+51
-27
@@ -100,8 +100,8 @@ sub verilator_bin {
|
||||
my $bin = "";
|
||||
# Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path
|
||||
$bin .= $ENV{VERILATOR_ROOT}."/" if defined($ENV{VERILATOR_ROOT});
|
||||
$bin .= ($ENV{VERILATOR_BIN}||"verilator_bin");
|
||||
if ($Debug) { $bin = "${bin}_dbg"; }
|
||||
$bin .= ($ENV{VERILATOR_BIN}
|
||||
|| ($Debug ? "verilator_bin_dbg" : "verilator_bin"));
|
||||
return $bin;
|
||||
}
|
||||
|
||||
@@ -202,13 +202,13 @@ descriptions in the next sections for more information.
|
||||
--MP Create phony dependency targets
|
||||
--Mdir <directory> Name of output object directory
|
||||
--mod-prefix <topname> Name to prepend to lower classes
|
||||
--no-pins64 Don't use uint64_t's for 33-64 bit sigs
|
||||
--no-skip-identical Disable skipping identical output
|
||||
-O0 Disable optimizations
|
||||
-O3 High performance optimizations
|
||||
-O<optimization-letter> Selectable optimizations
|
||||
--output-split <bytes> Split .cpp files into pieces
|
||||
--output-split-cfuncs <statements> Split .ccp functions
|
||||
--pins64 Use uint64_t's for 33-64 bit sigs
|
||||
--prefix <topname> Name of top level class
|
||||
--profile-cfuncs Name functions for profiling
|
||||
--private Debugging; see docs
|
||||
@@ -296,7 +296,7 @@ functions to avoid error C1061.
|
||||
|
||||
=item --coverage
|
||||
|
||||
Enables all forms of coverage, alias for --coverage-line, --coverage-user
|
||||
Enables all forms of coverage, alias for --coverage-line, --coverage-user.
|
||||
|
||||
=item --coverage-line
|
||||
|
||||
@@ -308,10 +308,6 @@ Coverage. At each such branch a unique counter is incremented. At the end
|
||||
of a test, the counters along with the filename and line number
|
||||
corresponding to each counter are written into logs/coverage.pl.
|
||||
|
||||
After running multiple tests, the vcoverage utility (from the SystemPerl
|
||||
package) is executed. Vcoverage reads the logs/coverage.pl file(s), and
|
||||
creates an annotated source code listing showing code coverage details.
|
||||
|
||||
Verilator automatically disables coverage of branches that have a $stop in
|
||||
them, as it is assumed $stop branches contain an error check that should
|
||||
not occur. A /*verilator coverage_block_off*/ comment will perform a
|
||||
@@ -321,10 +317,6 @@ Note Verilator may over-count combinatorial (non-clocked) blocks when those
|
||||
blocks receive signals which have had the UNOPTFLAT warning disabled; for
|
||||
most accurate results do not disable this warning when using coverage.
|
||||
|
||||
For an example, after running 'make test' in the Verilator distribution,
|
||||
see the test_sp/logs/coverage_source directory. Grep for lines starting
|
||||
with '%' to see what lines Verilator believes need more coverage.
|
||||
|
||||
=item --coverage-user
|
||||
|
||||
Enables user inserted functional coverage. Currently, all functional
|
||||
@@ -421,6 +413,12 @@ be placed in this directory. If not specified, "obj_dir" is used.
|
||||
Specifies the name to prepend to all lower level classes. Defaults to
|
||||
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.
|
||||
|
||||
=item --no-skip-identical
|
||||
|
||||
Rarely needed. Disables skipping execution of Verilator if all source
|
||||
@@ -462,11 +460,6 @@ operations, a new function will be created. With --output-split, this will
|
||||
enable GCC to compile faster, at a small loss in performance that increases
|
||||
with smaller statement values.
|
||||
|
||||
=item --pins64
|
||||
|
||||
Specifies SystemC outputs of 33-64 bits wide should use uint64_t instead of
|
||||
the backward-compatible default of sc_bv's.
|
||||
|
||||
=item --prefix I<topname>
|
||||
|
||||
Specifies the name of the top level class and makefile. Defaults to V
|
||||
@@ -572,7 +565,7 @@ Disable the specified warning message.
|
||||
=item -Wno-lint
|
||||
|
||||
Disable all lint related warning messages. This is equivelent to
|
||||
"-Wno-CASEINCOMPLETE -Wno-CASEOVERLAP -Wno-CASEX -Wno-CASEZWITHX
|
||||
"-Wno-CASEINCOMPLETE -Wno-CASEOVERLAP -Wno-CASEX -Wno-CASEWITHX
|
||||
-Wno-CMPCONST -Wno-IMPLICIT -Wno-UNDRIVEN -Wno-UNSIGNED -Wno-UNUSED
|
||||
-Wno-VARHIDDEN -Wno-WIDTH".
|
||||
|
||||
@@ -580,6 +573,10 @@ It is strongly recommended you cleanup your code rather than using this
|
||||
option, it is only intended to be use when running test-cases of code
|
||||
received from third parties.
|
||||
|
||||
=item -Wwarn-I<message>
|
||||
|
||||
Enables the specified warning message.
|
||||
|
||||
=item -x-assign 0
|
||||
|
||||
=item -x-assign 1
|
||||
@@ -977,11 +974,10 @@ Verilator will convert the top level module to a SC_MODULE. This module
|
||||
will plug directly into a SystemC netlist.
|
||||
|
||||
The SC_MODULE gets the same pinout as the Verilog module, with the
|
||||
following type conversions: Pins of a single bit become bool, unless they
|
||||
are marked with `systemc_clock, in which case they become sc_clock's (for
|
||||
SystemC 1.2, not needed in SystemC 2.0). Pins 2-32 bits wide become
|
||||
uint32_t's. Pins 33-64 bits wide become sc_bv's or uint64_t's depending on
|
||||
the -pins64 switch. Wider pins become sc_bv's.
|
||||
following type conversions: Pins of a single bit become bool. Pins 2-32
|
||||
bits wide become uint32_t's. Pins 33-64 bits wide become sc_bv's or
|
||||
uint64_t's depending on the --no-pins64 switch. Wider pins become sc_bv's.
|
||||
(Uints simulate the fastest so are used where possible.)
|
||||
|
||||
Lower modules are not pure SystemC code. This is a feature, as using the
|
||||
SystemC pin interconnect scheme everywhere would reduce performance by an
|
||||
@@ -1046,7 +1042,8 @@ always_ff, always_latch, do-while, and final.
|
||||
|
||||
It also supports .name and .* interconnection.
|
||||
|
||||
Verilator partially supports assert.
|
||||
Verilator partially supports concurrent assert and cover statements; see
|
||||
the enclosed coverage tests for the syntax which is allowed.
|
||||
|
||||
=head1 SUGAR/PSL SUPPORT
|
||||
|
||||
@@ -1343,7 +1340,9 @@ using the --public switch.
|
||||
=item /*verilator sc_clock*/
|
||||
|
||||
Used after a input declaration to indicate the signal should be declared in
|
||||
SystemC as a sc_clock instead of a bool.
|
||||
SystemC as a sc_clock instead of a bool. This was needed in SystemC 1.1
|
||||
and 1.2 only; versions 2.0 and later do not require clock pins to be
|
||||
sc_clocks and this is no longer needed.
|
||||
|
||||
=item /*verilator tracing_off*/
|
||||
|
||||
@@ -1728,6 +1727,13 @@ additional ones.)
|
||||
Ignoring this warning may make Verilator simulations differ from other
|
||||
simulators.
|
||||
|
||||
=item IMPERFECTSCH
|
||||
|
||||
Warns that the scheduling of the model is not absolutely perfect, and some
|
||||
manual code edits may result in faster performance. This warning defaults
|
||||
to off, and must be turned on explicitly before the top module statement is
|
||||
processed.
|
||||
|
||||
=item IMPLICIT
|
||||
|
||||
Warns that a wire is being implicitly declared (it is a single bit wide
|
||||
@@ -2091,6 +2097,24 @@ Verilator makes standard VCD (Value Change Dump) files. They are viewable
|
||||
with the public domain Dinotrace or GtkWave programs, or any of the many
|
||||
commercial offerings.
|
||||
|
||||
=item How do I do coverage analysis?
|
||||
|
||||
Verilator supports both block (line) coverage and user inserted functional
|
||||
coverage. First, run verilator with the --coverage option. If you're
|
||||
using your own makefile, compile the model with the GCC flag
|
||||
-DSP_COVERAGE_ENABLE (if using Verilator's, it will do this for you.)
|
||||
|
||||
Run your tests in different directories. Each test will create a
|
||||
logs/coverage.pl file.
|
||||
|
||||
After running all of your tests, the vcoverage utility (from the SystemPerl
|
||||
package) is executed. Vcoverage reads the logs/coverage.pl file(s), and
|
||||
creates an annotated source code listing showing code coverage details.
|
||||
|
||||
For an example, after running 'make test' in the Verilator distribution,
|
||||
see the test_sp/logs/coverage_source directory. Grep for lines starting
|
||||
with '%' to see what lines Verilator believes need more coverage.
|
||||
|
||||
=item Where is the translate_off command? (How do I ignore a construct?)
|
||||
|
||||
Translate on/off pragmas are generally a bad idea, as it's easy to have
|
||||
@@ -2200,7 +2224,7 @@ From the sc_main.cpp file, you'd then:
|
||||
|
||||
#include "Vour.h"
|
||||
#include "Vour_our.h"
|
||||
top->v.publicSetBool(value);
|
||||
top->v->publicSetBool(value);
|
||||
|
||||
See additional notes under the /*verilator public*/ section.
|
||||
|
||||
@@ -2235,7 +2259,7 @@ From the sc_main.cpp file, you'd then:
|
||||
|
||||
#include "Vour.h"
|
||||
#include "Vour_our.h"
|
||||
cout << "clock is " << top->v.clk << endl;
|
||||
cout << "clock is " << top->v->clk << endl;
|
||||
|
||||
In this example, clk is a bool you can read or set as any other variable.
|
||||
The value of normal signals may be set, though clocks shouldn't be changed
|
||||
|
||||
+42
-23
@@ -1,18 +1,7 @@
|
||||
: # -*-Mode: perl;-*- use perl, wherever it is
|
||||
eval 'exec perl -wS $0 ${1+"$@"}'
|
||||
if 0;
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2007-2008 by Wilson Snyder <[email protected]>. This
|
||||
# program 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.
|
||||
#
|
||||
# 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;
|
||||
@@ -20,6 +9,7 @@ use warnings;
|
||||
use Getopt::Long;
|
||||
use IO::File;
|
||||
use Pod::Usage;
|
||||
eval { use Data::Dumper; $Data::Dumper::Indent = 1; }; # Debug, ok if missing
|
||||
use strict;
|
||||
use vars qw ($Debug);
|
||||
|
||||
@@ -76,7 +66,8 @@ sub profcfunc {
|
||||
my %funcs;
|
||||
|
||||
while (defined (my $line=$fh->getline())) {
|
||||
if ($line =~ /^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+([0-9.]+)\s+.*\s+(\S+)\s*$/) {
|
||||
# %time cumesec selfsec calls {stuff} name
|
||||
if ($line =~ /^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+([0-9.]+)\s+[^a-zA-Z_]*([a-zA-Z_].*)$/) {
|
||||
my $pct=$1; my $sec=$2; my $calls=$3; my $func=$4;
|
||||
$funcs{$func}{pct} += $pct;
|
||||
$funcs{$func}{sec} += $sec;
|
||||
@@ -86,47 +77,75 @@ sub profcfunc {
|
||||
$fh->close;
|
||||
|
||||
# Find modules
|
||||
my %pointer_mods;
|
||||
my %verilated_mods;
|
||||
foreach my $func (keys %funcs) {
|
||||
if ($func =~ /(.*)::_eval\(.*__Syms.*\)$/) {
|
||||
if ($func =~ /(.*)::_eval\(([a-zA-Z_0-9]+__Syms).*\)$/) {
|
||||
$verilated_mods{$1} = qr/^$1/;
|
||||
$pointer_mods{$2} = $1;
|
||||
}
|
||||
}
|
||||
#print Dumper(\%pointer_mods, \%verilated_mods);
|
||||
|
||||
# Resort by Verilog name
|
||||
my %vfuncs;
|
||||
my %groups;
|
||||
foreach my $func (keys %funcs) {
|
||||
my $pct = $funcs{$func}{pct};
|
||||
my $vfunc = $func;
|
||||
my $design;
|
||||
|
||||
if ($func =~ /\(([a-zA-Z_0-9]+__Syms)/) {
|
||||
$design = $pointer_mods{$1};
|
||||
}
|
||||
|
||||
foreach my $vde (keys %verilated_mods) {
|
||||
last if $design;
|
||||
if ($func =~ /$verilated_mods{$vde}/) {
|
||||
$design=$vde;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
if ($vfunc =~ /__PROF__([a-zA-Z_0-9]+)__([0-9]+)\(/) {
|
||||
$vfunc = sprintf("VBlock %s:%d", $1, $2);
|
||||
$groups{"Verilog Blocks under $design"} += $funcs{$func}{pct};
|
||||
$groups{type}{"Verilog Blocks under $design"} += $pct;
|
||||
$groups{design}{$design} += $pct;
|
||||
$groups{module}{$1} += $pct;
|
||||
} else {
|
||||
if ($design) {
|
||||
$vfunc = sprintf("VCommon %s", $func);
|
||||
$groups{"Common code under $design"} += $funcs{$func}{pct};
|
||||
$groups{type}{"Common code under $design"} += $pct;
|
||||
$groups{design}{$design} += $pct;
|
||||
$groups{module}{$design." common code"} += $pct;
|
||||
} else {
|
||||
$vfunc = sprintf("C++ %s", $func);
|
||||
$groups{'C++'} += $funcs{$func}{pct};
|
||||
$groups{type}{'C++'} += $pct;
|
||||
$groups{design}{'C++'} += $pct;
|
||||
$groups{module}{'C++'} += $pct;
|
||||
}
|
||||
}
|
||||
$vfuncs{$vfunc} = $funcs{$func};
|
||||
}
|
||||
|
||||
print("Overall summary:\n");
|
||||
print(" % time\n");
|
||||
foreach (sort (keys %groups)) {
|
||||
printf(" %6.2f In all %s\n", $groups{$_}, $_);
|
||||
}
|
||||
print("\n");
|
||||
|
||||
foreach my $type qw(type design module) {
|
||||
my $missing = 100;
|
||||
foreach (sort (keys %{$groups{$type}})) {
|
||||
$missing -= $groups{$type}{$_};
|
||||
}
|
||||
if ($missing) {
|
||||
$groups{$type}{"\377Unaccounted for/rounding error"} = $missing;
|
||||
}
|
||||
|
||||
print("Overall summary by $type:\n");
|
||||
printf(" %-6s %s\n","% time",$type);
|
||||
foreach my $what (sort (keys %{$groups{$type}})) {
|
||||
(my $pwhat = $what) =~ s/^\377//; # Just used to establish sort order
|
||||
printf(" %6.2f %s\n", $groups{$type}{$what}, $pwhat);
|
||||
}
|
||||
print("\n");
|
||||
}
|
||||
|
||||
print("Verilog code profile:\n");
|
||||
print(" These are split into three categories:\n");
|
||||
|
||||
@@ -229,6 +229,22 @@ void _vl_vsformat(string& output, const char* formatp, va_list ap) {
|
||||
output += tmp;
|
||||
break;
|
||||
}
|
||||
case 't': { // Time
|
||||
int digits;
|
||||
if (VL_TIME_MULTIPLIER==1) {
|
||||
digits=sprintf(tmp,"%llu",ld);
|
||||
} else if (VL_TIME_MULTIPLIER==1000) {
|
||||
digits=sprintf(tmp,"%llu.%03llu",
|
||||
(QData)(ld/VL_TIME_MULTIPLIER),
|
||||
(QData)(ld%VL_TIME_MULTIPLIER));
|
||||
} else {
|
||||
vl_fatal(__FILE__,__LINE__,"","%%Error: Unsupported VL_TIME_MULTIPLIER");
|
||||
}
|
||||
int needmore = width-digits;
|
||||
if (needmore>0) output.append(needmore,' '); // Pre-pad spaces
|
||||
output += tmp;
|
||||
break;
|
||||
}
|
||||
case 'b':
|
||||
for (; lsb>=0; lsb--) {
|
||||
output += ((lwp[VL_BITWORD_I(lsb)]>>VL_BITBIT_I(lsb)) & 1) + '0';
|
||||
@@ -386,6 +402,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||
VL_SET_WQ(owp,ld);
|
||||
break;
|
||||
}
|
||||
case 't': // FALLTHRU // Time
|
||||
case 'u': { // Unsigned decimal
|
||||
_vl_vsss_skipspace(fp,floc,fromp);
|
||||
_vl_vsss_read(fp,floc,fromp, tmp, "0123456789+-xz?_");
|
||||
|
||||
+8
-4
@@ -255,13 +255,17 @@ static inline void _VL_DEBUG_PRINT_W(int lbits, WDataInP iwp) {
|
||||
//=========================================================================
|
||||
// Pli macros
|
||||
|
||||
#ifndef VL_TIME_MULTIPLIER
|
||||
# define VL_TIME_MULTIPLIER 1
|
||||
#endif
|
||||
|
||||
/// Return current simulation time
|
||||
#if defined(SYSTEMC_VERSION) && (SYSTEMC_VERSION>20011000)
|
||||
# define VL_TIME_I(ign) ((IData)sc_time_stamp().to_default_time_units())
|
||||
# define VL_TIME_Q(ign) ((QData)sc_time_stamp().to_default_time_units())
|
||||
# define VL_TIME_I(ign) ((IData)(sc_time_stamp().to_default_time_units()*VL_TIME_MULTIPLIER))
|
||||
# define VL_TIME_Q(ign) ((QData)(sc_time_stamp().to_default_time_units()*VL_TIME_MULTIPLIER))
|
||||
#else
|
||||
# define VL_TIME_I(ign) ((IData)sc_time_stamp())
|
||||
# define VL_TIME_Q(ign) ((QData)sc_time_stamp())
|
||||
# define VL_TIME_I(ign) ((IData)(sc_time_stamp()*VL_TIME_MULTIPLIER))
|
||||
# define VL_TIME_Q(ign) ((QData)(sc_time_stamp()*VL_TIME_MULTIPLIER))
|
||||
extern double sc_time_stamp();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ VK_CPPFLAGS_ALWAYS += \
|
||||
-I$(VERILATOR_ROOT)/include \
|
||||
-DVL_PRINTF=printf \
|
||||
-DVM_TRACE=$(VM_TRACE) \
|
||||
-DVM_COVERAGE=$(VM_COVERAGE) \
|
||||
|
||||
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
|
||||
VK_CPPFLAGS_WALL += -Wall \
|
||||
|
||||
+1
-12
@@ -1,16 +1,5 @@
|
||||
#!/usr/bin/perl -w
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2005-2008 by Wilson Snyder <[email protected]>. This
|
||||
# program 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.
|
||||
#
|
||||
# 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;
|
||||
|
||||
+1
-12
@@ -1,16 +1,5 @@
|
||||
#!/usr/bin/perl -w
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2005-2008 by Wilson Snyder <[email protected]>. This
|
||||
# program 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.
|
||||
#
|
||||
# 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;
|
||||
|
||||
Executable
+58
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/perl -w
|
||||
# See copyright, etc in below POD section.
|
||||
######################################################################
|
||||
|
||||
require 5.006_001;
|
||||
use strict;
|
||||
|
||||
#======================================================================
|
||||
# main
|
||||
|
||||
delete $ENV{MODULE_VERSION};
|
||||
_setup_modules();
|
||||
module('add','cadence_verif');
|
||||
exec('iccr',@ARGV);
|
||||
|
||||
#######################################################################
|
||||
# Modules package
|
||||
|
||||
sub _setup_modules {
|
||||
# Load the 'module' command into the environment
|
||||
my $init = "/sicortex/$ENV{DIRPROJECT_ARCH}/lib/Modules/default/init/perl";
|
||||
(-f $init) or die "%Error: Script not found: $init,";
|
||||
require $init;
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
invoke_iccr - Invoke tool under "modules" command
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
invoke_iccr {ncv arguments}
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2007-2008 by Wilson Snyder. This package 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
|
||||
|
||||
=cut
|
||||
|
||||
######################################################################
|
||||
### Local Variables:
|
||||
### compile-command: "./invoke_iccr -help"
|
||||
### End:
|
||||
+1
-12
@@ -1,16 +1,5 @@
|
||||
#!/usr/bin/perl -w
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2007-2008 by Wilson Snyder <[email protected]>. This
|
||||
# program 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.
|
||||
#
|
||||
# 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;
|
||||
|
||||
+1
-12
@@ -1,16 +1,5 @@
|
||||
#!/usr/bin/perl -w
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2005-2008 by Wilson Snyder <[email protected]>. This
|
||||
# program 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.
|
||||
#
|
||||
# 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;
|
||||
|
||||
+3
-5
@@ -31,7 +31,6 @@ LEX = @LEX@
|
||||
LFLAGS = -d
|
||||
PERL = @PERL@
|
||||
YACC = @YACC@
|
||||
YFLAGS = -y -d -v
|
||||
|
||||
prefix = @prefix@
|
||||
|
||||
@@ -98,6 +97,7 @@ endif
|
||||
HEADERS = $(wildcard V*.h v*.h)
|
||||
|
||||
ASTGEN = $(srcdir)/astgen
|
||||
BISONPRE = $(srcdir)/bisonpre
|
||||
|
||||
######################################################################
|
||||
#### Top level
|
||||
@@ -254,11 +254,9 @@ V3Ast__gen_classes.h : $(ASTGEN) V3Ast.h V3AstNodes.h
|
||||
y.tab.h: y.tab.c
|
||||
|
||||
# Have only one output file in this rule to prevent parallel make issues
|
||||
y.tab.c: verilog.y $(HEADERS)
|
||||
y.tab.c: verilog.y $(HEADERS) bisonpre
|
||||
@echo "If you get errors from verilog.y below, try upgrading bison to version 1.875 or newer."
|
||||
${YACC} ${YFLAGS} $<
|
||||
mv y.tab.c y_pregen.tab.c && $(PERL) $(srcdir)/bisonfix < y_pregen.tab.c > y.tab.c
|
||||
mv y.tab.h y_pregen.tab.h && $(PERL) $(srcdir)/bisonfix < y_pregen.tab.h > y.tab.h
|
||||
$(PERL) $(BISONPRE) --yacc ${YACC} -d -v -o y.tab.c $<
|
||||
|
||||
V3Lexer_pregen.yy.cpp: verilog.l y.tab.h $(HEADERS)
|
||||
${LEX} ${LFLAGS} -o$@ $<
|
||||
|
||||
+21
-3
@@ -43,6 +43,7 @@ private:
|
||||
|
||||
// STATE
|
||||
AstModule* m_modp; // Last module
|
||||
AstBegin* m_beginp; // Last begin
|
||||
V3Double0 m_statAsCover; // Statistic tracking
|
||||
V3Double0 m_statAsPsl; // Statistic tracking
|
||||
V3Double0 m_statAsFull; // Statistic tracking
|
||||
@@ -100,9 +101,11 @@ private:
|
||||
return bodysp;
|
||||
}
|
||||
|
||||
void newPslAssertion(AstNode* nodep, AstNode* propp, AstSenTree* sentreep, const string& message) {
|
||||
void newPslAssertion(AstNode* nodep, AstNode* propp, AstSenTree* sentreep,
|
||||
AstNode* stmtsp, const string& message) {
|
||||
propp->unlinkFrBack();
|
||||
sentreep->unlinkFrBack();
|
||||
if (stmtsp) stmtsp->unlinkFrBack();
|
||||
//
|
||||
AstNode* bodysp = NULL;
|
||||
bool selfDestruct = false;
|
||||
@@ -126,6 +129,7 @@ private:
|
||||
} else {
|
||||
nodep->v3fatalSrc("Unknown node type");
|
||||
}
|
||||
if (stmtsp) bodysp = bodysp->addNext(stmtsp);
|
||||
AstIf* ifp = new AstIf (nodep->fileline(), propp, bodysp, NULL);
|
||||
bodysp = ifp;
|
||||
if (nodep->castPslAssert()) ifp->branchPred(AstBranchPred::UNLIKELY);
|
||||
@@ -232,12 +236,15 @@ private:
|
||||
|
||||
virtual void visit(AstPslCover* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(), nodep->name()); nodep=NULL;
|
||||
if (m_beginp && nodep->name() == "") nodep->name(m_beginp->name());
|
||||
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(),
|
||||
nodep->stmtsp(), nodep->name()); nodep=NULL;
|
||||
m_statAsCover++;
|
||||
}
|
||||
virtual void visit(AstPslAssert* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(), nodep->name()); nodep=NULL;
|
||||
newPslAssertion(nodep, nodep->propp(), nodep->sentreep(),
|
||||
NULL, nodep->name()); nodep=NULL;
|
||||
m_statAsPsl++;
|
||||
}
|
||||
virtual void visit(AstVAssert* nodep, AstNUser*) {
|
||||
@@ -253,6 +260,16 @@ private:
|
||||
// Reset defaults
|
||||
m_modp = NULL;
|
||||
}
|
||||
virtual void visit(AstBegin* nodep, AstNUser*) {
|
||||
// This code is needed rather than a visitor in V3Begin,
|
||||
// because V3Assert is called before V3Begin
|
||||
AstBegin* lastp = m_beginp;
|
||||
{
|
||||
m_beginp = nodep;
|
||||
nodep->iterateChildren(*this);
|
||||
}
|
||||
m_beginp = lastp;
|
||||
}
|
||||
|
||||
// VISITORS //========== Temporal Layer
|
||||
|
||||
@@ -268,6 +285,7 @@ private:
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
AssertVisitor(AstNetlist* nodep) {
|
||||
m_beginp = NULL;
|
||||
m_modp = NULL;
|
||||
// Process
|
||||
AstNode::userClearTree(); // userp() used on entire tree
|
||||
|
||||
+36
-10
@@ -56,10 +56,17 @@ private:
|
||||
// Return NULL for always
|
||||
AstSenTree* newp = NULL;
|
||||
AstSenItem* senip = m_senip ? m_senip : m_seniDefaultp;
|
||||
if (senip) newp = new AstSenTree(nodep->fileline(), senip->cloneTree(true));
|
||||
if (!senip) nodep->v3error("Unsupported: Unclocked assertion");
|
||||
if (!senip) {
|
||||
nodep->v3error("Unsupported: Unclocked assertion");
|
||||
newp = new AstSenTree(nodep->fileline(), NULL);
|
||||
} else {
|
||||
newp = new AstSenTree(nodep->fileline(), senip->cloneTree(true));
|
||||
}
|
||||
return newp;
|
||||
}
|
||||
void clearAssertInfo() {
|
||||
m_senip = NULL;
|
||||
}
|
||||
|
||||
// VISITORS //========== Statements
|
||||
virtual void visit(AstPslDefClock* nodep, AstNUser*) {
|
||||
@@ -70,28 +77,47 @@ private:
|
||||
nodep->unlinkFrBack();
|
||||
pushDeletep(nodep); nodep=NULL;
|
||||
}
|
||||
virtual void visit(AstClocking* nodep, AstNUser*) {
|
||||
UINFO(8," CLOCKING"<<nodep<<endl);
|
||||
// Store the new default clock, reset on new module
|
||||
m_seniDefaultp = nodep->sensesp();
|
||||
// Trash it, keeping children
|
||||
if (nodep->bodysp()) {
|
||||
nodep->replaceWith(nodep->bodysp()->unlinkFrBack());
|
||||
} else {
|
||||
nodep->unlinkFrBack();
|
||||
}
|
||||
pushDeletep(nodep); nodep=NULL;
|
||||
}
|
||||
|
||||
virtual void visit(AstPslCover* nodep, AstNUser*) {
|
||||
// Prep
|
||||
m_senip = NULL;
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
clearAssertInfo();
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->sentreep(newSenTree(nodep));
|
||||
m_senip = NULL;
|
||||
clearAssertInfo();
|
||||
}
|
||||
virtual void visit(AstPslAssert* nodep, AstNUser*) {
|
||||
// Prep
|
||||
m_senip = NULL;
|
||||
if (nodep->sentreep()) return; // Already processed
|
||||
clearAssertInfo();
|
||||
nodep->iterateChildren(*this);
|
||||
nodep->sentreep(newSenTree(nodep));
|
||||
m_senip = NULL;
|
||||
clearAssertInfo();
|
||||
}
|
||||
virtual void visit(AstPslClocked* nodep, AstNUser*) {
|
||||
nodep->iterateChildren(*this);
|
||||
if (m_senip) {
|
||||
nodep->v3error("Unsupported: Only one PSL clock allowed per assertion\n");
|
||||
}
|
||||
// Unlink and just keep a pointer to it, convert to sentree as needed
|
||||
// Block is the new expression to evaluate
|
||||
AstNode* blockp = nodep->propp()->unlinkFrBack();
|
||||
if (nodep->disablep()) {
|
||||
blockp = new AstAnd(nodep->disablep()->fileline(),
|
||||
new AstNot(nodep->disablep()->fileline(),
|
||||
nodep->disablep()->unlinkFrBack()),
|
||||
blockp);
|
||||
}
|
||||
// Unlink and just keep a pointer to it, convert to sentree as needed
|
||||
m_senip = nodep->sensesp();
|
||||
nodep->replaceWith(blockp);
|
||||
pushDeletep(nodep); nodep=NULL;
|
||||
@@ -108,8 +134,8 @@ private:
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
AssertPreVisitor(AstNetlist* nodep) {
|
||||
m_senip = NULL;
|
||||
m_seniDefaultp = NULL;
|
||||
clearAssertInfo();
|
||||
// Process
|
||||
nodep->accept(*this);
|
||||
}
|
||||
|
||||
+59
-18
@@ -85,17 +85,40 @@ void AstNode::init() {
|
||||
string AstNode::encodeName(const string& namein) {
|
||||
string name2 = namein;
|
||||
string out;
|
||||
for (string::iterator pos = name2.begin(); pos != name2.end(); pos++) {
|
||||
if (pos[0]=='_' && pos[1]=='_') {
|
||||
out += "__ULUL_";
|
||||
pos++;
|
||||
} else {
|
||||
const char* start = name2.c_str();
|
||||
for (const char* pos = start; *pos; pos++) {
|
||||
if ((pos==start) ? isalpha(pos[0]) // digits can't lead identifiers
|
||||
: isalnum(pos[0])) {
|
||||
out += pos[0];
|
||||
} else if (pos[0]=='_') {
|
||||
if (pos[1]=='_') {
|
||||
out += "_"; out += "__5F"; // hex(_) = 0x5F
|
||||
pos++;
|
||||
} else {
|
||||
out += pos[0];
|
||||
}
|
||||
} else if (pos[0]=='.') {
|
||||
out += "__DOT__";
|
||||
} else if (pos[0]=='[') {
|
||||
out += "__BRA__";
|
||||
} else if (pos[0]==']') {
|
||||
out += "__KET__";
|
||||
} else {
|
||||
char hex[10]; sprintf(hex,"%02X",pos[0]);
|
||||
out += "__"; out += hex;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
string AstNode::encodeNumber(vlsint64_t num) {
|
||||
if (num < 0) {
|
||||
return "__2D"+cvtToStr(-num); // 2D=-
|
||||
} else {
|
||||
return cvtToStr(num);
|
||||
}
|
||||
}
|
||||
|
||||
string AstNode::shortName() const {
|
||||
string pretty = name();
|
||||
string::size_type pos;
|
||||
@@ -116,19 +139,37 @@ string AstNode::dedotName(const string& namein) {
|
||||
}
|
||||
|
||||
string AstNode::prettyName(const string& namein) {
|
||||
string pretty = namein;
|
||||
string::size_type pos;
|
||||
while ((pos=pretty.find("__BRA__")) != string::npos) {
|
||||
pretty.replace(pos, 7, "[");
|
||||
}
|
||||
while ((pos=pretty.find("__KET__")) != string::npos) {
|
||||
pretty.replace(pos, 7, "]");
|
||||
}
|
||||
while ((pos=pretty.find("__PVT__")) != string::npos) {
|
||||
pretty.replace(pos, 7, "");
|
||||
}
|
||||
while ((pos=pretty.find("__ULUL_")) != string::npos) {
|
||||
pretty.replace(pos, 7, "");
|
||||
string pretty;
|
||||
string name2 = namein;
|
||||
pretty = "";
|
||||
for (const char* pos = name2.c_str(); *pos; ) {
|
||||
if (0==strncmp(pos,"__BRA__",7)) {
|
||||
pretty += "[";
|
||||
pos += 7;
|
||||
}
|
||||
else if (0==strncmp(pos,"__KET__",7)) {
|
||||
pretty += "]";
|
||||
pos += 7;
|
||||
}
|
||||
else if (0==strncmp(pos,"__DOT__",7)) {
|
||||
pretty += ".";
|
||||
pos += 7;
|
||||
}
|
||||
else if (0==strncmp(pos,"__PVT__",7)) {
|
||||
pretty += "";
|
||||
pos += 7;
|
||||
}
|
||||
else if (pos[0]=='_' && pos[1]=='_' && isxdigit(pos[2]) && isxdigit(pos[3])) {
|
||||
char value = 0;
|
||||
value += 16*(isdigit(pos[2]) ? (pos[2]-'0') : (tolower(pos[2])-'a'+10));
|
||||
value += (isdigit(pos[3]) ? (pos[3]-'0') : (tolower(pos[3])-'a'+10));
|
||||
pretty += value;
|
||||
pos += 4;
|
||||
}
|
||||
else {
|
||||
pretty += pos[0];
|
||||
pos++;
|
||||
}
|
||||
}
|
||||
return AstNode::dedotName(pretty);
|
||||
}
|
||||
|
||||
@@ -579,6 +579,7 @@ public:
|
||||
static string dedotName(const string& namein); // Name with dots removed
|
||||
static string prettyName(const string& namein); // Name for printing out to the user
|
||||
static string encodeName(const string& namein); // Encode user name into internal C representation
|
||||
static string encodeNumber(vlsint64_t numin); // Encode number into internal C representation
|
||||
string prettyName() const { return prettyName(name()); }
|
||||
FileLine* fileline() const { return m_fileline; }
|
||||
int width() const { return m_width; }
|
||||
|
||||
+6
-2
@@ -43,11 +43,11 @@ void AstNodeVarRef::cloneRelink() {
|
||||
}
|
||||
|
||||
int AstNodeSel::bitConst() const {
|
||||
AstConst* constp=bitp()->castConst(); return (constp?constp->asInt():0);
|
||||
AstConst* constp=bitp()->castConst(); return (constp?constp->toSInt():0);
|
||||
}
|
||||
|
||||
bool AstVar::isSigPublic() const {
|
||||
return (m_sigPublic || (v3Global.opt.allPublic() && !isTemp()));
|
||||
return (m_sigPublic || (v3Global.opt.allPublic() && !isTemp() && !isGenVar()));
|
||||
}
|
||||
|
||||
bool AstVar::isScQuad() const {
|
||||
@@ -417,3 +417,7 @@ void AstCCall::dump(ostream& str) {
|
||||
funcp()->dump(str);
|
||||
}
|
||||
}
|
||||
void AstCFunc::dump(ostream& str) {
|
||||
this->AstNode::dump(str);
|
||||
if (slow()) str<<" [SLOW]";
|
||||
}
|
||||
|
||||
+49
-20
@@ -50,12 +50,13 @@ public:
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual string name() const { return num().ascii(); } // * = Value
|
||||
virtual const V3Number& num() const { return m_num; } // * = Value
|
||||
uint32_t asInt() const { return num().asInt(); }
|
||||
vluint64_t asQuad() const { return num().asQuad(); }
|
||||
uint32_t toUInt() const { return num().toUInt(); }
|
||||
vlsint32_t toSInt() const { return num().toSInt(); }
|
||||
vluint64_t toUQuad() const { return num().toUQuad(); }
|
||||
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
virtual bool cleanOut() { return true; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(num().asHash()); }
|
||||
virtual V3Hash sameHash() const { return V3Hash(num().toHash()); }
|
||||
virtual bool same(AstNode* samep) const {
|
||||
return num().isCaseEq(samep->castConst()->num()); }
|
||||
virtual int instrCount() const { return widthInstrs(); }
|
||||
@@ -78,8 +79,8 @@ struct AstRange : public AstNode {
|
||||
AstRange* cloneTree(bool cloneNextLink) { return AstNode::cloneTree(cloneNextLink)->castRange(); }
|
||||
AstNode* msbp() const { return op2p()->castNode(); } // op2 = Msb expression
|
||||
AstNode* lsbp() const { return op3p()->castNode(); } // op3 = Lsb expression
|
||||
int msbConst() const { AstConst* constp=msbp()->castConst(); return (constp?constp->asInt():0); }
|
||||
int lsbConst() const { AstConst* constp=lsbp()->castConst(); return (constp?constp->asInt():0); }
|
||||
int msbConst() const { AstConst* constp=msbp()->castConst(); return (constp?constp->toSInt():0); }
|
||||
int lsbConst() const { AstConst* constp=lsbp()->castConst(); return (constp?constp->toSInt():0); }
|
||||
int elementsConst() const { return msbConst()-lsbConst()+1; }
|
||||
virtual string emitC() { V3ERROR_NA; return ""; }
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
@@ -192,7 +193,7 @@ struct AstSel : public AstNodeTriop {
|
||||
// Children: varref|arraysel, math, constant math
|
||||
AstSel(FileLine* fl, AstNode* fromp, AstNode* lsbp, AstNode* widthp)
|
||||
:AstNodeTriop(fl, fromp, lsbp, widthp) {
|
||||
if (widthp->castConst()) width(widthp->castConst()->asInt(), widthp->castConst()->asInt());
|
||||
if (widthp->castConst()) width(widthp->castConst()->toUInt(), widthp->castConst()->toUInt());
|
||||
}
|
||||
AstSel(FileLine* fl, AstNode* fromp, int lsbp, int bitwidth)
|
||||
:AstNodeTriop(fl, fromp,
|
||||
@@ -204,7 +205,7 @@ struct AstSel : public AstNodeTriop {
|
||||
virtual AstNode* clone() { return new AstSel(*this); }
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
virtual void numberOperate(V3Number& out, const V3Number& from, const V3Number& bit, const V3Number& width) {
|
||||
out.opRange(from, bit.asInt()+width.asInt()-1, bit.asInt()); }
|
||||
out.opRange(from, bit.toUInt()+width.toUInt()-1, bit.toUInt()); }
|
||||
virtual string emitVerilog() { V3ERROR_NA; return ""; } // Implemented specially
|
||||
virtual string emitC() {
|
||||
return this->widthp()->isOne()
|
||||
@@ -221,9 +222,9 @@ struct AstSel : public AstNodeTriop {
|
||||
AstNode* fromp() const { return op1p()->castNode(); } // op1 = Extracting what (NULL=TBD during parsing)
|
||||
AstNode* lsbp() const { return op2p()->castNode(); } // op2 = Msb selection expression
|
||||
AstNode* widthp() const { return op3p()->castNode(); } // op3 = Width
|
||||
uint32_t lsbConst() const { return lsbp()->castConst()->asInt(); }
|
||||
uint32_t widthConst() const { return widthp()->castConst()->asInt(); }
|
||||
uint32_t msbConst() const { return lsbConst()+widthConst()-1; }
|
||||
int widthConst() const { return widthp()->castConst()->toSInt(); }
|
||||
int lsbConst() const { return lsbp()->castConst()->toSInt(); }
|
||||
int msbConst() const { return lsbConst()+widthConst()-1; }
|
||||
};
|
||||
|
||||
struct AstVar : public AstNode {
|
||||
@@ -362,8 +363,9 @@ public:
|
||||
bool attrIsolateAssign() const { return m_attrIsolateAssign; }
|
||||
int widthAlignBytes() const; // Structure alignment 1,2,4 or 8 bytes (arrays affect this)
|
||||
int widthTotalBytes() const; // Width in bytes rounding up 1,2,4,8,12,...
|
||||
uint32_t msb() const { if (!rangep()) return 0; return rangep()->msbConst(); }
|
||||
uint32_t lsb() const { if (!rangep()) return 0; return rangep()->lsbConst(); }
|
||||
int msb() const { if (!rangep()) return 0; return rangep()->msbConst(); }
|
||||
int lsb() const { if (!rangep()) return 0; return rangep()->lsbConst(); }
|
||||
int msbMaxSelect() const { return (lsb()<0 ? msb()-lsb() : msb()); } // Maximum value a [] select may index
|
||||
uint32_t arrayElements() const; // 1, or total multiplication of all dimensions
|
||||
virtual string verilogKwd() const;
|
||||
void propagateAttrFrom(AstVar* fromp) {
|
||||
@@ -1693,8 +1695,8 @@ struct AstTraceDecl : public AstNodeStmt {
|
||||
private:
|
||||
string m_showname; // Name of variable
|
||||
uint32_t m_code; // Trace identifier code; converted to ASCII by trace routines
|
||||
uint32_t m_lsb; // Property of var the trace details
|
||||
uint32_t m_msb; // Property of var the trace details
|
||||
int m_lsb; // Property of var the trace details
|
||||
int m_msb; // Property of var the trace details
|
||||
uint32_t m_arrayLsb; // Property of var the trace details
|
||||
uint32_t m_arrayMsb; // Property of var the trace details
|
||||
uint32_t m_codeInc; // Code increment
|
||||
@@ -1722,8 +1724,8 @@ public:
|
||||
uint32_t code() const { return m_code; }
|
||||
void code(uint32_t code) { m_code=code; }
|
||||
uint32_t codeInc() const { return m_codeInc; }
|
||||
uint32_t msb() const { return m_msb; }
|
||||
uint32_t lsb() const { return m_lsb; }
|
||||
int msb() const { return m_msb; }
|
||||
int lsb() const { return m_lsb; }
|
||||
uint32_t arrayMsb() const { return m_arrayMsb; }
|
||||
uint32_t arrayLsb() const { return m_arrayLsb; }
|
||||
uint32_t arrayWidth() const { if (!arrayMsb()) return 0; return arrayMsb()-arrayLsb()+1; }
|
||||
@@ -2830,6 +2832,27 @@ struct AstVAssert : public AstNodeStmt {
|
||||
AstNode* failsp() const { return op3p(); } // op3 = if fails
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
// Assertions
|
||||
|
||||
struct AstClocking : public AstNode {
|
||||
// Set default clock region
|
||||
// Parents: MODULE
|
||||
// Children: Assertions
|
||||
public:
|
||||
AstClocking(FileLine* fl, AstSenItem* sensesp, AstNode* bodysp)
|
||||
: AstNode(fl) {
|
||||
addOp1p(sensesp);
|
||||
addNOp2p(bodysp);
|
||||
}
|
||||
virtual ~AstClocking() {}
|
||||
virtual AstType type() const { return AstType::CLOCKING;}
|
||||
virtual AstNode* clone() { return new AstClocking(*this); }
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
AstSenItem* sensesp() const { return op1p()->castSenItem(); } // op1 = Sensitivity list
|
||||
AstNode* bodysp() const { return op2p(); } // op2 = Body
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
// PSL
|
||||
|
||||
@@ -2854,17 +2877,19 @@ struct AstPslClocked : public AstNode {
|
||||
// Parents: ASSERT|COVER (property)
|
||||
// Children: SENITEM, Properties
|
||||
public:
|
||||
AstPslClocked(FileLine* fl, AstSenItem* sensesp, AstNode* propp)
|
||||
AstPslClocked(FileLine* fl, AstSenItem* sensesp, AstNode* disablep, AstNode* propp)
|
||||
: AstNode(fl) {
|
||||
addNOp1p(sensesp);
|
||||
addOp2p(propp);
|
||||
addNOp2p(disablep);
|
||||
addOp3p(propp);
|
||||
}
|
||||
virtual ~AstPslClocked() {}
|
||||
virtual AstType type() const { return AstType::PSLCLOCKED;}
|
||||
virtual AstNode* clone() { return new AstPslClocked(*this); }
|
||||
virtual void accept(AstNVisitor& v, AstNUser* vup=NULL) { v.visit(this,vup); }
|
||||
AstSenItem* sensesp() const { return op1p()->castSenItem(); } // op1 = Sensitivity list
|
||||
AstNode* propp() const { return op2p(); } // op2 = property
|
||||
AstNode* disablep() const { return op2p(); } // op2 = disable
|
||||
AstNode* propp() const { return op3p(); } // op3 = property
|
||||
};
|
||||
|
||||
struct AstPslAssert : public AstNodeStmt {
|
||||
@@ -2898,10 +2923,11 @@ struct AstPslCover : public AstNodeStmt {
|
||||
private:
|
||||
string m_name; // Name to report
|
||||
public:
|
||||
AstPslCover(FileLine* fl, AstNode* propp, const string& name="")
|
||||
AstPslCover(FileLine* fl, AstNode* propp, AstNode* stmtsp, const string& name="")
|
||||
: AstNodeStmt(fl)
|
||||
, m_name(name) {
|
||||
addOp1p(propp);
|
||||
addNOp4p(stmtsp);
|
||||
}
|
||||
virtual ~AstPslCover() {}
|
||||
virtual AstType type() const { return AstType::PSLCOVER;}
|
||||
@@ -2910,11 +2936,13 @@ public:
|
||||
virtual string name() const { return m_name; } // * = Var name
|
||||
virtual V3Hash sameHash() const { return V3Hash(name()); }
|
||||
virtual bool same(AstNode* samep) const { return samep->name() == name(); }
|
||||
void name(const string& flag) { m_name = flag; }
|
||||
AstNode* propp() const { return op1p(); } // op1 = property
|
||||
AstSenTree* sentreep() const { return op2p()->castSenTree(); } // op2 = clock domain
|
||||
void sentreep(AstSenTree* sentreep) { addOp2p(sentreep); } // op2 = clock domain
|
||||
AstNode* coverincp() const { return op3p(); } // op3 = coverage node
|
||||
void coverincp(AstCoverInc* nodep) { addOp3p(nodep); } // op3 = coverage node
|
||||
AstNode* stmtsp() const { return op4p(); } // op4 = statements
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
@@ -3117,6 +3145,7 @@ public:
|
||||
virtual string name() const { return m_name; }
|
||||
virtual bool broken() const { return ( (m_scopep && !m_scopep->brokeExists())); }
|
||||
virtual bool maybePointedTo() const { return true; }
|
||||
virtual void dump(ostream& str=cout);
|
||||
virtual V3Hash sameHash() const { return V3Hash(); }
|
||||
virtual bool same(AstNode* samep) const { return ((funcType()==samep->castCFunc()->funcType())
|
||||
&& (rtnTypeVoid()==samep->castCFunc()->rtnTypeVoid())
|
||||
|
||||
+2
-2
@@ -164,10 +164,10 @@ private:
|
||||
} else {
|
||||
V3Number nummask (itemp->fileline(), iconstp->width());
|
||||
nummask.opBitsNonX(iconstp->num());
|
||||
uint32_t mask = nummask.asInt();
|
||||
uint32_t mask = nummask.toUInt();
|
||||
V3Number numval (itemp->fileline(), iconstp->width());
|
||||
numval.opBitsOne(iconstp->num());
|
||||
uint32_t val = numval.asInt();
|
||||
uint32_t val = numval.toUInt();
|
||||
for (uint32_t i=0; i<(1UL<<m_caseWidth); i++) {
|
||||
if ((i & mask) == val) {
|
||||
if (!m_valueItem[i]) {
|
||||
|
||||
@@ -63,6 +63,7 @@ private:
|
||||
vscp->v3fatalSrc("Not applicable\n");
|
||||
#endif
|
||||
AstVar* varp = vscp->varp();
|
||||
vscp->v3warn(IMPERFECTSCH,"Imperfect scheduling of variable: "<<vscp);
|
||||
if (varp->arraysp()) {
|
||||
vscp->v3error("Unsupported: Can't detect changes on arrayed variable (probably with UNOPTFLAT warning suppressed): "<<varp->prettyName());
|
||||
} else {
|
||||
|
||||
+21
-18
@@ -134,16 +134,16 @@ private:
|
||||
}
|
||||
bool operandHugeShiftL(AstNodeBiop* nodep) {
|
||||
return (nodep->rhsp()->castConst()
|
||||
&& nodep->rhsp()->castConst()->asInt() >= (uint32_t)(nodep->width()));
|
||||
&& nodep->rhsp()->castConst()->toUInt() >= (uint32_t)(nodep->width()));
|
||||
}
|
||||
bool operandHugeShiftR(AstNodeBiop* nodep) {
|
||||
return (nodep->rhsp()->castConst()
|
||||
&& nodep->rhsp()->castConst()->asInt() >= (uint32_t)(nodep->lhsp()->width()));
|
||||
&& nodep->rhsp()->castConst()->toUInt() >= (uint32_t)(nodep->lhsp()->width()));
|
||||
}
|
||||
bool operandIsTwo(AstNode* nodep) {
|
||||
return (nodep->castConst()
|
||||
&& nodep->width() <= VL_QUADSIZE
|
||||
&& nodep->castConst()->asQuad()==2);
|
||||
&& nodep->castConst()->toUQuad()==2);
|
||||
}
|
||||
bool operandIsTwostate(AstNode* nodep) {
|
||||
return (nodep->castConst()
|
||||
@@ -180,7 +180,7 @@ private:
|
||||
return (nodep->rhsp()->castConst()
|
||||
&& nodep->fromp()->castNodeVarRef()
|
||||
&& !nodep->fromp()->castNodeVarRef()->lvalue()
|
||||
&& ((int)(nodep->rhsp()->castConst()->asInt())
|
||||
&& ((int)(nodep->rhsp()->castConst()->toUInt())
|
||||
>= nodep->fromp()->castNodeVarRef()->varp()->widthWords()));
|
||||
}
|
||||
bool operandSelFull(AstSel* nodep) {
|
||||
@@ -215,15 +215,18 @@ private:
|
||||
bool warnSelect(AstSel* nodep) {
|
||||
AstNode* basefromp = AstArraySel::baseFromp(nodep->fromp());
|
||||
if (AstNodeVarRef* varrefp = basefromp->castNodeVarRef()) {
|
||||
AstVar* varp = varrefp->varp();
|
||||
if (m_warn
|
||||
&& nodep->lsbp()->castConst()
|
||||
&& nodep->widthp()->castConst()
|
||||
&& (!varrefp->varp()->rangep() || varrefp->varp()->msb()) // else it's non-resolvable parameterized
|
||||
&& ( ( (nodep->msbConst() > varrefp->varp()->msb())
|
||||
|| (nodep->lsbConst() > varrefp->varp()->msb())))) {
|
||||
&& (!varp->rangep() || varp->msb()) // else it's non-resolvable parameterized
|
||||
&& ( ( (nodep->msbConst() > varp->msbMaxSelect())
|
||||
|| (nodep->lsbConst() > varp->msbMaxSelect())))) {
|
||||
nodep->v3error("Selection index out of range: "
|
||||
<<nodep->msbConst()<<":"<<nodep->lsbConst()
|
||||
<<" outside "<<varrefp->varp()->msb()<<":0");
|
||||
<<" outside "<<varp->msbMaxSelect()<<":0"
|
||||
<<(varp->lsb()>=0 ? ""
|
||||
:" (adjusted +"+cvtToStr(-varp->lsb())+" to account for negative lsb)"));
|
||||
}
|
||||
}
|
||||
return false; // Not a transform, so NOP
|
||||
@@ -432,8 +435,8 @@ private:
|
||||
nodep->accept(*this); // Further reduce, either node may have more reductions.
|
||||
} else {
|
||||
// We know shift amounts are constant, but might be a mixed left/right shift
|
||||
int shift1 = shift1p->castConst()->asInt(); if (lhsp->castShiftR()) shift1=-shift1;
|
||||
int shift2 = shift2p->castConst()->asInt(); if (nodep->castShiftR()) shift2=-shift2;
|
||||
int shift1 = shift1p->castConst()->toUInt(); if (lhsp->castShiftR()) shift1=-shift1;
|
||||
int shift2 = shift2p->castConst()->toUInt(); if (nodep->castShiftR()) shift2=-shift2;
|
||||
int newshift = shift1+shift2;
|
||||
shift1p->deleteTree(); shift1p=NULL;
|
||||
shift2p->deleteTree(); shift1p=NULL;
|
||||
@@ -490,11 +493,11 @@ private:
|
||||
if (!varNotReferenced(nodep->rhsp(), varref1p->varp())) return false;
|
||||
if (!varNotReferenced(nextp->rhsp(), varref2p->varp())) return false;
|
||||
// Swap?
|
||||
if (( con1p->asInt() != con2p->asInt() + sel2p->width())
|
||||
&&(con2p->asInt() != con1p->asInt() + sel1p->width())) return false;
|
||||
bool lsbFirstAssign = (con1p->asInt() < con2p->asInt());
|
||||
if (( con1p->toSInt() != con2p->toSInt() + sel2p->width())
|
||||
&&(con2p->toSInt() != con1p->toSInt() + sel1p->width())) return false;
|
||||
bool lsbFirstAssign = (con1p->toUInt() < con2p->toUInt());
|
||||
// If the user already has nice 32-bit divisions, keep them to aid later subdivision
|
||||
//if (VL_BITBIT_I(con1p->asInt()) == 0) return false;
|
||||
//if (VL_BITBIT_I(con1p->toUInt()) == 0) return false;
|
||||
UINFO(4,"replaceAssignMultiSel "<<nodep<<endl);
|
||||
UINFO(4," && "<<nextp<<endl);
|
||||
//nodep->dumpTree(cout, "comb1: ");
|
||||
@@ -517,7 +520,7 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool varNotReferenced(AstNode* nodep, AstVar* varp, bool level=0) {
|
||||
bool varNotReferenced(AstNode* nodep, AstVar* varp, int level=0) {
|
||||
// Return true if varp never referenced under node.
|
||||
// Return false if referenced, or tree too deep to be worth it
|
||||
if (!nodep) return true;
|
||||
@@ -648,7 +651,7 @@ private:
|
||||
if (!nodep->castAnd()->rhsp()->castShiftR()) return false;
|
||||
AstShiftR* shiftp = nodep->castAnd()->rhsp()->castShiftR();
|
||||
if (!shiftp->rhsp()->castConst()) return false;
|
||||
if ((uint32_t)(nodep->width()) <= shiftp->rhsp()->castConst()->asInt()) return false;
|
||||
if ((uint32_t)(nodep->width()) <= shiftp->rhsp()->castConst()->toUInt()) return false;
|
||||
return true;
|
||||
}
|
||||
void replaceBoolShift(AstNode* nodep) {
|
||||
@@ -784,7 +787,7 @@ private:
|
||||
AstNode* newlsbp;
|
||||
if (lsb1p->castConst() && lsb2p->castConst()) {
|
||||
newlsbp = new AstConst(lsb1p->fileline(),
|
||||
lsb1p->castConst()->asInt() + lsb2p->castConst()->asInt());
|
||||
lsb1p->castConst()->toUInt() + lsb2p->castConst()->toUInt());
|
||||
lsb1p->deleteTree(); lsb1p=NULL;
|
||||
lsb2p->deleteTree(); lsb2p=NULL;
|
||||
} else {
|
||||
@@ -851,7 +854,7 @@ private:
|
||||
AstNode* widthp = nodep->widthp()->unlinkFrBack();
|
||||
AstSel* newp = new AstSel(nodep->fileline(),
|
||||
fromp,
|
||||
new AstConst(lsbp->fileline(), lsbp->asInt() % fromp->width()),
|
||||
new AstConst(lsbp->fileline(), lsbp->toUInt() % fromp->width()),
|
||||
widthp);
|
||||
newp->widthSignedFrom(nodep);
|
||||
nodep->replaceWith(newp); nodep->deleteTree(); nodep=NULL;
|
||||
|
||||
+5
-5
@@ -440,7 +440,7 @@ public:
|
||||
}
|
||||
virtual void visit(AstReplicate* nodep, AstNUser*) {
|
||||
if (nodep->lhsp()->widthMin() == 1 && !nodep->isWide()) {
|
||||
if (((int)nodep->rhsp()->castConst()->asInt()
|
||||
if (((int)nodep->rhsp()->castConst()->toUInt()
|
||||
* nodep->lhsp()->widthMin()) != nodep->widthMin())
|
||||
nodep->v3fatalSrc("Replicate non-constant or width miscomputed");
|
||||
puts("VL_REPLICATE_");
|
||||
@@ -484,11 +484,11 @@ public:
|
||||
}
|
||||
ofp()->printf(",0x%08x)", nodep->num().dataWord(0));
|
||||
} else if (nodep->isQuad()) {
|
||||
vluint64_t num = nodep->asQuad();
|
||||
vluint64_t num = nodep->toUQuad();
|
||||
if (num<10) ofp()->printf("VL_ULL(%lld)", (long long)num);
|
||||
else ofp()->printf("VL_ULL(0x%llx)", (long long)num);
|
||||
} else {
|
||||
uint32_t num = nodep->asInt();
|
||||
uint32_t num = nodep->toUInt();
|
||||
if (num<10) puts(cvtToStr(num));
|
||||
else ofp()->printf("0x%x", num);
|
||||
//Unneeded-Causes %lx format warnings:
|
||||
@@ -1051,7 +1051,7 @@ void EmitCStmts::displayArg(AstNode* dispp, AstNode** elistp, bool isScan,
|
||||
|
||||
//string pfmt = "%"+displayFormat(argp, vfmt, fmtLetter)+fmtLetter;
|
||||
string pfmt;
|
||||
if ((fmtLetter=='u' || fmtLetter=='d')
|
||||
if ((fmtLetter=='u' || fmtLetter=='d' || fmtLetter=='t')
|
||||
&& !isScan
|
||||
&& vfmt == "") { // Size decimal output. Spec says leading spaces, not zeros
|
||||
double mantissabits = argp->widthMin() - ((fmtLetter=='d')?1:0);
|
||||
@@ -1105,7 +1105,7 @@ void EmitCStmts::displayNode(AstNode* nodep, const string& vformat, AstNode* exp
|
||||
// Spec: h d o b c l
|
||||
case 'b': displayArg(nodep,&elistp,isScan, vfmt,'b'); break;
|
||||
case 'c': displayArg(nodep,&elistp,isScan, vfmt,'c'); break;
|
||||
case 't':
|
||||
case 't': displayArg(nodep,&elistp,isScan, vfmt,'t'); break;
|
||||
case 'd': displayArg(nodep,&elistp,isScan, vfmt,'u'); break; // Unsigned decimal
|
||||
case 'o': displayArg(nodep,&elistp,isScan, vfmt,'o'); break;
|
||||
case 'h':
|
||||
|
||||
@@ -46,6 +46,7 @@ public:
|
||||
of.putsHeader();
|
||||
of.puts("\n");
|
||||
|
||||
of.puts("VM_COVERAGE = "); of.puts(v3Global.opt.coverage()?"1":"0"); of.puts("\n");
|
||||
of.puts("VM_TRACE = "); of.puts(v3Global.opt.trace()?"1":"0"); of.puts("\n");
|
||||
of.puts("\n");
|
||||
|
||||
|
||||
+3
-3
@@ -362,11 +362,11 @@ public:
|
||||
if (nodep->widthp()->isOne()) {
|
||||
nodep->lsbp()->iterateAndNext(*this);
|
||||
} else {
|
||||
puts(cvtToStr(nodep->lsbp()->castConst()->asInt()
|
||||
+nodep->widthp()->castConst()->asInt()
|
||||
puts(cvtToStr(nodep->lsbp()->castConst()->toSInt()
|
||||
+nodep->widthp()->castConst()->toSInt()
|
||||
-1));
|
||||
puts(":");
|
||||
nodep->lsbp()->iterateAndNext(*this);
|
||||
puts(cvtToStr(nodep->lsbp()->castConst()->toSInt()));
|
||||
}
|
||||
} else {
|
||||
nodep->lsbp()->iterateAndNext(*this); puts("+:");
|
||||
|
||||
+25
-2
@@ -65,6 +65,17 @@ V3ErrorCode::V3ErrorCode(const char* msgp) {
|
||||
//######################################################################
|
||||
// FileLine class functions
|
||||
|
||||
FileLine::FileLine(FileLine::EmptySecret) {
|
||||
m_lineno=0;
|
||||
m_filename="COMMAND_LINE";
|
||||
|
||||
m_warnOff=0;
|
||||
for (int codei=V3ErrorCode::FIRST_WARN; codei<V3ErrorCode::MAX; codei++) {
|
||||
V3ErrorCode code = (V3ErrorCode)codei;
|
||||
if (code.defaultsOff()) warnOff(code, true);
|
||||
}
|
||||
}
|
||||
|
||||
void FileLine::lineDirective(const char* textp) {
|
||||
// Handle `line directive
|
||||
// Skip `line
|
||||
@@ -153,13 +164,23 @@ ostream& operator<<(ostream& os, FileLine* fileline) {
|
||||
return(os);
|
||||
}
|
||||
|
||||
bool FileLine::warnIsOff(V3ErrorCode code) {
|
||||
bool FileLine::warnIsOff(V3ErrorCode code) const {
|
||||
if (m_warnOff.test(code)) return true;
|
||||
// UNOPTFLAT implies UNOPT
|
||||
if (code==V3ErrorCode::UNOPT && m_warnOff.test(V3ErrorCode::UNOPTFLAT)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void FileLine::warnStateInherit(const FileLine& from) {
|
||||
// Any warnings that are off in "from", become off in "this".
|
||||
for (int codei=V3ErrorCode::FIRST_WARN; codei<V3ErrorCode::MAX; codei++) {
|
||||
V3ErrorCode code = (V3ErrorCode)codei;
|
||||
if (from.warnIsOff(code)) {
|
||||
this->warnOff(code, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FileLine::v3errorEnd(ostringstream& str) {
|
||||
if (this && m_lineno) {
|
||||
ostringstream nsstr;
|
||||
@@ -308,7 +329,9 @@ void V3Error::v3errorEnd (ostringstream& sstr) {
|
||||
#ifdef __COVERITY__
|
||||
if (s_errorCode==V3ErrorCode::FATAL) __coverity_panic__(x);
|
||||
#endif
|
||||
if (s_errorCode!=V3ErrorCode::SUPPRESS || debug()) {
|
||||
if (s_errorCode!=V3ErrorCode::SUPPRESS
|
||||
// On debug, show only non default-off warning to prevent pages of warnings
|
||||
|| (debug() && !s_errorCode.defaultsOff())) {
|
||||
cerr<<msgPrefix()<<sstr.str();
|
||||
if (sstr.str()[sstr.str().length()-1] != '\n') {
|
||||
cerr<<endl;
|
||||
|
||||
+7
-3
@@ -52,6 +52,7 @@ public:
|
||||
COMBDLY, // Combinatorial delayed assignment
|
||||
STMTDLY, // Delayed statement
|
||||
GENCLK, // Generated Clock
|
||||
IMPERFECTSCH, // Imperfect schedule (disabled by default)
|
||||
IMPLICIT, // Implicit wire
|
||||
IMPURE, // Impure function not being inlined
|
||||
MULTIDRIVEN, // Driven from multiple blocks
|
||||
@@ -81,7 +82,7 @@ public:
|
||||
" FIRST_WARN",
|
||||
"BLKANDNBLK",
|
||||
"CASEINCOMPLETE", "CASEOVERLAP", "CASEWITHX", "CASEX", "CMPCONST",
|
||||
"COMBDLY", "STMTDLY", "GENCLK", "IMPLICIT", "IMPURE",
|
||||
"COMBDLY", "STMTDLY", "GENCLK", "IMPERFECTSCH", "IMPLICIT", "IMPURE",
|
||||
"MULTIDRIVEN", "REDEFMACRO",
|
||||
"UNDRIVEN", "UNOPT", "UNOPTFLAT", "UNSIGNED", "UNUSED",
|
||||
"VARHIDDEN", "WIDTH", "WIDTHCONCAT",
|
||||
@@ -89,6 +90,8 @@ public:
|
||||
};
|
||||
return names[m_e];
|
||||
};
|
||||
// Warnings that default to off
|
||||
bool defaultsOff() const { return ( m_e==IMPERFECTSCH );};
|
||||
// Warnings that warn about nasty side effects
|
||||
bool dangerous() const { return ( m_e==COMBDLY );};
|
||||
// Warnings we'll present to the user as errors
|
||||
@@ -207,7 +210,7 @@ protected:
|
||||
public:
|
||||
FileLine (const string& filename, int lineno) { m_lineno=lineno; m_filename = filename; m_warnOff=s_defaultFileLine.m_warnOff; }
|
||||
FileLine (FileLine* fromp) { m_lineno=fromp->lineno(); m_filename = fromp->filename(); m_warnOff=fromp->m_warnOff; }
|
||||
FileLine (EmptySecret) { m_lineno=0; m_filename="COMMAND_LINE"; m_warnOff=0; }
|
||||
FileLine (EmptySecret);
|
||||
~FileLine() { }
|
||||
#ifdef VL_LEAK_CHECKS
|
||||
static void* operator new(size_t size);
|
||||
@@ -222,9 +225,10 @@ public:
|
||||
const string profileFuncname() const;
|
||||
void warnOff(V3ErrorCode code, bool flag) { m_warnOff.set(code,flag); } // Turn on/off warning messages on this line.
|
||||
bool warnOff(const string& code, bool flag); // Returns 1 if ok
|
||||
bool warnIsOff(V3ErrorCode code);
|
||||
bool warnIsOff(V3ErrorCode code) const;
|
||||
void warnLintOff(bool flag);
|
||||
void warnStateFrom(const FileLine& from) { m_warnOff=from.m_warnOff; }
|
||||
void warnStateInherit(const FileLine& from);
|
||||
void warnResetDefault() { warnStateFrom(s_defaultFileLine); }
|
||||
|
||||
void v3errorEnd(ostringstream& str);
|
||||
|
||||
+4
-4
@@ -172,7 +172,7 @@ private:
|
||||
// Return equation to get the VL_BITWORD of a constant or non-constant
|
||||
if (lsbp->castConst()) {
|
||||
return new AstConst (lsbp->fileline(),
|
||||
wordAdder + VL_BITWORD_I(lsbp->castConst()->asInt()));
|
||||
wordAdder + VL_BITWORD_I(lsbp->castConst()->toUInt()));
|
||||
} else {
|
||||
AstNode* shiftp = new AstShiftR (lsbp->fileline(),
|
||||
lsbp->cloneTree(true),
|
||||
@@ -203,7 +203,7 @@ private:
|
||||
// Return equation to get the VL_BITBIT of a constant or non-constant
|
||||
if (lsbp->castConst()) {
|
||||
return new AstConst (lsbp->fileline(),
|
||||
VL_BITBIT_I(lsbp->castConst()->asInt()));
|
||||
VL_BITBIT_I(lsbp->castConst()->toUInt()));
|
||||
} else {
|
||||
return new AstAnd (lsbp->fileline(),
|
||||
new AstConst(lsbp->fileline(), VL_WORDSIZE-1),
|
||||
@@ -688,7 +688,7 @@ private:
|
||||
UINFO(8," REPLICATE "<<nodep<<endl);
|
||||
AstConst* constp = nodep->rhsp()->castConst();
|
||||
if (!constp) nodep->v3fatalSrc("Replication value isn't a constant. Checked earlier!");
|
||||
uint32_t times = constp->asInt();
|
||||
uint32_t times = constp->toUInt();
|
||||
if (nodep->isQuad() && !lhsp->isQuad()) lhsp = new AstCast(nodep->fileline(), lhsp, nodep);
|
||||
newp = lhsp->cloneTree(true);
|
||||
for (unsigned repnum=1; repnum<times; repnum++) {
|
||||
@@ -713,7 +713,7 @@ private:
|
||||
int lhswidth = lhsp->widthMin();
|
||||
AstConst* constp = rhsp->rhsp()->castConst();
|
||||
if (!constp) rhsp->v3fatalSrc("Replication value isn't a constant. Checked earlier!");
|
||||
uint32_t times = constp->asInt();
|
||||
uint32_t times = constp->toUInt();
|
||||
for (int w=0; w<rhsp->widthWords(); w++) {
|
||||
AstNode* newp;
|
||||
if (lhswidth==1) {
|
||||
|
||||
@@ -172,6 +172,8 @@ private:
|
||||
m_modp->addStmtp(new AstAssignAlias(nodep->fileline(),
|
||||
new AstVarRef(nodep->fileline(), nodep, true),
|
||||
new AstVarRef(nodep->fileline(), exprvarrefp->varp(), false)));
|
||||
nodep->fileline()->warnStateInherit(exprvarrefp->varp()->fileline());
|
||||
exprvarrefp->varp()->fileline()->warnStateInherit(nodep->fileline());
|
||||
}
|
||||
}
|
||||
// Variable under the inline cell, need to rename to avoid conflicts
|
||||
|
||||
@@ -50,6 +50,7 @@ private:
|
||||
// AstNodeFTask::userp() // V3SymTable* Local Symbol table
|
||||
// AstBegin::userp() // V3SymTable* Local Symbol table
|
||||
// AstVar::userp() // V3SymTable* Table used to create this variable
|
||||
// AstVar::user2p() // bool True if port set for this variable
|
||||
|
||||
// ENUMS
|
||||
enum IdState { // Which loop through the tree
|
||||
@@ -60,6 +61,7 @@ private:
|
||||
// STATE
|
||||
// Below state needs to be preserved between each module call.
|
||||
AstModule* m_modp; // Current module
|
||||
AstNodeFTask* m_ftaskp; // Current function/task
|
||||
IdState m_idState; // Id linking mode (find or resolve)
|
||||
int m_paramNum; // Parameter number, for position based connection
|
||||
V3SymTable* m_curVarsp; // Symbol table of variables and tasks under table we're inserting into
|
||||
@@ -106,6 +108,7 @@ private:
|
||||
// VISITs
|
||||
virtual void visit(AstNetlist* nodep, AstNUser*) {
|
||||
AstNode::userClearTree();
|
||||
AstNode::user2ClearTree();
|
||||
// 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);
|
||||
@@ -164,6 +167,7 @@ private:
|
||||
if ((findvarp->isIO() && nodep->isSignal())
|
||||
|| (findvarp->isSignal() && nodep->isIO())) {
|
||||
findvarp->combineType(nodep);
|
||||
findvarp->fileline()->warnStateInherit(nodep->fileline());
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||
} else {
|
||||
nodep->v3error("Duplicate declaration of signal: "<<nodep->prettyName());
|
||||
@@ -188,6 +192,11 @@ private:
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_idState==ID_RESOLVE) {
|
||||
if (nodep->isIO() && !m_ftaskp && !nodep->user2()) {
|
||||
nodep->v3error("Input/output/inout does not appear in port list: "<<nodep->prettyName());
|
||||
}
|
||||
}
|
||||
}
|
||||
virtual void visit(AstVarRef* nodep, AstNUser*) {
|
||||
// VarRef: Resolve its reference
|
||||
@@ -235,7 +244,9 @@ private:
|
||||
m_curVarsp->insert(newvarp->name(), newvarp);
|
||||
}
|
||||
}
|
||||
m_ftaskp = nodep;
|
||||
nodep->iterateChildren(*this);
|
||||
m_ftaskp = NULL;
|
||||
}
|
||||
m_curVarsp = upperVarsp;
|
||||
if (m_idState==ID_FIND) {
|
||||
@@ -335,6 +346,7 @@ private:
|
||||
nodep->v3error("Pin is not a in/out/inout: "<<nodep->prettyName());
|
||||
} else {
|
||||
m_curVarsp->insert("__pinNumber"+cvtToStr(nodep->pinNum()), refp);
|
||||
refp->user2(true);
|
||||
}
|
||||
// Ports not needed any more
|
||||
nodep->unlinkFrBack()->deleteTree(); nodep=NULL;
|
||||
@@ -421,6 +433,7 @@ public:
|
||||
m_curVarsp = NULL;
|
||||
m_cellVarsp = NULL;
|
||||
m_modp = NULL;
|
||||
m_ftaskp = NULL;
|
||||
m_paramNum = 0;
|
||||
m_beginNum = 0;
|
||||
//
|
||||
|
||||
+2
-1
@@ -160,7 +160,8 @@ private:
|
||||
m_dotText = "";
|
||||
nodep->lhsp()->iterateAndNext(*this);
|
||||
if (AstConst* constp = nodep->rhsp()->castConst()) {
|
||||
m_dotText = m_dotText+"__BRA__"+cvtToStr(constp->asInt())+"__KET__";
|
||||
string index = AstNode::encodeNumber(constp->toSInt());
|
||||
m_dotText = m_dotText+"__BRA__"+index+"__KET__";
|
||||
} else {
|
||||
nodep->v3error("Unsupported: Non-constant inside []'s in the cell part of a dotted reference");
|
||||
}
|
||||
|
||||
@@ -223,7 +223,7 @@ private:
|
||||
AstNode* widthp;
|
||||
if (msbp->castConst() && lsbp->castConst()) {
|
||||
// Quite common, save V3Const some effort
|
||||
V3Number widnum (msbp->fileline(),32,msbp->castConst()->asInt() +1-lsbp->castConst()->asInt());
|
||||
V3Number widnum (msbp->fileline(),32,msbp->castConst()->toSInt() +1-lsbp->castConst()->toSInt());
|
||||
widnum.width(32,false); // Unsized so width from user
|
||||
widthp = new AstConst (msbp->fileline(), widnum);
|
||||
pushDeletep(msbp);
|
||||
|
||||
+32
-24
@@ -45,6 +45,7 @@ void V3Number::init (FileLine* fileline, int swidth) {
|
||||
m_fileline = fileline;
|
||||
m_signed = false;
|
||||
m_autoExtend = false;
|
||||
m_fromString = false;
|
||||
width(swidth);
|
||||
for (int i=0; i<words(); i++) m_value[i]=m_valueX[i] = 0;
|
||||
}
|
||||
@@ -52,6 +53,7 @@ void V3Number::init (FileLine* fileline, int swidth) {
|
||||
V3Number::V3Number(VerilogString, FileLine* fileline, const string& str) {
|
||||
// Create a number using a verilog string as the value, thus 8 bits per character.
|
||||
init(fileline, str.length()*8);
|
||||
m_fromString = true;
|
||||
for (unsigned pos=0; pos<str.length(); ++pos) {
|
||||
int topos = str.length()-1-pos;
|
||||
for (int bit=0; bit<8; ++bit) {
|
||||
@@ -429,7 +431,7 @@ string V3Number::displayed(const string& vformat) const {
|
||||
return str;
|
||||
}
|
||||
case '~': // Signed decimal
|
||||
case 't':
|
||||
case 't': // Time
|
||||
case 'd': { // Unsigned decimal
|
||||
bool issigned = (code == '~');
|
||||
if (fmtsize == "") {
|
||||
@@ -444,9 +446,9 @@ string V3Number::displayed(const string& vformat) const {
|
||||
return "ERR";
|
||||
}
|
||||
if (issigned) {
|
||||
str = cvtToStr(asSQuad());
|
||||
str = cvtToStr(toSQuad());
|
||||
} else {
|
||||
str = cvtToStr(asQuad());
|
||||
str = cvtToStr(toUQuad());
|
||||
}
|
||||
int intfmtsize = atoi(fmtsize.c_str());
|
||||
while ((int)(str.length()) < intfmtsize) str = " "+str;
|
||||
@@ -461,34 +463,40 @@ string V3Number::displayed(const string& vformat) const {
|
||||
//======================================================================
|
||||
// ACCESSORS - as numbers
|
||||
|
||||
uint32_t V3Number::asInt() const {
|
||||
UASSERT(!isFourState(),"asInt with 4-state "<<*this);
|
||||
uint32_t V3Number::toUInt() const {
|
||||
UASSERT(!isFourState(),"toUInt with 4-state "<<*this);
|
||||
UASSERT((width()<33 || (width()<65 && m_value[1]==0)), "Value too wide "<<*this);
|
||||
return m_value[0];
|
||||
}
|
||||
|
||||
vlsint32_t V3Number::asSInt() const {
|
||||
uint32_t v = asInt();
|
||||
uint32_t signExtend = (-(v & (1UL<<(width()-1))));
|
||||
uint32_t extended = v | signExtend;
|
||||
return (vlsint32_t)(extended);
|
||||
vlsint32_t V3Number::toSInt() const {
|
||||
if (isSigned()) {
|
||||
uint32_t v = toUInt();
|
||||
uint32_t signExtend = (-(v & (1UL<<(width()-1))));
|
||||
uint32_t extended = v | signExtend;
|
||||
return (vlsint32_t)(extended);
|
||||
} else {
|
||||
// Where we use this (widths, etc) and care about signedness,
|
||||
// we can reasonably assume the MSB isn't set on unsigned numbers.
|
||||
return (vlsint32_t)toUInt();
|
||||
}
|
||||
}
|
||||
|
||||
vluint64_t V3Number::asQuad() const {
|
||||
UASSERT(!isFourState(),"asQuad with 4-state "<<*this);
|
||||
vluint64_t V3Number::toUQuad() const {
|
||||
UASSERT(!isFourState(),"toUQuad with 4-state "<<*this);
|
||||
UASSERT(width()<65, "Value too wide "<<*this);
|
||||
if (width()<=32) return ((vluint64_t)(asInt()));
|
||||
if (width()<=32) return ((vluint64_t)(toUInt()));
|
||||
return ((vluint64_t)m_value[1]<<VL_ULL(32)) | ((vluint64_t)m_value[0]);
|
||||
}
|
||||
|
||||
vlsint64_t V3Number::asSQuad() const {
|
||||
vluint64_t v = asQuad();
|
||||
vlsint64_t V3Number::toSQuad() const {
|
||||
vluint64_t v = toUQuad();
|
||||
vluint64_t signExtend = (-(v & (VL_ULL(1)<<(width()-1))));
|
||||
vluint64_t extended = v | signExtend;
|
||||
return (vlsint64_t)(extended);
|
||||
}
|
||||
|
||||
uint32_t V3Number::asHash() const {
|
||||
uint32_t V3Number::toHash() const {
|
||||
return m_value[0];
|
||||
}
|
||||
|
||||
@@ -751,7 +759,7 @@ V3Number& V3Number::opRepl (const V3Number& lhs, const V3Number& rhs) { // rhs i
|
||||
// Hopefully the using routine has a error check too.
|
||||
// See also error in V3Width
|
||||
if (!lhs.sized()) m_fileline->v3warn(WIDTHCONCAT,"Unsized numbers/parameters not allowed in replications.");
|
||||
return opRepl(lhs, rhs.asInt());
|
||||
return opRepl(lhs, rhs.toUInt());
|
||||
}
|
||||
|
||||
V3Number& V3Number::opRepl (const V3Number& lhs, uint32_t rhsval) { // rhs is # of times to replicate
|
||||
@@ -937,7 +945,7 @@ V3Number& V3Number::opShiftR (const V3Number& lhs, const V3Number& rhs) {
|
||||
// L(lhs) bit return
|
||||
if (rhs.isFourState()) return setAllBitsX();
|
||||
setZero();
|
||||
uint32_t rhsval = rhs.asInt();
|
||||
uint32_t rhsval = rhs.toUInt();
|
||||
for (int bit=0; bit<this->width(); bit++) {
|
||||
setBit(bit,lhs.bitIs(bit + rhsval));
|
||||
}
|
||||
@@ -950,7 +958,7 @@ V3Number& V3Number::opShiftRS (const V3Number& lhs, const V3Number& rhs) {
|
||||
// We presume it is signed; as that's V3Signed's job to convert to opShiftR
|
||||
if (rhs.isFourState()) return setAllBitsX();
|
||||
setZero();
|
||||
uint32_t rhsval = rhs.asInt();
|
||||
uint32_t rhsval = rhs.toUInt();
|
||||
for (int bit=0; bit<this->width(); bit++) {
|
||||
setBit(bit,lhs.bitIsExtend(bit + rhsval));
|
||||
}
|
||||
@@ -960,7 +968,7 @@ V3Number& V3Number::opShiftRS (const V3Number& lhs, const V3Number& rhs) {
|
||||
V3Number& V3Number::opShiftL (const V3Number& lhs, const V3Number& rhs) {
|
||||
// L(lhs) bit return
|
||||
if (rhs.isFourState()) return setAllBitsX();
|
||||
uint32_t rhsval = rhs.asInt();
|
||||
uint32_t rhsval = rhs.toUInt();
|
||||
setZero();
|
||||
for (int bit=0; bit<this->width(); bit++) {
|
||||
if (bit >= (int)rhsval) {
|
||||
@@ -1009,7 +1017,7 @@ V3Number& V3Number::opMul (const V3Number& lhs, const V3Number& rhs) {
|
||||
if (lhs.isFourState() || rhs.isFourState()) return setAllBitsX();
|
||||
setZero();
|
||||
if (width() <= 64) {
|
||||
setQuad(lhs.asQuad() * rhs.asQuad());
|
||||
setQuad(lhs.toUQuad() * rhs.toUQuad());
|
||||
opCleanThis(); // Mult produces extra bits in result
|
||||
} else {
|
||||
for (int lword=0; lword<lhs.words(); lword++) {
|
||||
@@ -1046,7 +1054,7 @@ V3Number& V3Number::opDiv (const V3Number& lhs, const V3Number& rhs) {
|
||||
if (rhs.isEqZero()) return setAllBitsX();
|
||||
if (lhs.width()>64) m_fileline->v3fatalSrc("Unsupported: Large / math not implemented yet: "<<*this);
|
||||
if (rhs.width()>64) m_fileline->v3fatalSrc("Unsupported: Large / math not implemented yet: "<<*this);
|
||||
setQuad(lhs.asQuad() / rhs.asQuad());
|
||||
setQuad(lhs.toUQuad() / rhs.toUQuad());
|
||||
return *this;
|
||||
}
|
||||
V3Number& V3Number::opDivS (const V3Number& lhs, const V3Number& rhs) {
|
||||
@@ -1070,7 +1078,7 @@ V3Number& V3Number::opModDiv (const V3Number& lhs, const V3Number& rhs) {
|
||||
if (rhs.isEqZero()) return setAllBitsX();
|
||||
if (lhs.width()>64) m_fileline->v3fatalSrc("Unsupported: Large % math not implemented yet: "<<*this);
|
||||
if (rhs.width()>64) m_fileline->v3fatalSrc("Unsupported: Large % math not implemented yet: "<<*this);
|
||||
setQuad(lhs.asQuad() % rhs.asQuad());
|
||||
setQuad(lhs.toUQuad() % rhs.toUQuad());
|
||||
return *this;
|
||||
}
|
||||
V3Number& V3Number::opModDivS (const V3Number& lhs, const V3Number& rhs) {
|
||||
@@ -1151,7 +1159,7 @@ void V3Number::opCleanThis() {
|
||||
|
||||
V3Number& V3Number::opRange (const V3Number& lhs, const V3Number& msb, const V3Number& lsb) {
|
||||
if (lsb.isFourState() || msb.isFourState()) return setAllBitsX();
|
||||
return opRange(lhs, msb.asInt(), lsb.asInt());
|
||||
return opRange(lhs, msb.toUInt(), lsb.toUInt());
|
||||
}
|
||||
|
||||
V3Number& V3Number::opRange (const V3Number& lhs, uint32_t msbval, uint32_t lsbval) {
|
||||
|
||||
+7
-5
@@ -34,6 +34,7 @@ class V3Number {
|
||||
int m_width; // Width as specified/calculated.
|
||||
bool m_sized:1; // True if the user specified the width, else we track it.
|
||||
bool m_signed:1; // True if signed value
|
||||
bool m_fromString:1; // True if from string
|
||||
bool m_autoExtend:1; // True if SystemVerilog extend-to-any-width
|
||||
FileLine* m_fileline;
|
||||
vector<uint32_t> m_value; // The Value, with bit 0 being in bit 0 of this vector (unless X/Z)
|
||||
@@ -124,6 +125,7 @@ public:
|
||||
int minWidth() const; // Minimum width that can represent this number (~== log2(num)+1)
|
||||
bool sized() const { return m_sized; }
|
||||
bool autoExtend() const { return m_autoExtend; }
|
||||
bool isFromString() const { return m_fromString; }
|
||||
bool isSigned() const { return m_signed; } // Only correct for parsing of numbers from strings, otherwise not used (use AstConst::isSigned())
|
||||
bool isNegative() const { return bitIs1(width()-1); }
|
||||
bool isFourState() const { for (int i=0;i<words();i++) {if (m_valueX[i]) return true;} return false; }
|
||||
@@ -135,11 +137,11 @@ public:
|
||||
void width(int width, bool sized=true);
|
||||
void isSigned(bool ssigned) { m_signed=ssigned; }
|
||||
bool isUnknown() const;
|
||||
uint32_t asInt() const;
|
||||
vlsint32_t asSInt() const;
|
||||
vluint64_t asQuad() const;
|
||||
vlsint64_t asSQuad() const;
|
||||
uint32_t asHash() const;
|
||||
uint32_t toUInt() const;
|
||||
vlsint32_t toSInt() const;
|
||||
vluint64_t toUQuad() const;
|
||||
vlsint64_t toSQuad() const;
|
||||
uint32_t toHash() const;
|
||||
uint32_t dataWord(int word) const;
|
||||
uint32_t countOnes() const;
|
||||
uint32_t mostSetBitP1() const; // Highest bit set plus one, IE for 16 return 5, for 0 return 0.
|
||||
|
||||
@@ -82,7 +82,7 @@ void test(string lhss, string op, string rhss, string exps) {
|
||||
|
||||
V3Number ok (new FileLine("ck",__LINE__), 1);
|
||||
ok.opCaseEq(expnum,gotnum);
|
||||
if (ok.asInt()!=1) {
|
||||
if (ok.toUInt()!=1) {
|
||||
v3fatalSrc("%Error:Test FAILED\n");
|
||||
}
|
||||
}
|
||||
|
||||
+70
-35
@@ -132,7 +132,7 @@ string V3Options::allArgsString() {
|
||||
|
||||
V3LangCode::V3LangCode (const char* textp) {
|
||||
// Return code for given string, or ERROR, which is a bad code
|
||||
for (int codei=V3LangCode::ERROR; codei<V3LangCode::MAX; codei++) {
|
||||
for (int codei=V3LangCode::ERROR; codei<V3LangCode::MAX; ++codei) {
|
||||
V3LangCode code = (V3LangCode)codei;
|
||||
if (0==strcasecmp(textp,code.ascii())) {
|
||||
m_e = code; return;
|
||||
@@ -177,6 +177,30 @@ string V3Options::filenameNonExt (const string& filename) {
|
||||
return base;
|
||||
}
|
||||
|
||||
string V3Options::filenameSubstitute (const string& filename) {
|
||||
string out;
|
||||
for (string::size_type pos = 0; pos < filename.length(); ++pos) {
|
||||
if (filename[pos] == '$') {
|
||||
string::size_type endpos = pos+1;
|
||||
while ((endpos+1) < filename.length()
|
||||
&& (isalnum(filename[endpos+1]) || filename[endpos+1]=='_'))
|
||||
++endpos;
|
||||
string envvar = filename.substr(pos+1,endpos-pos);
|
||||
const char* envvalue = NULL;
|
||||
if (envvar != "") envvalue = getenv(envvar.c_str());
|
||||
if (envvalue) {
|
||||
out += envvalue;
|
||||
pos = endpos;
|
||||
} else {
|
||||
out += filename[pos]; // *pos == '$'
|
||||
}
|
||||
} else {
|
||||
out += filename[pos];
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
bool V3Options::fileStatDir(const string& filename) {
|
||||
struct stat m_stat; // Stat information
|
||||
int err = stat(filename.c_str(), &m_stat);
|
||||
@@ -281,12 +305,12 @@ void V3Options::unlinkRegexp(const string& dir, const string& regexp) {
|
||||
// Environment
|
||||
|
||||
string V3Options::getenvStr(const char* envvar, const char* defaultValue) {
|
||||
if (const char* envvalue = getenv(envvar)) {
|
||||
return envvalue;
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
if (const char* envvalue = getenv(envvar)) {
|
||||
return envvalue;
|
||||
} else {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
string V3Options::getenvSYSTEMC() {
|
||||
string var = getenvStr("SYSTEMC","");
|
||||
if (var == "" && string(DEFENV_SYSTEMC) != "") {
|
||||
@@ -406,7 +430,7 @@ bool V3Options::wildmatch(const char* s, const char* p) {
|
||||
|
||||
string V3Options::downcase(const string& str) {
|
||||
string out = str;
|
||||
for (string::iterator pos = out.begin(); pos != out.end(); pos++) {
|
||||
for (string::iterator pos = out.begin(); pos != out.end(); ++pos) {
|
||||
*pos = tolower(*pos);
|
||||
}
|
||||
return out;
|
||||
@@ -430,7 +454,7 @@ string V3Options::version() {
|
||||
string V3Options::argString (int argc, char** argv) {
|
||||
// Return list of arguments as simple string
|
||||
string opts;
|
||||
for (int i=0; i<argc; i++) {
|
||||
for (int i=0; i<argc; ++i) {
|
||||
if (i!=0) opts += " ";
|
||||
opts += string(argv[i]);
|
||||
}
|
||||
@@ -478,7 +502,7 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
||||
// Parse parameters
|
||||
// Note argc and argv DO NOT INCLUDE the filename in [0]!!!
|
||||
// May be called recursively when there are -f files.
|
||||
for (int i=0; i<argc; i++) {
|
||||
for (int i=0; i<argc; ++i) {
|
||||
addArg(argv[i]); // -f's really should be inserted in the middle, but this is for debug
|
||||
}
|
||||
#define shift { ++i; }
|
||||
@@ -490,7 +514,7 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
||||
addDefine (string (sw+strlen("+define+")));
|
||||
}
|
||||
else if ( !strncmp (sw, "+incdir+", 8)) {
|
||||
addIncDir (string (sw+strlen("+incdir+")));
|
||||
addIncDir (filenameSubstitute(string (sw+strlen("+incdir+"))));
|
||||
}
|
||||
else if ( !strncmp (sw, "+libext+", 8)) {
|
||||
string exts = string(sw+strlen("+libext+"));
|
||||
@@ -512,7 +536,7 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
||||
char *sw = argv[i];
|
||||
bool flag = true;
|
||||
// Allow gnu -- switches
|
||||
if (sw[0]=='-' && sw[1]=='-') sw++;
|
||||
if (sw[0]=='-' && sw[1]=='-') ++sw;
|
||||
// Switch tests
|
||||
if ( !strcmp (sw, "-debug") ) {
|
||||
setDebugMode(3);
|
||||
@@ -560,7 +584,7 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
||||
}
|
||||
else if ( !strcmp (sw, "-v") ) {
|
||||
shift;
|
||||
V3Options::addLibraryFile(argv[i]);
|
||||
V3Options::addLibraryFile(filenameSubstitute(argv[i]));
|
||||
}
|
||||
else if ( !strcmp (sw, "-version") ) {
|
||||
cout <<version();
|
||||
@@ -599,7 +623,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 (char* cp=sw+strlen("-O"); *cp; ++cp) {
|
||||
flag = isupper(*cp);
|
||||
switch (tolower(*cp)) {
|
||||
case '0': optimize(0); break; // 0=all off
|
||||
@@ -640,17 +664,6 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
||||
else if ( !strncmp (sw, "-U", 2)) {
|
||||
V3PreShell::undef (string (sw+strlen("-U")));
|
||||
}
|
||||
else if ( !strncmp (sw, "-Wno-",5) ) {
|
||||
if (!strcmp (sw, "-Wno-lint")) {
|
||||
FileLine::defaultFileLine().warnLintOff(true);
|
||||
}
|
||||
else {
|
||||
string msg = sw+strlen("-Wno-");
|
||||
if (!(FileLine::defaultFileLine().warnOff(msg, true))) {
|
||||
fl->v3fatal("Unknown warning disabled: "<<sw);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( !strncmp (sw, "-Werror-",strlen("-Werror-")) ) {
|
||||
string msg = sw+strlen("-Werror-");
|
||||
V3ErrorCode code (msg.c_str());
|
||||
@@ -667,6 +680,28 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
||||
// Note it may not be a future option, but one that is currently implemented.
|
||||
addFuture(msg);
|
||||
}
|
||||
else if ( !strncmp (sw, "-Wno-",5) ) {
|
||||
if (!strcmp (sw, "-Wno-lint")) {
|
||||
FileLine::defaultFileLine().warnLintOff(true);
|
||||
}
|
||||
else {
|
||||
string msg = sw+strlen("-Wno-");
|
||||
if (!(FileLine::defaultFileLine().warnOff(msg, true))) {
|
||||
fl->v3fatal("Unknown warning specified: "<<sw);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( !strncmp (sw, "-Wwarn-",5) ) {
|
||||
if (!strcmp (sw, "-Wwarn-lint")) {
|
||||
FileLine::defaultFileLine().warnLintOff(false);
|
||||
}
|
||||
else {
|
||||
string msg = sw+strlen("-Wwarn-");
|
||||
if (!(FileLine::defaultFileLine().warnOff(msg, false))) {
|
||||
fl->v3fatal("Unknown warning specified: "<<sw);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( !strcmp (sw, "-bin") && (i+1)<argc ) {
|
||||
shift; m_bin = argv[i];
|
||||
}
|
||||
@@ -683,7 +718,7 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
||||
}
|
||||
else if ( !strcmp (sw, "-f") && (i+1)<argc ) {
|
||||
shift;
|
||||
parseOptsFile(fl, argv[i]);
|
||||
parseOptsFile(fl, filenameSubstitute(argv[i]));
|
||||
}
|
||||
else if ( !strcmp (sw, "-gdb") && (i+1)<argc ) {
|
||||
shift; // Used only in perl shell
|
||||
@@ -718,14 +753,14 @@ void V3Options::parseOptsList(FileLine* fl, int argc, char** argv) {
|
||||
} // - options
|
||||
else {
|
||||
// Filename
|
||||
string filename = argv[i];
|
||||
string filename = filenameSubstitute(argv[i]);
|
||||
if (filename.find(".cpp") != string::npos
|
||||
|| filename.find(".cxx") != string::npos
|
||||
|| filename.find(".cc") != string::npos
|
||||
|| filename.find(".sp") != string::npos) {
|
||||
V3Options::addCppFile(argv[i]);
|
||||
V3Options::addCppFile(filename);
|
||||
} else {
|
||||
V3Options::addVFile(argv[i]);
|
||||
V3Options::addVFile(filename);
|
||||
}
|
||||
shift;
|
||||
}
|
||||
@@ -753,17 +788,17 @@ void V3Options::parseOptsFile(FileLine* fl, const string& filename) {
|
||||
getline(*ifp, line);
|
||||
// Strip simple comments
|
||||
string oline;
|
||||
for (string::const_iterator pos = line.begin(); pos != line.end(); pos++) {
|
||||
for (string::const_iterator pos = line.begin(); pos != line.end(); ++pos) {
|
||||
if (inCmt) {
|
||||
if (*pos=='*' && *(pos+1)=='/') {
|
||||
inCmt = false;
|
||||
pos++;
|
||||
++pos;
|
||||
}
|
||||
} else if (*pos=='/' && *(pos+1)=='/') {
|
||||
break; // Ignore to EOL
|
||||
} else if (*pos=='/' && *(pos+1)=='*') {
|
||||
inCmt = true;
|
||||
pos++;
|
||||
++pos;
|
||||
} else {
|
||||
oline += *pos;
|
||||
}
|
||||
@@ -786,9 +821,9 @@ void V3Options::parseOptsFile(FileLine* fl, const string& filename) {
|
||||
vector<string> args;
|
||||
string::size_type startpos = 0;
|
||||
while (startpos < whole_file.length()) {
|
||||
while (isspace(whole_file[startpos])) startpos++;
|
||||
while (isspace(whole_file[startpos])) ++startpos;
|
||||
string::size_type endpos = startpos;
|
||||
while (endpos < whole_file.length() && !isspace(whole_file[endpos])) endpos++;
|
||||
while (endpos < whole_file.length() && !isspace(whole_file[endpos])) ++endpos;
|
||||
if (startpos != endpos) {
|
||||
string arg (whole_file, startpos, endpos-startpos);
|
||||
args.reserve(args.size()+1);
|
||||
@@ -799,7 +834,7 @@ void V3Options::parseOptsFile(FileLine* fl, const string& filename) {
|
||||
|
||||
// Convert to argv style arg list and parse them
|
||||
char* argv [args.size()+1];
|
||||
for (unsigned i=0; i<args.size(); i++) {
|
||||
for (unsigned i=0; i<args.size(); ++i) {
|
||||
argv[i] = (char*)args[i].c_str();
|
||||
}
|
||||
parseOptsList(fl, args.size(), argv);
|
||||
@@ -822,7 +857,7 @@ V3Options::V3Options() {
|
||||
m_makeDepend = true;
|
||||
m_makePhony = false;
|
||||
m_outFormatOk = false;
|
||||
m_pins64 = false;
|
||||
m_pins64 = true;
|
||||
m_profileCFuncs = false;
|
||||
m_preprocOnly = false;
|
||||
m_psl = false;
|
||||
|
||||
@@ -266,6 +266,7 @@ class V3Options {
|
||||
static string filenameNonExt (const string& filename); ///< Return non-extensioned (no .) part of filename
|
||||
static string filenameNonDirExt (const string& filename) { return filenameNonExt(filenameNonDir(filename)); } ///< Return basename of filename
|
||||
static string filenameDir (const string& filename); ///< Return directory part of filename
|
||||
static string filenameSubstitute (const string& filename); ///< Return filename with env vars removed
|
||||
static void unlinkRegexp(const string& dir, const string& regexp);
|
||||
|
||||
// METHODS (environment)
|
||||
|
||||
+42
-2
@@ -256,7 +256,7 @@ private:
|
||||
AstSenTree* m_deleteDomainp;// Delete this from tree
|
||||
AstSenTree* m_settleDomainp;// Initial activation tree
|
||||
OrderInputsVertex* m_inputsVxp; // Top level vertex all inputs point from
|
||||
OrderSettleVertex* m_settleVxp; // Top level vertex all inputs point from
|
||||
OrderSettleVertex* m_settleVxp; // Top level vertex all settlement vertexes point from
|
||||
OrderLogicVertex* m_logicVxp; // Current statement being tracked, NULL=ignored
|
||||
AstTopScope* m_topScopep; // Current top scope being processed
|
||||
AstScope* m_scopetopp; // Scope under TOPSCOPE
|
||||
@@ -341,6 +341,8 @@ private:
|
||||
OrderVarVertex* processInsLoopNewVar(OrderVarVertex* oldVertexp, bool& createdr);
|
||||
void processBrokeLoop();
|
||||
void processCircular();
|
||||
void processInputs();
|
||||
void processInputsIterate(OrderEitherVertex* vertexp);
|
||||
void processSensitive();
|
||||
void processDomains();
|
||||
void processDomainsIterate(OrderEitherVertex* vertexp);
|
||||
@@ -927,6 +929,39 @@ void OrderVisitor::processBrokeLoop() {
|
||||
}
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
// Clock propagation
|
||||
|
||||
void OrderVisitor::processInputs() {
|
||||
m_graph.userClearVertices(); // Vertex::user() // true if added as begin/end
|
||||
processInputsIterate(m_inputsVxp);
|
||||
}
|
||||
|
||||
void OrderVisitor::processInputsIterate(OrderEitherVertex* vertexp) {
|
||||
// Propagate PrimaryIn through simple assignments
|
||||
if (vertexp->user()) return; // Already processed
|
||||
//UINFO(9," InIt "<<vertexp<<endl);
|
||||
vertexp->user(true);
|
||||
if (OrderVarStdVertex* vvertexp = dynamic_cast<OrderVarStdVertex*>(vertexp)) {
|
||||
vvertexp->isFromInput(true);
|
||||
}
|
||||
for (V3GraphEdge* edgep = vertexp->outBeginp(); edgep; edgep=edgep->outNextp()) {
|
||||
OrderEitherVertex* toVertexp = (OrderEitherVertex*)edgep->top();
|
||||
if (OrderVarStdVertex* vvertexp = dynamic_cast<OrderVarStdVertex*>(toVertexp)) {
|
||||
processInputsIterate(vvertexp);
|
||||
}
|
||||
if (OrderLogicVertex* vvertexp = dynamic_cast<OrderLogicVertex*>(toVertexp)) {
|
||||
if (AstNodeAssign* nodep = vvertexp->nodep()->castNodeAssign()) {
|
||||
if (nodep->lhsp()->castVarRef()
|
||||
&& nodep->rhsp()->castVarRef()) {
|
||||
UINFO(9," Input reassignment: "<<vvertexp<<endl);
|
||||
processInputsIterate(vvertexp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//######################################################################
|
||||
// Circular detection
|
||||
|
||||
@@ -936,7 +971,7 @@ void OrderVisitor::processCircular() {
|
||||
// The change detect code will use this to force changedets
|
||||
for (V3GraphVertex* itp = m_graph.verticesBeginp(); itp; itp=itp->verticesNextp()) {
|
||||
if (OrderVarStdVertex* vvertexp = dynamic_cast<OrderVarStdVertex*>(itp)) {
|
||||
if (vvertexp->isClock() && !vvertexp->varScp()->varp()->isPrimaryIn()) {
|
||||
if (vvertexp->isClock() && !vvertexp->isFromInput()) {
|
||||
// If a clock is generated internally, we need to do another loop
|
||||
// through the entire evaluation. This fixes races; see t_clk_dpulse test.
|
||||
UINFO(5,"Circular Clock "<<vvertexp<<endl);
|
||||
@@ -947,6 +982,7 @@ void OrderVisitor::processCircular() {
|
||||
if (edgep->weight()==0) { // was cut
|
||||
OrderEdge* oedgep = dynamic_cast<OrderEdge*>(edgep);
|
||||
if (!oedgep) vvertexp->varScp()->v3fatalSrc("Cuttable edge not of proper type");
|
||||
UINFO(6," CutCircularO: "<<vvertexp->name()<<endl);
|
||||
nodeMarkCircular(vvertexp, oedgep);
|
||||
}
|
||||
}
|
||||
@@ -954,6 +990,7 @@ void OrderVisitor::processCircular() {
|
||||
if (edgep->weight()==0) { // was cut
|
||||
OrderEdge* oedgep = dynamic_cast<OrderEdge*>(edgep);
|
||||
if (!oedgep) vvertexp->varScp()->v3fatalSrc("Cuttable edge not of proper type");
|
||||
UINFO(6," CutCircularI: "<<vvertexp->name()<<endl);
|
||||
nodeMarkCircular(vvertexp, oedgep);
|
||||
}
|
||||
}
|
||||
@@ -1542,6 +1579,9 @@ void OrderVisitor::process() {
|
||||
m_graph.order();
|
||||
m_graph.dumpDotFilePrefixed("orderg_order");
|
||||
|
||||
UINFO(2," Process Clocks...\n");
|
||||
processInputs(); // must be before processCircular
|
||||
|
||||
#ifndef NEW_ORDERING
|
||||
UINFO(2," Process Circulars...\n");
|
||||
processCircular(); // must be before processDomains
|
||||
|
||||
+31
-4
@@ -18,6 +18,30 @@
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//*************************************************************************
|
||||
// OrderGraph Class Hierarchy:
|
||||
//
|
||||
// V3GraphVertex
|
||||
// OrderMoveVertex
|
||||
// OrderEitherVertex
|
||||
// OrderInputsVertex
|
||||
// OrderSettleVertex
|
||||
// OrderLogicVertex
|
||||
// OrderLoopBeginVertex
|
||||
// OrderLoopEndVertex
|
||||
// OrderVarVertex
|
||||
// OrderVarStdVertex
|
||||
// OrderVarPreVertex
|
||||
// OrderVarPostVertex
|
||||
// OrderVarPordVertex
|
||||
// OrderVarSettleVertex
|
||||
//
|
||||
// V3GraphEdge
|
||||
// OrderEdge
|
||||
// OrderChangeDetEdge
|
||||
// OrderComboCutEdge
|
||||
// OrderPostCutEdge
|
||||
// OrderPreCutEdge
|
||||
//*************************************************************************
|
||||
|
||||
#include "config_build.h"
|
||||
#include "verilatedos.h"
|
||||
@@ -168,20 +192,23 @@ public:
|
||||
|
||||
class OrderVarVertex : public OrderEitherVertex {
|
||||
AstVarScope* m_varScp;
|
||||
bool m_isClock; // Used as clock
|
||||
OrderVarVertex* m_pilNewVertexp; // for processInsLoopNewVar
|
||||
bool m_isClock; // Used as clock
|
||||
bool m_isFromInput; // From input, or derrived therefrom (conservatively false)
|
||||
public:
|
||||
OrderVarVertex(V3Graph* graphp, AstScope* scopep, AstVarScope* varScp)
|
||||
: OrderEitherVertex(graphp, scopep, NULL), m_varScp(varScp), m_isClock(false)
|
||||
, m_pilNewVertexp(NULL)
|
||||
: OrderEitherVertex(graphp, scopep, NULL), m_varScp(varScp)
|
||||
, m_pilNewVertexp(NULL), m_isClock(false), m_isFromInput(false)
|
||||
{}
|
||||
virtual ~OrderVarVertex() {}
|
||||
virtual OrderVarVertex* clone (V3Graph* graphp) const = 0;
|
||||
virtual OrderVEdgeType type() const = 0;
|
||||
// Accessors
|
||||
AstVarScope* varScp() const { return m_varScp; }
|
||||
void isClock(bool clk) { m_isClock=clk; }
|
||||
void isClock(bool flag) { m_isClock=flag; }
|
||||
bool isClock() const { return m_isClock; }
|
||||
void isFromInput(bool flag) { m_isFromInput=flag; }
|
||||
bool isFromInput() const { return m_isFromInput; }
|
||||
OrderVarVertex* pilNewVertexp() const { return m_pilNewVertexp; }
|
||||
void pilNewVertexp (OrderVarVertex* vertexp) { m_pilNewVertexp = vertexp; }
|
||||
};
|
||||
|
||||
+2
-2
@@ -276,7 +276,7 @@ private:
|
||||
if (AstVarRef* varrefp = wordp->lhsp()->castVarRef()) {
|
||||
if (wordp->rhsp()->castConst()
|
||||
&& varrefp->varp()->isStatementTemp()) {
|
||||
int word = wordp->rhsp()->castConst()->asInt();
|
||||
int word = wordp->rhsp()->castConst()->toUInt();
|
||||
SubstVarEntry* entryp = getEntryp(varrefp);
|
||||
hit = true;
|
||||
if (m_ops > SUBST_MAX_OPS_SUBST) {
|
||||
@@ -313,7 +313,7 @@ private:
|
||||
&& constp) {
|
||||
// Nicely formed lvalues handled in NodeAssign
|
||||
// Other lvalues handled as unknown mess in AstVarRef
|
||||
int word = constp->asInt();
|
||||
int word = constp->toUInt();
|
||||
UINFO(8," USEword"<<word<<" "<<varrefp<<endl);
|
||||
SubstVarEntry* entryp = getEntryp(varrefp);
|
||||
if (AstNode* substp = entryp->substWord (nodep, word)) {
|
||||
|
||||
+15
-9
@@ -76,6 +76,11 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
int unrollCount() {
|
||||
return m_generate ? v3Global.opt.unrollCount()*16
|
||||
: v3Global.opt.unrollCount();
|
||||
}
|
||||
|
||||
bool forUnrollCheck(AstNode* nodep,
|
||||
AstNode* initp, // Maybe under nodep (no nextp), or standalone (ignore nextp)
|
||||
AstNode* precondsp, AstNode* condp,
|
||||
@@ -158,16 +163,16 @@ private:
|
||||
|| constStopp->width()>32 || constStopp->num().isFourState()
|
||||
|| constIncp->width()>32 || constIncp->num().isFourState())
|
||||
return cantUnroll(nodep, "init/final/increment too large or four state");
|
||||
vlsint32_t valInit = constInitp->num().asInt(); // Extract as unsigned, then make signed
|
||||
vlsint32_t valStop = constStopp->num().asInt(); // Extract as unsigned, then make signed
|
||||
vlsint32_t valInit = constInitp->num().toSInt();
|
||||
vlsint32_t valStop = constStopp->num().toSInt();
|
||||
if (lte) valStop++; if (gte) valStop--;
|
||||
vlsint32_t valInc = constIncp->num().asSInt();
|
||||
vlsint32_t valInc = constIncp->num().toSInt();
|
||||
if (subtract) valInc = -valInc;
|
||||
UINFO(8," In Numbers: for (v="<<valInit<<"; v<"<<valStop<<"; v=v+"<<valInc<<")\n");
|
||||
//
|
||||
if (!m_generate) {
|
||||
UINFO(8, " ~Iters: "<<((valStop - valInit)/valInc)<<" c="<<v3Global.opt.unrollCount()<<endl);
|
||||
if (((valStop - valInit)/valInc) > v3Global.opt.unrollCount())
|
||||
UINFO(8, " ~Iters: "<<((valStop - valInit)/valInc)<<" c="<<unrollCount()<<endl);
|
||||
if (((valStop - valInit)/valInc) > unrollCount())
|
||||
return cantUnroll(nodep, "too many iterations");
|
||||
|
||||
// Less than 10 statements in the body?
|
||||
@@ -253,8 +258,8 @@ private:
|
||||
else newbodysp = oneloopp;
|
||||
|
||||
m_statIters++;
|
||||
if (++times > v3Global.opt.unrollCount()*3) {
|
||||
nodep->v3error("Loop unrolling took too long; probably this is an infinite loop.");
|
||||
if (++times > unrollCount()*3) {
|
||||
nodep->v3error("Loop unrolling took too long; probably this is an infinite loop, or set --unroll-count above "<<unrollCount());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -347,9 +352,10 @@ private:
|
||||
) {
|
||||
// Rename it, as otherwise we may get a conflict
|
||||
// V3Begin sees these DOTs and makes CellInlines for us.
|
||||
string nname = (string)"genfor"+cvtToStr(m_varValuep->asInt())+"__DOT__"+nodep->name();
|
||||
string index = AstNode::encodeNumber(m_varValuep->toSInt());
|
||||
string nname = (string)"genfor"+index+"__DOT__"+nodep->name();
|
||||
// Verilog seems to drop the for loop name and tack on [#]
|
||||
nname = nodep->name() + "__BRA__" + cvtToStr(m_varValuep->asInt()) + "__KET__";
|
||||
nname = nodep->name() + "__BRA__" + index + "__KET__";
|
||||
//UINFO(8," Rename begin "<<nname<<" "<<nodep<<endl);
|
||||
nodep->name(nname);
|
||||
}
|
||||
|
||||
+20
-6
@@ -213,7 +213,7 @@ private:
|
||||
V3Const::constifyParam(nodep->rhsp());
|
||||
AstConst* constp = nodep->rhsp()->castConst();
|
||||
if (!constp) { nodep->v3error("Replication value isn't a constant."); return; }
|
||||
uint32_t times = constp->asInt();
|
||||
uint32_t times = constp->toUInt();
|
||||
if (times==0) { nodep->v3error("Replication value is 0."); times=1; }
|
||||
nodep->width((nodep->lhsp()->width() * times),
|
||||
(nodep->lhsp()->widthMin() * times));
|
||||
@@ -238,9 +238,9 @@ private:
|
||||
if (!lsbConstp) nodep->v3error("LSB of bit range isn't a constant");
|
||||
nodep->width(1,1); return;
|
||||
}
|
||||
uint32_t msb = msbConstp->asInt();
|
||||
uint32_t lsb = lsbConstp->asInt();
|
||||
if (msb > (1UL<<28)) nodep->v3error("MSB of bit range is huge; vector of over 1billion bits: 0x"<<hex<<msb);
|
||||
int msb = msbConstp->toSInt();
|
||||
int lsb = lsbConstp->toSInt();
|
||||
if (msb > (1<<28)) nodep->v3error("MSB of bit range is huge; vector of over 1billion bits: 0x"<<hex<<msb);
|
||||
if (msb<lsb) {
|
||||
// If it's a array, ok to have either ordering, we'll just correct
|
||||
// So, see if we're sitting under a variable's arrayp.
|
||||
@@ -296,7 +296,7 @@ private:
|
||||
int fromlsb = 0;
|
||||
AstNodeVarRef* varrp = nodep->fromp()->castNodeVarRef();
|
||||
if (varrp && varrp->varp()->rangep()) { // Selecting a bit from a multibit register
|
||||
frommsb = varrp->varp()->msb();
|
||||
frommsb = varrp->varp()->msbMaxSelect(); // Corrected for negative lsb
|
||||
fromlsb = varrp->varp()->lsb();
|
||||
}
|
||||
int selwidth = V3Number::log2b(frommsb+1-1)+1; // Width to address a bit
|
||||
@@ -332,6 +332,8 @@ private:
|
||||
frommsb = varrp->varp()->arrayp(dimension)->msbConst();
|
||||
fromlsb = varrp->varp()->arrayp(dimension)->lsbConst();
|
||||
if (fromlsb>frommsb) {int t=frommsb; frommsb=fromlsb; fromlsb=t; }
|
||||
// However, if the lsb<0 we may go negative, so need more bits!
|
||||
if (fromlsb < 0) frommsb += -fromlsb;
|
||||
nodep->width(outwidth,outwidth); // Width out = width of array
|
||||
}
|
||||
int selwidth = V3Number::log2b(frommsb+1-1)+1; // Width to address a bit
|
||||
@@ -462,7 +464,11 @@ private:
|
||||
}
|
||||
virtual void visit(AstPslClocked* nodep, AstNUser*) {
|
||||
nodep->propp()->iterateAndNext(*this,WidthVP(1,1,BOTH).p());
|
||||
nodep->sensesp()->iterate(*this);
|
||||
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,"Property",nodep->propp(),1,1); // it's like a if() condition.
|
||||
nodep->width(1,1);
|
||||
}
|
||||
@@ -635,6 +641,7 @@ private:
|
||||
virtual void visit(AstPslCover* nodep, AstNUser*) {
|
||||
// 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.
|
||||
}
|
||||
virtual void visit(AstPslAssert* nodep, AstNUser*) {
|
||||
@@ -906,6 +913,13 @@ void WidthVisitor::widthCheck (AstNode* nodep, const char* side,
|
||||
if (expWidthMin==0) expWidthMin = expWidth;
|
||||
bool bad = widthBad(underp,expWidth,expWidthMin);
|
||||
if (bad && fixAutoExtend(underp/*ref*/,expWidth)) bad=false; // Changes underp
|
||||
if (underp->castConst() && underp->castConst()->num().isFromString()
|
||||
&& expWidth > underp->width()
|
||||
&& (((expWidth - underp->width()) % 8) == 0)) { // At least it's character sized
|
||||
// reg [31:0] == "foo" we'll consider probably fine.
|
||||
// Maybe this should be a special warning? Not for now.
|
||||
ignoreWarn = true;
|
||||
}
|
||||
if (bad && !ignoreWarn) {
|
||||
if (debug()>4) nodep->backp()->dumpTree(cout," back: ");
|
||||
nodep->v3warn(WIDTH,"Operator "<<nodep->typeName()
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2008-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.
|
||||
#
|
||||
# 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: Edits bison output to get around various issues.
|
||||
|
||||
foreach my $line (<STDIN>) {
|
||||
# Fix bison 2.3 and GCC 4.2.1
|
||||
$line =~ s!\(YY_\("!(YY_((char*)"!g;
|
||||
print "$line";
|
||||
}
|
||||
Executable
+382
@@ -0,0 +1,382 @@
|
||||
#!/usr/bin/perl -w
|
||||
# See copyright, etc in below POD section.
|
||||
######################################################################
|
||||
|
||||
require 5.006_001;
|
||||
use Getopt::Long;
|
||||
use IO::File;
|
||||
use Pod::Usage;
|
||||
use strict;
|
||||
use vars qw ($Debug $VERSION);
|
||||
|
||||
$VERSION = '3.035';
|
||||
|
||||
#======================================================================
|
||||
# main
|
||||
|
||||
our $Opt_Debug;
|
||||
our $Opt_Definitions;
|
||||
our $Opt_File_Prefix;
|
||||
our $Opt_Name_Prefix;
|
||||
our $Opt_Output;
|
||||
our $Opt_Token_Table;
|
||||
our $Opt_Verbose;
|
||||
our $Opt_Yacc = "bison";
|
||||
our $Opt_Input;
|
||||
|
||||
autoflush STDOUT 1;
|
||||
autoflush STDERR 1;
|
||||
Getopt::Long::config ("no_auto_abbrev");
|
||||
if (! GetOptions (
|
||||
# Local options
|
||||
"help" => \&usage,
|
||||
"version" => sub { print "Version $VERSION\n"; exit(0); },
|
||||
"yacc=s" => \$Opt_Yacc,
|
||||
# Passed to Bison
|
||||
"t|debug" => sub { $Opt_Debug = 1; },
|
||||
"b|file-prefix=s" => \$Opt_File_Prefix,
|
||||
"d" => \$Opt_Definitions,
|
||||
"k|token-table" => \$Opt_Token_Table,
|
||||
"o=s" => \$Opt_Output,
|
||||
"p|name-prefix=s" => \$Opt_Name_Prefix,
|
||||
"v|verbose" => \$Opt_Verbose,
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
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";
|
||||
|
||||
process();
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub usage {
|
||||
print "Version $VERSION\n";
|
||||
pod2usage(-verbose=>2, -exitval => 2);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
sub parameter {
|
||||
my $param = shift;
|
||||
if (!defined $Opt_Input) {
|
||||
$Opt_Input = $param;
|
||||
} else {
|
||||
die "bisonpp: %Error: Unknown parameter: $param\n";
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
|
||||
sub process {
|
||||
remove_outputs();
|
||||
|
||||
clean_input($Opt_Input, tmp_prefix().".y");
|
||||
|
||||
# Run bison
|
||||
my $command = ($Opt_Yacc
|
||||
.($Opt_Debug?" -t":"")
|
||||
.($Opt_Definitions?" -d":"")
|
||||
.($Opt_Token_Table?" -k":"")
|
||||
.($Opt_Name_Prefix?" -p $Opt_Name_Prefix":"")
|
||||
.($Opt_Verbose?" -v":"")
|
||||
." -b ".tmp_prefix()
|
||||
." -o ".tmp_prefix().".c"
|
||||
." ".tmp_prefix().".y" );
|
||||
|
||||
print " $command\n";
|
||||
system $command;
|
||||
my $status = $?;
|
||||
if ($status != 0) {
|
||||
remove_outputs();
|
||||
my $v = bison_version_check();
|
||||
die "bisonpp: %Error: $Opt_Yacc version $v run failed due to errors\n";
|
||||
}
|
||||
|
||||
clean_output(tmp_prefix().".output",output_prefix().".output");
|
||||
warning_check(output_prefix().".output");
|
||||
|
||||
clean_output(tmp_prefix().".c", output_prefix().".c");
|
||||
clean_output(tmp_prefix().".h", output_prefix().".h");
|
||||
remove_tmp();
|
||||
}
|
||||
|
||||
sub tmp_prefix {
|
||||
return output_prefix().".pre";
|
||||
}
|
||||
|
||||
sub output_prefix {
|
||||
my $o;
|
||||
if ($Opt_Output) {
|
||||
(my $o = $Opt_Output) =~ s!\.[^.]*$!!;
|
||||
return $o;
|
||||
} else {
|
||||
return $Opt_File_Prefix.".tab";
|
||||
}
|
||||
}
|
||||
|
||||
sub remove_tmp {
|
||||
unlink(tmp_prefix().".c"); # Ok if errors
|
||||
unlink(tmp_prefix().".h"); # Ok if errors
|
||||
unlink(tmp_prefix().".output"); # Ok if errors
|
||||
}
|
||||
|
||||
sub remove_outputs {
|
||||
remove_tmp();
|
||||
unlink(output_prefix().".c"); # Ok if errors
|
||||
unlink(output_prefix().".h"); # Ok if errors
|
||||
# We don't remove .output file, as it's useful for debugging errors
|
||||
}
|
||||
|
||||
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";
|
||||
return $v;
|
||||
} else {
|
||||
die "bisonpp: %Error: '$Opt_Yacc' is not installed, or not working\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub clean_output {
|
||||
my $filename = shift;
|
||||
my $outname = shift || $filename;
|
||||
print " edit $filename $outname\n";
|
||||
|
||||
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n";
|
||||
my @lines = $fh->getlines;
|
||||
$fh->close;
|
||||
|
||||
(my $basename = tmp_prefix().".y") =~ s!.*/!!;
|
||||
$basename = quotemeta($basename);
|
||||
(my $newbase = output_prefix().".y") =~ s!.*/!!;
|
||||
|
||||
$fh = IO::File->new(">$outname") or die "%Error: $! writing $outname\n";
|
||||
foreach my $line (@lines) {
|
||||
# Fix bison 2.3 and GCC 4.2.1
|
||||
$line =~ s!\(YY_\("!(YY_((char*)"!g;
|
||||
# Fix filename refs
|
||||
$line =~ s!$basename!$newbase!g;
|
||||
$fh->write($line);
|
||||
}
|
||||
$fh->close;
|
||||
}
|
||||
|
||||
sub warning_check {
|
||||
my $filename = shift;
|
||||
|
||||
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n";
|
||||
while (defined(my $line = $fh->getline)) {
|
||||
if ($line =~ /(conflicts|warning:)/) {
|
||||
clean_output();
|
||||
die "%Error: $filename:$.: $line\n";
|
||||
}
|
||||
}
|
||||
$fh->close;
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
|
||||
sub clean_input {
|
||||
my $filename = shift;
|
||||
my $outname = shift || $filename; # Can == filename if desired
|
||||
print " edit $filename $outname\n";
|
||||
|
||||
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n";
|
||||
my @lines = $fh->getlines;
|
||||
$fh->close;
|
||||
|
||||
# Find "rule<type>:"
|
||||
my %types;
|
||||
{
|
||||
my @linesin = @lines; @lines=(); my $l=0;
|
||||
foreach my $line (@linesin) {
|
||||
if ($line =~ s/^(\S+)<(\S+)>:/$1:/) {
|
||||
$types{$2}{$1} = 1;
|
||||
}
|
||||
push @lines, $line;
|
||||
}
|
||||
}
|
||||
|
||||
# Find "BISONPRE_TYPES"
|
||||
{
|
||||
my @linesin = @lines; @lines=(); my $l=0;
|
||||
my $needmore = 0;
|
||||
foreach my $line (@linesin) {
|
||||
$l++;
|
||||
if ($line =~ m!//BISONPRE_TYPES!) {
|
||||
push @lines, $line;
|
||||
foreach my $type (sort keys %types) {
|
||||
my $line = "%type<$type>\t";
|
||||
foreach my $rule (sort keys %{$types{$type}}) {
|
||||
$line.=" ".$rule;
|
||||
}
|
||||
$line .= "\n";
|
||||
push @lines, $line;
|
||||
$needmore++
|
||||
}
|
||||
} elsif ($needmore) {
|
||||
# Bison doesn't have a #line directive, so we need somewhere to insert into
|
||||
$line =~ s!^\s*//.*$!!;
|
||||
($line =~ m/^\s*$/) or die "%Error: $filename:$l: Need $needmore more blank lines to insure line numbers are constant\n";
|
||||
$needmore--;
|
||||
} else {
|
||||
push @lines, $line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$fh = IO::File->new(">$outname") or die "%Error: $! writing $outname\n";
|
||||
foreach my $line (@lines) {
|
||||
$fh->write($line);
|
||||
}
|
||||
$fh->close;
|
||||
}
|
||||
|
||||
|
||||
#######################################################################
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
bisonpre - Bison wrapper with pre and post processing
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
bisonpre --yacc bison --debug --verbose --defines X.h -k $< -pX -o X.c
|
||||
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Bisonpre is a wrapper for the Bison YACC replacement. Input to Bison is
|
||||
preprocessed with substitution as described below under EXTENSIONS. Output
|
||||
from Bison is checked for additional errors, and corrected to work around
|
||||
various compile warnings.
|
||||
|
||||
=head1 EXTENSIONS
|
||||
|
||||
=over 4
|
||||
|
||||
=item //BISONPRE_TYPES
|
||||
|
||||
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.
|
||||
|
||||
=back
|
||||
|
||||
=head1 ARGUMENTS
|
||||
|
||||
=over 4
|
||||
|
||||
=item -b file-prefix
|
||||
=item --file-prefix=file-prefix
|
||||
|
||||
Passed to bison.
|
||||
|
||||
Specify a prefix to use for all bison output file names. The names are
|
||||
chosen as if the input file were named file-prefix.c.
|
||||
|
||||
=item -d
|
||||
|
||||
Passed to bison.
|
||||
|
||||
Write an extra output file containing macro definitions for the token type
|
||||
names defined in the grammar and the semantic value type YYSTYPE, as well
|
||||
as a few extern variable declarations. If the parser output file is named
|
||||
name.c then this file is named name.h. This output file is essential if
|
||||
you wish to put the definition of yylex in a separate source file, because
|
||||
yylex needs to be able to refer to token type codes and the variable
|
||||
yylval.
|
||||
|
||||
=item --help
|
||||
|
||||
Displays this message and program version and exits.
|
||||
|
||||
=item -k
|
||||
=item --token-table
|
||||
|
||||
Passed to bison.
|
||||
|
||||
This switch causes the name.tab.c output to include a list of token names
|
||||
in order by their token numbers; this is defined in the array yytname.
|
||||
Also generated are #defines for YYNTOKENS, YYNNTS, YYNRULES, and YYNSTATES.
|
||||
|
||||
=item -p prefix
|
||||
=item --name-prefix=prefix
|
||||
|
||||
Passed to bison.
|
||||
|
||||
Rename the external symbols used in the parser so that they start with
|
||||
prefix instead of yy. The precise list of symbols renamed is yyparse,
|
||||
yylex, yyerror, yylval, yychar, and yydebug. For example, if you use -p c,
|
||||
the names become cparse, clex, and so on.
|
||||
|
||||
==item -t
|
||||
==item --debug
|
||||
|
||||
Passed to bison.
|
||||
|
||||
In the parser file, define the macro YYDEBUG to 1 if it is not already
|
||||
defined, so that the debugging facilities are compiled.
|
||||
|
||||
==item -v
|
||||
==item --verbose
|
||||
|
||||
Passed to bison.
|
||||
|
||||
Write an extra output file containing verbose descriptions of the parser
|
||||
states and what is done for each type of look-ahead token in that state.
|
||||
This file also describes all the conflicts, both those resolved by operator
|
||||
precedence and the unresolved ones. The file's name is made by removing
|
||||
.tab.c or .c from the parser output file name, and adding .output instead.
|
||||
Therefore, if the input file is foo.y, then the parser file is called
|
||||
foo.tab.c by default. As a consequence, the verbose output file is called
|
||||
foo.output.
|
||||
|
||||
=item --version
|
||||
|
||||
Print the version number and exit.
|
||||
|
||||
=item --yacc
|
||||
|
||||
Specify the name of the bison executable, defaults to "bison."
|
||||
|
||||
=back
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
This is part of the L<http://www.veripool.org/> free Verilog EDA software
|
||||
tool suite. The latest version is available from CPAN and from
|
||||
L<http://www.veripool.org/>.
|
||||
|
||||
Copyright 2008-2008 by Wilson Snyder. This package 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.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Wilson Snyder <[email protected]>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
C<bison>
|
||||
|
||||
=cut
|
||||
|
||||
######################################################################
|
||||
### Local Variables:
|
||||
### compile-command: "./bisonpre "
|
||||
### End:
|
||||
@@ -24,7 +24,7 @@
|
||||
//**********************************************************************
|
||||
//**** Version and host name
|
||||
|
||||
#define DTVERSION "Verilator 3.670 2008/07/23"
|
||||
#define DTVERSION "Verilator 3.680 2008/10/08"
|
||||
|
||||
//**********************************************************************
|
||||
//**** Functions
|
||||
|
||||
+12
-23
@@ -187,6 +187,7 @@ escid \\[^ \t\f\r\n]+
|
||||
"casez" {yylval.fileline = CRELINE(); return yCASEZ;}
|
||||
"default" {yylval.fileline = CRELINE(); return yDEFAULT;}
|
||||
"defparam" {yylval.fileline = CRELINE(); return yDEFPARAM;}
|
||||
"disable" {yylval.fileline = CRELINE(); return yDISABLE;}
|
||||
"edge" {yylval.fileline = CRELINE(); return yaTIMINGSPEC;}
|
||||
"else" {yylval.fileline = CRELINE(); return yELSE;}
|
||||
"end" {yylval.fileline = CRELINE(); return yEND;}
|
||||
@@ -243,7 +244,6 @@ escid \\[^ \t\f\r\n]+
|
||||
"bufif1" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
"cmos" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
"deassign" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
"disable" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
"endprimitive" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
"endtable" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
"event" {yyerrorf("Unsupported: Verilog 1995 reserved word not implemented: %s",yytext);}
|
||||
@@ -349,8 +349,12 @@ escid \\[^ \t\f\r\n]+
|
||||
"always_comb" {yylval.fileline = CRELINE(); return yALWAYS;}
|
||||
"always_ff" {yylval.fileline = CRELINE(); return yALWAYS;}
|
||||
"always_latch" {yylval.fileline = CRELINE(); return yALWAYS;}
|
||||
"clocking" {yylval.fileline = CRELINE(); return yCLOCKING;}
|
||||
"do" {yylval.fileline = CRELINE(); return yDO;}
|
||||
"endclocking" {yylval.fileline = CRELINE(); return yENDCLOCKING;}
|
||||
"endproperty" {yylval.fileline = CRELINE(); return yENDPROPERTY;}
|
||||
"final" {yylval.fileline = CRELINE(); return yFINAL;}
|
||||
"iff" {yylval.fileline = CRELINE(); return yIFF;}
|
||||
"static" {yylval.fileline = CRELINE(); return ySTATIC;}
|
||||
/* Generic unsupported warnings */
|
||||
/* Note assert_strobe was in SystemVerilog 3.1, but removed for SystemVerilog 2005 */
|
||||
@@ -363,7 +367,6 @@ escid \\[^ \t\f\r\n]+
|
||||
"byte" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"chandle" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"class" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"clocking" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"constraint" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"context" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"continue" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
@@ -372,12 +375,10 @@ escid \\[^ \t\f\r\n]+
|
||||
"cross" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"dist" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"endclass" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"endclocking" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"endgroup" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"endinterface" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"endpackage" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"endprogram" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"endproperty" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"endsequence" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"enum" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"expect" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
@@ -387,7 +388,6 @@ escid \\[^ \t\f\r\n]+
|
||||
"first_match" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"foreach" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"forkjoin" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"iff" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"ignore_bins" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"illegal_bins" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
"import" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented: %s",yytext);}
|
||||
@@ -442,12 +442,12 @@ escid \\[^ \t\f\r\n]+
|
||||
<S05>{
|
||||
/* Keywords */
|
||||
"assert" {yylval.fileline = CRELINE(); return yASSERT;}
|
||||
"cover" {yylval.fileline = CRELINE(); return yCOVER;}
|
||||
"property" {yylval.fileline = CRELINE(); return yPROPERTY;}
|
||||
/* Generic unsupported warnings */
|
||||
"assume" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented in non-PSL context: %s",yytext);}
|
||||
"before" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented in non-PSL context: %s",yytext);}
|
||||
"const" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented in non-PSL context: %s",yytext);}
|
||||
"cover" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented in non-PSL context: %s",yytext);}
|
||||
"property" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented in non-PSL context: %s",yytext);}
|
||||
"sequence" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented in non-PSL context: %s",yytext);}
|
||||
"union" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented in non-PSL context: %s",yytext);}
|
||||
"within" {yyerrorf("Unsupported: SystemVerilog 2005 reserved word not implemented in non-PSL context: %s",yytext);}
|
||||
@@ -473,14 +473,14 @@ escid \\[^ \t\f\r\n]+
|
||||
"assert" {yylval.fileline = CRELINE(); return yPSL_ASSERT;}
|
||||
"assume" {yylval.fileline = CRELINE(); return yPSL_ASSERT;} //==assert
|
||||
"before_!" {yyerrorf("Illegal syntax, use before!_ instead of %s",yytext);}
|
||||
"clock" {yylval.fileline = CRELINE(); return yCLOCK;}
|
||||
"clock" {yylval.fileline = CRELINE(); return yPSL_CLOCK;}
|
||||
"countones" {yylval.fileline = CRELINE(); return yD_COUNTONES;}
|
||||
"cover" {yylval.fileline = CRELINE(); return yCOVER;}
|
||||
"cover" {yylval.fileline = CRELINE(); return yPSL_COVER;}
|
||||
"isunknown" {yylval.fileline = CRELINE(); return yD_ISUNKNOWN;}
|
||||
"onehot" {yylval.fileline = CRELINE(); return yD_ONEHOT; }
|
||||
"onehot0" {yylval.fileline = CRELINE(); return yD_ONEHOT0; }
|
||||
"until_!" {yyerrorf("Illegal syntax, use until!_ instead of %s",yytext);}
|
||||
"report" {yylval.fileline = CRELINE(); return yREPORT; }
|
||||
"report" {yylval.fileline = CRELINE(); return yPSL_REPORT; }
|
||||
"true" {yylval.fileline = CRELINE(); return yTRUE; }
|
||||
/* Generic unsupported warnings */
|
||||
/*"A" {yyerrorf("Unsupported: PSL branching reserved word not implemented: %s",yytext);} */
|
||||
@@ -654,19 +654,8 @@ escid \\[^ \t\f\r\n]+
|
||||
|
||||
/* Identifiers and numbers */
|
||||
<V95,V01,V05,S05,PSL>{
|
||||
{escid} { int i;
|
||||
for (i=0; yytext[i] != 0; i++)
|
||||
if (!isalnum(yytext[i]))
|
||||
yytext[i] = '_';
|
||||
if (isalpha(yytext[1])) {
|
||||
yylval.strp = V3Read::newString(
|
||||
AstNode::encodeName(
|
||||
string(yytext+1))); // +1 to skip the backslash
|
||||
} else {
|
||||
yylval.strp = V3Read::newString(
|
||||
AstNode::encodeName(
|
||||
yytext)); // Need _ as "6..." isn't legal ID
|
||||
}
|
||||
{escid} { yylval.strp = V3Read::newString
|
||||
(AstNode::encodeName(string(yytext+1))); // +1 to skip the backslash
|
||||
return yaID;
|
||||
}
|
||||
|
||||
|
||||
+323
-207
File diff suppressed because it is too large
Load Diff
@@ -2,9 +2,11 @@
|
||||
obj_dir
|
||||
vcs.key
|
||||
csrc
|
||||
cov_work
|
||||
simv*
|
||||
simx*
|
||||
*.log
|
||||
*.key
|
||||
ncverilog.*
|
||||
INCA_libs
|
||||
logs
|
||||
|
||||
@@ -33,7 +33,7 @@ endif
|
||||
PRODUCTS += --v3
|
||||
|
||||
ifeq ($(VERILATOR_AUTHOR_SITE),1)
|
||||
DRIVER_FLAGS += -j 4
|
||||
DRIVER_FLAGS += -j 0
|
||||
endif
|
||||
|
||||
######################################################################
|
||||
@@ -70,5 +70,5 @@ random_forever:
|
||||
######################################################################
|
||||
maintainer-copy::
|
||||
clean mostlyclean distclean maintainer-clean::
|
||||
-rm -rf obj_dir simv* simx* csrc INCA_libs *.log logs
|
||||
-rm -rf obj_dir simv* simx* csrc cov_work INCA_libs *.log *.key logs
|
||||
|
||||
|
||||
+45
-12
@@ -28,6 +28,7 @@ use Pod::Usage;
|
||||
use Data::Dumper;
|
||||
use strict;
|
||||
use vars qw ($Debug %Vars $Driver $Fork);
|
||||
use POSIX qw(strftime);
|
||||
|
||||
$::Driver = 1;
|
||||
|
||||
@@ -74,6 +75,9 @@ if (! GetOptions (
|
||||
)) {
|
||||
usage();
|
||||
}
|
||||
|
||||
$opt_jobs = calc_jobs() if defined $opt_jobs && $opt_jobs==0;
|
||||
|
||||
$Fork->max_proc($opt_jobs);
|
||||
|
||||
if (!$opt_vcs && !$opt_nc && !$opt_v3) {
|
||||
@@ -81,7 +85,7 @@ if (!$opt_vcs && !$opt_nc && !$opt_v3) {
|
||||
}
|
||||
|
||||
if ($#opt_tests<0) {
|
||||
push @opt_tests, glob ("t/*.pl");
|
||||
push @opt_tests, glob ("t/t_*.pl");
|
||||
}
|
||||
|
||||
mkdir "obj_dir";
|
||||
@@ -125,8 +129,8 @@ sub one_test {
|
||||
$test->oprint("FAILED: ","*"x60,"\n");
|
||||
push @fails, "\t#".$test->soprint("%Error: $test->{errors}\n");
|
||||
my $j = ($opt_jobs>1?" -j 2":"");
|
||||
push @fails, "\t\tmake$j && ( cd test_regress ; "
|
||||
.$test->{pl_filename}." ".join(' ',@Orig_ARGV_Sw)." )\n";
|
||||
push @fails, "\t\tmake$j && test_regress/"
|
||||
.$test->{pl_filename}." ".join(' ',@Orig_ARGV_Sw)."\n";
|
||||
$failcnt++;
|
||||
if ($opt_stop) { die "%Error: --stop and errors found\n"; }
|
||||
}
|
||||
@@ -134,14 +138,9 @@ sub one_test {
|
||||
)->ready();
|
||||
}
|
||||
|
||||
print "\n";
|
||||
print "="x70,"\n";
|
||||
print "TESTS Passed $okcnt Failed $failcnt\n";
|
||||
foreach my $f (@fails) {
|
||||
chomp $f;
|
||||
print "$f\n";
|
||||
}
|
||||
print "TESTS Passed $okcnt Failed $failcnt\n";
|
||||
report(\@fails, undef);
|
||||
report(\@fails, "obj_dir/driver_".strftime("%Y%m%d_%H%M%S.log", localtime));
|
||||
|
||||
exit(10) if $failcnt;
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@@ -164,6 +163,35 @@ sub parameter {
|
||||
}
|
||||
}
|
||||
|
||||
sub calc_jobs {
|
||||
my $ok = eval "
|
||||
use Unix::Processors;
|
||||
return Unix::Processors->new->max_online;
|
||||
";
|
||||
$ok && !$@ or die "%Error: Can't use -j: $@\n";
|
||||
print "driver.pl: Found $ok cores, using -j ",$ok+1,"\n";
|
||||
return $ok + 1;
|
||||
}
|
||||
|
||||
sub report {
|
||||
my $fails = shift;
|
||||
my $filename = shift;
|
||||
|
||||
my $fh = \*STDOUT;
|
||||
if ($filename) {
|
||||
$fh = IO::File->new(">$filename") or die "%Error: $! writing $filename,";
|
||||
}
|
||||
|
||||
$fh->print("\n");
|
||||
$fh->print("="x70,"\n");
|
||||
$fh->print("TESTS Passed $okcnt Failed $failcnt\n");
|
||||
foreach my $f (@$fails) {
|
||||
chomp $f;
|
||||
$fh->print("$f\n");
|
||||
}
|
||||
$fh->print("TESTS Passed $okcnt Failed $failcnt\n");
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#######################################################################
|
||||
#######################################################################
|
||||
@@ -543,6 +571,10 @@ sub _make_main {
|
||||
my $filename = "obj_dir/$self->{VM_PREFIX}__main.cpp";
|
||||
my $fh = IO::File->new(">$filename") or die "%Error: $! $filename,";
|
||||
|
||||
print $fh "// Test defines\n";
|
||||
print $fh "#define VL_TIME_MULTIPLIER $self->{vl_time_multiplier}\n" if $self->{vl_time_multiplier};
|
||||
|
||||
print $fh "// Generated header\n";
|
||||
my $VM_PREFIX = $self->{VM_PREFIX};
|
||||
print $fh "#include \"$VM_PREFIX.h\"\n";
|
||||
|
||||
@@ -892,7 +924,8 @@ Displays this message and program version and exits.
|
||||
|
||||
=item --j #
|
||||
|
||||
Run number of parallel tests. Requires Parallel::Forker project.
|
||||
Run number of parallel tests, or 0 to determine the count based on the
|
||||
number of cores installed. Requires Parallel::Forker project.
|
||||
|
||||
=item --optimize
|
||||
|
||||
|
||||
Executable
+21
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/perl
|
||||
# DESCRIPTION: Verilator: Verilog Test driver bootstrapper
|
||||
#
|
||||
# Copyright 2008 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
# This is exec'ed by every test that is run standalone (called from the
|
||||
# shell as ./t_test_name.pl)
|
||||
|
||||
use FindBin;
|
||||
use Cwd qw(chdir);
|
||||
|
||||
my @args = @ARGV;
|
||||
chdir("$FindBin::Bin/..");
|
||||
|
||||
@args = map { s!.*test_regress/!!; $_; } @args;
|
||||
|
||||
print "cd $ENV{PWD} && $FindBin::Bin/bootstrap.pl ",join(' ',@args),"\n";
|
||||
exec("./driver.pl", @args);
|
||||
die;
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
@@ -43,9 +43,6 @@ module t (/*AUTOARG*/
|
||||
// Aggregate outputs into a single result vector
|
||||
wire [63:0] result = {32'h0, out};
|
||||
|
||||
// What checksum will we end up with
|
||||
`define EXPECTED_SUM 64'h4afe43fb79d7b71e
|
||||
|
||||
// Test loop
|
||||
always @ (posedge clk) begin
|
||||
`ifdef TEST_VERBOSE
|
||||
@@ -66,6 +63,8 @@ module t (/*AUTOARG*/
|
||||
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'h4afe43fb79d7b71e
|
||||
if (sum !== `EXPECTED_SUM) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2004 by Wilson Snyder. This program is free software; you can
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# 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.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# 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.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# 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.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# 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.
|
||||
|
||||
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
#!/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.
|
||||
|
||||
top_filename("t/t_assert_cover.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => [$Last_Self->{v3}?'--assert --sp --coverage-user':''],
|
||||
nc_flags2 => ["+nccovoverwrite +nccoverage+all +nccovtest+$Last_Self->{name}"]
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
if ($Last_Self->{nc}) {
|
||||
my $name = $Last_Self->{name};
|
||||
my $cf = "obj_dir/${name}__nccover.cf";
|
||||
{
|
||||
my $fh = IO::File->new(">$cf") or die "%Error: $! writing $cf,";
|
||||
$fh->printf("report_summary -module *\n");
|
||||
$fh->printf("report_detail -both -module *\n");
|
||||
$fh->printf("report_html -both -module * > obj_dir/${name}__nccover.html\n");
|
||||
$fh->close;
|
||||
}
|
||||
$Last_Self->_run (logfile=>"obj_dir/${name}__nccover.log",
|
||||
tee=>0,
|
||||
cmd=>[($ENV{VERILATOR_ICCR}||'iccr'),
|
||||
"-test ${name} ${cf}"]);
|
||||
}
|
||||
|
||||
file_grep ("obj_dir/$Last_Self->{name}_simx.log", qr/COVER: Cyc==4/);
|
||||
file_grep ("obj_dir/$Last_Self->{name}_simx.log", qr/COVER: Cyc==5/);
|
||||
file_grep ("obj_dir/$Last_Self->{name}_simx.log", qr/COVER: Cyc==6/);
|
||||
file_grep ($Last_Self->{coverage_filename}, qr/cyc_eq_5.*,c=>[^0]/);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,116 @@
|
||||
// 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 test (/*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
|
||||
);
|
||||
|
||||
// Simple cover
|
||||
cover property (@(posedge clk) cyc==3);
|
||||
|
||||
// With statement, in generate
|
||||
generate if (1) begin
|
||||
cover property (@(posedge clk) cyc==4) $display("*COVER: Cyc==4");
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Labeled cover
|
||||
cyc_eq_5:
|
||||
cover property (@(posedge clk) cyc==5) $display("*COVER: Cyc==5");
|
||||
|
||||
// Using default clock
|
||||
default clocking @(posedge clk); endclocking
|
||||
cover property (cyc==6) $display("*COVER: Cyc==6");
|
||||
|
||||
// Disable statement
|
||||
// Note () after disable are required
|
||||
cover property (@(posedge clk) disable iff (toggle) cyc==8)
|
||||
$display("*COVER: Cyc==8");
|
||||
cover property (@(posedge clk) disable iff (!toggle) cyc==8)
|
||||
$stop;
|
||||
|
||||
`ifndef verilator // Unsupported
|
||||
// Using a more complicated property
|
||||
property C1;
|
||||
@(posedge clk)
|
||||
disable iff (!toggle)
|
||||
cyc==5;
|
||||
endproperty
|
||||
cover property (C1) $display("*COVER: Cyc==5");
|
||||
|
||||
// Using covergroup
|
||||
// Note a covergroup is really inheritance of a special system "covergroup" class.
|
||||
covergroup counter1 @ (posedge cyc);
|
||||
// Automatic methods: stop(), start(), sample(), set_inst_name()
|
||||
|
||||
// Each bin value must be <= 32 bits. Strange.
|
||||
cyc_value : coverpoint cyc {
|
||||
}
|
||||
|
||||
cyc_bined : coverpoint cyc {
|
||||
bins zero = {0};
|
||||
bins low = {1,5};
|
||||
// Note 5 is also in the bin above. Only the first bin matching is counted.
|
||||
bins mid = {[5:$]};
|
||||
// illegal_bins // Has precidence over "first matching bin", creates assertion
|
||||
// ignore_bins // Not counted, and not part of total
|
||||
}
|
||||
toggle : coverpoint (toggle) {
|
||||
bins off = {0};
|
||||
bins on = {1};
|
||||
}
|
||||
cyc5 : coverpoint (cyc==5) {
|
||||
bins five = {1};
|
||||
}
|
||||
|
||||
// option.at_least = {number}; // Default 1 - Hits to be considered covered
|
||||
// option.auto_bin_max = {number}; // Default 64
|
||||
// option.comment = {string}
|
||||
// option.goal = {number}; // Default 90%
|
||||
// option.name = {string}
|
||||
// option.per_instance = 1; // Default 0 - each instance separately counted (cadence default is 1)
|
||||
// option.weight = {number}; // Default 1
|
||||
|
||||
// CROSS
|
||||
value_and_toggle: // else default is __<firstlabel>_X_<secondlabel>_<n>
|
||||
cross cyc_value, toggle;
|
||||
endgroup
|
||||
counter1 c1 = new();
|
||||
`endif
|
||||
|
||||
endmodule
|
||||
Executable
+20
@@ -0,0 +1,20 @@
|
||||
#!/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.
|
||||
|
||||
top_filename("t/t_assert_cover.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => [],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# 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.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# 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.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# 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.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# 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.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2004 by Wilson Snyder. This program is free software; you can
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# 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.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
@@ -7,7 +7,7 @@ if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
v_flags2 => ["--stats --profile-cfuncs"],
|
||||
verilator_flags2 => ["--stats --profile-cfuncs"],
|
||||
);
|
||||
|
||||
if ($Last_Self->{v3}) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# 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.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# 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.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# 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.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# 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.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# 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.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# 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.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# 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.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# 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.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# 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.
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
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
|
||||
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/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.
|
||||
|
||||
$Last_Self->{vl_time_multiplier} = 1000;
|
||||
|
||||
compile (
|
||||
verilator_flags2 => ['-DVL_TIME_MULTIPLER=1000'],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
expect=> quotemeta(
|
||||
'default: [0.000] 0t time [ 0.000] No0 time
|
||||
'
|
||||
# Unsupported:
|
||||
#'default: [0] 0t time [ 0] No0 time
|
||||
#-9,0,,0: [0] 0t time [0] No0 time
|
||||
#-9,0,,10: [0] 0t time [ 0] No0 time
|
||||
#-9,0,ns,5: [0ns] 0t time [ 0ns] No0 time
|
||||
#-9,3,ns,8: [0.000ns] 0t time [ 0.000ns] No0 time
|
||||
#'
|
||||
),
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,26 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003 by Wilson Snyder.
|
||||
|
||||
`timescale 1ns/1ns
|
||||
|
||||
module t;
|
||||
initial begin
|
||||
// Display formatting
|
||||
$write("default: [%0t] 0t time [%t] No0 time\n",$time,$time);
|
||||
`ifndef verilator // Unsupported
|
||||
$timeformat(-9, 0, "", 0);
|
||||
$write("-9,0,,0: [%0t] 0t time [%t] No0 time\n",$time,$time);
|
||||
$timeformat(-9, 0, "", 10);
|
||||
$write("-9,0,,10: [%0t] 0t time [%t] No0 time\n",$time,$time);
|
||||
$timeformat(-9, 0, "ns", 5);
|
||||
$write("-9,0,ns,5: [%0t] 0t time [%t] No0 time\n",$time,$time);
|
||||
$timeformat(-9, 3, "ns", 8);
|
||||
$write("-9,3,ns,8: [%0t] 0t time [%t] No0 time\n",$time,$time);
|
||||
`endif
|
||||
$write("\n");
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user