mirror of
https://github.com/verilator/verilator.git
synced 2026-10-02 16:13:34 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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,28 @@ 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.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 +32,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
|
||||
|
||||
+45
-22
@@ -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
|
||||
@@ -981,7 +978,7 @@ 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.
|
||||
the --no-pins64 switch. Wider pins become sc_bv's.
|
||||
|
||||
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 +1043,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
|
||||
|
||||
@@ -1728,6 +1726,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 +2096,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 +2223,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 +2258,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);
|
||||
}
|
||||
|
||||
+51
-18
@@ -85,12 +85,27 @@ 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;
|
||||
@@ -116,19 +131,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);
|
||||
}
|
||||
|
||||
@@ -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]";
|
||||
}
|
||||
|
||||
+36
-8
@@ -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 asInt() const { return num().asInt(); } // Old, should be removed
|
||||
uint32_t toUInt() const { return num().toUInt(); }
|
||||
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(); }
|
||||
@@ -222,7 +223,7 @@ struct AstSel : public AstNodeTriop {
|
||||
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 widthConst() const { return widthp()->castConst()->toUInt(); }
|
||||
uint32_t msbConst() const { return lsbConst()+widthConst()-1; }
|
||||
};
|
||||
|
||||
@@ -2830,6 +2831,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 +2876,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 +2922,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 +2935,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 +3144,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 {
|
||||
|
||||
+4
-4
@@ -143,7 +143,7 @@ private:
|
||||
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) {
|
||||
@@ -494,7 +494,7 @@ private:
|
||||
&&(con2p->asInt() != con1p->asInt() + sel1p->width())) return false;
|
||||
bool lsbFirstAssign = (con1p->asInt() < con2p->asInt());
|
||||
// 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 +517,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;
|
||||
|
||||
+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");
|
||||
|
||||
|
||||
+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);
|
||||
|
||||
+2
-2
@@ -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
|
||||
|
||||
@@ -164,6 +164,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());
|
||||
|
||||
+21
-21
@@ -429,7 +429,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 +444,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 +461,34 @@ 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();
|
||||
vlsint32_t V3Number::toSInt() const {
|
||||
uint32_t v = toUInt();
|
||||
uint32_t signExtend = (-(v & (1UL<<(width()-1))));
|
||||
uint32_t extended = v | signExtend;
|
||||
return (vlsint32_t)(extended);
|
||||
}
|
||||
|
||||
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 +751,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 +937,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 +950,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 +960,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 +1009,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 +1046,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 +1070,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 +1151,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) {
|
||||
|
||||
+6
-5
@@ -135,11 +135,12 @@ 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 asInt() const { return toUInt(); } // Deprecated, use toUInt/toSInt
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
+23
-12
@@ -640,17 +640,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 +656,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];
|
||||
}
|
||||
@@ -822,7 +833,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;
|
||||
|
||||
+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)) {
|
||||
|
||||
+3
-3
@@ -158,10 +158,10 @@ 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().toUInt(); // Extract as unsigned, then make signed
|
||||
vlsint32_t valStop = constStopp->num().toUInt(); // Extract as unsigned, then make signed
|
||||
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");
|
||||
//
|
||||
|
||||
+7
-2
@@ -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));
|
||||
@@ -462,7 +462,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 +639,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*) {
|
||||
|
||||
@@ -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.671 2008/07/23"
|
||||
|
||||
//**********************************************************************
|
||||
//**** 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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -543,6 +543,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";
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
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("./driver.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
top_filename("t/t_assert_cover.v");
|
||||
|
||||
compile (
|
||||
v_flags2 => [],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -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}) {
|
||||
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.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
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,60 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2008 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Outputs
|
||||
q,
|
||||
// Inputs
|
||||
clk, d
|
||||
);
|
||||
input clk;
|
||||
input d;
|
||||
output wire [1:0] q;
|
||||
|
||||
// This demonstrates how warning disables should be propagated across module boundaries.
|
||||
|
||||
m1 m1 (/*AUTOINST*/
|
||||
// Outputs
|
||||
.q (q[1:0]),
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.d (d));
|
||||
endmodule
|
||||
|
||||
module m1
|
||||
(
|
||||
input clk,
|
||||
input d,
|
||||
output wire [1:0] q
|
||||
);
|
||||
|
||||
m2 m2 (/*AUTOINST*/
|
||||
// Outputs
|
||||
.q (q[1:0]),
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.d (d));
|
||||
endmodule
|
||||
|
||||
module m2
|
||||
(
|
||||
input clk,
|
||||
input d,
|
||||
// Due to bug the below disable used to be ignored.
|
||||
// verilator lint_off UNOPT
|
||||
output reg [1:0] q
|
||||
// verilator lint_on UNOPT
|
||||
);
|
||||
|
||||
always @* begin
|
||||
q[1] = d;
|
||||
end
|
||||
|
||||
always @* begin
|
||||
q[0] = q[1];
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -0,0 +1,415 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2008 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
input clk;
|
||||
|
||||
integer cyc=0;
|
||||
reg [63:0] crc;
|
||||
reg [63:0] sum;
|
||||
|
||||
// Take CRC data and apply to testblock inputs
|
||||
wire [7:0] sel = crc[7:0];
|
||||
wire [255+3:0] in = {crc[2:0],crc,crc,crc,crc};
|
||||
|
||||
/*AUTOWIRE*/
|
||||
// Beginning of automatic wires (for undeclared instantiated-module outputs)
|
||||
wire [3:0] out; // From test of Test.v
|
||||
// End of automatics
|
||||
|
||||
/* Test AUTO_TEMPLATE (
|
||||
.i\([0-9]+\) (in[\1 +:4]),
|
||||
); */
|
||||
|
||||
Test test (/*AUTOINST*/
|
||||
// Outputs
|
||||
.out (out[3:0]),
|
||||
// Inputs
|
||||
.sel (sel[7:0]),
|
||||
.i0 (in[0 +:4]), // Templated
|
||||
.i1 (in[1 +:4]), // Templated
|
||||
.i2 (in[2 +:4]), // Templated
|
||||
.i3 (in[3 +:4]), // Templated
|
||||
.i4 (in[4 +:4]), // Templated
|
||||
.i5 (in[5 +:4]), // Templated
|
||||
.i6 (in[6 +:4]), // Templated
|
||||
.i7 (in[7 +:4]), // Templated
|
||||
.i8 (in[8 +:4]), // Templated
|
||||
.i9 (in[9 +:4]), // Templated
|
||||
.i10 (in[10 +:4]), // Templated
|
||||
.i11 (in[11 +:4]), // Templated
|
||||
.i12 (in[12 +:4]), // Templated
|
||||
.i13 (in[13 +:4]), // Templated
|
||||
.i14 (in[14 +:4]), // Templated
|
||||
.i15 (in[15 +:4]), // Templated
|
||||
.i16 (in[16 +:4]), // Templated
|
||||
.i17 (in[17 +:4]), // Templated
|
||||
.i18 (in[18 +:4]), // Templated
|
||||
.i19 (in[19 +:4]), // Templated
|
||||
.i20 (in[20 +:4]), // Templated
|
||||
.i21 (in[21 +:4]), // Templated
|
||||
.i22 (in[22 +:4]), // Templated
|
||||
.i23 (in[23 +:4]), // Templated
|
||||
.i24 (in[24 +:4]), // Templated
|
||||
.i25 (in[25 +:4]), // Templated
|
||||
.i26 (in[26 +:4]), // Templated
|
||||
.i27 (in[27 +:4]), // Templated
|
||||
.i28 (in[28 +:4]), // Templated
|
||||
.i29 (in[29 +:4]), // Templated
|
||||
.i30 (in[30 +:4]), // Templated
|
||||
.i31 (in[31 +:4]), // Templated
|
||||
.i32 (in[32 +:4]), // Templated
|
||||
.i33 (in[33 +:4]), // Templated
|
||||
.i34 (in[34 +:4]), // Templated
|
||||
.i35 (in[35 +:4]), // Templated
|
||||
.i36 (in[36 +:4]), // Templated
|
||||
.i37 (in[37 +:4]), // Templated
|
||||
.i38 (in[38 +:4]), // Templated
|
||||
.i39 (in[39 +:4]), // Templated
|
||||
.i40 (in[40 +:4]), // Templated
|
||||
.i41 (in[41 +:4]), // Templated
|
||||
.i42 (in[42 +:4]), // Templated
|
||||
.i43 (in[43 +:4]), // Templated
|
||||
.i44 (in[44 +:4]), // Templated
|
||||
.i45 (in[45 +:4]), // Templated
|
||||
.i46 (in[46 +:4]), // Templated
|
||||
.i47 (in[47 +:4]), // Templated
|
||||
.i48 (in[48 +:4]), // Templated
|
||||
.i49 (in[49 +:4]), // Templated
|
||||
.i50 (in[50 +:4]), // Templated
|
||||
.i51 (in[51 +:4]), // Templated
|
||||
.i52 (in[52 +:4]), // Templated
|
||||
.i53 (in[53 +:4]), // Templated
|
||||
.i54 (in[54 +:4]), // Templated
|
||||
.i55 (in[55 +:4]), // Templated
|
||||
.i56 (in[56 +:4]), // Templated
|
||||
.i57 (in[57 +:4]), // Templated
|
||||
.i58 (in[58 +:4]), // Templated
|
||||
.i59 (in[59 +:4]), // Templated
|
||||
.i60 (in[60 +:4]), // Templated
|
||||
.i61 (in[61 +:4]), // Templated
|
||||
.i62 (in[62 +:4]), // Templated
|
||||
.i63 (in[63 +:4]), // Templated
|
||||
.i64 (in[64 +:4]), // Templated
|
||||
.i65 (in[65 +:4]), // Templated
|
||||
.i66 (in[66 +:4]), // Templated
|
||||
.i67 (in[67 +:4]), // Templated
|
||||
.i68 (in[68 +:4]), // Templated
|
||||
.i69 (in[69 +:4]), // Templated
|
||||
.i70 (in[70 +:4]), // Templated
|
||||
.i71 (in[71 +:4]), // Templated
|
||||
.i72 (in[72 +:4]), // Templated
|
||||
.i73 (in[73 +:4]), // Templated
|
||||
.i74 (in[74 +:4]), // Templated
|
||||
.i75 (in[75 +:4]), // Templated
|
||||
.i76 (in[76 +:4]), // Templated
|
||||
.i77 (in[77 +:4]), // Templated
|
||||
.i78 (in[78 +:4]), // Templated
|
||||
.i79 (in[79 +:4]), // Templated
|
||||
.i80 (in[80 +:4]), // Templated
|
||||
.i81 (in[81 +:4]), // Templated
|
||||
.i82 (in[82 +:4]), // Templated
|
||||
.i83 (in[83 +:4]), // Templated
|
||||
.i84 (in[84 +:4]), // Templated
|
||||
.i85 (in[85 +:4]), // Templated
|
||||
.i86 (in[86 +:4]), // Templated
|
||||
.i87 (in[87 +:4]), // Templated
|
||||
.i88 (in[88 +:4]), // Templated
|
||||
.i89 (in[89 +:4]), // Templated
|
||||
.i90 (in[90 +:4]), // Templated
|
||||
.i91 (in[91 +:4]), // Templated
|
||||
.i92 (in[92 +:4]), // Templated
|
||||
.i93 (in[93 +:4]), // Templated
|
||||
.i94 (in[94 +:4]), // Templated
|
||||
.i95 (in[95 +:4]), // Templated
|
||||
.i96 (in[96 +:4]), // Templated
|
||||
.i97 (in[97 +:4]), // Templated
|
||||
.i98 (in[98 +:4]), // Templated
|
||||
.i99 (in[99 +:4]), // Templated
|
||||
.i100 (in[100 +:4]), // Templated
|
||||
.i101 (in[101 +:4]), // Templated
|
||||
.i102 (in[102 +:4]), // Templated
|
||||
.i103 (in[103 +:4]), // Templated
|
||||
.i104 (in[104 +:4]), // Templated
|
||||
.i105 (in[105 +:4]), // Templated
|
||||
.i106 (in[106 +:4]), // Templated
|
||||
.i107 (in[107 +:4]), // Templated
|
||||
.i108 (in[108 +:4]), // Templated
|
||||
.i109 (in[109 +:4]), // Templated
|
||||
.i110 (in[110 +:4]), // Templated
|
||||
.i111 (in[111 +:4]), // Templated
|
||||
.i112 (in[112 +:4]), // Templated
|
||||
.i113 (in[113 +:4]), // Templated
|
||||
.i114 (in[114 +:4]), // Templated
|
||||
.i115 (in[115 +:4]), // Templated
|
||||
.i116 (in[116 +:4]), // Templated
|
||||
.i117 (in[117 +:4]), // Templated
|
||||
.i118 (in[118 +:4]), // Templated
|
||||
.i119 (in[119 +:4]), // Templated
|
||||
.i120 (in[120 +:4]), // Templated
|
||||
.i121 (in[121 +:4]), // Templated
|
||||
.i122 (in[122 +:4]), // Templated
|
||||
.i123 (in[123 +:4]), // Templated
|
||||
.i124 (in[124 +:4]), // Templated
|
||||
.i125 (in[125 +:4]), // Templated
|
||||
.i126 (in[126 +:4]), // Templated
|
||||
.i127 (in[127 +:4]), // Templated
|
||||
.i128 (in[128 +:4]), // Templated
|
||||
.i129 (in[129 +:4]), // Templated
|
||||
.i130 (in[130 +:4]), // Templated
|
||||
.i131 (in[131 +:4]), // Templated
|
||||
.i132 (in[132 +:4]), // Templated
|
||||
.i133 (in[133 +:4]), // Templated
|
||||
.i134 (in[134 +:4]), // Templated
|
||||
.i135 (in[135 +:4]), // Templated
|
||||
.i136 (in[136 +:4]), // Templated
|
||||
.i137 (in[137 +:4]), // Templated
|
||||
.i138 (in[138 +:4]), // Templated
|
||||
.i139 (in[139 +:4]), // Templated
|
||||
.i140 (in[140 +:4]), // Templated
|
||||
.i141 (in[141 +:4]), // Templated
|
||||
.i142 (in[142 +:4]), // Templated
|
||||
.i143 (in[143 +:4]), // Templated
|
||||
.i144 (in[144 +:4]), // Templated
|
||||
.i145 (in[145 +:4]), // Templated
|
||||
.i146 (in[146 +:4]), // Templated
|
||||
.i147 (in[147 +:4]), // Templated
|
||||
.i148 (in[148 +:4]), // Templated
|
||||
.i149 (in[149 +:4]), // Templated
|
||||
.i150 (in[150 +:4]), // Templated
|
||||
.i151 (in[151 +:4]), // Templated
|
||||
.i152 (in[152 +:4]), // Templated
|
||||
.i153 (in[153 +:4]), // Templated
|
||||
.i154 (in[154 +:4]), // Templated
|
||||
.i155 (in[155 +:4]), // Templated
|
||||
.i156 (in[156 +:4]), // Templated
|
||||
.i157 (in[157 +:4]), // Templated
|
||||
.i158 (in[158 +:4]), // Templated
|
||||
.i159 (in[159 +:4]), // Templated
|
||||
.i160 (in[160 +:4]), // Templated
|
||||
.i161 (in[161 +:4]), // Templated
|
||||
.i162 (in[162 +:4]), // Templated
|
||||
.i163 (in[163 +:4]), // Templated
|
||||
.i164 (in[164 +:4]), // Templated
|
||||
.i165 (in[165 +:4]), // Templated
|
||||
.i166 (in[166 +:4]), // Templated
|
||||
.i167 (in[167 +:4]), // Templated
|
||||
.i168 (in[168 +:4]), // Templated
|
||||
.i169 (in[169 +:4]), // Templated
|
||||
.i170 (in[170 +:4]), // Templated
|
||||
.i171 (in[171 +:4]), // Templated
|
||||
.i172 (in[172 +:4]), // Templated
|
||||
.i173 (in[173 +:4]), // Templated
|
||||
.i174 (in[174 +:4]), // Templated
|
||||
.i175 (in[175 +:4]), // Templated
|
||||
.i176 (in[176 +:4]), // Templated
|
||||
.i177 (in[177 +:4]), // Templated
|
||||
.i178 (in[178 +:4]), // Templated
|
||||
.i179 (in[179 +:4]), // Templated
|
||||
.i180 (in[180 +:4]), // Templated
|
||||
.i181 (in[181 +:4]), // Templated
|
||||
.i182 (in[182 +:4]), // Templated
|
||||
.i183 (in[183 +:4]), // Templated
|
||||
.i184 (in[184 +:4]), // Templated
|
||||
.i185 (in[185 +:4]), // Templated
|
||||
.i186 (in[186 +:4]), // Templated
|
||||
.i187 (in[187 +:4]), // Templated
|
||||
.i188 (in[188 +:4]), // Templated
|
||||
.i189 (in[189 +:4]), // Templated
|
||||
.i190 (in[190 +:4]), // Templated
|
||||
.i191 (in[191 +:4]), // Templated
|
||||
.i192 (in[192 +:4]), // Templated
|
||||
.i193 (in[193 +:4]), // Templated
|
||||
.i194 (in[194 +:4]), // Templated
|
||||
.i195 (in[195 +:4]), // Templated
|
||||
.i196 (in[196 +:4]), // Templated
|
||||
.i197 (in[197 +:4]), // Templated
|
||||
.i198 (in[198 +:4]), // Templated
|
||||
.i199 (in[199 +:4]), // Templated
|
||||
.i200 (in[200 +:4]), // Templated
|
||||
.i201 (in[201 +:4]), // Templated
|
||||
.i202 (in[202 +:4]), // Templated
|
||||
.i203 (in[203 +:4]), // Templated
|
||||
.i204 (in[204 +:4]), // Templated
|
||||
.i205 (in[205 +:4]), // Templated
|
||||
.i206 (in[206 +:4]), // Templated
|
||||
.i207 (in[207 +:4]), // Templated
|
||||
.i208 (in[208 +:4]), // Templated
|
||||
.i209 (in[209 +:4]), // Templated
|
||||
.i210 (in[210 +:4]), // Templated
|
||||
.i211 (in[211 +:4]), // Templated
|
||||
.i212 (in[212 +:4]), // Templated
|
||||
.i213 (in[213 +:4]), // Templated
|
||||
.i214 (in[214 +:4]), // Templated
|
||||
.i215 (in[215 +:4]), // Templated
|
||||
.i216 (in[216 +:4]), // Templated
|
||||
.i217 (in[217 +:4]), // Templated
|
||||
.i218 (in[218 +:4]), // Templated
|
||||
.i219 (in[219 +:4]), // Templated
|
||||
.i220 (in[220 +:4]), // Templated
|
||||
.i221 (in[221 +:4]), // Templated
|
||||
.i222 (in[222 +:4]), // Templated
|
||||
.i223 (in[223 +:4]), // Templated
|
||||
.i224 (in[224 +:4]), // Templated
|
||||
.i225 (in[225 +:4]), // Templated
|
||||
.i226 (in[226 +:4]), // Templated
|
||||
.i227 (in[227 +:4]), // Templated
|
||||
.i228 (in[228 +:4]), // Templated
|
||||
.i229 (in[229 +:4]), // Templated
|
||||
.i230 (in[230 +:4]), // Templated
|
||||
.i231 (in[231 +:4]), // Templated
|
||||
.i232 (in[232 +:4]), // Templated
|
||||
.i233 (in[233 +:4]), // Templated
|
||||
.i234 (in[234 +:4]), // Templated
|
||||
.i235 (in[235 +:4]), // Templated
|
||||
.i236 (in[236 +:4]), // Templated
|
||||
.i237 (in[237 +:4]), // Templated
|
||||
.i238 (in[238 +:4]), // Templated
|
||||
.i239 (in[239 +:4]), // Templated
|
||||
.i240 (in[240 +:4]), // Templated
|
||||
.i241 (in[241 +:4]), // Templated
|
||||
.i242 (in[242 +:4]), // Templated
|
||||
.i243 (in[243 +:4]), // Templated
|
||||
.i244 (in[244 +:4]), // Templated
|
||||
.i245 (in[245 +:4]), // Templated
|
||||
.i246 (in[246 +:4]), // Templated
|
||||
.i247 (in[247 +:4]), // Templated
|
||||
.i248 (in[248 +:4]), // Templated
|
||||
.i249 (in[249 +:4]), // Templated
|
||||
.i250 (in[250 +:4]), // Templated
|
||||
.i251 (in[251 +:4]), // Templated
|
||||
.i252 (in[252 +:4]), // Templated
|
||||
.i253 (in[253 +:4]), // Templated
|
||||
.i254 (in[254 +:4]), // Templated
|
||||
.i255 (in[255 +:4])); // Templated
|
||||
|
||||
// Aggregate outputs into a single result vector
|
||||
wire [63:0] result = {60'h0, out};
|
||||
|
||||
// What checksum will we end up with
|
||||
`define EXPECTED_SUM 64'h36f3051d15caf07a
|
||||
|
||||
// Test loop
|
||||
always @ (posedge clk) begin
|
||||
`ifdef TEST_VERBOSE
|
||||
$write("[%0t] cyc==%0d crc=%x result=%x\n",$time, cyc, crc, result);
|
||||
`endif
|
||||
cyc <= cyc + 1;
|
||||
crc <= {crc[62:0], crc[63]^crc[2]^crc[0]};
|
||||
sum <= result ^ {sum[62:0],sum[63]^sum[2]^sum[0]};
|
||||
if (cyc==0) begin
|
||||
// Setup
|
||||
crc <= 64'h5aef0c8d_d70a4497;
|
||||
end
|
||||
else if (cyc<10) begin
|
||||
sum <= 64'h0;
|
||||
end
|
||||
else if (cyc<90) begin
|
||||
end
|
||||
else if (cyc==99) begin
|
||||
$write("[%0t] cyc==%0d crc=%x sum=%x\n",$time, cyc, crc, sum);
|
||||
if (crc !== 64'hc77bb9b3784ea091) $stop;
|
||||
if (sum !== `EXPECTED_SUM) $stop;
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module Test
|
||||
( output wire [3:0] out,
|
||||
|
||||
input [7:0] sel,
|
||||
|
||||
input [3:0] i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16,
|
||||
i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33,
|
||||
i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, i45, i46, i47, i48, i49, i50,
|
||||
i51, i52, i53, i54, i55, i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, i67,
|
||||
i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, i78, i79, i80, i81, i82, i83, i84,
|
||||
i85, i86, i87, i88, i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, i100, i101,
|
||||
i102, i103, i104, i105, i106, i107, i108, i109, i110, i111, i112, i113, i114, i115,
|
||||
i116, i117, i118, i119, i120, i121, i122, i123, i124, i125, i126, i127, i128, i129,
|
||||
i130, i131, i132, i133, i134, i135, i136, i137, i138, i139, i140, i141, i142, i143,
|
||||
i144, i145, i146, i147, i148, i149, i150, i151, i152, i153, i154, i155, i156, i157,
|
||||
i158, i159, i160, i161, i162, i163, i164, i165, i166, i167, i168, i169, i170, i171,
|
||||
i172, i173, i174, i175, i176, i177, i178, i179, i180, i181, i182, i183, i184, i185,
|
||||
i186, i187, i188, i189, i190, i191, i192, i193, i194, i195, i196, i197, i198, i199,
|
||||
i200, i201, i202, i203, i204, i205, i206, i207, i208, i209, i210, i211, i212, i213,
|
||||
i214, i215, i216, i217, i218, i219, i220, i221, i222, i223, i224, i225, i226, i227,
|
||||
i228, i229, i230, i231, i232, i233, i234, i235, i236, i237, i238, i239, i240, i241,
|
||||
i242, i243, i244, i245, i246, i247, i248, i249, i250, i251, i252, i253, i254, i255
|
||||
);
|
||||
|
||||
assign out
|
||||
= (sel==8'h00) ? i0 : (sel==8'h01) ? i1 : (sel==8'h02) ? i2 : (sel==8'h03) ? i3
|
||||
: (sel==8'h04) ? i4 : (sel==8'h05) ? i5 : (sel==8'h06) ? i6 : (sel==8'h07) ? i7
|
||||
: (sel==8'h08) ? i8 : (sel==8'h09) ? i9 : (sel==8'h0a) ? i10 : (sel==8'h0b) ? i11
|
||||
: (sel==8'h0c) ? i12 : (sel==8'h0d) ? i13 : (sel==8'h0e) ? i14 : (sel==8'h0f) ? i15
|
||||
: (sel==8'h10) ? i16 : (sel==8'h11) ? i17 : (sel==8'h12) ? i18 : (sel==8'h13) ? i19
|
||||
: (sel==8'h14) ? i20 : (sel==8'h15) ? i21 : (sel==8'h16) ? i22 : (sel==8'h17) ? i23
|
||||
: (sel==8'h18) ? i24 : (sel==8'h19) ? i25 : (sel==8'h1a) ? i26 : (sel==8'h1b) ? i27
|
||||
: (sel==8'h1c) ? i28 : (sel==8'h1d) ? i29 : (sel==8'h1e) ? i30 : (sel==8'h1f) ? i31
|
||||
: (sel==8'h20) ? i32 : (sel==8'h21) ? i33 : (sel==8'h22) ? i34 : (sel==8'h23) ? i35
|
||||
: (sel==8'h24) ? i36 : (sel==8'h25) ? i37 : (sel==8'h26) ? i38 : (sel==8'h27) ? i39
|
||||
: (sel==8'h28) ? i40 : (sel==8'h29) ? i41 : (sel==8'h2a) ? i42 : (sel==8'h2b) ? i43
|
||||
: (sel==8'h2c) ? i44 : (sel==8'h2d) ? i45 : (sel==8'h2e) ? i46 : (sel==8'h2f) ? i47
|
||||
: (sel==8'h30) ? i48 : (sel==8'h31) ? i49 : (sel==8'h32) ? i50 : (sel==8'h33) ? i51
|
||||
: (sel==8'h34) ? i52 : (sel==8'h35) ? i53 : (sel==8'h36) ? i54 : (sel==8'h37) ? i55
|
||||
: (sel==8'h38) ? i56 : (sel==8'h39) ? i57 : (sel==8'h3a) ? i58 : (sel==8'h3b) ? i59
|
||||
: (sel==8'h3c) ? i60 : (sel==8'h3d) ? i61 : (sel==8'h3e) ? i62 : (sel==8'h3f) ? i63
|
||||
: (sel==8'h40) ? i64 : (sel==8'h41) ? i65 : (sel==8'h42) ? i66 : (sel==8'h43) ? i67
|
||||
: (sel==8'h44) ? i68 : (sel==8'h45) ? i69 : (sel==8'h46) ? i70 : (sel==8'h47) ? i71
|
||||
: (sel==8'h48) ? i72 : (sel==8'h49) ? i73 : (sel==8'h4a) ? i74 : (sel==8'h4b) ? i75
|
||||
: (sel==8'h4c) ? i76 : (sel==8'h4d) ? i77 : (sel==8'h4e) ? i78 : (sel==8'h4f) ? i79
|
||||
: (sel==8'h50) ? i80 : (sel==8'h51) ? i81 : (sel==8'h52) ? i82 : (sel==8'h53) ? i83
|
||||
: (sel==8'h54) ? i84 : (sel==8'h55) ? i85 : (sel==8'h56) ? i86 : (sel==8'h57) ? i87
|
||||
: (sel==8'h58) ? i88 : (sel==8'h59) ? i89 : (sel==8'h5a) ? i90 : (sel==8'h5b) ? i91
|
||||
: (sel==8'h5c) ? i92 : (sel==8'h5d) ? i93 : (sel==8'h5e) ? i94 : (sel==8'h5f) ? i95
|
||||
: (sel==8'h60) ? i96 : (sel==8'h61) ? i97 : (sel==8'h62) ? i98 : (sel==8'h63) ? i99
|
||||
: (sel==8'h64) ? i100 : (sel==8'h65) ? i101 : (sel==8'h66) ? i102 : (sel==8'h67) ? i103
|
||||
: (sel==8'h68) ? i104 : (sel==8'h69) ? i105 : (sel==8'h6a) ? i106 : (sel==8'h6b) ? i107
|
||||
: (sel==8'h6c) ? i108 : (sel==8'h6d) ? i109 : (sel==8'h6e) ? i110 : (sel==8'h6f) ? i111
|
||||
: (sel==8'h70) ? i112 : (sel==8'h71) ? i113 : (sel==8'h72) ? i114 : (sel==8'h73) ? i115
|
||||
: (sel==8'h74) ? i116 : (sel==8'h75) ? i117 : (sel==8'h76) ? i118 : (sel==8'h77) ? i119
|
||||
: (sel==8'h78) ? i120 : (sel==8'h79) ? i121 : (sel==8'h7a) ? i122 : (sel==8'h7b) ? i123
|
||||
: (sel==8'h7c) ? i124 : (sel==8'h7d) ? i125 : (sel==8'h7e) ? i126 : (sel==8'h7f) ? i127
|
||||
: (sel==8'h80) ? i128 : (sel==8'h81) ? i129 : (sel==8'h82) ? i130 : (sel==8'h83) ? i131
|
||||
: (sel==8'h84) ? i132 : (sel==8'h85) ? i133 : (sel==8'h86) ? i134 : (sel==8'h87) ? i135
|
||||
: (sel==8'h88) ? i136 : (sel==8'h89) ? i137 : (sel==8'h8a) ? i138 : (sel==8'h8b) ? i139
|
||||
: (sel==8'h8c) ? i140 : (sel==8'h8d) ? i141 : (sel==8'h8e) ? i142 : (sel==8'h8f) ? i143
|
||||
: (sel==8'h90) ? i144 : (sel==8'h91) ? i145 : (sel==8'h92) ? i146 : (sel==8'h93) ? i147
|
||||
: (sel==8'h94) ? i148 : (sel==8'h95) ? i149 : (sel==8'h96) ? i150 : (sel==8'h98) ? i151
|
||||
: (sel==8'h99) ? i152 : (sel==8'h9a) ? i153 : (sel==8'h9b) ? i154 : (sel==8'h9c) ? i155
|
||||
: (sel==8'h9d) ? i156 : (sel==8'h9e) ? i157 : (sel==8'h9f) ? i158 : (sel==8'ha0) ? i159
|
||||
: (sel==8'ha1) ? i160 : (sel==8'ha2) ? i161 : (sel==8'ha3) ? i162 : (sel==8'ha4) ? i163
|
||||
: (sel==8'ha5) ? i164 : (sel==8'ha6) ? i165 : (sel==8'ha7) ? i166 : (sel==8'ha8) ? i167
|
||||
: (sel==8'ha9) ? i168 : (sel==8'haa) ? i169 : (sel==8'hab) ? i170 : (sel==8'hac) ? i171
|
||||
: (sel==8'had) ? i172 : (sel==8'hae) ? i173 : (sel==8'haf) ? i174 : (sel==8'hb0) ? i175
|
||||
: (sel==8'hb1) ? i176 : (sel==8'hb2) ? i177 : (sel==8'hb3) ? i178 : (sel==8'hb4) ? i179
|
||||
: (sel==8'hb5) ? i180 : (sel==8'hb6) ? i181 : (sel==8'hb7) ? i182 : (sel==8'hb8) ? i183
|
||||
: (sel==8'hb9) ? i184 : (sel==8'hba) ? i185 : (sel==8'hbb) ? i186 : (sel==8'hbc) ? i187
|
||||
: (sel==8'hbd) ? i188 : (sel==8'hbe) ? i189 : (sel==8'hbf) ? i190 : (sel==8'hc0) ? i191
|
||||
: (sel==8'hc1) ? i192 : (sel==8'hc2) ? i193 : (sel==8'hc3) ? i194 : (sel==8'hc4) ? i195
|
||||
: (sel==8'hc5) ? i196 : (sel==8'hc6) ? i197 : (sel==8'hc7) ? i198 : (sel==8'hc8) ? i199
|
||||
: (sel==8'hc9) ? i200 : (sel==8'hca) ? i201 : (sel==8'hcb) ? i202 : (sel==8'hcc) ? i203
|
||||
: (sel==8'hcd) ? i204 : (sel==8'hce) ? i205 : (sel==8'hcf) ? i206 : (sel==8'hd0) ? i207
|
||||
: (sel==8'hd1) ? i208 : (sel==8'hd2) ? i209 : (sel==8'hd3) ? i210 : (sel==8'hd4) ? i211
|
||||
: (sel==8'hd5) ? i212 : (sel==8'hd6) ? i213 : (sel==8'hd7) ? i214 : (sel==8'hd8) ? i215
|
||||
: (sel==8'hd9) ? i216 : (sel==8'hda) ? i217 : (sel==8'hdb) ? i218 : (sel==8'hdc) ? i219
|
||||
: (sel==8'hdd) ? i220 : (sel==8'hde) ? i221 : (sel==8'hdf) ? i222 : (sel==8'he0) ? i223
|
||||
: (sel==8'he1) ? i224 : (sel==8'he2) ? i225 : (sel==8'he3) ? i226 : (sel==8'he4) ? i227
|
||||
: (sel==8'he5) ? i228 : (sel==8'he6) ? i229 : (sel==8'he7) ? i230 : (sel==8'he8) ? i231
|
||||
: (sel==8'he9) ? i232 : (sel==8'hea) ? i233 : (sel==8'heb) ? i234 : (sel==8'hec) ? i235
|
||||
: (sel==8'hed) ? i236 : (sel==8'hee) ? i237 : (sel==8'hef) ? i238 : (sel==8'hf0) ? i239
|
||||
: (sel==8'hf1) ? i240 : (sel==8'hf2) ? i241 : (sel==8'hf3) ? i242 : (sel==8'hf4) ? i243
|
||||
: (sel==8'hf5) ? i244 : (sel==8'hf6) ? i245 : (sel==8'hf7) ? i246 : (sel==8'hf8) ? i247
|
||||
: (sel==8'hf9) ? i248 : (sel==8'hfa) ? i249 : (sel==8'hfb) ? i250 : (sel==8'hfc) ? i251
|
||||
: (sel==8'hfd) ? i252 : (sel==8'hfe) ? i253 : (sel==8'hff) ? i254 : i255;
|
||||
|
||||
endmodule
|
||||
@@ -16,7 +16,7 @@ execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
file_grep ($Last_Self->{coverage_filename}, qr/t=>'psl_cover',o=>'cover',c=>2\);/);
|
||||
file_grep ($Last_Self->{coverage_filename}, qr/,o=>'cover'.*,c=>2\);/);
|
||||
file_grep ($Last_Self->{coverage_filename}, qr/DefaultClock.*,c=>1\);/);
|
||||
file_grep ($Last_Self->{coverage_filename}, qr/ToggleLogIf.*,c=>9\);/);
|
||||
|
||||
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
Executable
+25
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/perl
|
||||
if (!$::Driver) { use FindBin; exec("./driver.pl", @ARGV, $0); die; }
|
||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
|
||||
compile (
|
||||
# Access is so we can dump waves
|
||||
v_flags2 => [$Last_Self->{v3}?'-trace':' +access+rwc'],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
if ($Last_Self->{v3}) {
|
||||
file_grep ("obj_dir/$Last_Self->{name}_simx.vcd", qr/\$enddefinitions/x);
|
||||
my $sig = quotemeta("bra[ket]slash/dash-colon:9");
|
||||
file_grep ("obj_dir/$Last_Self->{name}_simx.vcd", qr/$sig/);
|
||||
}
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
@@ -0,0 +1,59 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2005 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Outputs
|
||||
\escaped_normal , double__underscore, \9num , \bra[ket]slash/dash-colon:9 ,
|
||||
// Inputs
|
||||
clk
|
||||
);
|
||||
|
||||
input clk;
|
||||
|
||||
integer cyc; initial cyc=1;
|
||||
|
||||
output \escaped_normal ;
|
||||
wire \escaped_normal = cyc[0];
|
||||
|
||||
output double__underscore ;
|
||||
wire double__underscore = cyc[0];
|
||||
|
||||
// C doesn't allow leading non-alpha, so must escape
|
||||
output \9num ;
|
||||
wire \9num = cyc[0];
|
||||
|
||||
output \bra[ket]slash/dash-colon:9 ;
|
||||
wire \bra[ket]slash/dash-colon:9 = cyc[0];
|
||||
|
||||
wire \check_alias = cyc[0];
|
||||
wire \check:alias = cyc[0];
|
||||
wire \check;alias = !cyc[0];
|
||||
|
||||
`ifndef verilator
|
||||
initial begin
|
||||
$dumpfile("obj_dir/t_var_escape_dump.vcd");
|
||||
$dumpvars( 0, t );
|
||||
$dumpon;
|
||||
end
|
||||
`endif
|
||||
|
||||
always @ (posedge clk) begin
|
||||
cyc <= cyc + 1;
|
||||
if (escaped_normal != cyc[0]) $stop;
|
||||
if (\escaped_normal != cyc[0]) $stop;
|
||||
if (double__underscore != cyc[0]) $stop;
|
||||
if (\9num != cyc[0]) $stop;
|
||||
if (\bra[ket]slash/dash-colon:9 != cyc[0]) $stop;
|
||||
if (\check_alias != cyc[0]) $stop;
|
||||
if (\check:alias != cyc[0]) $stop;
|
||||
if (\check;alias != !cyc[0]) $stop;
|
||||
|
||||
if (cyc==10) begin
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -3,6 +3,9 @@
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003 by Wilson Snyder.
|
||||
|
||||
// Also check that SystemC is ordering properly
|
||||
// verilator lint_on IMPERFECTSCH
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Inputs
|
||||
clk
|
||||
|
||||
+2
-2
@@ -51,10 +51,10 @@ int sc_main(int argc, char* argv[]) {
|
||||
sc_signal<bool> reset_l;
|
||||
sc_signal<bool> passed;
|
||||
sc_signal<uint32_t> in_small;
|
||||
sc_signal<sc_bv<40> > in_quad;
|
||||
sc_signal<uint64_t> in_quad;
|
||||
sc_signal<sc_bv<70> > in_wide;
|
||||
sc_signal<uint32_t> out_small;
|
||||
sc_signal<sc_bv<40> > out_quad;
|
||||
sc_signal<uint64_t> out_quad;
|
||||
sc_signal<sc_bv<70> > out_wide;
|
||||
|
||||
//==========
|
||||
|
||||
@@ -17,6 +17,8 @@ default: test
|
||||
VERILATOR_ROOT := $(shell pwd)/..
|
||||
export VERILATOR_ROOT
|
||||
|
||||
VERILATOR_NCVERILOG ?= ncverilog
|
||||
|
||||
# Pick up PERL and other variable settings
|
||||
include $(VERILATOR_ROOT)/include/verilated.mk
|
||||
|
||||
@@ -93,7 +95,7 @@ nonc:
|
||||
nc: nc_passed.log
|
||||
|
||||
nc_passed.log: vgen.v sim_main.v
|
||||
ncverilog +licqueue +define+ncverilog=1 -q vgen.v sim_main.v
|
||||
$(VERILATOR_NCVERILOG) +licqueue +define+ncverilog=1 -q vgen.v sim_main.v
|
||||
-rm -f nc_passed.log
|
||||
grep -q Finished ncverilog.log && grep Finished ncverilog.log > nc_passed.log
|
||||
|
||||
|
||||
Reference in New Issue
Block a user