Internals: Detab and fix spacing style issues in tests and scripts. No functional change.

This commit is contained in:
Wilson Snyder 2019-05-07 22:34:09 -04:00
parent 37c8cc82b2
commit f818ddc71c
77 changed files with 3109 additions and 3102 deletions

View File

@ -58,17 +58,17 @@ foreach my $sw (@ARGV) {
}
Getopt::Long::config("no_auto_abbrev","pass_through");
if (! GetOptions (
# Major operating modes
"help" => \&usage,
"debug:s" => \&debug,
# "version!" => \&version, # Also passthru'ed
# Switches
"gdb!" => \$opt_gdb,
"gdbbt!" => \$opt_gdbbt,
# Additional parameters
"<>" => sub {}, # Ignored
)) {
if (! GetOptions(
# Major operating modes
"help" => \&usage,
"debug:s" => \&debug,
# "version!" => \&version, # Also passthru'ed
# Switches
"gdb!" => \$opt_gdb,
"gdbbt!" => \$opt_gdbbt,
# Additional parameters
"<>" => sub {}, # Ignored
)) {
pod2usage(-exitstatus=>2, -verbose=>0);
}
@ -2082,7 +2082,7 @@ command line, or the link), you'd then:
#include "svdpi.h"
#include "Vour__Dpi.h"
int add (int a, int b) { return a+b; }
int add(int a, int b) { return a+b; }
=head2 DPI System Task/Functions
@ -2132,7 +2132,7 @@ respect to that top level module, then the scope could be set with
#include "svdpi.h"
...
svSetScope (svGetScopeFromName ("dut"));
svSetScope(svGetScopeFromName("dut"));
(Remember that Verilator adds a "V" to the top of the module hierarchy.)
@ -2146,7 +2146,7 @@ comments within the svdpi.h header for more information.
Verilator allows writing $display like functions using this syntax:
import "DPI-C" function void
\$my_display (input string formatted /*verilator sformat*/ );
\$my_display(input string formatted /*verilator sformat*/ );
The /*verilator sformat*/ indicates that this function accepts a $display
like format specifier followed by any number of arguments to satisfy the
@ -2254,7 +2254,7 @@ accesses the above signal "readme" would be:
#include "verilated_vpi.h" // Required to get definitions
vluint64_t main_time = 0; // See comments in first example
double sc_time_stamp () { return main_time; }
double sc_time_stamp() { return main_time; }
void read_and_check() {
vpiHandle vh1 = vpi_handle_by_name((PLI_BYTE8*)"TOP.our.readme", NULL);
@ -3416,7 +3416,7 @@ it's a bit slower than a non-delayed assignment.) Here's an example
always @ (posedge clk)
if (~reset_l) begin
for (i=0; i<`ARRAY_SIZE; i++) begin
array[i] = 0; // Non-delayed for verilator
array[i] = 0; // Non-delayed for verilator
end
This message is only seen on large or complicated loops because Verilator

View File

@ -19,8 +19,8 @@ require 5.006_001;
use warnings;
BEGIN {
if ($ENV{DIRPROJECT} && $ENV{DIRPROJECT_PERL_BOOT}) {
# Magic to allow author testing of perl packages in local directory
require $ENV{DIRPROJECT}."/".$ENV{DIRPROJECT_PERL_BOOT};
# Magic to allow author testing of perl packages in local directory
require $ENV{DIRPROJECT}."/".$ENV{DIRPROJECT_PERL_BOOT};
}
}
@ -56,12 +56,12 @@ foreach my $sw (@ARGV) {
Getopt::Long::config("no_auto_abbrev","pass_through");
if (! GetOptions (
# Major operating modes
"help" => \&usage,
"debug:s" => \&debug,
# "version!" => \&version, # Also passthru'ed
# Additional parameters
"<>" => sub {}, # Ignored
# Major operating modes
"help" => \&usage,
"debug:s" => \&debug,
# "version!" => \&version, # Also passthru'ed
# Additional parameters
"<>" => sub {}, # Ignored
)) {
pod2usage(-exitstatus=>2, -verbose=>0);
}
@ -90,25 +90,25 @@ sub verilator_coverage_bin {
my $bin = "";
# Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path
my $basename = ($ENV{VERILATOR_COVERAGE_BIN}
|| "verilator_coverage_bin_dbg");
|| "verilator_coverage_bin_dbg");
if (defined($ENV{VERILATOR_ROOT})) {
my $dir = $ENV{VERILATOR_ROOT};
my $dir = $ENV{VERILATOR_ROOT};
if (-x "$dir/bin/$basename"
|| -x "$dir/bin/$basename.exe") { # From a "make install" into VERILATOR_ROOT
$bin = "$dir/bin/$basename";
} else {
$bin = "$dir/$basename"; # From pointing to kit directory
}
$bin = "$dir/bin/$basename";
} else {
$bin = "$dir/$basename"; # From pointing to kit directory
}
} else {
if (-x "$RealBin/$basename"
|| -x "$RealBin/$basename.exe") {
$bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed
} else {
$bin = $basename; # Find in PATH
}
# Note we don't look under bin/$basename which would be right if running
# in the kit dir. Running that would likely break, since
# VERILATOR_ROOT wouldn't be set and Verilator won't find internal files.
$bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed
} else {
$bin = $basename; # Find in PATH
}
# Note we don't look under bin/$basename which would be right if running
# in the kit dir. Running that would likely break, since
# VERILATOR_ROOT wouldn't be set and Verilator won't find internal files.
}
return $bin;
}
@ -125,23 +125,23 @@ sub run {
system($command);
my $status = $?;
if ($status) {
if ($! =~ /no such file or directory/i) {
warn "%Error: verilator_coverage: Misinstalled, or VERILATOR_ROOT might need to be in environment\n";
}
if ($Debug) { # For easy rerunning
warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n";
warn "%Error: $command\n";
}
if ($status & 127) {
if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV
warn "%Error: Verilator_coverage internal fault, sorry.\n" if !$Debug;
} elsif (($status & 127) == 6) { # SIGABRT
warn "%Error: Verilator_coverage aborted.\n" if !$Debug;
} else {
warn "%Error: Verilator_coverage threw signal $status.\n" if !$Debug;
}
}
die "%Error: Command Failed $command\n";
if ($! =~ /no such file or directory/i) {
warn "%Error: verilator_coverage: Misinstalled, or VERILATOR_ROOT might need to be in environment\n";
}
if ($Debug) { # For easy rerunning
warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n";
warn "%Error: $command\n";
}
if ($status & 127) {
if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV
warn "%Error: Verilator_coverage internal fault, sorry.\n" if !$Debug;
} elsif (($status & 127) == 6) { # SIGABRT
warn "%Error: Verilator_coverage aborted.\n" if !$Debug;
} else {
warn "%Error: Verilator_coverage threw signal $status.\n" if !$Debug;
}
}
die "%Error: Command Failed $command\n";
}
}

View File

@ -38,11 +38,11 @@ my $Opt_Lineno = 1;
autoflush STDOUT 1;
autoflush STDERR 1;
Getopt::Long::config("no_auto_abbrev");
if (! GetOptions (
"help" => \&usage,
"debug" => \&debug,
"<>" => \&parameter,
"lineno!" => \$Opt_Lineno,
if (! GetOptions(
"help" => \&usage,
"debug" => \&debug,
"<>" => \&parameter,
"lineno!" => \$Opt_Lineno,
)) {
die "%Error: Bad usage, try 'verilator_difftree --help'\n";
}
@ -68,22 +68,22 @@ sub diff_dir {
my %files;
foreach my $fn (glob("$a/*.tree")) {
(my $base = $fn) =~ s!.*/!!;
$files{$base}{a} = $fn;
(my $base = $fn) =~ s!.*/!!;
$files{$base}{a} = $fn;
}
foreach my $fn (glob("$b/*.tree")) {
(my $base = $fn) =~ s!.*/!!;
$files{$base}{b} = $fn;
(my $base = $fn) =~ s!.*/!!;
$files{$base}{b} = $fn;
}
my $any;
foreach my $base (sort (keys %files)) {
my $a = $files{$base}{a};
my $b = $files{$base}{b};
next if !$a || !$b;
print "="x70,"\n";
print "= $a <-> $b\n";
diff_file($a,$b);
$any = 1;
my $a = $files{$base}{a};
my $b = $files{$base}{b};
next if !$a || !$b;
print "="x70,"\n";
print "= $a <-> $b\n";
diff_file($a,$b);
$any = 1;
}
$any or warn("%Warning: No .tree files found that have similar base names:\n "
.join("\n ", sort keys %files),"\n");
@ -101,7 +101,7 @@ sub diff_file {
my $vera = version_from($a);
my $verb = version_from($b);
my $verCvt = (($vera < 0x3900 && $verb >= 0x3900)
|| ($vera >= 0x3900 && $verb < 0x3900));
|| ($vera >= 0x3900 && $verb < 0x3900));
filter($a, $tmp_a, $verCvt);
filter($b, $tmp_b, $verCvt);
@ -115,8 +115,8 @@ sub version_from {
# Return dump format
my $f1 = IO::File->new ($fn) or die "%Error: $! $fn,";
while (defined (my $line=$f1->getline())) {
last if $. > 10;
return hex $1 if $line =~ /\(format (0x[0-9.]+)\)/;
last if $. > 10;
return hex $1 if $line =~ /\(format (0x[0-9.]+)\)/;
}
return 1.0;
}
@ -130,36 +130,36 @@ sub filter {
my $f2 = IO::File->new ($fn2,"w") or die "%Error: $! $fn2,";
while (defined (my $line=$f1->getline())) {
same_line:
next if $line =~ / This=/;
$line =~ s/0x[a-f0-9]+/0x/g;
$line =~ s/<e[0-9]+\#?>/<e>/g;
$line =~ s/{[a-z]*\d+}/{}/g if !$Opt_Lineno;
if ($verCvt) {
next if $line =~ /^ NETLIST/;
$line =~ s!\@dt=0x\(G?/?([^)]+)\)!$1!g; # NEW: @dt -> OLD: non @dt format
# # Below Ver1_Non_Dtyped may replace above further
if ($line =~ /: ([A-Z]+) /) {
my $type = $1;
next if $type =~ 'DTYPE';
if ($type eq 'TYPETABLE' || $type eq 'RANGE') {
$line =~ /^(\s+\S+:) /; my $prefix = $1;
while (defined ($line=$f1->getline())) {
next if $line =~ /^\s+[a-z]/; # Table body
next if $line =~ /^${prefix}[0-9]:/;
goto same_line;
}
next;
}
if ($Ver1_Non_Dtyped{$type}) {
$line =~ s! w[0-9]+!!g;
}
}
$line =~ s!\@dt=0$!NoW!g; # NEW: dt=null -> common format
$line =~ s!\@dt=0 !NoW !g; # NEW: dt=null -> common format
$line =~ s! s?w0$! NoW!g; # OLD: no width -> common format
$line =~ s! s?w0 ! NoW !g; # OLD: no width -> common format
}
print $f2 $line;
next if $line =~ / This=/;
$line =~ s/0x[a-f0-9]+/0x/g;
$line =~ s/<e[0-9]+\#?>/<e>/g;
$line =~ s/{[a-z]*\d+}/{}/g if !$Opt_Lineno;
if ($verCvt) {
next if $line =~ /^ NETLIST/;
$line =~ s!\@dt=0x\(G?/?([^)]+)\)!$1!g; # NEW: @dt -> OLD: non @dt format
# # Below Ver1_Non_Dtyped may replace above further
if ($line =~ /: ([A-Z]+) /) {
my $type = $1;
next if $type =~ 'DTYPE';
if ($type eq 'TYPETABLE' || $type eq 'RANGE') {
$line =~ /^(\s+\S+:) /; my $prefix = $1;
while (defined ($line=$f1->getline())) {
next if $line =~ /^\s+[a-z]/; # Table body
next if $line =~ /^${prefix}[0-9]:/;
goto same_line;
}
next;
}
if ($Ver1_Non_Dtyped{$type}) {
$line =~ s! w[0-9]+!!g;
}
}
$line =~ s!\@dt=0$!NoW!g; # NEW: dt=null -> common format
$line =~ s!\@dt=0 !NoW !g; # NEW: dt=null -> common format
$line =~ s! s?w0$! NoW!g; # OLD: no width -> common format
$line =~ s! s?w0 ! NoW !g; # OLD: no width -> common format
}
print $f2 $line;
}
$f1->close;
$f2->close;
@ -179,11 +179,11 @@ sub debug {
sub parameter {
my $param = shift;
if (!defined $Opt_A) {
$Opt_A = $param;
$Opt_A = $param;
} elsif (!defined $Opt_B) {
$Opt_B = $param;
$Opt_B = $param;
} else {
die "%Error: Unknown parameter: $param\n";
die "%Error: Unknown parameter: $param\n";
}
}

View File

@ -24,11 +24,11 @@ my $Opt_File;
autoflush STDOUT 1;
autoflush STDERR 1;
Getopt::Long::config("no_auto_abbrev");
if (! GetOptions (
"help" => \&usage,
"debug" => \&debug,
"<>" => \&parameter,
)) {
if (! GetOptions(
"help" => \&usage,
"debug" => \&debug,
"<>" => \&parameter,
)) {
die "%Error: Bad usage, try 'verilator_profcfunc --help'\n";
}
@ -50,9 +50,9 @@ sub debug {
sub parameter {
my $param = shift;
if (!defined $Opt_File) {
$Opt_File = $param;
$Opt_File = $param;
} else {
die "%Error: Unknown parameter: $param\n";
die "%Error: Unknown parameter: $param\n";
}
}
@ -66,13 +66,13 @@ sub profcfunc {
my %funcs;
while (defined (my $line=$fh->getline())) {
# %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;
$funcs{$func}{calls} += $calls;
}
# %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;
$funcs{$func}{calls} += $calls;
}
# Older gprofs have no call column for single-call functions
# %time cumesec selfsec {stuff} name
elsif ($line =~ /^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+[^a-zA-Z_]*([a-zA-Z_].*)$/) {
@ -88,10 +88,10 @@ sub profcfunc {
my %pointer_mods;
my %verilated_mods;
foreach my $func (keys %funcs) {
if ($func =~ /(.*)::_eval\(([a-zA-Z_0-9]+__Syms).*\)$/) {
$verilated_mods{$1} = qr/^$1/;
$pointer_mods{$2} = $1;
}
if ($func =~ /(.*)::_eval\(([a-zA-Z_0-9]+__Syms).*\)$/) {
$verilated_mods{$1} = qr/^$1/;
$pointer_mods{$2} = $1;
}
}
#print Dumper(\%pointer_mods, \%verilated_mods);
@ -99,72 +99,72 @@ sub profcfunc {
my %vfuncs;
my %groups;
foreach my $func (keys %funcs) {
my $pct = $funcs{$func}{pct};
my $vfunc = $func;
my $design;
my $pct = $funcs{$func}{pct};
my $vfunc = $func;
my $design;
if ($func =~ /\(([a-zA-Z_0-9]+__Syms)/) {
$design = $pointer_mods{$1};
}
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;
}
}
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]+)__l?([0-9]+)\(/) {
$vfunc = sprintf("VBlock %s:%d", $1, $2);
$groups{type}{"Verilog Blocks under $design"} += $pct;
$groups{design}{$design} += $pct;
$groups{module}{$1} += $pct;
} else {
if ($design) {
$vfunc = sprintf("VCommon %s", $func);
$groups{type}{"Common code under $design"} += $pct;
$groups{design}{$design} += $pct;
$groups{module}{$design." common code"} += $pct;
} elsif ($func =~ /^VL_[A-Z0-9_]+/
|| $func =~ /^_?vl_[a-zA-Z0-9_]+/
|| $func =~ /^verilated/i) {
$vfunc = sprintf("VLib %s", $func);
$groups{type}{'VLib'} += $pct;
$groups{design}{'VLib'} += $pct;
$groups{module}{'VLib'} += $pct;
} elsif ($func =~ /^_mcount_private/) {
$vfunc = sprintf("Prof %s", $func);
$groups{type}{'Prof'} += $pct;
$groups{design}{'Prof'} += $pct;
$groups{module}{'Prof'} += $pct;
} else {
$vfunc = sprintf("C++ %s", $func);
$groups{type}{'C++'} += $pct;
$groups{design}{'C++'} += $pct;
$groups{module}{'C++'} += $pct;
}
}
$vfuncs{$vfunc} = $funcs{$func};
if ($vfunc =~ /__PROF__([a-zA-Z_0-9]+)__l?([0-9]+)\(/) {
$vfunc = sprintf("VBlock %s:%d", $1, $2);
$groups{type}{"Verilog Blocks under $design"} += $pct;
$groups{design}{$design} += $pct;
$groups{module}{$1} += $pct;
} else {
if ($design) {
$vfunc = sprintf("VCommon %s", $func);
$groups{type}{"Common code under $design"} += $pct;
$groups{design}{$design} += $pct;
$groups{module}{$design." common code"} += $pct;
} elsif ($func =~ /^VL_[A-Z0-9_]+/
|| $func =~ /^_?vl_[a-zA-Z0-9_]+/
|| $func =~ /^verilated/i) {
$vfunc = sprintf("VLib %s", $func);
$groups{type}{'VLib'} += $pct;
$groups{design}{'VLib'} += $pct;
$groups{module}{'VLib'} += $pct;
} elsif ($func =~ /^_mcount_private/) {
$vfunc = sprintf("Prof %s", $func);
$groups{type}{'Prof'} += $pct;
$groups{design}{'Prof'} += $pct;
$groups{module}{'Prof'} += $pct;
} else {
$vfunc = sprintf("C++ %s", $func);
$groups{type}{'C++'} += $pct;
$groups{design}{'C++'} += $pct;
$groups{module}{'C++'} += $pct;
}
}
$vfuncs{$vfunc} = $funcs{$func};
}
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;
}
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("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");
@ -181,14 +181,14 @@ sub profcfunc {
my $cume = 0;
foreach my $func (sort {$vfuncs{$b}{sec} <=> $vfuncs{$a}{sec}
|| $a cmp $b}
(keys %vfuncs)) {
$cume += $vfuncs{$func}{sec};
printf +("%6.2f %9.2f %8.2f %8d %s\n",
$vfuncs{$func}{pct},
$cume, $vfuncs{$func}{sec},
$vfuncs{$func}{calls},
$func);
|| $a cmp $b}
(keys %vfuncs)) {
$cume += $vfuncs{$func}{sec};
printf +("%6.2f %9.2f %8.2f %8d %s\n",
$vfuncs{$func}{pct},
$cume, $vfuncs{$func}{sec},
$vfuncs{$func}{calls},
$func);
}
}

View File

@ -41,7 +41,7 @@ int main(int argc, char** argv, char** env) {
Verilated::commandArgs(argc, argv);
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
Vtop* top = new Vtop; // Or use a const unique_ptr, or the VL_UNIQUE_PTR wrapper
Vtop* top = new Vtop; // Or use a const unique_ptr, or the VL_UNIQUE_PTR wrapper
#if VM_TRACE
// If verilator was invoked with --trace argument,
@ -94,14 +94,14 @@ int main(int argc, char** argv, char** env) {
#if VM_TRACE
// Dump trace data for this cycle
if (tfp) tfp->dump (main_time);
if (tfp) tfp->dump(main_time);
#endif
// Read outputs
VL_PRINTF ("[%" VL_PRI64 "d] clk=%x rstl=%x iquad=%" VL_PRI64 "x"
" -> oquad=%" VL_PRI64"x owide=%x_%08x_%08x\n",
main_time, top->clk, top->reset_l, top->in_quad,
top->out_quad, top->out_wide[2], top->out_wide[1], top->out_wide[0]);
VL_PRINTF("[%" VL_PRI64 "d] clk=%x rstl=%x iquad=%" VL_PRI64 "x"
" -> oquad=%" VL_PRI64"x owide=%x_%08x_%08x\n",
main_time, top->clk, top->reset_l, top->in_quad,
top->out_quad, top->out_wide[2], top->out_wide[1], top->out_wide[0]);
}
// Final model cleanup

View File

@ -115,9 +115,9 @@ int sc_main(int argc, char* argv[]) {
// Apply inputs
if (VL_TIME_Q() > 1 && VL_TIME_Q() < 10) {
reset_l = !1; // Assert reset
reset_l = !1; // Assert reset
} else if (VL_TIME_Q() > 1) {
reset_l = !0; // Deassert reset
reset_l = !0; // Deassert reset
}
// Simulate 1ns

View File

@ -49,7 +49,7 @@ module sub
// An example assertion
always_ff @ (posedge clk) begin
AssertionExample: assert (!reset_l || count_c<100);
AssertionExample: assert(!reset_l || count_c<100);
end
// And example coverage analysis

View File

@ -23,9 +23,9 @@ our $Debug;
our $Opt_Unsup;
if (! GetOptions (
#"help" => \&usage,
"debug" => sub { $Debug = 1; },
"unsup!" => \$Opt_Unsup, # Ignore unsupported
#"help" => \&usage,
"debug" => sub { $Debug = 1; },
"unsup!" => \$Opt_Unsup, # Ignore unsupported
)) {
die "usage();"
}
@ -59,24 +59,24 @@ sub prep {
my $rule = "";
my $skip = 1;
while (defined(my $line = $fh->getline)) {
if ($skip == 1) {
next if $line !~ /%token/;
$skip = 2;
}
if ($skip == 1) {
next if $line !~ /%token/;
$skip = 2;
}
if ($Opt_Unsup) {
$line =~ s!//UNSUP!|!g;
$line =~ s!(\s+)\|(\s+)!$1$2!g; # As "UNSUP" often replaces "|"
}
if ($Opt_Unsup) {
$line =~ s!//UNSUP!|!g;
$line =~ s!(\s+)\|(\s+)!$1$2!g; # As "UNSUP" often replaces "|"
}
# %type<foo>
$line =~ s/^(%\S+)<(\S+)>/$1/;
# rule<foo>
$line =~ s/^([a-zA-Z0-9_]+)<\S+>:/$1:/;
# Productions
$line =~ s/[ \t]{[^}]*?}/\t{}/g;
# %type<foo>
$line =~ s/^(%\S+)<(\S+)>/$1/;
# rule<foo>
$line =~ s/^([a-zA-Z0-9_]+)<\S+>:/$1:/;
# Productions
$line =~ s/[ \t]{[^}]*?}/\t{}/g;
$fho->print($line);
$fho->print($line);
}
}

View File

@ -32,27 +32,27 @@ foreach my $line (<STDIN>) {
$line =~ s!\s+! !g;
next if $line eq '';
if ($line =~ m!^\%\%!) {
$body++;
$body++;
} elsif ($body == 1) {
$rule .= $line;
if ($line =~ m!^\s*;\s*$!) {
#print "Rule: $rule\n";
($rule =~ /^([a-zA-Z0-9_]+)(<\S+>)?:(.*)$/) or die "%Error: No rule name: $1\n";
my $rulename = $1; my $preaction = $3;
$declared{$rulename} = $lineno;
$preaction =~ s/\{[^\}]*\}/ /g;
#print "RULEN $rulename PA $preaction\n" if $Debug;
$rule = '';
foreach my $ref (split /\s+/, $preaction) {
next if $ref !~ /^[a-zA-Z]/;
next if $ref eq $rulename;
if (!$used{$ref} && $declared{$ref}) {
print " %Warning: $lineno: $ref used by $rulename after declaration\n";
}
$used{$ref} = $lineno;
print " ref $ref\n" if $Debug;
}
}
$rule .= $line;
if ($line =~ m!^\s*;\s*$!) {
#print "Rule: $rule\n";
($rule =~ /^([a-zA-Z0-9_]+)(<\S+>)?:(.*)$/) or die "%Error: No rule name: $1\n";
my $rulename = $1; my $preaction = $3;
$declared{$rulename} = $lineno;
$preaction =~ s/\{[^\}]*\}/ /g;
#print "RULEN $rulename PA $preaction\n" if $Debug;
$rule = '';
foreach my $ref (split /\s+/, $preaction) {
next if $ref !~ /^[a-zA-Z]/;
next if $ref eq $rulename;
if (!$used{$ref} && $declared{$ref}) {
print " %Warning: $lineno: $ref used by $rulename after declaration\n";
}
$used{$ref} = $lineno;
print " ref $ref\n" if $Debug;
}
}
}
}

View File

@ -24,11 +24,11 @@ $Debug = 0;
my $opt_filename;
autoflush STDOUT 1;
autoflush STDERR 1;
if (! GetOptions (
"help" => \&usage,
"debug" => \&debug,
"<>" => \&parameter,
)) {
if (! GetOptions(
"help" => \&usage,
"debug" => \&debug,
"<>" => \&parameter,
)) {
usage();
}
@ -49,9 +49,9 @@ sub debug {
sub parameter {
my $param = shift;
if (!$opt_filename) {
$opt_filename = $param;
$opt_filename = $param;
} else {
die "%Error: Unknown parameter: $param\n";
die "%Error: Unknown parameter: $param\n";
}
}
@ -64,30 +64,30 @@ sub dotread {
my $header = 1;
my $vnum = 0;
while (defined (my $line = $fh->getline)) {
if ($line =~ /^\t([a-zA-Z0-9_]+)\t(.*)$/) {
next if $1 eq 'nTITLE';
$header = 0;
$Vertexes{$1} = {num => $vnum++,
line => $line,
name => $1,};
}
elsif ($line =~ /^\t([a-zA-Z0-9_]+)\s+->\s+([a-zA-Z0-9_]+)\s+(.*)$/) {
my $from=$1; my $to=$2;
my $weight = 1; $weight = $1 if $line =~ /weight=(\d+)/;
my $cutable = undef; $cutable = $1 if $line =~ /style=(\S+)/;
my $edge = {num => $vnum++,
line => $line,
weight => $weight,
cutable => $cutable,
from => $from,
to => $to,};
push @Edges, $edge;
$Edges{$from}{$to} = $edge;
}
elsif ($header) {
push @Header, $line;
print "IGNORE: $line";
}
if ($line =~ /^\t([a-zA-Z0-9_]+)\t(.*)$/) {
next if $1 eq 'nTITLE';
$header = 0;
$Vertexes{$1} = {num => $vnum++,
line => $line,
name => $1,};
}
elsif ($line =~ /^\t([a-zA-Z0-9_]+)\s+->\s+([a-zA-Z0-9_]+)\s+(.*)$/) {
my $from=$1; my $to=$2;
my $weight = 1; $weight = $1 if $line =~ /weight=(\d+)/;
my $cutable = undef; $cutable = $1 if $line =~ /style=(\S+)/;
my $edge = {num => $vnum++,
line => $line,
weight => $weight,
cutable => $cutable,
from => $from,
to => $to,};
push @Edges, $edge;
$Edges{$from}{$to} = $edge;
}
elsif ($header) {
push @Header, $line;
print "IGNORE: $line";
}
}
}
@ -100,14 +100,14 @@ sub cwrite {
$fh->print("void V3GraphTestImport::dotImport() {\n");
$fh->print(" DfaGraph* gp = &m_graph;\n");
foreach my $ver (sort {$a->{num} <=> $b->{num}} (values %Vertexes)) {
$fh->printf(" V3GraphTestVertex* %s = new V3GraphTestVertex(gp, \"%s\"); if (%s) {}\n",
$ver->{name}, $ver->{name}, $ver->{name});
$fh->printf(" V3GraphTestVertex* %s = new V3GraphTestVertex(gp, \"%s\"); if (%s) {}\n",
$ver->{name}, $ver->{name}, $ver->{name});
}
$fh->print("\n");
foreach my $edge (@Edges) {
$fh->printf(" new V3GraphEdge(gp, %s, %s, %s, %s);\n",
$edge->{from}, $edge->{to},
$edge->{weight}, $edge->{cutable}?"true":"false");
$fh->printf(" new V3GraphEdge(gp, %s, %s, %s, %s);\n",
$edge->{from}, $edge->{to},
$edge->{weight}, $edge->{cutable}?"true":"false");
}
$fh->print("}\n");
}

View File

@ -26,12 +26,12 @@ my $opt_filename;
my $opt_circle;
autoflush STDOUT 1;
autoflush STDERR 1;
if (! GetOptions (
"help" => \&usage,
"debug" => \&debug,
"<>" => \&parameter,
"circle=s" => \$opt_circle,
)) {
if (! GetOptions(
"help" => \&usage,
"debug" => \&debug,
"<>" => \&parameter,
"circle=s" => \$opt_circle,
)) {
usage();
}
@ -54,9 +54,9 @@ sub debug {
sub parameter {
my $param = shift;
if (!$opt_filename) {
$opt_filename = $param;
$opt_filename = $param;
} else {
die "%Error: Unknown parameter: $param\n";
die "%Error: Unknown parameter: $param\n";
}
}
@ -68,16 +68,16 @@ sub dotread {
my $fh = IO::File->new($filename) or die "%Error: $! $filename,";
my $header = 1;
while (defined (my $line = $fh->getline)) {
if ($line =~ /^\t([a-zA-Z0-9_]+)\t(.*)$/) {
$header = 0;
$Vertexes{$1} = $2;
}
elsif ($line =~ /^\t([a-zA-Z0-9_]+)\s+->\s+([a-zA-Z0-9_]+)\s+(.*)$/) {
$Edges{$1}{$2} = $3;
}
elsif ($header) {
push @Header, $line;
}
if ($line =~ /^\t([a-zA-Z0-9_]+)\t(.*)$/) {
$header = 0;
$Vertexes{$1} = $2;
}
elsif ($line =~ /^\t([a-zA-Z0-9_]+)\s+->\s+([a-zA-Z0-9_]+)\s+(.*)$/) {
$Edges{$1}{$2} = $3;
}
elsif ($header) {
push @Header, $line;
}
}
}
@ -85,12 +85,12 @@ sub dotread {
sub simplify {
foreach my $ver (sort (keys %Vertexes)) {
$Vertexes{$ver} = _simplify($Vertexes{$ver});
$Vertexes{$ver} = _simplify($Vertexes{$ver});
}
foreach my $v1 (sort (keys %Edges)) {
foreach my $v2 (sort (keys %{$Edges{$v1}})) {
$Edges{$v1}{$v2} = _simplify($Edges{$v1}{$v2});
}
foreach my $v2 (sort (keys %{$Edges{$v1}})) {
$Edges{$v1}{$v2} = _simplify($Edges{$v1}{$v2});
}
}
}
@ -103,15 +103,15 @@ sub _simplify {
sub dotwrite {
foreach my $line (@Header) {
print "$line";
print "$line";
}
foreach my $ver (sort (keys %Vertexes)) {
print "\t$ver\t$Vertexes{$ver}\n";
print "\t$ver\t$Vertexes{$ver}\n";
}
foreach my $v1 (sort (keys %Edges)) {
foreach my $v2 (sort (keys %{$Edges{$v1}})) {
print "\t$v1 -> $v2\t$Edges{$v1}{$v2}\n";
}
foreach my $v2 (sort (keys %{$Edges{$v1}})) {
print "\t$v1 -> $v2\t$Edges{$v1}{$v2}\n";
}
}
print "}\n";
}
@ -125,15 +125,15 @@ sub circle {
_circle_recurse($node, 1);
foreach my $ver (keys %Vertexes) {
if (!$User{$ver}) {
delete $Vertexes{$ver};
delete $Edges{$ver};
}
if (!$User{$ver}) {
delete $Vertexes{$ver};
delete $Edges{$ver};
}
}
foreach my $v1 (sort (keys %Edges)) {
foreach my $v2 (sort (keys %{$Edges{$v1}})) {
if (!$Vertexes{$v2}) { delete $Edges{$v1}{$v2}; }
}
foreach my $v2 (sort (keys %{$Edges{$v1}})) {
if (!$Vertexes{$v2}) { delete $Edges{$v1}{$v2}; }
}
}
}
@ -148,7 +148,7 @@ sub _circle_recurse {
$User2{$node} = 1;
my $r = 0;
foreach my $v2 (keys %{$Edges{$node}}) {
$r |= _circle_recurse($v2,$level++)||0;
$r |= _circle_recurse($v2,$level++)||0;
}
$User{$node} = 1 if $r;
$User2{$node} = 2;

View File

@ -18,11 +18,11 @@ our $Opt_Jobs = calc_jobs();
autoflush STDOUT 1;
autoflush STDERR 1;
Getopt::Long::config("no_auto_abbrev");
if (! GetOptions (
"debug" => sub { $Debug = 1; },
"<>" => sub { die "%Error: Unknown parameter: $_[0]\n"; },
"stage=i" => \$Opt_Stage,
"j=i" => \$Opt_Jobs,
if (! GetOptions(
"debug" => sub { $Debug = 1; },
"<>" => sub { die "%Error: Unknown parameter: $_[0]\n"; },
"stage=i" => \$Opt_Stage,
"j=i" => \$Opt_Jobs,
)) {
die "%Error: Bad usage, try 'install_test --help'\n";
}
@ -46,51 +46,51 @@ sub test {
my $testdirn= $srcdir."/test_regress/obj_dir/install_test_testn";
if ($Opt_Stage <= 0) {
run("/bin/rm -rf $blddir");
run("/bin/mkdir -p $blddir");
run("cd $blddir && $srcdir/configure --prefix $prefix");
run("cd $blddir && make -j $Opt_Jobs");
run("/bin/rm -rf $blddir");
run("/bin/mkdir -p $blddir");
run("cd $blddir && $srcdir/configure --prefix $prefix");
run("cd $blddir && make -j $Opt_Jobs");
}
# Install it under the prefix
if ($Opt_Stage <= 1) {
run("/bin/rm -rf $prefix");
run("/bin/mkdir -p $prefix");
run("cd $blddir && make install");
run("test -e $prefix/share/man/man1/verilator.1");
run("/bin/rm -rf $prefix");
run("/bin/mkdir -p $prefix");
run("cd $blddir && make install");
run("test -e $prefix/share/man/man1/verilator.1");
run("test -e $prefix/share/verilator/examples/tracing_c/Makefile");
run("test -e $prefix/share/verilator/include/verilated.h");
run("test -e $prefix/bin/verilator");
run("test -e $prefix/bin/verilator_bin");
run("test -e $prefix/bin/verilator_bin_dbg");
run("test -e $prefix/share/verilator/include/verilated.h");
run("test -e $prefix/bin/verilator");
run("test -e $prefix/bin/verilator_bin");
run("test -e $prefix/bin/verilator_bin_dbg");
run("test -e $prefix/bin/verilator_gantt");
run("test -e $prefix/bin/verilator_profcfunc");
run("test -e $prefix/bin/verilator_profcfunc");
}
# Run a test using just the path
if ($Opt_Stage <= 2) {
my $dir = $testdirp;
run("/bin/rm -rf $dir");
run("/bin/mkdir -p $dir");
my $bin1 = $prefix."/bin";
my $bin2 = $prefix."/share/bin";
write_verilog($dir);
run("cd $dir && PATH=$bin1:$bin2:\$PATH verilator --cc foo.v --exe foo.cpp");
run("cd $dir/obj_dir && PATH=$bin1:$bin2:\$PATH make -f Vfoo.mk");
run("cd $dir && PATH=$bin1:$bin2:\$PATH obj_dir/Vfoo");
my $dir = $testdirp;
run("/bin/rm -rf $dir");
run("/bin/mkdir -p $dir");
my $bin1 = $prefix."/bin";
my $bin2 = $prefix."/share/bin";
write_verilog($dir);
run("cd $dir && PATH=$bin1:$bin2:\$PATH verilator --cc foo.v --exe foo.cpp");
run("cd $dir/obj_dir && PATH=$bin1:$bin2:\$PATH make -f Vfoo.mk");
run("cd $dir && PATH=$bin1:$bin2:\$PATH obj_dir/Vfoo");
}
# Run a test using exact path to binary
if ($Opt_Stage <= 3) {
my $dir = $testdirn;
run("/bin/rm -rf $dir");
run("/bin/mkdir -p $dir");
write_verilog($dir);
my $bin1 = $prefix."/bin";
my $bin2 = $prefix."/share/bin";
run("cd $dir && $bin1/verilator --cc foo.v --exe foo.cpp");
run("cd $dir/obj_dir && make -f Vfoo.mk");
run("cd $dir/obj_dir && ./Vfoo");
my $dir = $testdirn;
run("/bin/rm -rf $dir");
run("/bin/mkdir -p $dir");
write_verilog($dir);
my $bin1 = $prefix."/bin";
my $bin2 = $prefix."/share/bin";
run("cd $dir && $bin1/verilator --cc foo.v --exe foo.cpp");
run("cd $dir/obj_dir && make -f Vfoo.mk");
run("cd $dir/obj_dir && ./Vfoo");
}
if ($Opt_Stage <= 9) {
@ -102,29 +102,29 @@ sub write_verilog {
my $dir = shift;
IO::File->new(">$dir/foo.v")->print('module t; initial begin $display("HELLO WORLD"); $finish; end endmodule'."\n");
my $fh = IO::File->new(">$dir/foo.cpp");
$fh->print('#include "Vfoo.h"' ,"\n");
$fh->print('unsigned int main_time = 0;' ,"\n");
$fh->print('#include "Vfoo.h"' ,"\n");
$fh->print('unsigned int main_time = 0;' ,"\n");
$fh->print('double sc_time_stamp() {' ,"\n");
$fh->print(' return main_time;' ,"\n");
$fh->print('}' ,"\n");
$fh->print('int main() {' ,"\n");
$fh->print(' Vfoo *top = new Vfoo;' ,"\n");
$fh->print(' return main_time;' ,"\n");
$fh->print('}' ,"\n");
$fh->print('int main() {' ,"\n");
$fh->print(' Vfoo *top = new Vfoo;' ,"\n");
$fh->print(' while (!Verilated::gotFinish()) {',"\n");
$fh->print(' top->eval();' ,"\n");
$fh->print(' main_time++;' ,"\n");
$fh->print(' }' ,"\n");
$fh->print(' top->final();' ,"\n");
$fh->print('}' ,"\n");
$fh->print(' }' ,"\n");
$fh->print(' top->final();' ,"\n");
$fh->print('}' ,"\n");
}
sub cleanenv {
foreach my $var (keys %ENV) {
if ($var eq "VERILATOR_ROOT"
if ($var eq "VERILATOR_ROOT"
|| $var eq "VERILATOR_INCLUDE"
|| $var eq "VERILATOR_NO_OPT_BUILD") {
print "unset $var # Was '$ENV{$var}'\n";
delete $ENV{$var}
}
print "unset $var # Was '$ENV{$var}'\n";
delete $ENV{$var}
}
}
}
@ -132,8 +132,8 @@ sub cleanenv {
sub calc_jobs {
my $ok = eval "
use Unix::Processors;
return Unix::Processors->new->max_online;
use Unix::Processors;
return Unix::Processors->new->max_online;
";
$ok && !$@ or return 1;
print "driver.pl: Found $ok cores, using -j ",$ok+1,"\n" if $Debug;

View File

@ -23,11 +23,11 @@ $Debug = 0;
my $opt_filename;
autoflush STDOUT 1;
autoflush STDERR 1;
if (! GetOptions (
"help" => \&usage,
"debug" => \&debug,
"<>" => \&parameter,
)) {
if (! GetOptions(
"help" => \&usage,
"debug" => \&debug,
"<>" => \&parameter,
)) {
usage();
}
@ -51,9 +51,9 @@ sub debug {
sub parameter {
my $param = shift;
if (!$opt_filename) {
$opt_filename = $param;
$opt_filename = $param;
} else {
die "%Error: Unknown parameter: $param\n";
die "%Error: Unknown parameter: $param\n";
}
}
@ -64,45 +64,45 @@ sub vread {
my $fh = IO::File->new($filename) or die "%Error: $! $filename,";
my $lasthier="";
$Tree = {
op => 'NETLIST',
t => [[],[],[],[],[],],
op => 'NETLIST',
t => [[],[],[],[],[],],
};
my @stack;
$stack[1] = $Tree;
while (defined (my $line = $fh->getline)) {
if ($line =~ /^\s+(\S+):\s+(\S+)\s+0x\S+\s+{(\d+)}\s+w(\d+)\s+(.*)$/) {
my $hier = $1;
my $op = $2;
my $lineno = $3;
my $width = $4;
my $etc = $5;
if ($line =~ /^\s+(\S+):\s+(\S+)\s+0x\S+\s+{(\d+)}\s+w(\d+)\s+(.*)$/) {
my $hier = $1;
my $op = $2;
my $lineno = $3;
my $width = $4;
my $etc = $5;
$etc =~ s/__DOT__/./g;
$etc =~ s/__PVT__//g;
$etc =~ s/__DOT__/./g;
$etc =~ s/__PVT__//g;
my $self = {
op => $op,
#width => $width,
#lineno => $lineno,
#line => $line,
etc => $etc,
args => [split(/[ \t]+/,$etc)],
t => [[],[],[],[],[],],
};
my $self = {
op => $op,
#width => $width,
#lineno => $lineno,
#line => $line,
etc => $etc,
args => [split(/[ \t]+/,$etc)],
t => [[],[],[],[],[],],
};
my @hiers = (1,split(/:/,$hier));
my $depth = $#hiers+1;
my $newchild = $hiers[$#hiers];
my @hiers = (1,split(/:/,$hier));
my $depth = $#hiers+1;
my $newchild = $hiers[$#hiers];
#print "DD $depth $newchild $op\n";
#print "DD $depth $newchild $op\n";
push @{$stack[$depth-1]->{t}[$newchild]}, $self;
$stack[$depth] = $self;
push @{$stack[$depth-1]->{t}[$newchild]}, $self;
$stack[$depth] = $self;
$lasthier = $hier;
#print " $lasthier\n";
#print Dumper($Tree);
}
$lasthier = $hier;
#print " $lasthier\n";
#print Dumper($Tree);
}
}
}
@ -168,125 +168,125 @@ sub nl { p "\n"," "x$Indent; }
sub gentree {
%OpMap = (
'NULLNODE' => sub { "" },
'NETLIST' => sub { nl;t1;t2;t3;t4;t5; },
'ACTIVE' => sub { p "always_act @(";t1;p ") begin";indentInc;nl;t2;t3;t4;t5;indentDec;p "end";nl; },
'ADD' => sub { p1;p " + ";p2; },
'ALWAYS' => sub { p "always @(";t1;p ") begin";indentInc;nl;t2;t3;t4;t5;indentDec;p "end";nl; },
'ALWAYSPOST' => sub { p "ALWAYSPOST what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'AND' => sub { p1;p " & ";p2; },
'ARRAYSEL' => sub { t1;p "[";t2;p "]"; },
'ASSIGN' => sub { t2;p " = ";t1;p ";";nl; },
'ASSIGNDLY' => sub { t2;p " <= ";t1;p ";";nl; },
'ASSIGNPOST' => sub { p "ASSIGNPOST what{";t1;p " = ";t2;p ";";nl; },
'ASSIGNPRE' => sub { p "ASSIGNPRE what{";t1;p " = ";t2;p ";";nl; },
'ASSIGNW' => sub { p "assign ";t2;p " = ";t1;p ";";nl; },
'ATTROF' => sub { p "ATTROF what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'BEGIN' => sub { p "begin";indentInc;nl;t1;t2;t3;t4;t5;indentDec;p "end";nl; },
'BITSEL' => sub { t1;local $Avoid_Hex=1; p "[";t2;p "]"; },
'CASE' => sub { p "CASE what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CASEITEM' => sub { p "CASEITEM what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CAST' => sub { p "CAST what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CCALL' => sub { p "CCALL what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CELL' => sub { a1;p " ";a7;p " (/*CELL*/);"; nl; },
'CFUNC' => sub { p "CFUNC what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CHANGEDET' => sub { p "CHANGEDET what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CINCLUDE' => sub { p "CINCLUDE what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'COMMENT' => sub { p "//COMMENT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl;nl; },
'CONCAT' => sub { p "{";p1;p ",";p2;p "}"; },
'CONDITIONAL' => sub { p1;p " ? ";p2;p " : ";p3; },
'CONST' => sub { p_const(); },
'COVER' => sub { p "COVER what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CRETURN' => sub { p "CRETURN what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CSTMT' => sub { p "CSTMT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'DEFPARAM' => sub { p "defparam ";p1;p " = ";p2;p ";";nl; },
'DISPLAY' => sub { p '$write("';p1;p "\",";p2;p3;p4;p5;p ");";nl; },
'DIV' => sub { p1;p " / ";p2; },
'EQ' => sub { p1;p " == ";p2; },
'EQCASE' => sub { p1;p " === ";p2; },
'EXTEND' => sub { t1; },
'EXTRACT' => sub { t1;local $Avoid_Hex=1; p "[";t2;p ":";t3;p "]"; },
'FINISH' => sub { p '$finish;';nl },
'FOR' => sub { p "for (";p1;p ",";p2;p ",";p3;p ") begin";indentInc;nl;p4;p5;indentDec;p "end";nl; },
'FUNC' => sub { p "FUNC what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'FUNCREF' => sub { p "FUNCREF what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'GT' => sub { p1;p " > ";p2; },
'GTE' => sub { p1;p " >= ";p2; },
'IF' => sub { p "if (";p1;p ") begin";indentInc;nl;t2;indentDec;if (exists3) {p "end else begin";indentInc;nl;t3;indentDec;} p "end"; nl; },
'INITARRAY' => sub { p "INITARRAY what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'INITIAL' => sub { p "initial begin";indentInc;nl;t1;t2;t3;t4;t5;indentDec;p "end";nl; },
'LOGAND' => sub { p1;p " && ";p2; },
'LOGNOT' => sub { p1;p " || ";p2; },
'LOGOR' => sub { p "!";p1; },
'LT' => sub { p1;p " < ";p2; },
'LTE' => sub { p1;p " <= ";p2; },
'MODDIV' => sub { p1;p " % ";p2; },
'MODULE' => sub { p "module ";a1;p " (/*AUTOARG*/);";indentInc;nl;t1;t2;t3;t4;t5;indentDec;nl;p "endmodule";nl; },
'MUL' => sub { p1;p " * ";p2; },
'NEQ' => sub { p1;p " != ";p2; },
'NEQCASE' => sub { p1;p " !== ";p2; },
'NOT' => sub { p " ~";p1; },
'OR' => sub { p1;p " | ";p2; },
'PIN' => sub { p ";p ";p1;p " (";p2;p "),";nl; },
'PORT' => sub { p ""; },
'PRAGMA' => sub { p "PRAGMA what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'RAND' => sub { p '$rand'; },
'RANGE' => sub { t1; local $Avoid_Hex=1; p "[";t2;p ":";t3;p "]"; },
'REDAND' => sub { p "&(";p1;p ")"; },
'REDOR' => sub { p "|(";p1;p ")"; },
'REDXNOR' => sub { p "~|(";p1;p ")"; },
'REDXOR' => sub { p "~^(";p1;p ")"; },
'REPLICATE' => sub { p "{";p1;p "{";p2;p "}}"; },
'SCCTOR' => sub { p "SCCTOR what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'SCHDR' => sub { p "SCHDR what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'SCIMP' => sub { p "SCIMP what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'SCINT' => sub { p "SCINT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'SCOPE' => sub { t1;t2;t3;t4;t5; },
'SENITEM' => sub { a1;p " ";t1; },
'SENTREE' => sub { t1;t2;t3;t4;t5; },
'SHIFTL' => sub { p1;p " << ";p2; },
'SHIFTR' => sub { p1;p " >> ";p2; },
'STOP' => sub { p '$stop;';nl; },
'SUB' => sub { p1;p " - ";p2; },
'TASK' => sub { p "TASK what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'TASKREF' => sub { p "TASKREF what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'TEXT' => sub { p "TEXT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'TIME' => sub { p '$time'; },
'TOPSCOPE' => sub { t1;t2;t3;t4;t5; },
'TRACE' => sub { p "TRACE what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'UCFUNC' => sub { p '$c(';p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p ")"; },
'UCSTMT' => sub { p '$c(';p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p ");";nl; },
'NEGATE' => sub { p " -";p1; },
'VAR' => sub { p_var(); },
'VARPIN' => sub { p "VARPIN what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'VARREF' => sub { a1; },
'VARSCOPE' => sub { },
'WHILE' => sub { t1; p "while (";t2;p ") begin";indentInc;nl;t3;t4;indentDec;p "end";nl; },
'WORDSEL' => sub { p1;p "[";p2;p ":";p3;p "]"; },
'XNOR' => sub { p1;p " ~^ ";p2; },
'XOR' => sub { p1;p " ^";p2; },
'NULLNODE' => sub { "" },
'NETLIST' => sub { nl;t1;t2;t3;t4;t5; },
'ACTIVE' => sub { p "always_act @(";t1;p ") begin";indentInc;nl;t2;t3;t4;t5;indentDec;p "end";nl; },
'ADD' => sub { p1;p " + ";p2; },
'ALWAYS' => sub { p "always @(";t1;p ") begin";indentInc;nl;t2;t3;t4;t5;indentDec;p "end";nl; },
'ALWAYSPOST' => sub { p "ALWAYSPOST what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'AND' => sub { p1;p " & ";p2; },
'ARRAYSEL' => sub { t1;p "[";t2;p "]"; },
'ASSIGN' => sub { t2;p " = ";t1;p ";";nl; },
'ASSIGNDLY' => sub { t2;p " <= ";t1;p ";";nl; },
'ASSIGNPOST' => sub { p "ASSIGNPOST what{";t1;p " = ";t2;p ";";nl; },
'ASSIGNPRE' => sub { p "ASSIGNPRE what{";t1;p " = ";t2;p ";";nl; },
'ASSIGNW' => sub { p "assign ";t2;p " = ";t1;p ";";nl; },
'ATTROF' => sub { p "ATTROF what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'BEGIN' => sub { p "begin";indentInc;nl;t1;t2;t3;t4;t5;indentDec;p "end";nl; },
'BITSEL' => sub { t1;local $Avoid_Hex=1; p "[";t2;p "]"; },
'CASE' => sub { p "CASE what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CASEITEM' => sub { p "CASEITEM what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CAST' => sub { p "CAST what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CCALL' => sub { p "CCALL what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CELL' => sub { a1;p " ";a7;p " (/*CELL*/);"; nl; },
'CFUNC' => sub { p "CFUNC what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CHANGEDET' => sub { p "CHANGEDET what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CINCLUDE' => sub { p "CINCLUDE what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'COMMENT' => sub { p "//COMMENT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl;nl; },
'CONCAT' => sub { p "{";p1;p ",";p2;p "}"; },
'CONDITIONAL' => sub { p1;p " ? ";p2;p " : ";p3; },
'CONST' => sub { p_const(); },
'COVER' => sub { p "COVER what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CRETURN' => sub { p "CRETURN what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'CSTMT' => sub { p "CSTMT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'DEFPARAM' => sub { p "defparam ";p1;p " = ";p2;p ";";nl; },
'DISPLAY' => sub { p '$write("';p1;p "\",";p2;p3;p4;p5;p ");";nl; },
'DIV' => sub { p1;p " / ";p2; },
'EQ' => sub { p1;p " == ";p2; },
'EQCASE' => sub { p1;p " === ";p2; },
'EXTEND' => sub { t1; },
'EXTRACT' => sub { t1;local $Avoid_Hex=1; p "[";t2;p ":";t3;p "]"; },
'FINISH' => sub { p '$finish;';nl },
'FOR' => sub { p "for (";p1;p ",";p2;p ",";p3;p ") begin";indentInc;nl;p4;p5;indentDec;p "end";nl; },
'FUNC' => sub { p "FUNC what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'FUNCREF' => sub { p "FUNCREF what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'GT' => sub { p1;p " > ";p2; },
'GTE' => sub { p1;p " >= ";p2; },
'IF' => sub { p "if (";p1;p ") begin";indentInc;nl;t2;indentDec;if (exists3) {p "end else begin";indentInc;nl;t3;indentDec;} p "end"; nl; },
'INITARRAY' => sub { p "INITARRAY what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'INITIAL' => sub { p "initial begin";indentInc;nl;t1;t2;t3;t4;t5;indentDec;p "end";nl; },
'LOGAND' => sub { p1;p " && ";p2; },
'LOGNOT' => sub { p1;p " || ";p2; },
'LOGOR' => sub { p "!";p1; },
'LT' => sub { p1;p " < ";p2; },
'LTE' => sub { p1;p " <= ";p2; },
'MODDIV' => sub { p1;p " % ";p2; },
'MODULE' => sub { p "module ";a1;p " (/*AUTOARG*/);";indentInc;nl;t1;t2;t3;t4;t5;indentDec;nl;p "endmodule";nl; },
'MUL' => sub { p1;p " * ";p2; },
'NEQ' => sub { p1;p " != ";p2; },
'NEQCASE' => sub { p1;p " !== ";p2; },
'NOT' => sub { p " ~";p1; },
'OR' => sub { p1;p " | ";p2; },
'PIN' => sub { p ";p ";p1;p " (";p2;p "),";nl; },
'PORT' => sub { p ""; },
'PRAGMA' => sub { p "PRAGMA what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'RAND' => sub { p '$rand'; },
'RANGE' => sub { t1; local $Avoid_Hex=1; p "[";t2;p ":";t3;p "]"; },
'REDAND' => sub { p "&(";p1;p ")"; },
'REDOR' => sub { p "|(";p1;p ")"; },
'REDXNOR' => sub { p "~|(";p1;p ")"; },
'REDXOR' => sub { p "~^(";p1;p ")"; },
'REPLICATE' => sub { p "{";p1;p "{";p2;p "}}"; },
'SCCTOR' => sub { p "SCCTOR what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'SCHDR' => sub { p "SCHDR what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'SCIMP' => sub { p "SCIMP what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'SCINT' => sub { p "SCINT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'SCOPE' => sub { t1;t2;t3;t4;t5; },
'SENITEM' => sub { a1;p " ";t1; },
'SENTREE' => sub { t1;t2;t3;t4;t5; },
'SHIFTL' => sub { p1;p " << ";p2; },
'SHIFTR' => sub { p1;p " >> ";p2; },
'STOP' => sub { p '$stop;';nl; },
'SUB' => sub { p1;p " - ";p2; },
'TASK' => sub { p "TASK what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'TASKREF' => sub { p "TASKREF what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'TEXT' => sub { p "TEXT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'TIME' => sub { p '$time'; },
'TOPSCOPE' => sub { t1;t2;t3;t4;t5; },
'TRACE' => sub { p "TRACE what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'UCFUNC' => sub { p '$c(';p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p ")"; },
'UCSTMT' => sub { p '$c(';p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p ");";nl; },
'NEGATE' => sub { p " -";p1; },
'VAR' => sub { p_var(); },
'VARPIN' => sub { p "VARPIN what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
'VARREF' => sub { a1; },
'VARSCOPE' => sub { },
'WHILE' => sub { t1; p "while (";t2;p ") begin";indentInc;nl;t3;t4;indentDec;p "end";nl; },
'WORDSEL' => sub { p1;p "[";p2;p ":";p3;p "]"; },
'XNOR' => sub { p1;p " ~^ ";p2; },
'XOR' => sub { p1;p " ^";p2; },
);
}
sub p_var {
my $self = $Code_Self;
if ($self->{etc} =~ /\[I\]/) {
print "input";
print "input";
} elsif ($self->{etc} =~ /\[O\]/) {
print "output";
print "output";
} else {
print "reg";
print "reg";
}
p "\t";
{
local $Avoid_Hex=1;
t1;
local $Avoid_Hex=1;
t1;
}
p "\t";
a1;
if (exists2()) {
p " = ";
t2;
p " = ";
t2;
}
p ";";
nl;
@ -295,10 +295,10 @@ sub p_var {
sub p_const {
my $v = $Code_Self->{args}[0];
if ($v =~ /\?32\?h(.*)$/
|| ($Avoid_Hex && $v =~ /^[0-9?]*h(.*)$/)) {
print hex $1;
|| ($Avoid_Hex && $v =~ /^[0-9?]*h(.*)$/)) {
print hex $1;
} else {
print $v;
print $v;
}
}

View File

@ -7,7 +7,7 @@ use Getopt::Long;
use IO::File;
use Pod::Usage;
use strict;
use vars qw ($Debug @Types %Classes %Children %ClassRefs %Stages);
use vars qw($Debug @Types %Classes %Children %ClassRefs %Stages);
#======================================================================
# main
@ -17,8 +17,8 @@ my $opt_classes;
my $opt_report;
my @Opt_Cpt;
my @Opt_I;
Getopt::Long::config ("pass_through", "no_auto_abbrev");
if (! GetOptions (
Getopt::Long::config("pass_through", "no_auto_abbrev");
if (! GetOptions(
"help" => \&usage,
"debug" => sub { $Debug = 1; },
"classes!" => \$opt_classes,
@ -51,17 +51,17 @@ foreach my $cpt (@Opt_Cpt) {
sub usage {
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
exit (1);
exit(1);
}
sub parameter {
my $param = shift;
if ($param =~ /^-+I(\S+)/) {
push @Opt_I, $1;
push @Opt_I, $1;
} elsif ($param =~ s/\.cpp$//) {
push @Opt_Cpt, $param;
push @Opt_Cpt, $param;
} else {
die "%Error: Unknown parameter: $param,";
die "%Error: Unknown parameter: $param,";
}
}
@ -72,21 +72,21 @@ sub read_types {
my $fh = IO::File->new($filename) or die "%Error: $! $filename,";
while (defined (my $line = $fh->getline())) {
$line =~ s/\/\/.*$//;
next if $line =~ /^\s*$/;
if ($line =~ /^\s*(class|struct)\s*(\S+)/) {
my $class = $2;
my $inh = "";
$inh = $1 if ($line =~ /:\s*public\s+(\S+)/);
print "class $class : $inh\n" if $Debug;
$inh = "" if $class eq "AstNode";
if ($inh =~ /Ast/ || $class eq "AstNode") {
$class =~ s/^Ast//;
$inh =~ s/^Ast//;
$Classes{$class} = $inh;
$Children{$inh}{$class} = 1;
}
}
$line =~ s/\/\/.*$//;
next if $line =~ /^\s*$/;
if ($line =~ /^\s*(class|struct)\s*(\S+)/) {
my $class = $2;
my $inh = "";
$inh = $1 if ($line =~ /:\s*public\s+(\S+)/);
print "class $class : $inh\n" if $Debug;
$inh = "" if $class eq "AstNode";
if ($inh =~ /Ast/ || $class eq "AstNode") {
$class =~ s/^Ast//;
$inh =~ s/^Ast//;
$Classes{$class} = $inh;
$Children{$inh}{$class} = 1;
}
}
}
}
@ -96,14 +96,14 @@ sub read_stages {
my $fh = IO::File->new($filename) or die "%Error: $! $filename,";
my $n = 0;
while (defined (my $line = $fh->getline())) {
$line =~ s/\/\/.*$//;
next if $line =~ /^\s*$/;
if ($line =~ /^\s*([A-Za-z0-9]+)::/) {
my $stage = $1.".cpp";
if (!defined ($Stages{$stage})) {
$Stages{$stage} = $n++;
}
}
$line =~ s/\/\/.*$//;
next if $line =~ /^\s*$/;
if ($line =~ /^\s*([A-Za-z0-9]+)::/) {
my $stage = $1.".cpp";
if (!defined ($Stages{$stage})) {
$Stages{$stage} = $n++;
}
}
}
}
@ -111,17 +111,17 @@ sub read_refs {
my @filenames = @_;
foreach my $filename (@filenames) {
(my $basename = $filename) =~ s!.*/!!;
my $fh = IO::File->new($filename) or die "%Error: $! $filename,";
while (defined (my $line = $fh->getline())) {
$line =~ s/\/\/.*$//;
while ($line =~ /\bnew\s*(Ast[A-Za-z0-9_]+)/g) {
$ClassRefs{$1}{newed}{$basename} = 1;
}
while ($line =~ /\b(Ast[A-Za-z0-9_]+)/g) {
$ClassRefs{$1}{used}{$basename} = 1;
}
}
(my $basename = $filename) =~ s!.*/!!;
my $fh = IO::File->new($filename) or die "%Error: $! $filename,";
while (defined (my $line = $fh->getline())) {
$line =~ s/\/\/.*$//;
while ($line =~ /\bnew\s*(Ast[A-Za-z0-9_]+)/g) {
$ClassRefs{$1}{newed}{$basename} = 1;
}
while ($line =~ /\b(Ast[A-Za-z0-9_]+)/g) {
$ClassRefs{$1}{used}{$basename} = 1;
}
}
}
#use Data::Dumper;print Dumper(\%ClassRefs);
}
@ -142,8 +142,8 @@ sub subclasses_of {
my @cllist;
for (my $subclass = $::Classes{$type}; $subclass; ) {
push @cllist, $subclass;
$subclass = $::Classes{$subclass};
push @cllist, $subclass;
$subclass = $::Classes{$subclass};
}
return (reverse @cllist);
@ -156,10 +156,10 @@ sub children_of {
my @todo;
push @todo, $type;
while (my $subclass = shift @todo) {
foreach my $child (sort keys %{$::Children{$subclass}}) {
push @todo, $child;
push @cllist, $child;
}
foreach my $child (sort keys %{$::Children{$subclass}}) {
push @todo, $child;
push @cllist, $child;
}
}
return (@cllist);
@ -173,39 +173,39 @@ sub write_report {
$fh->print("Processing stages (approximate, based on order in Verilator.cpp):\n");
foreach my $class (sort {$Stages{$a} <=> $Stages{$b}} keys %Stages) {
$fh->print("\t$class\n");
$fh->print("\t$class\n");
}
$fh->print("\nProcessing stages (approximate, based on order in Verilator.cpp):\n");
foreach my $type (sort (keys %Classes)) {
printf $fh " class %-20s\n", "Ast${type}";
$fh->print("\tparent:\t");
foreach my $subclass (subclasses_of($type)) {
next if $subclass eq 'Node';
printf $fh "Ast%-12s ",$subclass;
}
printf $fh "\n";
$fh->print("\tchilds:\t");
foreach my $subclass (children_of($type)) {
next if $subclass eq 'Node';
printf $fh "Ast%-12s ",$subclass;
}
printf $fh "\n";
if (my $refs = $ClassRefs{"Ast${type}"}) {
$fh->print("\tnewed:\t");
foreach my $stage (sort {($Stages{$a}||-1) <=> ($Stages{$b}||-1)}
keys %{$refs->{newed}}) {
$fh->print($stage." ");
}
$fh->print("\n");
$fh->print("\tused:\t");
foreach my $stage (sort {($Stages{$a}||-1) <=> ($Stages{$b}||-1)}
keys %{$refs->{used}}) {
$fh->print($stage." ");
}
$fh->print("\n");
}
$fh->print("\n");
printf $fh " class %-20s\n", "Ast${type}";
$fh->print("\tparent:\t");
foreach my $subclass (subclasses_of($type)) {
next if $subclass eq 'Node';
printf $fh "Ast%-12s ",$subclass;
}
printf $fh "\n";
$fh->print("\tchilds:\t");
foreach my $subclass (children_of($type)) {
next if $subclass eq 'Node';
printf $fh "Ast%-12s ",$subclass;
}
printf $fh "\n";
if (my $refs = $ClassRefs{"Ast${type}"}) {
$fh->print("\tnewed:\t");
foreach my $stage (sort {($Stages{$a}||-1) <=> ($Stages{$b}||-1)}
keys %{$refs->{newed}}) {
$fh->print($stage." ");
}
$fh->print("\n");
$fh->print("\tused:\t");
foreach my $stage (sort {($Stages{$a}||-1) <=> ($Stages{$b}||-1)}
keys %{$refs->{used}}) {
$fh->print($stage." ");
}
$fh->print("\n");
}
$fh->print("\n");
}
}
@ -213,11 +213,11 @@ sub write_classes {
my $fh = open_file(@_);
printf $fh "class AstNode;\n";
foreach my $type (sort (keys %Classes)) {
printf $fh "class %-20s // ", "Ast${type};";
foreach my $subclass (subclasses_of($type)) {
printf $fh "Ast%-12s ",$subclass;
}
printf $fh "\n";
printf $fh "class %-20s // ", "Ast${type};";
foreach my $subclass (subclasses_of($type)) {
printf $fh "Ast%-12s ",$subclass;
}
printf $fh "\n";
}
$fh->close();
}
@ -225,12 +225,12 @@ sub write_classes {
sub write_visitor {
my $fh = open_file(@_);
foreach my $type (sort (keys %Classes)) {
my $base = $Classes{$type};
if ($base) {
printf $fh " virtual void visit(Ast${type}* nodep) { visit((Ast${base}*)(nodep)); }\n";
} else {
printf $fh " virtual void visit(Ast${type}*) = 0;\n";
}
my $base = $Classes{$type};
if ($base) {
printf $fh " virtual void visit(Ast${type}* nodep) { visit((Ast${base}*)(nodep)); }\n";
} else {
printf $fh " virtual void visit(Ast${type}*) = 0;\n";
}
}
$fh->close();
}
@ -262,11 +262,11 @@ sub write_impl {
print $fh "\n";
print $fh " // These for use by VN_IS macro only\n";
foreach my $type (sort (keys %Classes)) {
if (children_of($type)) {
if (children_of($type)) {
print $fh "inline bool AstNode::privateIs",$type,"(const AstNode* nodep) { return (bool)(dynamic_cast<const Ast",$type,"*>(nodep)); }\n";
} else {
} else {
print $fh "inline bool AstNode::privateIs",$type,"(const AstNode* nodep) { return nodep && nodep->type() == AstType::at",$type,"; }\n";
}
}
}
foreach my $type (sort (keys %Classes)) {
@ -285,16 +285,16 @@ sub write_types {
printf $fh " enum en {\n";
# Add "at" prefix to avoid conflicting with FOPEN and other macros in include files
foreach my $type (sort (keys %Classes)) {
next if $type =~ /^Node/;
print $fh "\tat",$type,",\n";
next if $type =~ /^Node/;
print $fh "\tat",$type,",\n";
}
printf $fh "\t_ENUM_END\n";
printf $fh " };\n";
printf $fh " const char* ascii() const {\n";
printf $fh " const char* const names[] = {\n";
foreach my $type (sort (keys %Classes)) {
next if $type =~ /^Node/;
print $fh "\t\"", uc $type, "\",\n";
next if $type =~ /^Node/;
print $fh "\t\"", uc $type, "\",\n";
}
printf $fh "\t\"_ENUM_END\"\n";
printf $fh " };\n";
@ -332,11 +332,11 @@ sub _output_line {
sub process {
my $self = {
in_filename => undef,
out_filename => undef,
out_lines => [],
out_linenum => 1,
@_,
in_filename => undef,
out_filename => undef,
out_lines => [],
out_linenum => 1,
@_,
};
bless $self, __PACKAGE__;
@ -346,25 +346,25 @@ sub process {
# Read the file and parse into list of functions that generate output
my $fhi = IO::File->new($self->{in_filename}) or die "%Error: $! $self->{in_filename},";
while (defined(my $line = $fhi->getline)) {
if (!$didln) {
$self->print("#line $. \"$self->{in_filename}\"\n");
$didln = 1;
}
if ($line =~ /^\s+(TREE.*)$/) {
my $func = $1;
$self->{in_linenum} = $.;
$self->print("//$line");
$self->output_func(sub{my $self=shift; $self->_output_line(); });
$self->tree_line ($func);
$didln = 0;
}
elsif ($line !~ /^\s*\/[\/\*]\s*TREE/
&& $line =~ /\s+TREE/) {
$self->error("Unknown astgen line: $line");
}
else {
$self->print($line);
}
if (!$didln) {
$self->print("#line $. \"$self->{in_filename}\"\n");
$didln = 1;
}
if ($line =~ /^\s+(TREE.*)$/) {
my $func = $1;
$self->{in_linenum} = $.;
$self->print("//$line");
$self->output_func(sub{my $self=shift; $self->_output_line(); });
$self->tree_line($func);
$didln = 0;
}
elsif ($line !~ /^\s*\/[\/\*]\s*TREE/
&& $line =~ /\s+TREE/) {
$self->error("Unknown astgen line: $line");
}
else {
$self->print($line);
}
}
$fhi->close;
@ -373,16 +373,16 @@ sub process {
my $fho = ::open_file($self->{out_filename});
my @togen = @{$self->{out_lines}};
foreach my $line (@togen) {
if (ref $line) {
$self->{out_lines} = [];
&$line($self);
} else {
$self->{out_lines} = [$line];
}
foreach my $out (@{$self->{out_lines}}) {
$self->{out_linenum}++ while ($out =~ /\n/smg);
print $fho $out;
}
if (ref $line) {
$self->{out_lines} = [];
&$line($self);
} else {
$self->{out_lines} = [$line];
}
foreach my $out (@{$self->{out_lines}}) {
$self->{out_linenum}++ while ($out =~ /\n/smg);
print $fho $out;
}
}
$fho->close;
}
@ -396,64 +396,64 @@ sub tree_line {
# doflag "S" indicates an op specifying short-circuiting for a type.
if ($func =~ /TREEOP(1?)([VCS]?)\s*\(\s* \"([^\"]*)\" \s*,\s* \"([^\"]*)\" \s*\)/sx) {
my $order = $1; my $doflag = $2; my $from = $3; my $to = $4;
#$self->print("// $from $to\n");
if (!$self->{did_out_tree}) {
$self->{did_out_tree} = 1;
$self->output_func(sub{ my $self=shift;
$self->tree_match();
$self->tree_base();
});
}
$from =~ /Ast([a-zA-Z0-9]+)\s*\{(.*)\}\s*$/
or $self->error("Can't parse from function: $func");
my $type = $1;
my $subnodes = $2;
(::subclasses_of($type)) or $self->error("Unknown AstNode type: $type: in $func");
my $order = $1; my $doflag = $2; my $from = $3; my $to = $4;
#$self->print("// $from $to\n");
if (!$self->{did_out_tree}) {
$self->{did_out_tree} = 1;
$self->output_func(sub{ my $self=shift;
$self->tree_match();
$self->tree_base();
});
}
$from =~ /Ast([a-zA-Z0-9]+)\s*\{(.*)\}\s*$/
or $self->error("Can't parse from function: $func");
my $type = $1;
my $subnodes = $2;
(::subclasses_of($type)) or $self->error("Unknown AstNode type: $type: in $func");
my $mif;
if ($doflag eq '') { $mif = "m_doNConst"; }
elsif ($doflag eq 'V') { $mif = "m_doV"; }
elsif ($doflag eq 'C') { $mif = ""; }
elsif ($doflag eq 'S') { $mif = "m_doNConst"; } # Not just for m_doGenerate
else { die; }
$subnodes =~ s/,,/__ESCAPEDCOMMA__/g;
foreach my $subnode (split /\s*,\s*/, $subnodes) {
$subnode =~ s/__ESCAPEDCOMMA__/,/g;
next if $subnode =~ /^\$([a-z0-9]+)$/gi; # "$lhs" is just a comment that this op has a lhs
$mif .= " && " if $mif;
my $subnodeif = $subnode;
my $mif;
if ($doflag eq '') { $mif = "m_doNConst"; }
elsif ($doflag eq 'V') { $mif = "m_doV"; }
elsif ($doflag eq 'C') { $mif = ""; }
elsif ($doflag eq 'S') { $mif = "m_doNConst"; } # Not just for m_doGenerate
else { die; }
$subnodes =~ s/,,/__ESCAPEDCOMMA__/g;
foreach my $subnode (split /\s*,\s*/, $subnodes) {
$subnode =~ s/__ESCAPEDCOMMA__/,/g;
next if $subnode =~ /^\$([a-z0-9]+)$/gi; # "$lhs" is just a comment that this op has a lhs
$mif .= " && " if $mif;
my $subnodeif = $subnode;
$subnodeif =~ s/\$([a-zA-Z0-9]+)\.cast([A-Z][A-Za-z0-9]+)$/VN_IS(nodep->$1(),$2)/g;
$subnodeif =~ s/\$([a-zA-Z0-9]+)\.([a-zA-Z0-9]+)$/nodep->$1()->$2()/g;
$subnodeif = add_nodep($subnodeif);
$mif .= $subnodeif;
}
$subnodeif =~ s/\$([a-zA-Z0-9]+)\.([a-zA-Z0-9]+)$/nodep->$1()->$2()/g;
$subnodeif = add_nodep($subnodeif);
$mif .= $subnodeif;
}
my $exec_func = treeop_exec_func($self, $to);
my $exec_func = treeop_exec_func($self, $to);
while ($exec_func =~ s/([-()a-zA-Z0-9_>]+)->cast([A-Z][A-Za-z0-9]+)\(\)/VN_CAST($1,$2)/) {}
$self->{treeop}{$type} ||= [];
my $n = $#{$self->{treeop}{$type}} + 1;
my $typefunc = {
order => $order,
comment => $func,
match_func => "match_${type}_${n}",
match_if => $mif,
exec_func => $exec_func,
uinfo_level => ($to =~ /^!/ ? 0:7),
short_circuit => ($doflag eq 'S'),
};
$self->{treeop}{$type} ||= [];
my $n = $#{$self->{treeop}{$type}} + 1;
my $typefunc = {
order => $order,
comment => $func,
match_func => "match_${type}_${n}",
match_if => $mif,
exec_func => $exec_func,
uinfo_level => ($to =~ /^!/ ? 0:7),
short_circuit => ($doflag eq 'S'),
};
($typefunc->{uinfo} = $func) =~ s/[ \t\"\{\}]+/ /g;
push @{$self->{treeop}{$type}}, $typefunc;
($typefunc->{uinfo} = $func) =~ s/[ \t\"\{\}]+/ /g;
push @{$self->{treeop}{$type}}, $typefunc;
}
elsif ($func =~ /TREE_SKIP_VISIT\s*\(\s* \"([^\"]*)\" \s*\)/sx) {
my $type = $1;
$self->{tree_skip_visit}{$type} = 1;
$::Classes{$type} or $self->error("Unknown node type: $type");
my $type = $1;
$self->{tree_skip_visit}{$type} = 1;
$::Classes{$type} or $self->error("Unknown node type: $type");
}
else {
$self->error("Unknown astgen op: $func");
$self->error("Unknown astgen op: $func");
}
}
@ -468,12 +468,12 @@ our $_Exec_Nsyms;
sub _exec_syms_recurse {
my $aref = shift;
foreach my $sym (@{$aref}) {
if (ref $sym) { _exec_syms_recurse($sym); }
elsif ($sym =~ /^\$.*/) {
if (!defined $_Exec_Syms{$sym}) {
$_Exec_Syms{$sym} = "arg".(++$_Exec_Nsyms)."p";
}
}
if (ref $sym) { _exec_syms_recurse($sym); }
elsif ($sym =~ /^\$.*/) {
if (!defined $_Exec_Syms{$sym}) {
$_Exec_Syms{$sym} = "arg".(++$_Exec_Nsyms)."p";
}
}
}
}
@ -482,14 +482,14 @@ sub _exec_new_recurse {
my $out = "new ".$aref->[0]."(nodep->fileline()";
my $first = 1;
foreach my $sym (@{$aref}) {
if ($first) { $first=0; next; }
$out .= ", ";
if (ref $sym) { $out.=_exec_new_recurse($sym); }
elsif ($sym =~ /^\$.*/) {
$out .= $_Exec_Syms{$sym};
} else {
$out .= $sym;
}
if ($first) { $first=0; next; }
$out .= ", ";
if (ref $sym) { $out.=_exec_new_recurse($sym); }
elsif ($sym =~ /^\$.*/) {
$out .= $_Exec_Syms{$sym};
} else {
$out .= $sym;
}
}
return $out.")";
}
@ -500,142 +500,142 @@ sub treeop_exec_func {
my $out = "";
$func =~ s/^!//;
if ($func =~ /^\s*[a-zA-Z0-9]+\s*\(/) { # Function call
(my $outl = $func) =~ s/\$([a-zA-Z0-9]+)/nodep->$1()/g;
$out .= $outl.";";
(my $outl = $func) =~ s/\$([a-zA-Z0-9]+)/nodep->$1()/g;
$out .= $outl.";";
}
elsif ($func =~ /^\s*Ast([a-zA-Z0-9]+) \s*\{\s* (.*) \s* \}$/x) {
my $nargs = 0;
my %argnums; # Number for each argument name
my $nargs = 0;
my %argnums; # Number for each argument name
my $aref = undef; # Recursive array with structure to form
my @astack;
my $forming = "";
my $argtext = $func . "\000"; # EOF character
#print "FF $func\n" if $Debug;
while ($argtext =~ s/^(.)//) {
my $tok = $1;
#print "TOK: $tok $forming\n" if $tok !~ /[a-zA-Z0-9]/;
my $aref = undef; # Recursive array with structure to form
my @astack;
my $forming = "";
my $argtext = $func . "\000"; # EOF character
#print "FF $func\n" if $Debug;
while ($argtext =~ s/^(.)//) {
my $tok = $1;
#print "TOK: $tok $forming\n" if $tok !~ /[a-zA-Z0-9]/;
if ($tok eq "\000") {
} elsif ($tok =~ /\s+/) {
} elsif ($tok eq "{") {
my $newref = [$forming];
push @{$aref}, $newref;
push @astack, $aref if $aref;
$aref = $newref;
$forming = "";
} elsif ($tok eq "}") {
push @{$aref}, $forming if $forming;
$aref = pop @astack;
$aref or $self->error("Too many } in execution function: $func\n");
$forming = "";
} elsif ($tok eq ",") {
push @{$aref}, $forming if $forming;
$forming = "";
} else {
$forming .= $tok;
}
}
($aref && ref $aref->[0] && !$aref->[1]) or $self->error("Badly formed execution function: $func\n");
$aref = $aref->[0];
#use Data::Dumper; print Dumper($aref),"\n";
if ($tok eq "\000") {
} elsif ($tok =~ /\s+/) {
} elsif ($tok eq "{") {
my $newref = [$forming];
push @{$aref}, $newref;
push @astack, $aref if $aref;
$aref = $newref;
$forming = "";
} elsif ($tok eq "}") {
push @{$aref}, $forming if $forming;
$aref = pop @astack;
$aref or $self->error("Too many } in execution function: $func\n");
$forming = "";
} elsif ($tok eq ",") {
push @{$aref}, $forming if $forming;
$forming = "";
} else {
$forming .= $tok;
}
}
($aref && ref $aref->[0] && !$aref->[1]) or $self->error("Badly formed execution function: $func\n");
$aref = $aref->[0];
#use Data::Dumper; print Dumper($aref),"\n";
# Assign numbers to each $ symbol
%_Exec_Syms = ();
$_Exec_Nsyms = 0;
_exec_syms_recurse($aref);
# Assign numbers to each $ symbol
%_Exec_Syms = ();
$_Exec_Nsyms = 0;
_exec_syms_recurse($aref);
foreach my $sym (sort {$_Exec_Syms{$a} cmp $_Exec_Syms{$b}} (keys %_Exec_Syms)) {
my $argnp = $_Exec_Syms{$sym};
my $arg = add_nodep($sym);
$out .= "AstNode* ${argnp} = ${arg}->unlinkFrBack();\n";
}
foreach my $sym (sort {$_Exec_Syms{$a} cmp $_Exec_Syms{$b}} (keys %_Exec_Syms)) {
my $argnp = $_Exec_Syms{$sym};
my $arg = add_nodep($sym);
$out .= "AstNode* ${argnp} = ${arg}->unlinkFrBack();\n";
}
$out .= "AstNode* newp = " . _exec_new_recurse($aref).";\n";
$out .= "nodep->replaceWith(newp);";
$out .= "nodep->deleteTree(); VL_DANGLING(nodep);";
#print "FF $out\n" if $Debug;
$out .= "AstNode* newp = " . _exec_new_recurse($aref).";\n";
$out .= "nodep->replaceWith(newp);";
$out .= "nodep->deleteTree(); VL_DANGLING(nodep);";
#print "FF $out\n" if $Debug;
} elsif ($func eq "NEVER") {
$out .= "nodep->v3fatalSrc(\"Executing transform that was NEVERed\");";
$out .= "nodep->v3fatalSrc(\"Executing transform that was NEVERed\");";
} elsif ($func eq "DONE") {
} else {
$self->error("Unknown execution function format: $func\n");
$self->error("Unknown execution function format: $func\n");
}
return $out;
}
sub tree_match {
my $self = shift;
$self->print (" // TREEOP functions, each return true if they matched & transformed\n");
$self->print(" // TREEOP functions, each return true if they matched & transformed\n");
#use Data::Dumper; print Dumper($self);
foreach my $base (sort (keys %{$self->{treeop}})) {
foreach my $typefunc (@{$self->{treeop}{$base}}) {
$self->print(" // Generated by astgen\n");
$self->print(" bool $typefunc->{match_func}(Ast${base}* nodep) {\n",
"\t// $typefunc->{comment}\n",);
$self->print( "\tif ($typefunc->{match_if}) {\n");
foreach my $typefunc (@{$self->{treeop}{$base}}) {
$self->print(" // Generated by astgen\n");
$self->print(" bool $typefunc->{match_func}(Ast${base}* nodep) {\n",
"\t// $typefunc->{comment}\n",);
$self->print( "\tif ($typefunc->{match_if}) {\n");
$self->print( "\t UINFO($typefunc->{uinfo_level},cvtToHex(nodep)"
."<<\" $typefunc->{uinfo}\\n\");\n");
$self->print( "\t $typefunc->{exec_func}\n");
$self->print( "\t return true;\n");
$self->print( "\t}\n");
$self->print( "\treturn false;\n");
$self->print(" }\n",);
}
$self->print( "\t $typefunc->{exec_func}\n");
$self->print( "\t return true;\n");
$self->print( "\t}\n");
$self->print( "\treturn false;\n");
$self->print(" }\n",);
}
}
}
sub tree_base {
my $self = shift;
$self->print (" // TREEOP visitors, call each base type's match\n");
$self->print (" // Bottom class up, as more simple transforms are generally better\n");
$self->print(" // TREEOP visitors, call each base type's match\n");
$self->print(" // Bottom class up, as more simple transforms are generally better\n");
foreach my $type (sort (keys %::Classes)) {
my $base = $::Classes{$type};
my @out_for_type_sc;
my @out_for_type;
foreach my $base (::subclasses_of($type), $type) {
foreach my $typefunc (@{$self->{treeop}{$base}}) {
my $base = $::Classes{$type};
my @out_for_type_sc;
my @out_for_type;
foreach my $base (::subclasses_of($type), $type) {
foreach my $typefunc (@{$self->{treeop}{$base}}) {
my @lines = (" if ($typefunc->{match_func}(nodep)) return;\n",);
if ($typefunc->{short_circuit}) { # short-circuit match fn
push @out_for_type_sc, @lines;
} else { # Standard match fn
if ($typefunc->{order}) {
unshift @out_for_type, @lines; # TREEOP1's go in front of others
} else {
push @out_for_type, @lines;
}
}
}
}
if ($typefunc->{short_circuit}) { # short-circuit match fn
push @out_for_type_sc, @lines;
} else { # Standard match fn
if ($typefunc->{order}) {
unshift @out_for_type, @lines; # TREEOP1's go in front of others
} else {
push @out_for_type, @lines;
}
}
}
}
# We need to deal with two cases. For short circuited functions we
# evaluate the LHS, then apply the short-circuit matches, then
# evaluate the RHS and possibly THS (ternary operators may
# short-circuit) and apply all the other matches.
# We need to deal with two cases. For short circuited functions we
# evaluate the LHS, then apply the short-circuit matches, then
# evaluate the RHS and possibly THS (ternary operators may
# short-circuit) and apply all the other matches.
# For types without short-circuits, we just use iterateChildren, which
# saves one comparison.
if ($out_for_type_sc[0]) { # Short-circuited types
$self->print(" // Generated by astgen with short-circuiting\n",
" virtual void visit(Ast${type}* nodep) {\n",
# For types without short-circuits, we just use iterateChildren, which
# saves one comparison.
if ($out_for_type_sc[0]) { # Short-circuited types
$self->print(" // Generated by astgen with short-circuiting\n",
" virtual void visit(Ast${type}* nodep) {\n",
" iterateAndNextNull(nodep->lhsp());\n",
@out_for_type_sc);
@out_for_type_sc);
$self->print(" iterateAndNextNull(nodep->rhsp());\n",
" AstNodeTriop *tnp = VN_CAST(nodep, NodeTriop);\n",
" if (tnp && tnp->thsp()) iterateAndNextNull(tnp->thsp());\n",
@out_for_type,
" }\n") if ($out_for_type[0]);
} elsif ($out_for_type[0]) { # Other types with something to print
my $skip = $self->{tree_skip_visit}{$type};
my $gen = $skip ? "Gen" : "";
$self->print(" // Generated by astgen\n",
" virtual void visit$gen(Ast${type}* nodep) {\n",
($skip?"":
@out_for_type,
" }\n") if ($out_for_type[0]);
} elsif ($out_for_type[0]) { # Other types with something to print
my $skip = $self->{tree_skip_visit}{$type};
my $gen = $skip ? "Gen" : "";
$self->print(" // Generated by astgen\n",
" virtual void visit$gen(Ast${type}* nodep) {\n",
($skip?"":
" iterateChildren(nodep);\n"),
@out_for_type,
" }\n");
}
@out_for_type,
" }\n");
}
}
}

View File

@ -7,7 +7,7 @@ use Getopt::Long;
use IO::File;
use Pod::Usage;
use strict;
use vars qw ($Debug $VERSION);
use vars qw($Debug $VERSION);
$VERSION = '3.404';
@ -28,21 +28,21 @@ 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,
"<>" => \&parameter,
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,
"<>" => \&parameter,
)) {
die "%Error: Bad usage, try 'bisonpre --help'\n";
}
@ -57,15 +57,15 @@ process();
sub usage {
print "Version $VERSION\n";
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT, -noperldoc=>1);
exit (1);
exit(1);
}
sub parameter {
my $param = shift;
if (!defined $Opt_Input) {
$Opt_Input = $param;
$Opt_Input = $param;
} else {
die "bisonpre: %Error: Unknown parameter: $param\n";
die "bisonpre: %Error: Unknown parameter: $param\n";
}
}
@ -81,31 +81,31 @@ sub process {
# Run bison
my $command = ($Opt_Yacc
.($Opt_Debug?" -t":"")
.($Opt_Definitions?" -d":"")
.($Opt_Token_Table?" -k":"")
.($Opt_Verbose?" -v":"")
.(($Opt_Verbose && $supports_report)?" --report=itemset --report=lookahead":"")
# -p required for GLR parsers; they write to -p basename, not -o
.($Opt_Name_Prefix?" -p $Opt_Name_Prefix":"")
." -b ".tmp_prefix()
." -o ".tmp_prefix().".c"
." ".tmp_prefix().".y" );
.($Opt_Debug?" -t":"")
.($Opt_Definitions?" -d":"")
.($Opt_Token_Table?" -k":"")
.($Opt_Verbose?" -v":"")
.(($Opt_Verbose && $supports_report)?" --report=itemset --report=lookahead":"")
# -p required for GLR parsers; they write to -p basename, not -o
.($Opt_Name_Prefix?" -p $Opt_Name_Prefix":"")
." -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 "bisonpre: %Error: $Opt_Yacc version $v run failed due to errors\n";
remove_outputs();
my $v = bison_version_check();
die "bisonpre: %Error: $Opt_Yacc version $v run failed due to errors\n";
}
clean_output(tmp_prefix().".output",output_prefix().".output", 1,0);
warning_check(output_prefix().".output");
clean_output(tmp_prefix().".c", output_prefix().".c", 0,1);
clean_output(tmp_prefix().".h", output_prefix().".h", 0,1);
clean_output(tmp_prefix().".c", output_prefix().".c", 0,1);
clean_output(tmp_prefix().".h", output_prefix().".h", 0,1);
remove_tmp();
}
@ -116,10 +116,10 @@ sub tmp_prefix {
sub output_prefix {
my $o;
if ($Opt_Output) {
(my $o = $Opt_Output) =~ s!\.[^.]*$!!;
return $o;
(my $o = $Opt_Output) =~ s!\.[^.]*$!!;
return $o;
} else {
return $Opt_File_Prefix.".tab";
return $Opt_File_Prefix.".tab";
}
}
@ -139,11 +139,11 @@ sub remove_outputs {
sub bison_version_check {
my $v = `$Opt_Yacc --version`;
if ($v && $v =~ /([0-9]+\.[0-9]+)/) {
my $v = $1;
($v >= 1.875) or die "bisonpre: %Error: '$Opt_Yacc' is version $v; version 1.875 or newer is required\n";
return $v;
my $v = $1;
($v >= 1.875) or die "bisonpre: %Error: '$Opt_Yacc' is version $v; version 1.875 or newer is required\n";
return $v;
} else {
die "bisonpre: %Error: '$Opt_Yacc' is not installed, or not working\n";
die "bisonpre: %Error: '$Opt_Yacc' is not installed, or not working\n";
}
}
@ -164,55 +164,55 @@ sub clean_output {
$newbase =~ s/\.y/./;
if ($is_output) {
my %state_line; my $l=0;
foreach my $line (@lines) {
$l++;
# We add a colon so it's easy to search for the definition
$state_line{$1} = $l if $line =~ s/^state (\d+)\s*$/state $1:/;
}
my @out;
foreach my $line (@lines) {
if ($line =~ /^State (\d+) (conflicts)/) {
chomp $line;
$line .= " // line $state_line{$1}" if $state_line{$1};
$line .= "\n";
}
push @out, $line;
}
@lines = @out; @out = ();
my %state_line; my $l=0;
foreach my $line (@lines) {
$l++;
# We add a colon so it's easy to search for the definition
$state_line{$1} = $l if $line =~ s/^state (\d+)\s*$/state $1:/;
}
my @out;
foreach my $line (@lines) {
if ($line =~ /^State (\d+) (conflicts)/) {
chomp $line;
$line .= " // line $state_line{$1}" if $state_line{$1};
$line .= "\n";
}
push @out, $line;
}
@lines = @out; @out = ();
}
if ($is_c) {
my %token_values;
my $in_en=0;
foreach my $line (@lines) {
$in_en=1 if $line =~ /enum\s+yytokentype/;
$in_en=0 if $line =~ /;/;
$token_values{$2} = $1 if $in_en && $line =~ /\b(\S+) = (\d+)/;
}
my @out;
foreach my $line (@lines) {
if ($line =~ /BISONPRE_TOKEN_NAMES/) {
push @out, $line;
foreach my $tv (sort keys %token_values) {
push @out, sprintf("\tcase %d: return \"%s\";\n",
$tv, $token_values{$tv});
}
next;
}
push @out, $line;
}
@lines = @out; @out = ();
my %token_values;
my $in_en=0;
foreach my $line (@lines) {
$in_en=1 if $line =~ /enum\s+yytokentype/;
$in_en=0 if $line =~ /;/;
$token_values{$2} = $1 if $in_en && $line =~ /\b(\S+) = (\d+)/;
}
my @out;
foreach my $line (@lines) {
if ($line =~ /BISONPRE_TOKEN_NAMES/) {
push @out, $line;
foreach my $tv (sort keys %token_values) {
push @out, sprintf("\tcase %d: return \"%s\";\n",
$tv, $token_values{$tv});
}
next;
}
push @out, $line;
}
@lines = @out; @out = ();
}
$fh = IO::File->new(">$outname") or die "%Error: $! writing $outname\n";
foreach my $line (@lines) {
# Fix filename refs
$line =~ s!$basename!$newbase!g;
# Fix bison 2.3 and GCC 4.2.1
$line =~ s!\(YY_\("!(YY_((char*)"!g;
# Fix bison 2.3 glr-parser warning about yyerrorloc.YYTYPE::yydummy uninit
$line =~ s!(YYLTYPE yyerrloc;)!$1 yyerrloc.yydummy=0;/*bisonpre*/!g;
$fh->write($line);
# Fix filename refs
$line =~ s!$basename!$newbase!g;
# Fix bison 2.3 and GCC 4.2.1
$line =~ s!\(YY_\("!(YY_((char*)"!g;
# Fix bison 2.3 glr-parser warning about yyerrorloc.YYTYPE::yydummy uninit
$line =~ s!(YYLTYPE yyerrloc;)!$1 yyerrloc.yydummy=0;/*bisonpre*/!g;
$fh->write($line);
}
$fh->close;
}
@ -222,9 +222,9 @@ sub warning_check {
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n";
while (defined(my $line = $fh->getline)) {
if ($line =~ /(conflicts|warning:|^useless)/i) {
die "%Error: $filename:$.: $line\n";
}
if ($line =~ /(conflicts|warning:|^useless)/i) {
die "%Error: $filename:$.: $line\n";
}
}
$fh->close;
}
@ -249,160 +249,160 @@ sub clean_input {
my $last_rule;
my $section = 1;
{
my @linesin = @lines; @lines=(); my $l=0;
foreach my $line (@linesin) {
$l++;
# ^/ to prevent comments from matching
$line =~ m!^[a-zA-Z0-9_<>]+:[^/]*[a-zA-Z]! and die "%Error: $filename:$l: Move text on rule line to next line: $line\n";
if ($line =~ /^%%/) {
$section++;
if ($section==2) { $last_rule = undef; }
}
elsif ($line =~ s/^([a-zA-Z0-9_]+)<(\S*)>:/$1:/) {
!$rules{$1}{name} or die "%Error: $filename:$l: Redeclaring '$1': $line\n";
$types{$2}{$1} = 1;
$rules{$1}{name} = $1;
$rules{$1}{type} = $2;
!$last_rule or die "%Error: $filename:$l: Unterminated previous rule\n";
$last_rule = $1;
} elsif ($line =~ /^([a-zA-Z0-9_]+):/) {
!$rules{$1}{name} or die "%Error: $filename:$l: Redeclaring '$1': $line\n";
$rules{$1}{name} = $1;
$rules{$1}{type} = "";
!$last_rule or die "%Error: $filename:$l: Unterminated previous rule\n";
$last_rule = $1;
}
push @lines, $line;
# Now clean the line and extract some more info
(my $cline = $line) =~ s/\/\/.*$/\n/;
(my $rline = $line) =~ s/\/\/.*$/\n/;
if ($cline =~ /^\s*;/) {
$last_rule or die "%Error: $filename:$l: Stray semicolon\n";
$last_rule = undef;
} elsif ($last_rule) {
$rules{$last_rule}{rules_and_productions} .= $cline;
}
if ($cline =~ /^%token\s*<(\S+)>\s*(\S+)/) {
!$tokens{$2} or die "%Error: $filename:$l: Redeclaring '$2': $line\n";
$tokens{$2} = $1;
}
foreach my $tok (split /[^a-zA-Z0-9_]+/, $cline) {
if ($last_rule && $tok=~/^[a-zA-Z]/) {
#print "TT $last_rule $tok\n";
$rules{$last_rule}{subrules}{$tok} = 1;
$rules{$tok}{parentrules}{$last_rule} = 1;
}
}
}
my @linesin = @lines; @lines=(); my $l=0;
foreach my $line (@linesin) {
$l++;
# ^/ to prevent comments from matching
$line =~ m!^[a-zA-Z0-9_<>]+:[^/]*[a-zA-Z]! and die "%Error: $filename:$l: Move text on rule line to next line: $line\n";
if ($line =~ /^%%/) {
$section++;
if ($section==2) { $last_rule = undef; }
}
elsif ($line =~ s/^([a-zA-Z0-9_]+)<(\S*)>:/$1:/) {
!$rules{$1}{name} or die "%Error: $filename:$l: Redeclaring '$1': $line\n";
$types{$2}{$1} = 1;
$rules{$1}{name} = $1;
$rules{$1}{type} = $2;
!$last_rule or die "%Error: $filename:$l: Unterminated previous rule\n";
$last_rule = $1;
} elsif ($line =~ /^([a-zA-Z0-9_]+):/) {
!$rules{$1}{name} or die "%Error: $filename:$l: Redeclaring '$1': $line\n";
$rules{$1}{name} = $1;
$rules{$1}{type} = "";
!$last_rule or die "%Error: $filename:$l: Unterminated previous rule\n";
$last_rule = $1;
}
push @lines, $line;
# Now clean the line and extract some more info
(my $cline = $line) =~ s/\/\/.*$/\n/;
(my $rline = $line) =~ s/\/\/.*$/\n/;
if ($cline =~ /^\s*;/) {
$last_rule or die "%Error: $filename:$l: Stray semicolon\n";
$last_rule = undef;
} elsif ($last_rule) {
$rules{$last_rule}{rules_and_productions} .= $cline;
}
if ($cline =~ /^%token\s*<(\S+)>\s*(\S+)/) {
!$tokens{$2} or die "%Error: $filename:$l: Redeclaring '$2': $line\n";
$tokens{$2} = $1;
}
foreach my $tok (split /[^a-zA-Z0-9_]+/, $cline) {
if ($last_rule && $tok=~/^[a-zA-Z]/) {
#print "TT $last_rule $tok\n";
$rules{$last_rule}{subrules}{$tok} = 1;
$rules{$tok}{parentrules}{$last_rule} = 1;
}
}
}
}
#use Data::Dumper; print Dumper(\%rules);
# Replace BISONPRE_VERSION(ver,,...) with expanded list
{
my @linesin = @lines; @lines=(); my $l=0;
foreach my $line (@linesin) {
$l++;
if ($line =~ /BISONPRE_VERSION/) {
# 1 3 4
($line =~ /BISONPRE_VERSION\((\S+)\s*,\s*((\S+)\s*,)?\s*([^\),]+)\)\s*$/)
or die "%Error: $filename:$l: Bad form of BISONPRE_VERSION: $line\n";
my $ver=$1; my $ver_max=$3; my $cmd=$4;
if ($Self->{bison_version} >= $1
&& (!$ver_max || $Self->{bison_version} <= $ver_max)) {
$line = $cmd."\n";
} else {
$line = "//NOP: $line";
}
}
push @lines, $line;
}
my @linesin = @lines; @lines=(); my $l=0;
foreach my $line (@linesin) {
$l++;
if ($line =~ /BISONPRE_VERSION/) {
# 1 3 4
($line =~ /BISONPRE_VERSION\((\S+)\s*,\s*((\S+)\s*,)?\s*([^\),]+)\)\s*$/)
or die "%Error: $filename:$l: Bad form of BISONPRE_VERSION: $line\n";
my $ver=$1; my $ver_max=$3; my $cmd=$4;
if ($Self->{bison_version} >= $1
&& (!$ver_max || $Self->{bison_version} <= $ver_max)) {
$line = $cmd."\n";
} else {
$line = "//NOP: $line";
}
}
push @lines, $line;
}
}
# Replace BISONPRE_NOT(type,...) with expanded list
{
my @linesin = @lines; @lines=(); my $l=0;
foreach my $line (@linesin) {
$l++;
if ($line =~ /BISONPRE_NOT/) {
($line =~ s/BISONPRE_NOT\((\S+)\)\s*(\{[^}]+})\s*$//)
or die "%Error: $filename:$l: Bad form of BISONPRE_NOT: $line\n";
my $endtok = $1; my $action = $2;
my @endtoks = split (/,/, $endtok);
map { $tokens{$_} or die "%Error: $filename:$l: Can't find definition for token: $_\n"
} @endtoks;
# Push it all onto one line to avoid error messages changing
my $bar = "";
tok:
foreach my $tok (sort keys %tokens) {
foreach (@endtoks) {
next tok if $tok eq $_;
}
if ($endtok ne $tok) {
$line .= "\t$bar $tok $action";
$bar = "|";
}
}
$line .= "\n";
}
push @lines, $line;
}
my @linesin = @lines; @lines=(); my $l=0;
foreach my $line (@linesin) {
$l++;
if ($line =~ /BISONPRE_NOT/) {
($line =~ s/BISONPRE_NOT\((\S+)\)\s*(\{[^}]+})\s*$//)
or die "%Error: $filename:$l: Bad form of BISONPRE_NOT: $line\n";
my $endtok = $1; my $action = $2;
my @endtoks = split(/,/, $endtok);
map { $tokens{$_} or die "%Error: $filename:$l: Can't find definition for token: $_\n"
} @endtoks;
# Push it all onto one line to avoid error messages changing
my $bar = "";
tok:
foreach my $tok (sort keys %tokens) {
foreach (@endtoks) {
next tok if $tok eq $_;
}
if ($endtok ne $tok) {
$line .= "\t$bar $tok $action";
$bar = "|";
}
}
$line .= "\n";
}
push @lines, $line;
}
}
# Replace BISONPRE_COPY(type,{code})
{
my @linesin = @lines; @lines=(); my $l=0;
foreach my $line (@linesin) {
$l++;
if ($line =~ /BISONPRE_COPY/) {
$line = _bisonpre_copy($line,$l,0);
}
push @lines, $line;
}
my @linesin = @lines; @lines=(); my $l=0;
foreach my $line (@linesin) {
$l++;
if ($line =~ /BISONPRE_COPY/) {
$line = _bisonpre_copy($line,$l,0);
}
push @lines, $line;
}
}
# Replace ~[x]~ - must be after BISONPRE_COPY expansion
{
my @linesin = @lines; @lines=(); my $l=0;
foreach my $line (@linesin) {
$l++;
$line =~ s/~[a-zA-Z0-9_]+~//g;
push @lines, $line;
}
my @linesin = @lines; @lines=(); my $l=0;
foreach my $line (@linesin) {
$l++;
$line =~ s/~[a-zA-Z0-9_]+~//g;
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) {
next if !$type;
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;
}
}
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) {
next if !$type;
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->write($line);
}
$fh->close;
}
@ -412,28 +412,28 @@ sub _bisonpre_copy {
my $l = shift;
my $depth = shift;
while ($text =~ /BISONPRE_COPY/) {
($text =~ s/BISONPRE_COPY(_ONCE)?\((\S+)\s*,\s*\{([^}]*)}\s*\)/{HERE}/)
or die "%Error: $Self->{filename}:$l: Bad form of BISONPRE_NOT: $text\n";
my $once = $1; my $rule = $2; my $code = $3;
$Self->{rules}{$rule} or die "%Error: $Self->{filename}:$l: Can't find definition for rule: $rule\n";
if ($depth > 0 && $once) {
# _ONCE means don't inherit
$text =~ s/\|[ \t]+{HERE}//; # Don't OR in nothing
$text =~ s/{HERE}//;
} else {
# Push it all onto one line to avoid error messages changing
my $insert = $Self->{rules}{$rule}{rules_and_productions};
$insert =~ s/^\S+://g; # Strip rule name
# Recurse so BISONPRE under B
#print "COPY $l code $code\n";
#print "COPY $l in $insert\n";
$_=$insert; eval("$code; \$_;"); $insert = $_;
#print "COPY $l out $insert\n";
while ($insert =~ s/[ \t\n]+\n/\n/go) {}
while ($insert =~ s/\n/ /go) {} # Optional - preserve line numbering
$text =~ s/{HERE}/$insert/;
}
$depth++;
($text =~ s/BISONPRE_COPY(_ONCE)?\((\S+)\s*,\s*\{([^}]*)}\s*\)/{HERE}/)
or die "%Error: $Self->{filename}:$l: Bad form of BISONPRE_NOT: $text\n";
my $once = $1; my $rule = $2; my $code = $3;
$Self->{rules}{$rule} or die "%Error: $Self->{filename}:$l: Can't find definition for rule: $rule\n";
if ($depth > 0 && $once) {
# _ONCE means don't inherit
$text =~ s/\|[ \t]+{HERE}//; # Don't OR in nothing
$text =~ s/{HERE}//;
} else {
# Push it all onto one line to avoid error messages changing
my $insert = $Self->{rules}{$rule}{rules_and_productions};
$insert =~ s/^\S+://g; # Strip rule name
# Recurse so BISONPRE under B
#print "COPY $l code $code\n";
#print "COPY $l in $insert\n";
$_=$insert; eval("$code; \$_;"); $insert = $_;
#print "COPY $l out $insert\n";
while ($insert =~ s/[ \t\n]+\n/\n/go) {}
while ($insert =~ s/\n/ /go) {} # Optional - preserve line numbering
$text =~ s/{HERE}/$insert/;
}
$depth++;
}
return $text;
}

View File

@ -7,7 +7,7 @@ use Getopt::Long;
use IO::File;
use Pod::Usage;
use strict;
use vars qw ($Debug $VERSION);
use vars qw($Debug $VERSION);
$VERSION = '3.881';
@ -23,12 +23,12 @@ our $Opt_Debug;
autoflush STDOUT 1;
autoflush STDERR 1;
Getopt::Long::config ("no_auto_abbrev","pass_through");
Getopt::Long::config("no_auto_abbrev","pass_through");
our @Opt_Args = ("cppcheck", @ARGV);
if (! GetOptions (
# Local options
"help" => \&usage,
"version" => sub { print "Version $VERSION\n"; system("cppcheck","--version"); exit(0); },
if (! GetOptions(
# Local options
"help" => \&usage,
"version" => sub { print "Version $VERSION\n"; system("cppcheck","--version"); exit(0); },
)) {
die "%Error: Bad usage, try 'cppcheck_filtered --help'\n";
}
@ -40,7 +40,7 @@ process();
sub usage {
print "Version $VERSION\n";
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT, -noperldoc=>1);
exit (1);
exit(1);
}
#######################################################################
@ -54,72 +54,72 @@ sub process {
my %errs;
my $last_error = "";
while (defined(my $line = $fh->getline())) {
$line =~ s/^\s+//;
$line =~ s/Checking usage of global functions\.+//; # Sometimes tacked at end-of-line
# General gunk
next if $uniq{$line}++;
next if $line =~ m!^<\?xml version!;
next if $line =~ m!^<cppcheck!;
next if $line =~ m!^<results!;
next if $line =~ m!^</results>!;
next if $line =~ m!^<errors!;
next if $line =~ m!^</error>!;
next if $line =~ m!^</errors>!;
next if $line =~ m!^<error.*id="unmatchedSuppression"!; # --suppress=unmatchedSuppression doesn't work
next if $line =~ m!Cppcheck cannot find all the include files!; # An earlier id line is more specific
next if $line =~ m!^Checking !;
next if $line =~ m!^make.*Entering directory !;
next if $line =~ m!^make.*Leaving directory !;
next if $line =~ m!^\s+$!g;
$line =~ s/^\s+//;
$line =~ s/Checking usage of global functions\.+//; # Sometimes tacked at end-of-line
# General gunk
next if $uniq{$line}++;
next if $line =~ m!^<\?xml version!;
next if $line =~ m!^<cppcheck!;
next if $line =~ m!^<results!;
next if $line =~ m!^</results>!;
next if $line =~ m!^<errors!;
next if $line =~ m!^</error>!;
next if $line =~ m!^</errors>!;
next if $line =~ m!^<error.*id="unmatchedSuppression"!; # --suppress=unmatchedSuppression doesn't work
next if $line =~ m!Cppcheck cannot find all the include files!; # An earlier id line is more specific
next if $line =~ m!^Checking !;
next if $line =~ m!^make.*Entering directory !;
next if $line =~ m!^make.*Leaving directory !;
next if $line =~ m!^\s+$!g;
# Specific suppressions (see _suppress also)
next if $line =~ m!id="unusedPrivateFunction" .*::debug!; # Doesn't know UINFO will use it
# Output
if ($line =~ /^cppcheck --/) {
print $line if $Debug;
} elsif ($line =~ m!^\d+/\d+ files checked!) {
print $line;
} else {
my $suppress;
# --xml-format=1
if ($line =~ /file="([^"]+)"\s+line="(\d+)"\s+id="([^"]+)"/) {
my $file = $1; my $linenum = $2; my $id = $3;
$suppress = 1 if _suppress($file,$linenum,$id);
}
# --xml-format=2
if ($line =~ /<error id.*/) {
$last_error = $line;
chomp $last_error;
$suppress = 1;
}
elsif ($line =~ /<location.* file="([^"]+)"\s+line="(\d+)"/) {
my $file = $1; my $linenum = $2; my $id;
if ($last_error =~ / id="([^"]+)"/) {
$id = $1;
} else {
$id = "?";
}
$suppress = 1 if _suppress($file,$linenum,$id);
$suppress = 1 if $file eq "*";
if (!$suppress) {
chomp $line;
print "$file:$linenum: ".$last_error."\n";
$suppress = 1;
}
}
if (!$suppress) {
my $eline = "%Error: cppcheck: $line";
print $eline;
$errs{$eline}++;
}
}
# Output
if ($line =~ /^cppcheck --/) {
print $line if $Debug;
} elsif ($line =~ m!^\d+/\d+ files checked!) {
print $line;
} else {
my $suppress;
# --xml-format=1
if ($line =~ /file="([^"]+)"\s+line="(\d+)"\s+id="([^"]+)"/) {
my $file = $1; my $linenum = $2; my $id = $3;
$suppress = 1 if _suppress($file,$linenum,$id);
}
# --xml-format=2
if ($line =~ /<error id.*/) {
$last_error = $line;
chomp $last_error;
$suppress = 1;
}
elsif ($line =~ /<location.* file="([^"]+)"\s+line="(\d+)"/) {
my $file = $1; my $linenum = $2; my $id;
if ($last_error =~ / id="([^"]+)"/) {
$id = $1;
} else {
$id = "?";
}
$suppress = 1 if _suppress($file,$linenum,$id);
$suppress = 1 if $file eq "*";
if (!$suppress) {
chomp $line;
print "$file:$linenum: ".$last_error."\n";
$suppress = 1;
}
}
if (!$suppress) {
my $eline = "%Error: cppcheck: $line";
print $eline;
$errs{$eline}++;
}
}
}
if (scalar(keys %errs)) {
#my $all = join('',sort(keys %errs));
#$Self->error("Cppcheck errors:\n$all");
#die "%Error: cppcheck_filtered found errors\n";
exit(1);
#my $all = join('',sort(keys %errs));
#$Self->error("Cppcheck errors:\n$all");
#die "%Error: cppcheck_filtered found errors\n";
exit(1);
}
}
@ -143,32 +143,32 @@ sub _suppress {
my $fh = IO::File->new("<$filename");
if (!$fh) {
warn "%Warning: $! $filename,";
return undef;
warn "%Warning: $! $filename,";
return undef;
}
my $l = 0;
while (defined(my $line = $fh->getline())) {
++$l;
if ($l+1 == $linenum) {
if ($line =~ /cppcheck-suppress((\s+\S+)+)/) {
my $supids = $1;
foreach my $supid (split /\s+/, $supids) {
if ($supid eq $id
|| $supid eq ($SuppressMap{$id}||'')) {
return 1;
}
}
warn "%Warning: $filename: $l: Found suppress for ids='$supids', not expected id='$id'\n";
}
}
if ($l == $linenum) {
if (0 && # We now use VL_DANGLING instead of this rule
$id eq "uselessAssignmentPtrArg"
&& $line =~ /(delete|Delete|Edit).*p *= *(NULL|nullptr);/) {
# delete(nodep); nodep=NULL; # This is ok, it's how we prevent later using nodep
return 1;
}
}
++$l;
if ($l+1 == $linenum) {
if ($line =~ /cppcheck-suppress((\s+\S+)+)/) {
my $supids = $1;
foreach my $supid (split /\s+/, $supids) {
if ($supid eq $id
|| $supid eq ($SuppressMap{$id}||'')) {
return 1;
}
}
warn "%Warning: $filename: $l: Found suppress for ids='$supids', not expected id='$id'\n";
}
}
if ($l == $linenum) {
if (0 && # We now use VL_DANGLING instead of this rule
$id eq "uselessAssignmentPtrArg"
&& $line =~ /(delete|Delete|Edit).*p *= *(NULL|nullptr);/) {
# delete(nodep); nodep=NULL; # This is ok, it's how we prevent later using nodep
return 1;
}
}
}
return undef;
}

View File

@ -7,7 +7,7 @@ use Getopt::Long;
use IO::File;
use Pod::Usage;
use strict;
use vars qw ($Debug);
use vars qw($Debug);
our @Items;
@ -16,12 +16,12 @@ our @Items;
$Debug = 0;
my $Opt_Srcdir = ".";
Getopt::Long::config ("pass_through", "no_auto_abbrev");
if (! GetOptions (
"help" => \&usage,
"debug" => sub { $Debug = 1; },
"srcdir=s" => \$Opt_Srcdir,
"<>" => sub { die "%Error: Unknown parameter: $_[0],"; },
Getopt::Long::config("pass_through", "no_auto_abbrev");
if (! GetOptions(
"help" => \&usage,
"debug" => sub { $Debug = 1; },
"srcdir=s" => \$Opt_Srcdir,
"<>" => sub { die "%Error: Unknown parameter: $_[0],"; },
)) {
usage();
}
@ -34,7 +34,7 @@ write_keys("$Opt_Srcdir/../include/verilated_cov_key.h");
sub usage {
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
exit (1);
exit(1);
}
#######################################################################
@ -44,17 +44,17 @@ sub read_keys {
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename,";
while (defined (my $line = $fh->getline())) {
$line =~ s/\/\/.*$//;
next if $line =~ /^\s*$/;
if ($line =~ /^\s*VLCOVGEN_ITEM/) {
$line =~ /^\s*VLCOVGEN_ITEM *\( *"([^"]+)" *\)/
or die "%Error: $filename:$.: Misformed VLCOVGEN_ITEM line,";
my @data;
my $code = "\@data = ($1);";
eval $code;
die "%Error: $filename:$.: Parsing '$code': $@," if $@;
push @Items, {@data};
}
$line =~ s/\/\/.*$//;
next if $line =~ /^\s*$/;
if ($line =~ /^\s*VLCOVGEN_ITEM/) {
$line =~ /^\s*VLCOVGEN_ITEM *\( *"([^"]+)" *\)/
or die "%Error: $filename:$.: Misformed VLCOVGEN_ITEM line,";
my @data;
my $code = "\@data = ($1);";
eval $code;
die "%Error: $filename:$.: Parsing '$code': $@," if $@;
push @Items, {@data};
}
}
}
@ -64,11 +64,11 @@ sub lint {
my %shorts;
my $ok = 1;
foreach my $itemref (@Items) {
if ($shorts{$itemref->{short}}) {
warn "%Error: Duplicate short code: $itemref->{short},";
$ok = 0;
}
$shorts{$itemref->{short}} = 1;
if ($shorts{$itemref->{short}}) {
warn "%Error: Duplicate short code: $itemref->{short},";
$ok = 0;
}
$shorts{$itemref->{short}} = 1;
}
return $ok;
}
@ -82,40 +82,40 @@ sub write_keys {
my @out;
my $deleting;
while (defined(my $line = $fh->getline)) {
push @in, $line;
if ($line =~ /VLCOVGEN_CIK_AUTO_EDIT_BEGIN/) {
$deleting = 1;
push @out, $line;
foreach my $keyref (sort {$a->{name} cmp $b->{name}} @Items) {
push @out, sprintf("#define VL_CIK_%s \"%s\"\n",
uc $keyref->{name}, $keyref->{short});
}
}
elsif ($line =~ /VLCOVGEN_SHORT_AUTO_EDIT_BEGIN/) {
$deleting = 1;
push @out, $line;
foreach my $keyref (sort {$a->{name} cmp $b->{name}} @Items) {
push @in, $line;
if ($line =~ /VLCOVGEN_CIK_AUTO_EDIT_BEGIN/) {
$deleting = 1;
push @out, $line;
foreach my $keyref (sort {$a->{name} cmp $b->{name}} @Items) {
push @out, sprintf("#define VL_CIK_%s \"%s\"\n",
uc $keyref->{name}, $keyref->{short});
}
}
elsif ($line =~ /VLCOVGEN_SHORT_AUTO_EDIT_BEGIN/) {
$deleting = 1;
push @out, $line;
foreach my $keyref (sort {$a->{name} cmp $b->{name}} @Items) {
push @out, sprintf(" if (key == \"%s\") return VL_CIK_%s;\n",
$keyref->{name}, uc $keyref->{name});
}
}
elsif ($line =~ /VLCOVGEN_.*AUTO_EDIT_END/) {
$deleting = 0;
push @out, $line;
}
elsif ($deleting) {
}
else {
push @out, $line;
}
$keyref->{name}, uc $keyref->{name});
}
}
elsif ($line =~ /VLCOVGEN_.*AUTO_EDIT_END/) {
$deleting = 0;
push @out, $line;
}
elsif ($deleting) {
}
else {
push @out, $line;
}
}
$fh->close;
my $ok = join("", @out) eq join("", @in);
if (!$ok) {
my $fh = IO::File->new(">$filename") or die "%Error: $! writing $filename\n";
$fh->print(join "", @out);
$fh->close;
my $fh = IO::File->new(">$filename") or die "%Error: $! writing $filename\n";
$fh->print(join "", @out);
$fh->close;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -19,34 +19,35 @@
class TestSimulator {
private:
struct SimTypes {
int verilator;
int icarus;
int mti;
int ncsim;
int vcs;
int verilator;
int icarus;
int mti;
int ncsim;
int vcs;
};
s_vpi_vlog_info m_info;
SimTypes m_simulators;
s_vpi_vlog_info m_info;
SimTypes m_simulators;
public:
TestSimulator() {
vpi_get_vlog_info(&m_info);
if (0 == strcmp(m_info.product, "Verilator")) {
m_simulators.verilator = true;
} else if (0 == strcmp(m_info.product, "Verilator")) {
m_simulators.icarus = true;
} else if (0 == strncmp(m_info.product, "Chronologic Simulation VCS", strlen("Chronologic Simulation VCS"))) {
m_simulators.vcs = true;
} else {
printf("%%Warning: %s:%d: Unknown simulator in TestSimulator.h: %s\n",
__FILE__, __LINE__, m_info.product);
}
vpi_get_vlog_info(&m_info);
if (0 == strcmp(m_info.product, "Verilator")) {
m_simulators.verilator = true;
} else if (0 == strcmp(m_info.product, "Verilator")) {
m_simulators.icarus = true;
} else if (0 == strncmp(m_info.product, "Chronologic Simulation VCS",
strlen("Chronologic Simulation VCS"))) {
m_simulators.vcs = true;
} else {
printf("%%Warning: %s:%d: Unknown simulator in TestSimulator.h: %s\n",
__FILE__, __LINE__, m_info.product);
}
}
~TestSimulator() { }
// METHORS
private:
static TestSimulator& singleton() {
static TestSimulator s_singleton;
return s_singleton;
static TestSimulator s_singleton;
return s_singleton;
}
static const SimTypes& simulators() { return singleton().m_simulators; }
public:
@ -62,19 +63,19 @@ public:
static bool has_get_scalar() { return !simulators().icarus; }
// return test level scope
static const char* top() {
if (simulators().verilator) {
return "t";
} else {
return "top.t";
}
if (simulators().verilator) {
return "t";
} else {
return "top.t";
}
}
// return absolute scope of obj
static const char* rooted(const char *obj) {
static string buf;
ostringstream os;
os<<top()<<"."<<obj;
buf = os.str();
return buf.c_str();
static string buf;
ostringstream os;
os<<top()<<"."<<obj;
buf = os.str();
return buf.c_str();
}
};

View File

@ -24,7 +24,7 @@ class TestVpiHandle {
public:
TestVpiHandle() : m_handle(NULL), m_free(true) { }
TestVpiHandle(vpiHandle h) : m_handle(h), m_free(true) { }
~TestVpiHandle() { if (m_handle && m_free) { vpi_free_object(m_handle); m_handle=NULL; } } // icarus has yet to catch up with 1800-2009
~TestVpiHandle() { if (m_handle && m_free) { vpi_free_object(m_handle); m_handle=NULL; } }
operator vpiHandle() const { return m_handle; }
inline TestVpiHandle& operator= (vpiHandle h) { m_handle = h; return *this; }
TestVpiHandle& nofree() {

View File

@ -14,7 +14,7 @@ compile(
);
if ($Self->{vlt_all}) {
file_grep ($Self->{stats}, qr/Optimizations, Split always\s+(\d+)/i, 0);
file_grep($Self->{stats}, qr/Optimizations, Split always\s+(\d+)/i, 0);
}
execute(

View File

@ -14,7 +14,7 @@ compile(
);
if ($Self->{vlt_all}) {
file_grep ($Self->{stats}, qr/Optimizations, Split always\s+(\d+)/i, 0);
file_grep($Self->{stats}, qr/Optimizations, Split always\s+(\d+)/i, 0);
}
execute(

View File

@ -23,7 +23,7 @@ execute(
fails => $Self->{vlt_all},
);
file_grep ("$Self->{obj_dir}/vlt_compile.log",
file_grep("$Self->{obj_dir}/vlt_compile.log",
qr/%Warning-USERFATAL: Parameter 5 is invalid...string and constant both work/);
ok(1);

View File

@ -20,9 +20,9 @@ execute(
fails => 1
);
file_grep ($Self->{run_log_filename}, qr/'assert property' failed/);
file_grep($Self->{run_log_filename}, qr/'assert property' failed/);
# We expect to get a message when this assert fires:
file_grep ($Self->{run_log_filename}, qr/cyc != 3/);
file_grep($Self->{run_log_filename}, qr/cyc != 3/);
ok(1);
1;

View File

@ -20,7 +20,7 @@ execute(
fails => 1
);
file_grep ($Self->{run_log_filename}, qr/'assert property' failed/);
file_grep($Self->{run_log_filename}, qr/'assert property' failed/);
ok(1);
1;

View File

@ -15,8 +15,8 @@ compile(
verilator_flags2 => ["--stats --prof-cfuncs -CFLAGS '-pg' -LDFLAGS '-pg'"],
);
file_grep ($Self->{stats}, qr/Optimizations, Tables created\s+(\d+)/i, 10);
file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 10);
file_grep($Self->{stats}, qr/Optimizations, Tables created\s+(\d+)/i, 10);
file_grep($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i, 10);
unlink $_ foreach (glob "$Self->{obj_dir}/gmon.out.*");
$ENV{GMON_OUT_PREFIX} = "$Self->{obj_dir}/gmon.out";
@ -36,7 +36,7 @@ run(cmd => ["cd $Self->{obj_dir} && gprof $Self->{VM_PREFIX} $gmon_base > gprof.
run(cmd => ["cd $Self->{obj_dir} && $ENV{VERILATOR_ROOT}/bin/verilator_profcfunc gprof.out > cfuncs.out"],
check_finished => 0);
file_grep ("$Self->{obj_dir}/cfuncs.out", qr/Overall summary by/);
file_grep("$Self->{obj_dir}/cfuncs.out", qr/Overall summary by/);
ok(1);
1;

View File

@ -18,7 +18,7 @@ compile(
expect_filename => $Self->{golden_filename},
);
file_grep ("$Self->{obj_dir}/V$Self->{name}__cdc.txt", qr/CDC Report/);
file_grep("$Self->{obj_dir}/V$Self->{name}__cdc.txt", qr/CDC Report/);
ok(1);
1;

View File

@ -18,7 +18,7 @@ execute(
);
if ($Self->{vlt_all}) {
file_grep ($Self->{stats}, qr/Optimizations, Gate assign merged\s+(\d+)/i, 28);
file_grep($Self->{stats}, qr/Optimizations, Gate assign merged\s+(\d+)/i, 28);
};
ok(1);

View File

@ -38,16 +38,16 @@ int main(int argc, char *argv[]) {
Verilated::debug(0);
for (int i = 0; i < 2; i++) {
clockit(0, 0);
clockit(0, 1);
clockit(1, 1);
clockit(0, 0);
clockit(1, 1);
clockit(1, 0);
clockit(0, 0);
clockit(0, 1);
clockit(1, 0);
clockit(0, 0);
clockit(0, 0);
clockit(0, 1);
clockit(1, 1);
clockit(0, 0);
clockit(1, 1);
clockit(1, 0);
clockit(0, 0);
clockit(0, 1);
clockit(1, 0);
clockit(0, 0);
}
topp->check = 1;
clockit(0,0);

View File

@ -20,7 +20,7 @@ execute(
# Read the input .v file and do any CHECK_COVER requests
inline_checks();
file_grep ($Self->{stats}, qr/Coverage, Toggle points joined\s+(\d+)/i, 25)
file_grep($Self->{stats}, qr/Coverage, Toggle points joined\s+(\d+)/i, 25)
if $Self->{vlt_all};
ok(1);

View File

@ -14,7 +14,7 @@ compile(
);
if ($Self->{vlt_all}) {
file_grep ($Self->{stats}, qr/Optimizations, Gate sigs deduped\s+(\d+)/i, 4);
file_grep($Self->{stats}, qr/Optimizations, Gate sigs deduped\s+(\d+)/i, 4);
}
ok(1);

View File

@ -14,7 +14,7 @@ compile(
);
if ($Self->{vlt_all}) {
file_grep ($Self->{stats}, qr/Optimizations, Gate sigs deduped\s+(\d+)/i, 6);
file_grep($Self->{stats}, qr/Optimizations, Gate sigs deduped\s+(\d+)/i, 6);
}
ok(1);

View File

@ -18,8 +18,8 @@ execute(
expect_filename => $Self->{golden_filename},
);
file_grep ("$Self->{obj_dir}/$Self->{VM_PREFIX}__stats.txt",
qr/Node count, DISPLAY \s+ 32 \s+ 25 \s+ 25 \s+ 25/);
file_grep("$Self->{obj_dir}/$Self->{VM_PREFIX}__stats.txt",
qr/Node count, DISPLAY \s+ 32 \s+ 25 \s+ 25 \s+ 25/);
ok(1);
1;

File diff suppressed because it is too large Load Diff

View File

@ -51,58 +51,58 @@ extern "C" {
int dpic_line() {
svScope scope = svGetScope();
if (!scope) {
printf("%%Warning: svGetScope failed\n");
return 0;
printf("%%Warning: svGetScope failed\n");
return 0;
}
#ifdef VERILATOR
static int didDump = 0;
if (didDump++ == 0) {
Verilated::scopesDump();
Verilated::scopesDump();
}
#endif
const char* scopenamep = svGetNameFromScope(scope);
if (!scopenamep) {
printf("%%Warning: svGetNameFromScope failed\n");
return 0;
printf("%%Warning: svGetNameFromScope failed\n");
return 0;
}
if (scope != svGetScopeFromName(scopenamep)) {
printf("%%Warning: svGetScopeFromName repeat failed\n");
return 0;
printf("%%Warning: svGetScopeFromName repeat failed\n");
return 0;
}
const char* filenamep = "";
int lineno = 0;
if (svGetCallerInfo(&filenamep, &lineno)) {
printf("Call from %s:%d:%s\n", filenamep, lineno, scopenamep);
printf("Call from %s:%d:%s\n", filenamep, lineno, scopenamep);
} else {
printf("%%Warning: svGetCallerInfo failed\n");
return 0;
printf("%%Warning: svGetCallerInfo failed\n");
return 0;
}
return lineno;
}
extern int Dpic_Unique;
int Dpic_Unique = 0; // Address used for uniqueness
int Dpic_Unique = 0; // Address used for uniqueness
int dpic_save(int value) {
svScope scope = svGetScope();
if (!scope) {
printf("%%Warning: svGetScope failed\n");
return 0;
printf("%%Warning: svGetScope failed\n");
return 0;
}
// Use union to avoid cast to different size pointer warnings
union valpack {
void* ptr;
int i;
void* ptr;
int i;
} vp;
vp.i = value;
if (svPutUserData(scope, &Dpic_Unique, vp.ptr)) {
printf("%%Warning: svPutUserData failed\n");
return 0;
printf("%%Warning: svPutUserData failed\n");
return 0;
}
return 1;
}
@ -110,21 +110,21 @@ int dpic_save(int value) {
int dpic_restore() {
svScope scope = svGetScope();
if (!scope) {
printf("%%Warning: svGetScope failed\n");
return 0;
printf("%%Warning: svGetScope failed\n");
return 0;
}
if (void* userp = svGetUserData(scope, (void*)&Dpic_Unique)) {
// Use union to avoid cast to different size pointer warnings
union valpack {
void* ptr;
int i;
} vp;
vp.ptr = userp;
return vp.i;
// Use union to avoid cast to different size pointer warnings
union valpack {
void* ptr;
int i;
} vp;
vp.ptr = userp;
return vp.i;
} else {
printf("%%Warning: svGetUserData failed\n");
return 0;
printf("%%Warning: svGetUserData failed\n");
return 0;
}
}

View File

@ -19,7 +19,7 @@
#ifdef _WIN32
# define T_PRI64 "I64"
#else // Linux or compliant Unix flavors
#else // Linux or compliant Unix flavors
# define T_PRI64 "ll"
#endif
@ -71,20 +71,20 @@ extern "C" {
//======================================================================
#define CHECK_RESULT(type, got, exp) \
if ((got) != (exp)) { \
printf("%%Error: %s:%d:", __FILE__,__LINE__); \
union { type a; long long l; } u; \
u.l = 0; u.a = got; \
printf(" GOT = %" T_PRI64 "x", u.l); \
u.l = 0; u.a = exp; \
printf(" EXP = %" T_PRI64 "x\n", u.l); \
return __LINE__; \
#define CHECK_RESULT(type, got, exp) \
if ((got) != (exp)) { \
printf("%%Error: %s:%d:", __FILE__,__LINE__); \
union { type a; long long l; } u; \
u.l = 0; u.a = got; \
printf(" GOT = %" T_PRI64 "x", u.l); \
u.l = 0; u.a = exp; \
printf(" EXP = %" T_PRI64 "x\n", u.l); \
return __LINE__; \
}
#define CHECK_RESULT_NNULL(got) \
if (!(got)) { \
printf("%%Error: %s:%d: GOT = %p EXP = !NULL\n", __FILE__,__LINE__, (got)); \
return __LINE__; \
printf("%%Error: %s:%d: GOT = %p EXP = !NULL\n", __FILE__,__LINE__, (got)); \
return __LINE__; \
}
static int check_sub(const char* name, int i) {
@ -112,69 +112,69 @@ int dpix_run_tests() {
static int didDump = 0;
if (didDump++ == 0) {
# ifdef TEST_VERBOSE
Verilated::internalsDump();
Verilated::internalsDump();
# endif
}
#endif
#ifndef CADENCE // Unimplemented; how hard is it?
#ifndef CADENCE // Unimplemented; how hard is it?
printf("svDpiVersion: %s\n",svDpiVersion());
CHECK_RESULT (bool,
strcmp(svDpiVersion(), "1800-2005")==0
|| strcmp(svDpiVersion(), "P1800-2005")==0
, 1);
CHECK_RESULT(bool,
strcmp(svDpiVersion(), "1800-2005")==0
|| strcmp(svDpiVersion(), "P1800-2005")==0
, 1);
#endif
CHECK_RESULT (int, dpix_int123(), 0x123 );
CHECK_RESULT(int, dpix_int123(), 0x123 );
#ifndef CADENCE // No export calls from an import
int o;
dpix_t_int(0x456, &o);
CHECK_RESULT (unsigned long, o, ~0x456UL);
CHECK_RESULT(unsigned long, o, ~0x456UL);
dpix_t_renamed(0x456, &o);
CHECK_RESULT (int, o, 0x458UL);
CHECK_RESULT(int, o, 0x458UL);
#endif
svBitVecVal vec10[1] = {0x10};
CHECK_RESULT (int, dpix_f_bit(1), 0x0);
CHECK_RESULT (int, dpix_f_bit(0), 0x1);
CHECK_RESULT (int, dpix_f_bit15(vec10) & 0x7fUL, 0x6f);
CHECK_RESULT(int, dpix_f_bit(1), 0x0);
CHECK_RESULT(int, dpix_f_bit(0), 0x1);
CHECK_RESULT(int, dpix_f_bit15(vec10) & 0x7fUL, 0x6f);
// Simulators disagree over the next three's sign extension unless we mask the upper bits
CHECK_RESULT (int, dpix_f_int(1) & 0xffffffffUL, 0xfffffffeUL);
CHECK_RESULT (int, dpix_f_byte(1) & 0xffUL, 0xfe);
CHECK_RESULT (int, dpix_f_shortint(1) & 0xffffUL, 0xfffeUL);
CHECK_RESULT(int, dpix_f_int(1) & 0xffffffffUL, 0xfffffffeUL);
CHECK_RESULT(int, dpix_f_byte(1) & 0xffUL, 0xfe);
CHECK_RESULT(int, dpix_f_shortint(1) & 0xffffUL, 0xfffeUL);
CHECK_RESULT (unsigned long long, dpix_f_longint(1), 0xfffffffffffffffeULL);
CHECK_RESULT (void*, dpix_f_chandle((void*)(12345)), (void*)(12345));
CHECK_RESULT(unsigned long long, dpix_f_longint(1), 0xfffffffffffffffeULL);
CHECK_RESULT(void*, dpix_f_chandle((void*)(12345)), (void*)(12345));
{
svBitVecVal i_vec48[2] = {0xab782a12,0x8a413bd9};
svBitVecVal o_vec48[2] = {0,0};
dpix_t_bit48(i_vec48, o_vec48);
CHECK_RESULT(int, o_vec48[0], ~i_vec48[0]);
svBitVecVal i_vec48[2] = {0xab782a12,0x8a413bd9};
svBitVecVal o_vec48[2] = {0,0};
dpix_t_bit48(i_vec48, o_vec48);
CHECK_RESULT(int, o_vec48[0], ~i_vec48[0]);
#ifdef VCS // VCS has bug where doesn't clean input
CHECK_RESULT(int, o_vec48[1], (~i_vec48[1]));
CHECK_RESULT(int, o_vec48[1], (~i_vec48[1]));
#else
CHECK_RESULT(int, o_vec48[1], (~i_vec48[1])&0x0000ffffUL);
CHECK_RESULT(int, o_vec48[1], (~i_vec48[1])&0x0000ffffUL);
#endif
}
{
svBitVecVal i_vec95[3] = {0x72912312,0xab782a12,0x8a413bd9};
svBitVecVal o_vec95[3] = {0,0,0};
dpix_t_bit95(i_vec95, o_vec95);
CHECK_RESULT(int, o_vec95[0], ~i_vec95[0]);
CHECK_RESULT(int, o_vec95[1], ~i_vec95[1]);
CHECK_RESULT(int, o_vec95[2], (~i_vec95[2])&0x7fffffffUL);
svBitVecVal i_vec95[3] = {0x72912312,0xab782a12,0x8a413bd9};
svBitVecVal o_vec95[3] = {0,0,0};
dpix_t_bit95(i_vec95, o_vec95);
CHECK_RESULT(int, o_vec95[0], ~i_vec95[0]);
CHECK_RESULT(int, o_vec95[1], ~i_vec95[1]);
CHECK_RESULT(int, o_vec95[2], (~i_vec95[2])&0x7fffffffUL);
}
{
svBitVecVal i_vec96[3] = {0xf2912312,0xab782a12,0x8a413bd9};
svBitVecVal o_vec96[3] = {0,0,0};
dpix_t_bit96(i_vec96, o_vec96);
CHECK_RESULT(int, o_vec96[0], ~i_vec96[0]);
CHECK_RESULT(int, o_vec96[1], ~i_vec96[1]);
CHECK_RESULT(int, o_vec96[2], ~i_vec96[2]);
svBitVecVal i_vec96[3] = {0xf2912312,0xab782a12,0x8a413bd9};
svBitVecVal o_vec96[3] = {0,0,0};
dpix_t_bit96(i_vec96, o_vec96);
CHECK_RESULT(int, o_vec96[0], ~i_vec96[0]);
CHECK_RESULT(int, o_vec96[1], ~i_vec96[1]);
CHECK_RESULT(int, o_vec96[2], ~i_vec96[2]);
}
extern void dpix_t_reg(svLogic i, svLogic* o);

View File

@ -54,23 +54,23 @@ extern "C" {
extern double dpii_f_real (double i);
extern float dpii_f_shortreal(float i);
extern void dpii_v_bit (unsigned char i, unsigned char* o);
extern void dpii_v_int (int i, int *o);
extern void dpii_v_uint (unsigned int i, unsigned int *o);
extern void dpii_v_byte (char i, char *o);
extern void dpii_v_shortint (short int i, short int *o);
extern void dpii_v_ushort (unsigned short i, unsigned short *o);
extern void dpii_v_longint (long long i, long long *o);
extern void dpii_v_ulong (unsigned long long i, unsigned long long *o);
extern void dpii_v_struct (const svBitVecVal* i, svBitVecVal* o);
extern void dpii_v_substruct (const svBitVecVal* i, int* o);
extern void dpii_v_chandle (void* i, void* *o);
extern void dpii_v_bit (unsigned char i, unsigned char* o);
extern void dpii_v_int (int i, int *o);
extern void dpii_v_uint (unsigned int i, unsigned int *o);
extern void dpii_v_byte (char i, char *o);
extern void dpii_v_shortint (short int i, short int *o);
extern void dpii_v_ushort (unsigned short i, unsigned short *o);
extern void dpii_v_longint (long long i, long long *o);
extern void dpii_v_ulong (unsigned long long i, unsigned long long *o);
extern void dpii_v_struct (const svBitVecVal* i, svBitVecVal* o);
extern void dpii_v_substruct (const svBitVecVal* i, int* o);
extern void dpii_v_chandle (void* i, void* *o);
extern void dpii_v_string (const char* i, const char** o);
extern void dpii_v_real (double i, double* o);
extern void dpii_v_shortreal(float i, float* o);
extern void dpii_v_struct (const svBitVecVal* i, svBitVecVal* o);
extern void dpii_v_substruct (const svBitVecVal* i, int* o);
extern void dpii_v_struct (const svBitVecVal* i, svBitVecVal* o);
extern void dpii_v_substruct (const svBitVecVal* i, int* o);
extern void dpii_v_bit64(const svBitVecVal* i, svBitVecVal* o);
extern void dpii_v_bit95(const svBitVecVal* i, svBitVecVal* o);
extern void dpii_v_bit96(const svBitVecVal* i, svBitVecVal* o);
@ -100,17 +100,17 @@ svBitVecVal dpii_f_bit9 (const svBitVecVal *i) { return 0x1ffUL & ~*i;
svBitVecVal dpii_f_bit16(const svBitVecVal *i) { return 0xffffUL & ~*i; }
svBitVecVal dpii_f_bit17(const svBitVecVal *i) { return 0x1ffffUL & ~*i; }
svBitVecVal dpii_f_bit32(const svBitVecVal *i) { return ~*i; }
long long dpii_f_bit33(const svBitVecVal *i) { return ((1ULL<<33)-1) & ~((long long)(i[1])<<32ULL | i[0]); }
long long dpii_f_bit64(const svBitVecVal *i) { return ~((long long)(i[1])<<32ULL | i[0]); }
long long dpii_f_bit33(const svBitVecVal *i) { return ((1ULL<<33)-1) & ~((long long)(i[1])<<32ULL | i[0]); }
long long dpii_f_bit64(const svBitVecVal *i) { return ~((long long)(i[1])<<32ULL | i[0]); }
int dpii_f_int (int i) { return ~i; }
char dpii_f_byte (char i) { return ~i; }
short int dpii_f_shortint(short int i) { return ~i; }
long long dpii_f_longint (long long i) { return ~i; }
void* dpii_f_chandle (void* i) { return i; }
const char* dpii_f_string (const char* i) { return i; }
double dpii_f_real (double i) { return i+1.5; }
float dpii_f_shortreal(float i) { return i+1.5f; }
int dpii_f_int (int i) { return ~i; }
char dpii_f_byte (char i) { return ~i; }
short int dpii_f_shortint(short int i) { return ~i; }
long long dpii_f_longint (long long i) { return ~i; }
void* dpii_f_chandle (void* i) { return i; }
const char* dpii_f_string (const char* i) { return i; }
double dpii_f_real (double i) { return i+1.5; }
float dpii_f_shortreal(float i) { return i+1.5f; }
void dpii_v_bit(unsigned char i, unsigned char *o) { *o = 1 & ~i; }
void dpii_v_int(int i, int *o) { *o = ~i; }
@ -149,33 +149,33 @@ void dpii_v_time(const svLogicVecVal* i, svLogicVecVal* o) {
o[1].bval = 0;
}
void dpii_v_struct (const svBitVecVal* i, svBitVecVal* o) {
void dpii_v_struct(const svBitVecVal* i, svBitVecVal* o) {
o[0] = ~i[0];
o[1] = ~i[1];
o[2] = ~i[2];
}
void dpii_v_substruct (const svBitVecVal* i, int* o) {
void dpii_v_substruct(const svBitVecVal* i, int* o) {
// To be most like other tools, this should automagically take the substruct_t
// as an argument, and not require this cast...
substruct_t* issp = (substruct_t*) i;
o[0] = issp->b - issp->a;
}
void dpii_v_bit64(const svBitVecVal* i, svBitVecVal* o) {
void dpii_v_bit64(const svBitVecVal* i, svBitVecVal* o) {
o[0] = ~i[0];
o[1] = ~i[1];
}
void dpii_v_bit95(const svBitVecVal* i, svBitVecVal* o) {
void dpii_v_bit95(const svBitVecVal* i, svBitVecVal* o) {
o[0] = (~i[0]);
o[1] = (~i[1]);
o[2] = (~i[2]) & 0x7fffffffUL;
}
void dpii_v_bit96(const svBitVecVal* i, svBitVecVal* o) {
void dpii_v_bit96(const svBitVecVal* i, svBitVecVal* o) {
o[0] = ~i[0];
o[1] = ~i[1];
o[2] = ~i[2];
}
int dpii_f_strlen (const char* i) { return strlen(i); }
int dpii_f_strlen(const char* i) { return strlen(i); }
//======================================================================

View File

@ -56,9 +56,9 @@ int dpii_failure() { return failure; }
void dpii_lib_bit_check() {
svBitVecVal bv [3];
bv[0] = 0xa3a2a1a0; // 31..0
bv[1] = 0xa7a6a5a4; // 63..32
bv[2] = 0xabaaa9a8; // 95..64
bv[0] = 0xa3a2a1a0; // 31..0
bv[1] = 0xa7a6a5a4; // 63..32
bv[2] = 0xabaaa9a8; // 95..64
CHECK_RESULT_HEX((int)svGetBitselBit(bv, 32), 0);
CHECK_RESULT_HEX((int)svGetBitselBit(bv, 33), 0);
CHECK_RESULT_HEX((int)svGetBitselBit(bv, 34), 1);
@ -88,12 +88,12 @@ void dpii_lib_bit_check() {
void dpii_lib_logic_check() {
svLogicVecVal lv [3];
lv[0].aval = 0xb3b2b1b0; // 31..0
lv[1].aval = 0xb7b6b5b4; // 63..32
lv[2].aval = 0xbbbab9b8; // 95..64
lv[0].bval = 0xc3c2c1c0; // 31..0
lv[1].bval = 0xc7c6c5c4; // 63..32
lv[2].bval = 0xcbcac9c8; // 95..64
lv[0].aval = 0xb3b2b1b0; // 31..0
lv[1].aval = 0xb7b6b5b4; // 63..32
lv[2].aval = 0xbbbab9b8; // 95..64
lv[0].bval = 0xc3c2c1c0; // 31..0
lv[1].bval = 0xc7c6c5c4; // 63..32
lv[2].bval = 0xcbcac9c8; // 95..64
CHECK_RESULT_HEX((int)svGetBitselLogic(lv, 32), 0);
CHECK_RESULT_HEX((int)svGetBitselLogic(lv, 33), 0);
CHECK_RESULT_HEX((int)svGetBitselLogic(lv, 34), 3);

View File

@ -85,7 +85,7 @@ int dpii_failure() { return failure; }
#ifdef _WIN32
# define T_PRI64 "I64"
#else // Linux or compliant Unix flavors
#else // Linux or compliant Unix flavors
# define T_PRI64 "ll"
#endif

View File

@ -47,10 +47,10 @@ int main(int argc, char *argv[]) {
topp->in = 1.1;
topp->eval();
if (topp->out != 1.2) {
VL_PRINTF("*-* All Finished *-*\n");
topp->final();
VL_PRINTF("*-* All Finished *-*\n");
topp->final();
} else {
vl_fatal(__FILE__,__LINE__,"top", "Unexpected results\n");
vl_fatal(__FILE__,__LINE__,"top", "Unexpected results\n");
}
return 0;
}

View File

@ -42,7 +42,7 @@ void mon_do(MyMon* monp) {
#ifdef TEST_VERBOSE
VL_PRINTF("- mon_do(%08x(&%p) -> %08x(&%p));\n",
*(monp->sigsp[0]), monp->sigsp[0], *(monp->sigsp[1]), monp->sigsp[1]);
*(monp->sigsp[0]), monp->sigsp[0], *(monp->sigsp[1]), monp->sigsp[1]);
#endif
}
@ -74,13 +74,13 @@ void mon_register_b(const char* namep, int isOut) {
const VerilatedScope* scopep = Verilated::dpiScope();
const VerilatedVar* varp = scopep->varFind(namep);
if (!varp) {
VL_PRINTF("%%Warning: mon_register_b signal not found: \"%s\"\n", namep);
VL_PRINTF("%%Warning: mon_register_b signal not found: \"%s\"\n", namep);
} else if (varp->vltype() != VLVT_UINT32) {
VL_PRINTF("%%Warning: wrong type for signal: \"%s\"\n", namep);
VL_PRINTF("%%Warning: wrong type for signal: \"%s\"\n", namep);
} else {
vluint32_t* datap = (vluint32_t*)(varp->datap());
VL_PRINTF("- mon_register_b('%s', \"%s\", %p, %d);\n", modp, namep, datap, isOut);
mons[1].sigsp[isOut] = (vluint32_t*)(varp->datap());
vluint32_t* datap = (vluint32_t*)(varp->datap());
VL_PRINTF("- mon_register_b('%s', \"%s\", %p, %d);\n", modp, namep, datap, isOut);
mons[1].sigsp[isOut] = (vluint32_t*)(varp->datap());
}
}
@ -93,10 +93,10 @@ void mon_register_done() {
// Print list of all signals - if we didn't register2 anything we'd pick them off here
const VerilatedScope* scopep = Verilated::dpiScope();
if (VerilatedVarNameMap* varsp = scopep->varsp()) {
for (VerilatedVarNameMap::const_iterator it = varsp->begin();
it != varsp->end(); ++it) {
VL_PRINTF("- mon2: %s\n", it->first);
}
for (VerilatedVarNameMap::const_iterator it = varsp->begin();
it != varsp->end(); ++it) {
VL_PRINTF("- mon2: %s\n", it->first);
}
}
}
@ -132,13 +132,13 @@ int main(int argc, char **argv, char **env) {
main_time += 10;
while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) {
main_time += 1;
topp->eval();
topp->clk = !topp->clk;
//mon_do();
main_time += 1;
topp->eval();
topp->clk = !topp->clk;
//mon_do();
}
if (!Verilated::gotFinish()) {
vl_fatal(__FILE__,__LINE__,"main", "%Error: Timeout; never got a $finish");
vl_fatal(__FILE__,__LINE__,"main", "%Error: Timeout; never got a $finish");
}
topp->final();

View File

@ -45,24 +45,24 @@ extern "C" {
//======================================================================
extern int T_Embed_Child_Unique;
int T_Embed_Child_Unique = 0; // Address used for uniqueness
int T_Embed_Child_Unique = 0; // Address used for uniqueness
Vt_embed1_child* __get_modelp() {
svScope scope = svGetScope();
if (!scope) {
vl_fatal(__FILE__,__LINE__,__FILE__,"svGetScope failed");
return NULL;
vl_fatal(__FILE__,__LINE__,__FILE__,"svGetScope failed");
return NULL;
}
void* __modelp = svGetUserData(scope, &T_Embed_Child_Unique);
if (!__modelp) {
// Create the model
const char* scopenamep = svGetNameFromScope(scope);
if (!scopenamep) vl_fatal(__FILE__,__LINE__,__FILE__,"svGetNameFromScope failed");
__modelp = new Vt_embed1_child(scopenamep);
if (svPutUserData(scope, &T_Embed_Child_Unique, __modelp)) {
vl_fatal(__FILE__,__LINE__,__FILE__,"svPutUserData failed");
}
// Create the model
const char* scopenamep = svGetNameFromScope(scope);
if (!scopenamep) vl_fatal(__FILE__,__LINE__,__FILE__,"svGetNameFromScope failed");
__modelp = new Vt_embed1_child(scopenamep);
if (svPutUserData(scope, &T_Embed_Child_Unique, __modelp)) {
vl_fatal(__FILE__,__LINE__,__FILE__,"svPutUserData failed");
}
}
return (Vt_embed1_child*)(__modelp);
}
@ -97,8 +97,8 @@ void t_embed_child_io_eval(unsigned char clk,
VL_DEBUG_IF(VL_PRINTF(" t_embed1_child_io_eval\n"); );
Vt_embed1_child* __modelp = __get_modelp();
VL_DEBUG_IF(VL_PRINTF("[%0ld] in clk=%x b=%x V=%x R=%x\n",
(long int) (VL_TIME_Q()), clk, bit_in, vec_in[0],
is_ref););
(long int) (VL_TIME_Q()), clk, bit_in, vec_in[0],
is_ref););
__modelp->clk = clk;
__modelp->bit_in = bit_in;
__modelp->vec_in = vec_in[0];
@ -120,6 +120,6 @@ void t_embed_child_io_eval(unsigned char clk,
wide_out[3] = __modelp->wide_out[3];
*did_init_out = __modelp->did_init_out;
VL_DEBUG_IF(VL_PRINTF("[%0ld] out b=%x V=%x DI=%x\n",
(long int)(VL_TIME_Q()), *bit_out, *vec_out,
*did_init_out););
(long int)(VL_TIME_Q()), *bit_out, *vec_out,
*did_init_out););
}

View File

@ -17,7 +17,7 @@ scenarios(vlt => 1);
print "Old mtime=",$oldstats[9],"\n";
$oldstats[9] or error("No output file found: $outfile\n");
sleep (1); # Or else it might take < 1 second to compile and see no diff.
sleep(1); # Or else it might take < 1 second to compile and see no diff.
compile();

View File

@ -15,13 +15,13 @@ int main(int argc, char *argv[]) {
printf("\nTesting\n");
for (int i = 0; i < 10; i++) {
topp->clk = 0;
topp->eval();
topp->clk = 1;
topp->eval();
topp->clk = 0;
topp->eval();
topp->clk = 1;
topp->eval();
}
if (topp->Rand != 0xfeed0fad) {
vl_fatal(__FILE__,__LINE__,"top", "Unexpected value for Rand output\n");
vl_fatal(__FILE__,__LINE__,"top", "Unexpected value for Rand output\n");
}
printf("*-* All Finished *-*\n");
}

View File

@ -52,7 +52,7 @@ my $global_mtask_ct = 0;
$gantt_line_ct++;
my $this_thread_mtask_ct = 0;
my @mtasks = split(/\[/, $line);
shift @mtasks; # throw the '>> ' away
shift @mtasks; # throw the '>> ' away
foreach my $mtask (@mtasks) {
# Format of each mtask is "[123--]" where the hyphens
# number or ] may or may not appear; it depends on exact timing.

View File

@ -53,7 +53,7 @@ execute(
);
# Must be <<9000 above to prove this worked
file_grep ($Self->{stats}, qr/Optimizations, Gate sigs deleted\s+(\d+)/i, 8575);
file_grep($Self->{stats}, qr/Optimizations, Gate sigs deleted\s+(\d+)/i, 8575);
ok(1);
1;

View File

@ -22,7 +22,7 @@ foreach my $prog (
logfile => "$Self->{obj_dir}/t_help.log",
tee => 0,
);
file_grep ("$Self->{obj_dir}/t_help.log", qr/DISTRIBUTION/i);
file_grep("$Self->{obj_dir}/t_help.log", qr/DISTRIBUTION/i);
}
ok(1);

View File

@ -38,8 +38,8 @@ sub checkRelativeRefs {
if ($Self->{vlt_all}) {
# We expect to combine sequent functions across multiple instances of
# l2, l3, l4, l5. If this number drops, please confirm this has not broken.
file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i,
($Self->{vltmt} ? 84 : 52));
file_grep($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i,
($Self->{vltmt} ? 84 : 52));
# Expect absolute refs in CFuncs for t (top module) and l1 (because it
# has only one instance)

View File

@ -18,8 +18,8 @@ compile(
if ($Self->{vlt_all}) {
# Fewer optimizations than t_inst_tree_inl0_pub1 which allows
# relative CFuncs:
file_grep ($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i,
($Self->{vltmt} ? 0 : 31));
file_grep($Self->{stats}, qr/Optimizations, Combined CFuncs\s+(\d+)/i,
($Self->{vltmt} ? 0 : 31));
# Should not find any 'this->' except some 'this->__VlSymsp'
my @files = `ls $Self->{obj_dir}/*.cpp`;

View File

@ -11,7 +11,7 @@ scenarios(simulator => 1);
compile(
v_flags2 => ['+libext+.vi+.extranoneed'],
nc => 0, # Error: Multiple +libext flags found
nc => 0, # Error: Multiple +libext flags found
vcs => 0,
);

View File

@ -20,7 +20,7 @@ double sc_time_stamp() {
long long get_memory_usage() {
// Return memory usage. Return 0 if the system doesn't look quite right.
#if 0 // BSD only.
#if 0 // BSD only.
struct rusage usage;
getrusage(RUSAGE_SELF, &usage);
return usage.ru_ixrss + usage.ru_idrss + usage.ru_isrss;
@ -29,20 +29,20 @@ long long get_memory_usage() {
FILE* fp = fopen("/proc/self/stat", "r");
if (!fp) return 0;
int ps_ign;
vluint64_t ps_vsize, ps_rss;
int ps_ign;
vluint64_t ps_vsize, ps_rss;
int items = fscanf(fp, ("%d (%*[^) ]) %*1s %d %*d %*d %*d %*d %u"
" %u %u %u %u %d %d %d %d"
" %*d %*d %*u %*u %d %" VL_PRI64 "u %" VL_PRI64 "u "),
&ps_ign, &ps_ign, &ps_ign,
&ps_ign, &ps_ign, &ps_ign, &ps_ign,
&ps_ign, &ps_ign, &ps_ign, &ps_ign,
&ps_ign, &ps_vsize, &ps_rss);
" %u %u %u %u %d %d %d %d"
" %*d %*d %*u %*u %d %" VL_PRI64 "u %" VL_PRI64 "u "),
&ps_ign, &ps_ign, &ps_ign,
&ps_ign, &ps_ign, &ps_ign, &ps_ign,
&ps_ign, &ps_ign, &ps_ign, &ps_ign,
&ps_ign, &ps_vsize, &ps_rss);
fclose(fp);
if (items >= 14) {
return ps_vsize;
return ps_vsize;
} else {
return 0;
return 0;
}
}
@ -54,9 +54,9 @@ void make_and_destroy() {
topp->eval();
topp->clk = true;
while (!Verilated::gotFinish()) {
main_time+=5;
topp->clk=!topp->clk;
topp->eval();
main_time+=5;
topp->clk=!topp->clk;
topp->eval();
}
delete topp; topp=NULL;
@ -67,22 +67,22 @@ int main(int argc, char *argv[]) {
// Warmup phase
for (int i=0; i<1000; i++) {
make_and_destroy();
make_and_destroy();
}
firstUsage = get_memory_usage();
printf("Memory size %" VL_PRI64 "d bytes\n", firstUsage);
int loops = 100*1000;
for (int left=loops; left>0;) {
for (int j=0; j<1000; j++, left--) {
make_and_destroy();
}
for (int j=0; j<1000; j++, left--) {
make_and_destroy();
}
}
vluint64_t leaked = get_memory_usage() - firstUsage;
if (leaked > 64*1024) { // Have to allow some slop for this code.
printf("Leaked %" VL_PRI64 "d bytes, or ~ %" VL_PRI64 "d bytes/construt\n", leaked, leaked/loops);
vl_fatal(__FILE__,__LINE__,"top", "Leaked memory\n");
vl_fatal(__FILE__,__LINE__,"top", "Leaked memory\n");
}
printf("*-* All Finished *-*\n");

View File

@ -6,7 +6,7 @@
QData MaskVal(int lbit, int hbit) {
QData val;
for (val = 0; lbit <= hbit; lbit++)
val |= (1ULL << lbit);
val |= (1ULL << lbit);
return val;
}
@ -18,35 +18,35 @@ int main(int argc, char *argv[]) {
int errs=0;
for (lbit = 0; lbit < 32; lbit++) {
for (hbit = lbit; hbit < 32; hbit++) {
QData expected;
for (hbit = lbit; hbit < 32; hbit++) {
QData expected;
sim->LowMaskSel_Bot = lbit;
sim->LowMaskSel_Top = lbit;
sim->HighMaskSel_Bot = hbit;
sim->HighMaskSel_Top = hbit;
sim->LowMaskSel_Bot = lbit;
sim->LowMaskSel_Top = lbit;
sim->HighMaskSel_Bot = hbit;
sim->HighMaskSel_Top = hbit;
sim->eval();
sim->eval();
expected = (MaskVal(sim->LowMaskSel_Top, sim->HighMaskSel_Top) << 32ULL)
| MaskVal(sim->LowMaskSel_Bot, sim->HighMaskSel_Bot);
if (sim->LogicImm != expected) {
if (sim->LogicImm != expected) {
printf("%%Error: %d.%d,%d.%d -> %016" VL_PRI64 "x/%016" VL_PRI64 "x -> %016" VL_PRI64 "x (expected %016" VL_PRI64 "x)\n",
sim->LowMaskSel_Top, sim->HighMaskSel_Top,
sim->LowMaskSel_Bot, sim->HighMaskSel_Bot,
sim->LowLogicImm, sim->HighLogicImm,
sim->LogicImm, expected);
errs=1;
}
}
errs=1;
}
}
}
if (errs) {
vl_stop(__FILE__, __LINE__, "TOP-cpp");
exit(10);
vl_stop(__FILE__, __LINE__, "TOP-cpp");
exit(10);
} else {
printf("*-* All Finished *-*\n");
exit(0);
exit(0);
}
}

View File

@ -14,8 +14,8 @@ double sc_time_stamp() {
void check(const char* bus, int got, int exp) {
if (got != exp) {
VL_PRINTF("%%Error: Data mismatch on '%s', got=%x, exp=%x\n", bus, got, exp);
pass = false;
VL_PRINTF("%%Error: Data mismatch on '%s', got=%x, exp=%x\n", bus, got, exp);
pass = false;
}
}
@ -29,22 +29,22 @@ int main()
tb = new VM_PREFIX("tb");
#ifdef SYSTEMC_VERSION
sc_signal<vluint32_t> i3;
sc_signal<vluint32_t> o3;
sc_signal<vluint32_t> i34[4];
sc_signal<vluint32_t> o34[4];
sc_signal<vluint32_t> i345[4][5];
sc_signal<vluint32_t> o345[4][5];
sc_signal<vluint32_t> i3;
sc_signal<vluint32_t> o3;
sc_signal<vluint32_t> i34[4];
sc_signal<vluint32_t> o34[4];
sc_signal<vluint32_t> i345[4][5];
sc_signal<vluint32_t> o345[4][5];
tb->i3(i3);
tb->o3(o3);
for (int i=0; i<4; i++) {
tb->i34[i](i34[i]);
tb->o34[i](o34[i]);
for (int j=0; j<5; j++) {
tb->i345[i][j](i345[i][j]);
tb->o345[i][j](o345[i][j]);
}
tb->i34[i](i34[i]);
tb->o34[i](o34[i]);
for (int j=0; j<5; j++) {
tb->i345[i][j](i345[i][j]);
tb->o345[i][j](o345[i][j]);
}
}
#endif
@ -61,10 +61,10 @@ int main()
ASSIGN(i3, 13);
for (int i=0; i<4; i++) {
ASSIGN(i34[i], i);
for (int j=0; j<5; j++) {
ASSIGN(i345[i][j], i*8 + j);
}
ASSIGN(i34[i], i);
for (int j=0; j<5; j++) {
ASSIGN(i345[i][j], i*8 + j);
}
}
#ifdef SYSTEMC_VERSION
@ -75,16 +75,16 @@ int main()
check("o3", READ(o3), 13);
for (int i=0; i<4; i++) {
check("o34", READ(o34[i]), i);
for (int j=0; j<5; j++) {
check("o345", READ(o345[i][j]), i*8 + j);
}
check("o34", READ(o34[i]), i);
for (int j=0; j<5; j++) {
check("o345", READ(o345[i][j]), i*8 + j);
}
}
if (pass) {
VL_PRINTF("*-* All Finished *-*\n");
VL_PRINTF("*-* All Finished *-*\n");
} else {
vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from test\n");
vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from test\n");
}
return 0;
}

View File

@ -25,9 +25,9 @@ int main()
bool pass = true;
if (pass) {
VL_PRINTF("*-* All Finished *-*\n");
VL_PRINTF("*-* All Finished *-*\n");
} else {
vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from test\n");
vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from test\n");
}
return 0;
}

View File

@ -14,7 +14,7 @@ compile(
);
if ($Self->{vlt_all}) {
file_grep ($Self->{stats}, qr/Optimizations, Delayed shared-sets\s+(\d+)/i, 14);
file_grep($Self->{stats}, qr/Optimizations, Delayed shared-sets\s+(\d+)/i, 14);
}
execute(

View File

@ -30,9 +30,9 @@ unsigned int StepSim(Vt_mem_slot *sim, unsigned int slot, unsigned int bit, unsi
}
if (val)
Array[slot] |= (1 << bit);
Array[slot] |= (1 << bit);
else
Array[slot] &= ~(1 << bit);
Array[slot] &= ~(1 << bit);
return sim->OutputVal;
}
@ -45,7 +45,7 @@ int main(int argc, char *argv[]) {
/* clear all bits in the array */
for (slot = 0; slot < 3; slot++)
for (bit = 0; bit < 2; bit++)
for (bit = 0; bit < 2; bit++)
StepSim(sim, slot, bit, 0, 0);
printf("\nTesting\n");

View File

@ -21,8 +21,8 @@ bool fail = false;
void check(QData got, QData exp) {
if (got != exp) {
VL_PRINTF("%%Error: got=0x%" VL_PRI64 "x exp=0x%" VL_PRI64 "x\n", got, exp);
fail = true;
VL_PRINTF("%%Error: got=0x%" VL_PRI64 "x exp=0x%" VL_PRI64 "x\n", got, exp);
fail = true;
}
}
@ -41,10 +41,10 @@ int main(int argc, char *argv[]) {
topp->final();
if (!fail) {
VL_PRINTF("*-* All Finished *-*\n");
topp->final();
VL_PRINTF("*-* All Finished *-*\n");
topp->final();
} else {
vl_fatal(__FILE__,__LINE__,"top", "Unexpected results\n");
vl_fatal(__FILE__,__LINE__,"top", "Unexpected results\n");
}
return 0;
}

View File

@ -17,38 +17,38 @@ print STDERR "t_pipe_filter.pf: Hello in Perl\n" if $Debug;
while (defined(my $cmd = <STDIN>)) {
print STDERR "t_pipe_filter.pf: gotcmd: $cmd" if $Debug;
if ($cmd =~ /^read "(.*)"/) {
my $filename = $1;
open(my $fh, "<$filename")
or die "t_pipe_filter.pf: %Error: $! $filename\n";
my $filename = $1;
open(my $fh, "<$filename")
or die "t_pipe_filter.pf: %Error: $! $filename\n";
my $wholefile="";
# It's faster to slurp the whole file then scan (if needed),
# then to read it into an array with getlines
{ local $/; undef $/; $wholefile = <$fh>; }
close $fh;
my $wholefile="";
# It's faster to slurp the whole file then scan (if needed),
# then to read it into an array with getlines
{ local $/; undef $/; $wholefile = <$fh>; }
close $fh;
if ($wholefile =~ /example_lint/) { # else short circuit
my $lineno = 1; my $pos=0;
my @prefixes;
while (1) {
my $newpos=index($wholefile,"\n",$pos);
last if $newpos<$pos;
my $line = substr($wholefile,$pos,$newpos-$pos);
if ($line =~ /example_lint/) {
# We don't have a way to specify this yet, so just for now
#print STDERR $line;
push @prefixes, "int lint_off_line_${lineno} = 1;\n";
}
$lineno++;
$pos = $newpos+1;
}
#print STDERR "Line count: $lineno\n";
$wholefile = join('',@prefixes) . $wholefile;
}
if ($wholefile =~ /example_lint/) { # else short circuit
my $lineno = 1; my $pos=0;
my @prefixes;
while (1) {
my $newpos=index($wholefile,"\n",$pos);
last if $newpos<$pos;
my $line = substr($wholefile,$pos,$newpos-$pos);
if ($line =~ /example_lint/) {
# We don't have a way to specify this yet, so just for now
#print STDERR $line;
push @prefixes, "int lint_off_line_${lineno} = 1;\n";
}
$lineno++;
$pos = $newpos+1;
}
#print STDERR "Line count: $lineno\n";
$wholefile = join('',@prefixes) . $wholefile;
}
print STDOUT "Content-Length: ".length($wholefile)."\n".$wholefile."\n";
print STDOUT "Content-Length: ".length($wholefile)."\n".$wholefile."\n";
} else {
die "t_pipe_filter.pf: %Error: Unknown command: $cmd\n";
die "t_pipe_filter.pf: %Error: Unknown command: $cmd\n";
}
}

View File

@ -19,10 +19,10 @@ execute(
);
if ($Self->{vlt_all}) {
file_grep ($Self->{stats}, qr/Optimizations, Reloop iterations\s+(\d+)/i,
768);
file_grep ($Self->{stats}, qr/Optimizations, Reloops\s+(\d+)/i,
3);
file_grep($Self->{stats}, qr/Optimizations, Reloop iterations\s+(\d+)/i,
768);
file_grep($Self->{stats}, qr/Optimizations, Reloops\s+(\d+)/i,
3);
}
ok(1);

View File

@ -13,7 +13,7 @@ top_filename("t/t_sys_readmem.v");
# Use random reset to ensure we're fully initializing arrays before
# $writememh, to avoid miscompares with X's on 4-state simulators.
$Self->{verilated_randReset} = 2; # 2 == truly random
$Self->{verilated_randReset} = 2; # 2 == truly random
compile(v_flags2 => [
"+define+WRITEMEM_READ_BACK=1",

View File

@ -17,7 +17,7 @@ execute(
check_finished => 1,
);
file_grep ("$Self->{obj_dir}/simx.vcd", qr/\$enddefinitions/x);
file_grep("$Self->{obj_dir}/simx.vcd", qr/\$enddefinitions/x);
ok(1);
1;

View File

@ -39,26 +39,26 @@ int main(int argc, char **argv, char **env) {
while (main_time < 190) { // Creates 2 files
top->clk = !top->clk;
top->eval();
top->eval();
if ((main_time % 100) == 0) {
if ((main_time % 100) == 0) {
#if defined(T_TRACE_CAT)
tfp->openNext(true);
tfp->openNext(true);
#elif defined(T_TRACE_CAT_REOPEN)
tfp->close();
tfp->open(trace_name());
tfp->close();
tfp->open(trace_name());
#elif defined(T_TRACE_CAT_RENEW)
tfp->close();
delete tfp;
tfp = new VerilatedVcdC;
top->trace(tfp,99);
tfp->open(trace_name());
tfp->close();
delete tfp;
tfp = new VerilatedVcdC;
top->trace(tfp,99);
tfp->open(trace_name());
#else
# error "Unknown test"
#endif
}
tfp->dump((unsigned int)(main_time));
++main_time;
}
tfp->dump((unsigned int)(main_time));
++main_time;
}
tfp->close();
top->final();

View File

@ -19,7 +19,7 @@ execute(
check_finished => 1,
);
file_grep ("$Self->{obj_dir}/simx.vcd", qr/ PARAM /);
file_grep ("$Self->{obj_dir}/simx.vcd", qr/ PARAM /);
vcd_identical("$Self->{obj_dir}/simx.vcd", $Self->{golden_filename});

View File

@ -25,7 +25,7 @@ else {
if ($Self->{vlt_all}) {
# Note more checks in _cc.pl
file_grep ("$Self->{obj_dir}/simx.vcd", qr/\$enddefinitions/x);
file_grep ("$Self->{obj_dir}/simx.vcd", qr/\$enddefinitions/x);
vcd_identical("$Self->{obj_dir}/simx.vcd", $Self->{golden_filename});
}

View File

@ -33,13 +33,13 @@ int main(int argc, char **argv, char **env) {
tfp->open(STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
while (main_time <= 20) {
top->CLK = (main_time/dt_2)%2;
top->eval();
top->CLK = (main_time/dt_2)%2;
top->eval();
top->t->glbl->setGSR(main_time < 7);
top->t->glbl->setGSR(main_time < 7);
tfp->dump((unsigned int)(main_time));
++main_time;
tfp->dump((unsigned int)(main_time));
++main_time;
}
tfp->close();
top->final();

View File

@ -33,13 +33,13 @@ int main(int argc, char **argv, char **env) {
tfp->open(STRINGIFY(TEST_OBJ_DIR) "/simx.vcd");
while (main_time <= 20) {
top->CLK = (main_time/dt_2)%2;
top->eval();
top->CLK = (main_time/dt_2)%2;
top->eval();
top->t->glbl->GSR = (main_time < 7);
top->t->glbl->GSR = (main_time < 7);
tfp->dump((unsigned int)(main_time));
++main_time;
tfp->dump((unsigned int)(main_time));
++main_time;
}
tfp->close();
top->final();

View File

@ -36,11 +36,11 @@ int main(int argc, char **argv, char **env) {
while (main_time < 190*VL_TIME_MULTIPLIER) {
top->clk = !top->clk;
top->eval();
tfp->dump((unsigned int)(main_time));
// Advance by 0.5 time units, to make sure our fractional
// time is working correctly
main_time += VL_TIME_MULTIPLIER/2;
top->eval();
tfp->dump((unsigned int)(main_time));
// Advance by 0.5 time units, to make sure our fractional
// time is working correctly
main_time += VL_TIME_MULTIPLIER/2;
}
tfp->close();
top->final();

View File

@ -21,16 +21,16 @@ bool check() {
#endif
if(tb->W == c && tb->X == c && tb->Y == c && tb->Z == c) {
pass = true;
if (verbose) printf("- pass: ");
pass = true;
if (verbose) printf("- pass: ");
} else {
pass = false;
verbose = true;
printf("%%E-FAIL: ");
pass = false;
verbose = true;
printf("%%E-FAIL: ");
}
if (verbose) {
printf("SEL=%d A=%d got: W=%d X=%d Y=%d Z=%d exp: WXYZ=%d\n",
tb->SEL, tb->A, tb->W, tb->X, tb->Y, tb->Z, c);
printf("SEL=%d A=%d got: W=%d X=%d Y=%d Z=%d exp: WXYZ=%d\n",
tb->SEL, tb->A, tb->W, tb->X, tb->Y, tb->Z, c);
}
return pass;
}
@ -43,19 +43,19 @@ int main() {
// loop through every possibility and check the result
for (tb->SEL=0; tb->SEL<2; tb->SEL++) {
for (tb->A=0; tb->A<4; tb->A++) {
tb->eval();
if(!check()) {
pass =false;
}
}
for (tb->A=0; tb->A<4; tb->A++) {
tb->eval();
if(!check()) {
pass =false;
}
}
}
if(pass) {
VL_PRINTF("*-* All Finished *-*\n");
tb->final();
VL_PRINTF("*-* All Finished *-*\n");
tb->final();
} else {
vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from tristate test\n");
vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from tristate test\n");
}
return 0;
}

View File

@ -15,17 +15,17 @@ bool check() {
bool pass;
int Z;
if (tb->SEL) {
Z = tb->A;
Z = tb->A;
} else {
Z = tb->B;
Z = tb->B;
}
if (tb->Z == tb->Y1 && tb->Z == tb->Y2 && tb->Z == Z) {
printf("PASS: ");
pass = true;
printf("PASS: ");
pass = true;
} else {
printf("FAIL: ");
pass = false;
printf("FAIL: ");
pass = false;
}
#ifdef TEST_VERBOSE
printf("SEL=%d A=%d B=%d Z=%d Y1=%d Y2=%d\n", tb->SEL, tb->A, tb->B, tb->Z, tb->Y1, tb->Y2);
@ -41,21 +41,21 @@ int main() {
// loop through every possibility and check the result
for (tb->SEL=0; tb->SEL<2; tb->SEL++) {
for (tb->A=0; tb->A<2; tb->A++) {
for (tb->B=0; tb->B<2; tb->B++) {
tb->eval();
if (!check()) {
pass = false;
}
}
}
for (tb->A=0; tb->A<2; tb->A++) {
for (tb->B=0; tb->B<2; tb->B++) {
tb->eval();
if (!check()) {
pass = false;
}
}
}
}
if(pass) {
VL_PRINTF("*-* All Finished *-*\n");
tb->final();
VL_PRINTF("*-* All Finished *-*\n");
tb->final();
} else {
vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from inout test\n");
vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from inout test\n");
}
return 0;
}

View File

@ -15,13 +15,13 @@ bool check() {
bool pass;
int Z, Y, X;
if (tb->OE) {
Z = tb->A;
Y = tb->A;
X = tb->A;
Z = tb->A;
Y = tb->A;
X = tb->A;
} else {
Z = 1;
Y = 0;
X = 1;
Z = 1;
Y = 0;
X = 1;
}
#ifdef TEST_VERBOSE
@ -31,12 +31,12 @@ bool check() {
#endif
if (tb->Z == Z && tb->Y == Y && tb->X == X) {
if (verbose) printf("PASS: ");
pass = true;
if (verbose) printf("PASS: ");
pass = true;
} else {
printf("%%E-FAIL: ");
verbose = true;
pass = false;
printf("%%E-FAIL: ");
verbose = true;
pass = false;
}
if (verbose) printf("OE=%d A=%d X=%d xexp=%d Y=%d yexp=%d Z=%d zexp=%d\n", tb->OE, tb->A, tb->X,X, tb->Y,Y, tb->Z,Z);
return pass;
@ -50,19 +50,19 @@ int main() {
// loop through every possibility and check the result
for (tb->OE=0; tb->OE<2; tb->OE++) {
for (tb->A=0; tb->A<2; tb->A++) {
tb->eval();
if (!check()) {
pass = false;
}
}
for (tb->A=0; tb->A<2; tb->A++) {
tb->eval();
if (!check()) {
pass = false;
}
}
}
if (pass) {
VL_PRINTF("*-* All Finished *-*\n");
tb->final();
VL_PRINTF("*-* All Finished *-*\n");
tb->final();
} else {
vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from pullup test\n");
vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from pullup test\n");
}
return 0;
}

View File

@ -17,24 +17,24 @@ bool check() {
#endif
int Y = ((tb->OE1) & (!tb->OE2)) ? tb->A1
: ((!tb->OE1) & (tb->OE2)) ? tb->A2
: ((tb->OE1) & (tb->OE2)) ? (tb->A1 | tb->A2)
: 3; // pullup
: ((!tb->OE1) & (tb->OE2)) ? tb->A2
: ((tb->OE1) & (tb->OE2)) ? (tb->A1 | tb->A2)
: 3; // pullup
int W = (((tb->OE2) ? (tb->A2 & 0x1) : 0) << tb->A1)
| (((tb->OE1) ? (tb->A2 >> 1)&0x1 : 0) << tb->A2);
| (((tb->OE1) ? (tb->A2 >> 1)&0x1 : 0) << tb->A2);
if(tb->Y1 == Y && tb->Y2 == Y && tb->Y3 == Y && tb->W == W) {
pass = true;
if (verbose) printf("- pass: ");
pass = true;
if (verbose) printf("- pass: ");
} else {
pass = false;
verbose = true;
printf("%%E-Fail: ");
pass = false;
verbose = true;
printf("%%E-Fail: ");
}
if (verbose) printf("Read: OE1=%d OE2=%d A1=0x%x A2=0x%x Y1=0x%x Y2=0x%x Y3=0x%x W=0x%x Expected: Y1=Y2=Y3=%d and W=0x%x\n",
tb->OE1, tb->OE2, tb->A1, tb->A2, tb->Y1, tb->Y2, tb->Y3, tb->W, Y,W);
tb->OE1, tb->OE2, tb->A1, tb->A2, tb->Y1, tb->Y2, tb->Y3, tb->W, Y,W);
return pass;
}
@ -46,23 +46,23 @@ int main() {
// loop through every possibility and check the result
for (tb->OE1=0; tb->OE1<2; tb->OE1++) {
for (tb->OE2=0; tb->OE2<2; tb->OE2++) {
for (tb->A1=0; tb->A1<4; tb->A1++) {
for (tb->A2=0; tb->A2<4; tb->A2++) {
tb->eval();
if(!check()) {
pass = false;
}
}
}
}
for (tb->OE2=0; tb->OE2<2; tb->OE2++) {
for (tb->A1=0; tb->A1<4; tb->A1++) {
for (tb->A2=0; tb->A2<4; tb->A2++) {
tb->eval();
if(!check()) {
pass = false;
}
}
}
}
}
if(pass) {
VL_PRINTF("*-* All Finished *-*\n");
tb->final();
VL_PRINTF("*-* All Finished *-*\n");
tb->final();
} else {
vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from t_tri_select\n");
vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from t_tri_select\n");
}
return 0;
}

View File

@ -35,7 +35,7 @@ int main(int argc, char **argv, char **env) {
topp->eval();
main_time += 10;
topp->clk = 0x2; // ILLEGAL
topp->clk = 0x2; // ILLEGAL
topp->eval();
topp->final();

View File

@ -53,37 +53,37 @@ unsigned int main_time = false;
#define CHECK_RESULT_VH(got, exp) \
if ((got) != (exp)) { \
printf("%%Error: %s:%d: GOT = %p EXP = %p\n", \
FILENM,__LINE__, (got), (exp)); \
return __LINE__; \
printf("%%Error: %s:%d: GOT = %p EXP = %p\n", \
FILENM,__LINE__, (got), (exp)); \
return __LINE__; \
}
#define CHECK_RESULT_NZ(got) \
if (!(got)) { \
printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM,__LINE__); \
return __LINE__; \
printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM,__LINE__); \
return __LINE__; \
}
// Use cout to avoid issues with %d/%lx etc
#define CHECK_RESULT(got, exp) \
if ((got) != (exp)) { \
cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__ \
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<endl; \
return __LINE__; \
if ((got) != (exp)) { \
cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__ \
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<endl; \
return __LINE__; \
}
#define CHECK_RESULT_HEX(got, exp) \
if ((got) != (exp)) { \
cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__<<hex \
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<endl; \
return __LINE__; \
if ((got) != (exp)) { \
cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__<<hex \
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<endl; \
return __LINE__; \
}
#define CHECK_RESULT_CSTR(got, exp) \
if (strcmp((got),(exp))) { \
printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", \
FILENM,__LINE__, (got)?(got):"<null>", (exp)?(exp):"<null>"); \
return __LINE__; \
printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", \
FILENM,__LINE__, (got)?(got):"<null>", (exp)?(exp):"<null>"); \
return __LINE__; \
}
#define CHECK_RESULT_CSTR_STRIP(got, exp) \
@ -91,7 +91,7 @@ unsigned int main_time = false;
static int _mon_check_props(TestVpiHandle& handle, int size, int direction, int scalar, int type) {
s_vpi_value value = {
vpiIntVal, .value = {.integer = 0}
vpiIntVal, .value = {.integer = 0}
};
// check size of object
int vpisize = vpi_get(vpiSize, handle);
@ -145,7 +145,7 @@ static int _mon_check_props(TestVpiHandle& handle, int size, int direction, int
CHECK_RESULT(vpitype, type);
}
return 0; // Ok
return 0; // Ok
}
struct params {
@ -201,7 +201,7 @@ int mon_check_props() {
int mon_check() {
// Callback from initial block in monitor
if (int status = mon_check_props()) return status;
return 0; // Ok
return 0; // Ok
}
//======================================================================
@ -267,17 +267,17 @@ int main(int argc, char **argv, char **env) {
main_time += 10;
while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) {
main_time += 1;
topp->eval();
VerilatedVpi::callValueCbs();
topp->clk = !topp->clk;
//mon_do();
main_time += 1;
topp->eval();
VerilatedVpi::callValueCbs();
topp->clk = !topp->clk;
//mon_do();
#if VM_TRACE
if (tfp) tfp->dump (main_time);
if (tfp) tfp->dump (main_time);
#endif
}
if (!Verilated::gotFinish()) {
vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish");
vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish");
}
topp->final();

View File

@ -53,37 +53,37 @@ unsigned int main_time = false;
#define CHECK_RESULT_VH(got, exp) \
if ((got) != (exp)) { \
printf("%%Error: %s:%d: GOT = %p EXP = %p\n", \
FILENM,__LINE__, (got), (exp)); \
return __LINE__; \
printf("%%Error: %s:%d: GOT = %p EXP = %p\n", \
FILENM,__LINE__, (got), (exp)); \
return __LINE__; \
}
#define CHECK_RESULT_NZ(got) \
if (!(got)) { \
printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM,__LINE__); \
return __LINE__; \
printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM,__LINE__); \
return __LINE__; \
}
// Use cout to avoid issues with %d/%lx etc
#define CHECK_RESULT(got, exp) \
if ((got) != (exp)) { \
cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__ \
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<endl; \
return __LINE__; \
cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__ \
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<endl; \
return __LINE__; \
}
#define CHECK_RESULT_HEX(got, exp) \
if ((got) != (exp)) { \
cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__<<hex \
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<endl; \
return __LINE__; \
cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__<<hex \
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<endl; \
return __LINE__; \
}
#define CHECK_RESULT_CSTR(got, exp) \
if (strcmp((got),(exp))) { \
printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", \
FILENM,__LINE__, (got)?(got):"<null>", (exp)?(exp):"<null>"); \
return __LINE__; \
printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", \
FILENM,__LINE__, (got)?(got):"<null>", (exp)?(exp):"<null>"); \
return __LINE__; \
}
#define CHECK_RESULT_CSTR_STRIP(got, exp) \
@ -92,7 +92,7 @@ unsigned int main_time = false;
int _mon_check_range(TestVpiHandle& handle, int size, int left, int right) {
TestVpiHandle iter_h, left_h, right_h;
s_vpi_value value = {
vpiIntVal, .value = {.integer = 0}
vpiIntVal, .value = {.integer = 0}
};
// check size of object
int vpisize = vpi_get(vpiSize, handle);
@ -115,15 +115,15 @@ int _mon_check_range(TestVpiHandle& handle, int size, int left, int right) {
// calculate size & check
coherency = abs(coherency) + 1;
CHECK_RESULT(coherency, size);
return 0; // Ok
return 0; // Ok
}
int _mon_check_memory() {
int cnt;
TestVpiHandle mem_h, lcl_h;
vpiHandle iter_h; // icarus does not like auto free of iterator handles
vpiHandle iter_h; // Icarus does not like auto free of iterator handles
s_vpi_value value = {
vpiIntVal, .value = {.integer = 0}
vpiIntVal, .value = {.integer = 0}
};
vpi_printf((PLI_BYTE8*)"Check memory vpi ...\n");
mem_h = vpi_handle_by_name((PLI_BYTE8*)TestSimulator::rooted("mem0"), NULL);
@ -136,12 +136,12 @@ int _mon_check_memory() {
iter_h = vpi_iterate(vpiMemoryWord, mem_h);
cnt = 0;
while ((lcl_h = vpi_scan(iter_h))) {
value.value.integer = ++cnt;
value.value.integer = ++cnt;
vpi_put_value(lcl_h, &value, NULL, vpiNoDelay);
// check size and range
if (int status = _mon_check_range(lcl_h, 32, 31, 0)) return status;
}
CHECK_RESULT(cnt, 16); // should be 16 addresses
CHECK_RESULT(cnt, 16); // should be 16 addresses
// iterate and accumulate
iter_h = vpi_iterate(vpiMemoryWord, mem_h);
cnt = 0;
@ -150,12 +150,12 @@ int _mon_check_memory() {
vpi_get_value(lcl_h, &value);
CHECK_RESULT(value.value.integer, cnt);
}
CHECK_RESULT(cnt, 16); // should be 16 addresses
CHECK_RESULT(cnt, 16); // should be 16 addresses
// don't care for non verilator
// (crashes on Icarus)
if (TestSimulator::is_icarus()) {
vpi_printf((PLI_BYTE8*)"Skipping property checks for simulator %s\n", TestSimulator::get_info().product);
return 0; // Ok
vpi_printf((PLI_BYTE8*)"Skipping property checks for simulator %s\n", TestSimulator::get_info().product);
return 0; // Ok
}
// make sure trying to get properties that don't exist
// doesn't crash
@ -169,13 +169,13 @@ int _mon_check_memory() {
CHECK_RESULT(should_be_NULL, 0);
should_be_NULL = vpi_handle(vpiScope, iter_h);
CHECK_RESULT(should_be_NULL, 0);
return 0; // Ok
return 0; // Ok
}
int mon_check() {
// Callback from initial block in monitor
if (int status = _mon_check_memory()) return status;
return 0; // Ok
return 0; // Ok
}
//======================================================================
@ -220,7 +220,8 @@ int main(int argc, char **argv, char **env) {
double sim_time = 1100;
Verilated::commandArgs(argc, argv);
Verilated::debug(0);
Verilated::fatalOnVpiError(0); // we're going to be checking for these errors do don't crash out
// we're going to be checking for these errors do don't crash out
Verilated::fatalOnVpiError(0);
VM_PREFIX* topp = new VM_PREFIX(""); // Note null name - we're flattening it out
@ -243,17 +244,17 @@ int main(int argc, char **argv, char **env) {
main_time += 10;
while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) {
main_time += 1;
topp->eval();
VerilatedVpi::callValueCbs();
topp->clk = !topp->clk;
//mon_do();
main_time += 1;
topp->eval();
VerilatedVpi::callValueCbs();
topp->clk = !topp->clk;
//mon_do();
#if VM_TRACE
if (tfp) tfp->dump (main_time);
if (tfp) tfp->dump (main_time);
#endif
}
if (!Verilated::gotFinish()) {
vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish");
vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish");
}
topp->final();
@ -266,4 +267,3 @@ int main(int argc, char **argv, char **env) {
}
#endif

View File

@ -41,37 +41,37 @@ unsigned int callback_count = false;
#define CHECK_RESULT_VH(got, exp) \
if ((got) != (exp)) { \
printf("%%Error: %s:%d: GOT = %p EXP = %p\n", \
FILENM,__LINE__, (got), (exp)); \
return __LINE__; \
printf("%%Error: %s:%d: GOT = %p EXP = %p\n", \
FILENM,__LINE__, (got), (exp)); \
return __LINE__; \
}
#define CHECK_RESULT_NZ(got) \
if (!(got)) { \
printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM,__LINE__); \
return __LINE__; \
printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM,__LINE__); \
return __LINE__; \
}
// Use cout to avoid issues with %d/%lx etc
#define CHECK_RESULT(got, exp) \
if ((got) != (exp)) { \
std::cout<<std::dec<<"%Error: "<<FILENM<<":"<<__LINE__ \
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<std::endl; \
return __LINE__; \
std::cout<<std::dec<<"%Error: "<<FILENM<<":"<<__LINE__ \
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<std::endl; \
return __LINE__; \
}
#define CHECK_RESULT_HEX(got, exp) \
if ((got) != (exp)) { \
std::cout<<std::dec<<"%Error: "<<FILENM<<":"<<__LINE__<<std::hex \
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<std::endl; \
return __LINE__; \
std::cout<<std::dec<<"%Error: "<<FILENM<<":"<<__LINE__<<std::hex \
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<std::endl; \
return __LINE__; \
}
#define CHECK_RESULT_CSTR(got, exp) \
if (strcmp((got),(exp))) { \
printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", \
FILENM,__LINE__, (got)?(got):"<null>", (exp)?(exp):"<null>"); \
return __LINE__; \
printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", \
FILENM,__LINE__, (got)?(got):"<null>", (exp)?(exp):"<null>"); \
return __LINE__; \
}
#define CHECK_RESULT_CSTR_STRIP(got, exp) \
@ -80,28 +80,28 @@ unsigned int callback_count = false;
int _mon_check_unimpl(p_cb_data cb_data) {
static TestVpiHandle cb, clk_h;
if (cb_data) {
// this is the callback
// this is the callback
s_vpi_error_info info;
vpi_chk_error(&info);
callback_count++;
callback_count++;
printf("%%Info: got pli message %s\n", info.message);
} else {
// setup and install
static t_cb_data cb_data;
// setup and install
static t_cb_data cb_data;
clk_h = vpi_handle_by_name((PLI_BYTE8*)"t.clk", NULL);
cb_data.reason = cbPLIError;
cb_data.cb_rtn = _mon_check_unimpl; // this function
cb_data.cb_rtn = _mon_check_unimpl; // this function
cb = vpi_register_cb(&cb_data);
CHECK_RESULT_NZ(cb);
// now exercise unimplemented fns
vpi_get_cb_info(cb, NULL);
vpi_get_cb_info(cb, NULL);
CHECK_RESULT(callback_count, 1);
vpi_register_systf(NULL);
vpi_register_systf(NULL);
CHECK_RESULT(callback_count, 2);
vpi_get_systf_info(NULL, NULL);
vpi_get_systf_info(NULL, NULL);
CHECK_RESULT(callback_count, 3);
vpi_handle_multi(0, NULL, NULL);
CHECK_RESULT(callback_count, 4);
@ -111,34 +111,34 @@ int _mon_check_unimpl(p_cb_data cb_data) {
CHECK_RESULT(callback_count, 6);
vpi_put_delays(NULL, NULL);
CHECK_RESULT(callback_count, 7);
vpi_get_value_array(NULL, NULL, NULL, 0);
vpi_get_value_array(NULL, NULL, NULL, 0);
CHECK_RESULT(callback_count, 8);
vpi_put_value_array(NULL, NULL, NULL, 0);
vpi_put_value_array(NULL, NULL, NULL, 0);
CHECK_RESULT(callback_count, 9);
vpi_get_time(NULL, NULL);
vpi_get_time(NULL, NULL);
CHECK_RESULT(callback_count, 10);
vpi_mcd_name(0);
vpi_mcd_name(0);
CHECK_RESULT(callback_count, 11);
vpi_compare_objects(NULL, NULL);
CHECK_RESULT(callback_count, 12);
vpi_get_data(0, NULL, 0);
vpi_get_data(0, NULL, 0);
CHECK_RESULT(callback_count, 13);
vpi_put_data(0, NULL, 0);
vpi_put_data(0, NULL, 0);
CHECK_RESULT(callback_count, 14);
vpi_get_userdata(NULL);
vpi_get_userdata(NULL);
CHECK_RESULT(callback_count, 15);
vpi_put_userdata(NULL, NULL);
vpi_put_userdata(NULL, NULL);
CHECK_RESULT(callback_count, 16);
vpi_handle_by_multi_index(NULL, 0, NULL);
CHECK_RESULT(callback_count, 17);
}
return 0; // Ok
return 0; // Ok
}
int mon_check() {
// Callback from initial block in monitor
if (int status = _mon_check_unimpl(NULL)) return status;
return 0; // Ok
return 0; // Ok
}
//======================================================================
@ -151,7 +151,8 @@ int main(int argc, char **argv, char **env) {
double sim_time = 1100;
Verilated::commandArgs(argc, argv);
Verilated::debug(0);
Verilated::fatalOnVpiError(0); // we're going to be checking for these errors do don't crash out
// we're going to be checking for these errors do don't crash out
Verilated::fatalOnVpiError(0);
VM_PREFIX* topp = new VM_PREFIX(""); // Note null name - we're flattening it out
@ -174,18 +175,18 @@ int main(int argc, char **argv, char **env) {
main_time += 10;
while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) {
main_time += 1;
topp->eval();
//VerilatedVpi::callValueCbs(); // Make sure can link without verilated_vpi.h included
topp->clk = !topp->clk;
//mon_do();
main_time += 1;
topp->eval();
//VerilatedVpi::callValueCbs(); // Make sure can link without verilated_vpi.h included
topp->clk = !topp->clk;
//mon_do();
#if VM_TRACE
if (tfp) tfp->dump (main_time);
if (tfp) tfp->dump (main_time);
#endif
}
CHECK_RESULT(callback_count, 17);
if (!Verilated::gotFinish()) {
vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish");
vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish");
}
topp->final();

View File

@ -55,37 +55,37 @@ unsigned int callback_count_strs_max = 500;
#define CHECK_RESULT_VH(got, exp) \
if ((got) != (exp)) { \
printf("%%Error: %s:%d: GOT = %p EXP = %p\n", \
FILENM,__LINE__, (got), (exp)); \
return __LINE__; \
printf("%%Error: %s:%d: GOT = %p EXP = %p\n", \
FILENM,__LINE__, (got), (exp)); \
return __LINE__; \
}
#define CHECK_RESULT_NZ(got) \
if (!(got)) { \
printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM,__LINE__); \
return __LINE__; \
printf("%%Error: %s:%d: GOT = NULL EXP = !NULL\n", FILENM,__LINE__); \
return __LINE__; \
}
// Use cout to avoid issues with %d/%lx etc
#define CHECK_RESULT(got, exp) \
if ((got) != (exp)) { \
cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__ \
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<endl; \
return __LINE__; \
if ((got) != (exp)) { \
cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__ \
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<endl; \
return __LINE__; \
}
#define CHECK_RESULT_HEX(got, exp) \
if ((got) != (exp)) { \
cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__<<hex \
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<endl; \
return __LINE__; \
if ((got) != (exp)) { \
cout<<dec<<"%Error: "<<FILENM<<":"<<__LINE__<<hex \
<<": GOT = "<<(got)<<" EXP = "<<(exp)<<endl; \
return __LINE__; \
}
#define CHECK_RESULT_CSTR(got, exp) \
if (strcmp((got),(exp))) { \
printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", \
FILENM,__LINE__, (got)?(got):"<null>", (exp)?(exp):"<null>"); \
return __LINE__; \
printf("%%Error: %s:%d: GOT = '%s' EXP = '%s'\n", \
FILENM,__LINE__, (got)?(got):"<null>", (exp)?(exp):"<null>"); \
return __LINE__; \
}
#define CHECK_RESULT_CSTR_STRIP(got, exp) \
@ -103,9 +103,9 @@ int _mon_check_mcd() {
CHECK_RESULT_NZ(mcd);
{ // Check it got written
FILE* fp = fopen(filename,"r");
CHECK_RESULT_NZ(fp);
fclose(fp);
FILE* fp = fopen(filename,"r");
CHECK_RESULT_NZ(fp);
fclose(fp);
}
status = vpi_mcd_printf(mcd, (PLI_BYTE8*)"hello %s", "vpi_mcd_printf");
@ -167,8 +167,8 @@ int _value_callback_half(p_cb_data cb_data) {
int _value_callback_quad(p_cb_data cb_data) {
for (int index=0;index<2;index++) {
CHECK_RESULT_HEX(cb_data->value->value.vector[1].aval, (unsigned long)((index==2)?0x1c77bb9bUL:0x12819213UL));
CHECK_RESULT_HEX(cb_data->value->value.vector[0].aval, (unsigned long)((index==2)?0x3784ea09UL:0xabd31a1cUL));
CHECK_RESULT_HEX(cb_data->value->value.vector[1].aval, (unsigned long)((index==2)?0x1c77bb9bUL:0x12819213UL));
CHECK_RESULT_HEX(cb_data->value->value.vector[0].aval, (unsigned long)((index==2)?0x3784ea09UL:0xabd31a1cUL));
}
callback_count_quad++;
return 0;
@ -264,30 +264,30 @@ int _mon_check_var() {
t_vpi_value tmpValue;
tmpValue.format = vpiIntVal;
{
TestVpiHandle vh10 = vpi_handle(vpiLeftRange, vh4);
CHECK_RESULT_NZ(vh10);
vpi_get_value(vh10, &tmpValue);
CHECK_RESULT(tmpValue.value.integer,4);
TestVpiHandle vh10 = vpi_handle(vpiLeftRange, vh4);
CHECK_RESULT_NZ(vh10);
vpi_get_value(vh10, &tmpValue);
CHECK_RESULT(tmpValue.value.integer,4);
}
{
TestVpiHandle vh10 = vpi_handle(vpiRightRange, vh4);
CHECK_RESULT_NZ(vh10);
vpi_get_value(vh10, &tmpValue);
CHECK_RESULT(tmpValue.value.integer,3);
TestVpiHandle vh10 = vpi_handle(vpiRightRange, vh4);
CHECK_RESULT_NZ(vh10);
vpi_get_value(vh10, &tmpValue);
CHECK_RESULT(tmpValue.value.integer,3);
}
{
TestVpiHandle vh10 = vpi_iterate(vpiMemoryWord, vh4);
CHECK_RESULT_NZ(vh10);
TestVpiHandle vh11 = vpi_scan(vh10);
CHECK_RESULT_NZ(vh11);
TestVpiHandle vh12 = vpi_handle(vpiLeftRange, vh11);
CHECK_RESULT_NZ(vh12);
vpi_get_value(vh12, &tmpValue);
CHECK_RESULT(tmpValue.value.integer,2);
TestVpiHandle vh13 = vpi_handle(vpiRightRange, vh11);
CHECK_RESULT_NZ(vh13);
vpi_get_value(vh13, &tmpValue);
CHECK_RESULT(tmpValue.value.integer,1);
TestVpiHandle vh10 = vpi_iterate(vpiMemoryWord, vh4);
CHECK_RESULT_NZ(vh10);
TestVpiHandle vh11 = vpi_scan(vh10);
CHECK_RESULT_NZ(vh11);
TestVpiHandle vh12 = vpi_handle(vpiLeftRange, vh11);
CHECK_RESULT_NZ(vh12);
vpi_get_value(vh12, &tmpValue);
CHECK_RESULT(tmpValue.value.integer,2);
TestVpiHandle vh13 = vpi_handle(vpiRightRange, vh11);
CHECK_RESULT_NZ(vh13);
vpi_get_value(vh13, &tmpValue);
CHECK_RESULT(tmpValue.value.integer,1);
}
return 0;
@ -382,12 +382,12 @@ int _mon_check_quad() {
int _mon_check_string() {
static struct {
const char *name;
const char *name;
const char *initial;
const char *value;
} text_test_obs[] = {
{"text_byte", "B", "xxA"}, // x's dropped
{"text_half", "Hf", "xxT2"}, // x's dropped
{"text_byte", "B", "xxA"}, // x's dropped
{"text_half", "Hf", "xxT2"}, // x's dropped
{"text_word", "Word", "Tree"},
{"text_long", "Long64b", "44Four44"},
{"text" , "Verilog Test module", "lorem ipsum"},
@ -404,7 +404,7 @@ int _mon_check_string() {
v.format = vpiStringVal;
vpi_get_value(vh1, &v);
if (vpi_chk_error(&e)) {
printf("%%vpi_chk_error : %s\n", e.message);
printf("%%vpi_chk_error : %s\n", e.message);
}
CHECK_RESULT_CSTR_STRIP(v.value.str, text_test_obs[i].initial);
@ -419,43 +419,43 @@ int _mon_check_string() {
int _mon_check_putget_str(p_cb_data cb_data) {
static TestVpiHandle cb;
static struct {
TestVpiHandle scope, sig, rfr, check, verbose;
char str[128+1]; // char per bit plus null terminator
int type; // value type in .str
TestVpiHandle scope, sig, rfr, check, verbose;
char str[128+1]; // char per bit plus null terminator
int type; // value type in .str
union {
PLI_INT32 integer;
s_vpi_vecval vector[4];
} value; // reference
} value; // reference
} data[129];
if (cb_data) {
// this is the callback
// this is the callback
static unsigned int seed = 1;
s_vpi_time t;
t.type = vpiSimTime;
t.high = 0;
t.low = 0;
for (int i=2; i<=128; i++) {
static s_vpi_value v;
static s_vpi_value v;
int words = (i+31)>>5;
TEST_MSG("========== %d ==========\n", i);
TEST_MSG("========== %d ==========\n", i);
if (callback_count_strs) {
// check persistance
// check persistance
if (data[i].type) {
v.format = data[i].type;
} else {
static PLI_INT32 vals[] = {vpiBinStrVal, vpiOctStrVal, vpiHexStrVal, vpiDecStrVal};
} else {
static PLI_INT32 vals[] = {vpiBinStrVal, vpiOctStrVal, vpiHexStrVal, vpiDecStrVal};
v.format = vals[rand_r(&seed) % ((words>2)?3:4)];
TEST_MSG("new format %d\n", v.format);
}
TEST_MSG("new format %d\n", v.format);
}
vpi_get_value(data[i].sig, &v);
TEST_MSG("%s\n", v.value.str);
TEST_MSG("%s\n", v.value.str);
if (data[i].type) {
CHECK_RESULT_CSTR(v.value.str, data[i].str);
} else {
} else {
data[i].type = v.format;
strcpy(data[i].str, v.value.str);
}
}
}
}
// check for corruption
v.format = (words==1)?vpiIntVal:vpiVectorVal;
@ -463,12 +463,12 @@ int _mon_check_putget_str(p_cb_data cb_data) {
if (v.format == vpiIntVal) {
TEST_MSG("%08x %08x\n", v.value.integer, data[i].value.integer);
CHECK_RESULT(v.value.integer, data[i].value.integer);
} else {
} else {
for (int k=0; k < words; k++) {
TEST_MSG("%d %08x %08x\n", k, v.value.vector[k].aval, data[i].value.vector[k].aval);
TEST_MSG("%d %08x %08x\n", k, v.value.vector[k].aval, data[i].value.vector[k].aval);
CHECK_RESULT_HEX(v.value.vector[k].aval, data[i].value.vector[k].aval);
}
}
}
}
if (callback_count_strs & 7) {
// put same value back - checking encoding/decoding equivalent
@ -479,53 +479,53 @@ int _mon_check_putget_str(p_cb_data cb_data) {
v.value.integer = 1;
//vpi_put_value(data[i].verbose, &v, &t, vpiNoDelay);
vpi_put_value(data[i].check, &v, &t, vpiNoDelay);
} else {
} else {
// stick a new random value in
unsigned int mask = ((i&31)?(1<<(i&31)):0)-1;
if (words == 1) {
v.value.integer = rand_r(&seed);
data[i].value.integer = v.value.integer &= mask;
v.format = vpiIntVal;
TEST_MSG("new value %08x\n", data[i].value.integer);
} else {
TEST_MSG("new value\n");
for (int j=0; j<4; j++) {
TEST_MSG("new value %08x\n", data[i].value.integer);
} else {
TEST_MSG("new value\n");
for (int j=0; j<4; j++) {
data[i].value.vector[j].aval = rand_r(&seed);
if (j==(words-1)) {
data[i].value.vector[j].aval &= mask;
}
TEST_MSG(" %08x\n", data[i].value.vector[j].aval);
}
data[i].value.vector[j].aval &= mask;
}
TEST_MSG(" %08x\n", data[i].value.vector[j].aval);
}
v.value.vector = data[i].value.vector;
v.format = vpiVectorVal;
}
}
vpi_put_value(data[i].sig, &v, &t, vpiNoDelay);
vpi_put_value(data[i].rfr, &v, &t, vpiNoDelay);
}
}
if ((callback_count_strs & 1) == 0) data[i].type = 0;
}
}
if (++callback_count_strs == callback_count_strs_max) {
int success = vpi_remove_cb(cb);
CHECK_RESULT_NZ(success);
};
};
} else {
// setup and install
// setup and install
for (int i=1; i<=128; i++) {
char buf[32];
snprintf(buf, sizeof(buf), TestSimulator::rooted("arr[%d].arr"), i);
CHECK_RESULT_NZ(data[i].scope = vpi_handle_by_name((PLI_BYTE8*)buf, NULL));
CHECK_RESULT_NZ(data[i].sig = vpi_handle_by_name((PLI_BYTE8*)"sig", data[i].scope));
CHECK_RESULT_NZ(data[i].rfr = vpi_handle_by_name((PLI_BYTE8*)"rfr", data[i].scope));
CHECK_RESULT_NZ(data[i].check = vpi_handle_by_name((PLI_BYTE8*)"check", data[i].scope));
CHECK_RESULT_NZ(data[i].verbose = vpi_handle_by_name((PLI_BYTE8*)"verbose", data[i].scope));
}
CHECK_RESULT_NZ(data[i].scope = vpi_handle_by_name((PLI_BYTE8*)buf, NULL));
CHECK_RESULT_NZ(data[i].sig = vpi_handle_by_name((PLI_BYTE8*)"sig", data[i].scope));
CHECK_RESULT_NZ(data[i].rfr = vpi_handle_by_name((PLI_BYTE8*)"rfr", data[i].scope));
CHECK_RESULT_NZ(data[i].check = vpi_handle_by_name((PLI_BYTE8*)"check", data[i].scope));
CHECK_RESULT_NZ(data[i].verbose = vpi_handle_by_name((PLI_BYTE8*)"verbose", data[i].scope));
}
static t_cb_data cb_data;
static s_vpi_value v;
static t_cb_data cb_data;
static s_vpi_value v;
static TestVpiHandle count_h = VPI_HANDLE("count");
cb_data.reason = cbValueChange;
cb_data.cb_rtn = _mon_check_putget_str; // this function
cb_data.cb_rtn = _mon_check_putget_str; // this function
cb_data.obj = count_h;
cb_data.value = &v;
cb_data.time = NULL;
@ -567,7 +567,7 @@ int mon_check() {
#ifndef IS_VPI
VerilatedVpi::selfTest();
#endif
return 0; // Ok
return 0; // Ok
}
//======================================================================
@ -634,13 +634,13 @@ int main(int argc, char **argv, char **env) {
main_time += 10;
while (sc_time_stamp() < sim_time && !Verilated::gotFinish()) {
main_time += 1;
topp->eval();
VerilatedVpi::callValueCbs();
topp->clk = !topp->clk;
//mon_do();
main_time += 1;
topp->eval();
VerilatedVpi::callValueCbs();
topp->clk = !topp->clk;
//mon_do();
#if VM_TRACE
if (tfp) tfp->dump (main_time);
if (tfp) tfp->dump (main_time);
#endif
}
CHECK_RESULT(callback_count, 501);
@ -648,7 +648,7 @@ int main(int argc, char **argv, char **env) {
CHECK_RESULT(callback_count_quad, 2);
CHECK_RESULT(callback_count_strs, callback_count_strs_max);
if (!Verilated::gotFinish()) {
vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish");
vl_fatal(FILENM,__LINE__,"main", "%Error: Timeout; never got a $finish");
}
topp->final();

View File

@ -9,95 +9,95 @@ use Pod::Usage;
use Data::Dumper; $Data::Dumper::Indent = 1;
use Bit::Vector;
use strict;
use vars qw ($Debug);
use vars qw($Debug);
our @Orig_ARGV = @ARGV;
our $Rerun_Args = $0." ".join(' ',@Orig_ARGV);
$Rerun_Args =~ s/\s+$//;
use vars qw (@Blocks
%Vars
%VarAttrs
%VarsBlock
%Tree
@Commit
$Depth
%IdWidth
%Ops);
use vars qw(@Blocks
%Vars
%VarAttrs
%VarsBlock
%Tree
@Commit
$Depth
%IdWidth
%Ops);
#======================================================================
# width=> Number of bits the output size is, 0=you tell me.
# func=> What to put in output file
# signed=> 0=unsigned output, 1=signed output, '%1'=signed if op1 signed
# lsb=> LSB for variable declarations
# em=> How to calculate emulated return value
# %w Width of this output op ($treeref->{width})
# %v Output value ($treeref->{val})
# %1r First operand ($treeref->{op1})
# %1v First operand value ($treeref->{op1}{val})
# %1w First operand width ($treeref->{op1}{width})
# width=> Number of bits the output size is, 0=you tell me.
# func=> What to put in output file
# signed=> 0=unsigned output, 1=signed output, '%1'=signed if op1 signed
# lsb=> LSB for variable declarations
# em=> How to calculate emulated return value
# %w Width of this output op ($treeref->{width})
# %v Output value ($treeref->{val})
# %1r First operand ($treeref->{op1})
# %1v First operand value ($treeref->{op1}{val})
# %1w First operand width ($treeref->{op1}{width})
our $Raise_Weight_Max = 50;
%Ops =
(
'VCONST'=> {weight=>1&&20, width=>0, sc=>1, terminal=>1, v=>'%v', },
'VIDNEW'=> {weight=>1&&10, width=>0, sc=>1, terminal=>0, v=>'%i', },
'VIDOLD'=> {weight=>1&&20, width=>0, sc=>1, terminal=>0, v=>'%i', },
'VIDSAME'=> {weight=>1&&20, width=>0, sc=>1, terminal=>0, v=>'%i', },
'VRANGE'=> {weight=>1&&30, width=>0, signed=>0,sc=>0, terminal=>0, v=>'%i[%2:%3]', },
'VBITSEL'=> {weight=>1&&10, width=>1, signed=>0,sc=>0, terminal=>0, v=>'%i[%2]', },
'VBITSELP'=> {weight=>1&&10, width=>0, signed=>0,sc=>0, terminal=>0, v=>'%i[%2+:%3]', },
'VBITSELM'=> {weight=>1&&10, width=>0, signed=>0,sc=>0, terminal=>0, v=>'%i[%2-:%3]', },
'VCONST'=> {weight=>1&&20, width=>0, sc=>1, terminal=>1, v=>'%v', },
'VIDNEW'=> {weight=>1&&10, width=>0, sc=>1, terminal=>0, v=>'%i', },
'VIDOLD'=> {weight=>1&&20, width=>0, sc=>1, terminal=>0, v=>'%i', },
'VIDSAME'=> {weight=>1&&20, width=>0, sc=>1, terminal=>0, v=>'%i', },
'VRANGE'=> {weight=>1&&30, width=>0, signed=>0,sc=>0, terminal=>0, v=>'%i[%2:%3]', },
'VBITSEL'=> {weight=>1&&10, width=>1, signed=>0,sc=>0, terminal=>0, v=>'%i[%2]', },
'VBITSELP'=> {weight=>1&&10, width=>0, signed=>0,sc=>0, terminal=>0, v=>'%i[%2+:%3]', },
'VBITSELM'=> {weight=>1&&10, width=>0, signed=>0,sc=>0, terminal=>0, v=>'%i[%2-:%3]', },
# Unary
'VEXTEND'=> {weight=>1&&3, width=>-2, signed=>0,sc=>0, terminal=>0, v=>'{%xd\'h0,%1}', },
'VLOGNOT'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(! %1)', },
'VREDAND'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(& %1)', },
'VREDOR'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(| %1)', },
'VREDNAND'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(~& %1)', },
'VREDNOR'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(~| %1)', },
'VREDXNOR'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(^~ %1)', },
'VREDXOR'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(^ %1)', },
'VNOT'=> {weight=>1&&3, width=>0, sc=>1, terminal=>0, v=>'(~ %1)', },
'VNEGATE'=> {weight=>1&&2, width=>0, sc=>1, terminal=>0, v=>'(- %1)', },
'VCOUNTONES'=> {weight=>0&&2, width=>32, signed=>0, sc=>0, terminal=>0, v=>'\$countones(%1)', }, # No ncv support
'VONEHOT'=> {weight=>0&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'\$onehot(%1)', }, # No ncv support
'VONEHOT0'=> {weight=>0&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'\$onehot0(%1)', }, # No ncv support
'VEXTEND'=> {weight=>1&&3, width=>-2, signed=>0,sc=>0, terminal=>0, v=>'{%xd\'h0,%1}', },
'VLOGNOT'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(! %1)', },
'VREDAND'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(& %1)', },
'VREDOR'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(| %1)', },
'VREDNAND'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(~& %1)', },
'VREDNOR'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(~| %1)', },
'VREDXNOR'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(^~ %1)', },
'VREDXOR'=> {weight=>1&&1, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(^ %1)', },
'VNOT'=> {weight=>1&&3, width=>0, sc=>1, terminal=>0, v=>'(~ %1)', },
'VNEGATE'=> {weight=>1&&2, width=>0, sc=>1, terminal=>0, v=>'(- %1)', },
'VCOUNTONES'=> {weight=>0&&2, width=>32, signed=>0, sc=>0, terminal=>0, v=>'\$countones(%1)', }, # No ncv support
'VONEHOT'=> {weight=>0&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'\$onehot(%1)', }, # No ncv support
'VONEHOT0'=> {weight=>0&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'\$onehot0(%1)', }, # No ncv support
# Binary
'VAND'=> {weight=>1&&2, width=>0, sc=>1, terminal=>0, v=>'(%1 & %2)', },
'VOR'=> {weight=>1&&2, width=>0, sc=>1, terminal=>0, v=>'(%1 | %2)', },
'VNAND'=> {weight=>1&&0, width=>0, sc=>0, terminal=>0, v=>'(%1 ~& %2)', }, #FIX vcs bug!
'VNOR'=> {weight=>1&&0, width=>0, sc=>0, terminal=>0, v=>'(%1 ~| %2)', }, #FIX vcs bug!
'VXOR'=> {weight=>1&&2, width=>0, sc=>1, terminal=>0, v=>'(%1 ^ %2)', },
'VXNOR'=> {weight=>1&&0, width=>0, sc=>0, terminal=>0, v=>'(%1 ^~ %2)', }, #FIX vcs bug!
'VEQ'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 == %2)', },
'VNEQ'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 != %2)', },
'VGT'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 > %2)', },
'VGTE'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 >= %2)', },
'VLT'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 < %2)', },
'VLTE'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 <= %2)', },
'VEQCASE'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 === %2)', }, # FIX just a = for now
'VNEQCASE'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 !== %2)', }, # FIX just a != for now
'VLOGOR'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 || %2)', },
'VLOGAND'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 && %2)', },
'VADD'=> {weight=>1&&10, width=>0, sc=>1, terminal=>0, v=>'(%1 + %2)', },
'VSUB'=> {weight=>1&&10, width=>0, sc=>1, terminal=>0, v=>'(%1 - %2)', },
'VMUL'=> {weight=>1&&15,width=>0, sc=>1, terminal=>0, v=>'(%1 * %2)', }, # High % as rarely applyable
'VAND'=> {weight=>1&&2, width=>0, sc=>1, terminal=>0, v=>'(%1 & %2)', },
'VOR'=> {weight=>1&&2, width=>0, sc=>1, terminal=>0, v=>'(%1 | %2)', },
'VNAND'=> {weight=>1&&0, width=>0, sc=>0, terminal=>0, v=>'(%1 ~& %2)', }, #FIX vcs bug!
'VNOR'=> {weight=>1&&0, width=>0, sc=>0, terminal=>0, v=>'(%1 ~| %2)', }, #FIX vcs bug!
'VXOR'=> {weight=>1&&2, width=>0, sc=>1, terminal=>0, v=>'(%1 ^ %2)', },
'VXNOR'=> {weight=>1&&0, width=>0, sc=>0, terminal=>0, v=>'(%1 ^~ %2)', }, #FIX vcs bug!
'VEQ'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 == %2)', },
'VNEQ'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 != %2)', },
'VGT'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 > %2)', },
'VGTE'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 >= %2)', },
'VLT'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 < %2)', },
'VLTE'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 <= %2)', },
'VEQCASE'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 === %2)', }, # FIX just a = for now
'VNEQCASE'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 !== %2)', }, # FIX just a != for now
'VLOGOR'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 || %2)', },
'VLOGAND'=> {weight=>1&&2, width=>1, signed=>0, sc=>0, terminal=>0, v=>'(%1 && %2)', },
'VADD'=> {weight=>1&&10, width=>0, sc=>1, terminal=>0, v=>'(%1 + %2)', },
'VSUB'=> {weight=>1&&10, width=>0, sc=>1, terminal=>0, v=>'(%1 - %2)', },
'VMUL'=> {weight=>1&&15,width=>0, sc=>1, terminal=>0, v=>'(%1 * %2)', }, # High % as rarely applyable
# Unspecified behavior with == (a-signed / b) -- see t_math_signed5.v test
'VDIV'=> {weight=>1&&8, width=>0, signed=>0, sc=>1, terminal=>0, v=>'((%2)==%xw\'h0 ? %xw\'%xsh0:(%1 / %2))', },
'VMODDIV'=> {weight=>1&&8, width=>0, signed=>0, sc=>1, terminal=>0, v=>'((%2)==%xw\'h0 ? %xw\'%xsh0:(%1 %% %2))', },
#'VPOW'=> {weight=>2&&0,width=>-64, sc=>0, terminal=>0, v=>'(%1 ** %2)', },
'VSHIFTL'=> {weight=>1&&8, width=>0, signed=>0, sc=>0, terminal=>0, v=>'(%1 << %2)', },
'VSHIFTLS'=> {weight=>1&&8, width=>0, signed=>1, sc=>0, terminal=>0, v=>'(%1 <<< %2)', },
'VSHIFTR'=> {weight=>1&&8, width=>0, signed=>0, sc=>0, terminal=>0, v=>'(%1 >> %2)', },
'VSHIFTRS'=> {weight=>1&&15,width=>0, signed=>1, sc=>0, terminal=>0, v=>'(%1 >>> %2)', }, # ShiftR seems to sign extend differently for <=32 and >32 bits
'VCONCAT'=> {weight=>1&&4, width=>-2,signed=>0, sc=>0, terminal=>0, v=>'{%1,%2}', },
'VREPLIC'=> {weight=>1&&2, width=>0, signed=>0, sc=>0, terminal=>0, v=>'{%1{%2}}', },
'VREPLIC1W'=> {weight=>1&&2, width=>0, signed=>0, sc=>0, terminal=>0, v=>'{%1{%2}}', },
'VSIGNED'=> {weight=>1&&2, width=>0, signed=>1, sc=>0, terminal=>0, v=>'\$signed(%1)', },
'VUNSIGNED'=> {weight=>1&&2, width=>0, signed=>0, sc=>0, terminal=>0, v=>'\$unsigned(%1)', },
'VDIV'=> {weight=>1&&8, width=>0, signed=>0, sc=>1, terminal=>0, v=>'((%2)==%xw\'h0 ? %xw\'%xsh0:(%1 / %2))', },
'VMODDIV'=> {weight=>1&&8, width=>0, signed=>0, sc=>1, terminal=>0, v=>'((%2)==%xw\'h0 ? %xw\'%xsh0:(%1 %% %2))', },
#'VPOW'=> {weight=>2&&0,width=>-64, sc=>0, terminal=>0, v=>'(%1 ** %2)', },
'VSHIFTL'=> {weight=>1&&8, width=>0, signed=>0, sc=>0, terminal=>0, v=>'(%1 << %2)', },
'VSHIFTLS'=> {weight=>1&&8, width=>0, signed=>1, sc=>0, terminal=>0, v=>'(%1 <<< %2)', },
'VSHIFTR'=> {weight=>1&&8, width=>0, signed=>0, sc=>0, terminal=>0, v=>'(%1 >> %2)', },
'VSHIFTRS'=> {weight=>1&&15,width=>0, signed=>1, sc=>0, terminal=>0, v=>'(%1 >>> %2)', }, # ShiftR seems to sign extend differently for <=32 and >32 bits
'VCONCAT'=> {weight=>1&&4, width=>-2,signed=>0, sc=>0, terminal=>0, v=>'{%1,%2}', },
'VREPLIC'=> {weight=>1&&2, width=>0, signed=>0, sc=>0, terminal=>0, v=>'{%1{%2}}', },
'VREPLIC1W'=> {weight=>1&&2, width=>0, signed=>0, sc=>0, terminal=>0, v=>'{%1{%2}}', },
'VSIGNED'=> {weight=>1&&2, width=>0, signed=>1, sc=>0, terminal=>0, v=>'\$signed(%1)', },
'VUNSIGNED'=> {weight=>1&&2, width=>0, signed=>0, sc=>0, terminal=>0, v=>'\$unsigned(%1)', },
# Triops
'VCOND'=> {weight=>1&&4, width=>0, sc=>0, terminal=>0, v=>'(%1 ? %2 : %3)', },
'VCOND'=> {weight=>1&&4, width=>0, sc=>0, terminal=>0, v=>'(%1 ? %2 : %3)', },
# Control flow
#VIF
#VFOR
@ -108,86 +108,86 @@ our $Raise_Weight_Max = 50;
my %ops2 =
(
'VCONST'=> {pl=>'', rnd=>'rnd_const(%tr);'},
'VIDNEW'=> {pl=>'%tv=$Vars{%i}{val};',
rnd=>'%i=next_id(%tw);'
.' $Vars{%i}=gen_leaf(width=>%tw,trunc=>1,signed=>%tg);'
.' $VarAttrs{%i}{lsb} = rnd_lsb();'
.' id_commit(%tr,"%i");1;',},
'VIDOLD'=> {pl=>'%tv=$Vars{%i}{val};', rnd=>'%i=id_old(%tr);', ok_id_width=>1,},
'VIDSAME'=> {pl=>'%tv=$Vars{%i}{val};', rnd=>'%i=id_same(%tr);', ok_id_width=>1,},
'VCONST'=> {pl=>'', rnd=>'rnd_const(%tr);'},
'VIDNEW'=> {pl=>'%tv=$Vars{%i}{val};',
rnd=>'%i=next_id(%tw);'
.' $Vars{%i}=gen_leaf(width=>%tw,trunc=>1,signed=>%tg);'
.' $VarAttrs{%i}{lsb} = rnd_lsb();'
.' id_commit(%tr,"%i");1;',},
'VIDOLD'=> {pl=>'%tv=$Vars{%i}{val};', rnd=>'%i=id_old(%tr);', ok_id_width=>1,},
'VIDSAME'=> {pl=>'%tv=$Vars{%i}{val};', rnd=>'%i=id_same(%tr);', ok_id_width=>1,},
# These create IDs they then extract from
'VRANGE'=> {pl=>'VRANGE(%tr,$Vars{%i}{val},%2v,%3v,$VarAttrs{%i}{lsb});',
rnd=>'%i=next_id(%tw); $VarAttrs{%i}{lsb} = 0&&rnd_lsb();'
.' my $lsb=rnd(128-%tw); my $msb=$lsb+%tw-1;'
.' %2r=val_leaf($msb); %3r=val_leaf($lsb);'
.' $Vars{%i}=gen_leaf(width=>($msb+1));'},
'VBITSEL'=> {pl=>'VRANGE(%tr,$Vars{%i}{val},%2v,%2v,$VarAttrs{%i}{lsb});',
rnd=>'%i=next_id(%tw); $VarAttrs{%i}{lsb} = 0&&rnd_lsb();'
.' my $wid=min(128,rnd_width()|3);'
.' %2r=gen_leaf(width=>(log2($wid)-1),signed=>0);'
.' $Vars{%i}=gen_leaf(width=>$wid);'},
'VBITSELP'=> {pl=>'VBITSELP(%tr,$Vars{%i}{val},%2v,%3v,$VarAttrs{%i}{lsb});',
rnd=>'%i=next_id(%tw); $VarAttrs{%i}{lsb} = 0&&rnd_lsb();'
.' my $wid=min(128,(%tw+rnd_width()|3)); %3r=val_leaf(%tw); my $maxval = $wid-%tw; %2r=(($maxval<4)?val_leaf($maxval):gen_leaf(width=>(log2($maxval)-1),signed=>0));'
.' $Vars{%i}=gen_leaf(width=>$wid);'},
'VBITSELM'=> {pl=>'VBITSELM(%tr,$Vars{%i}{val},%2v,%3v,$VarAttrs{%i}{lsb});',
rnd=>'%i=next_id(%tw); $VarAttrs{%i}{lsb} = 0&&rnd_lsb();'
.' my $wid=min(128,(%tw+rnd_width()|3)); %3r=val_leaf(%tw); my $maxval = $wid-1; my $minval=%tw-1; %2r=val_leaf(rnd($maxval-$minval)+$minval);'
.' $Vars{%i}=gen_leaf(width=>$wid);'}, # No easy way to make expr with specified minimum
'VRANGE'=> {pl=>'VRANGE(%tr,$Vars{%i}{val},%2v,%3v,$VarAttrs{%i}{lsb});',
rnd=>'%i=next_id(%tw); $VarAttrs{%i}{lsb} = 0&&rnd_lsb();'
.' my $lsb=rnd(128-%tw); my $msb=$lsb+%tw-1;'
.' %2r=val_leaf($msb); %3r=val_leaf($lsb);'
.' $Vars{%i}=gen_leaf(width=>($msb+1));'},
'VBITSEL'=> {pl=>'VRANGE(%tr,$Vars{%i}{val},%2v,%2v,$VarAttrs{%i}{lsb});',
rnd=>'%i=next_id(%tw); $VarAttrs{%i}{lsb} = 0&&rnd_lsb();'
.' my $wid=min(128,rnd_width()|3);'
.' %2r=gen_leaf(width=>(log2($wid)-1),signed=>0);'
.' $Vars{%i}=gen_leaf(width=>$wid);'},
'VBITSELP'=> {pl=>'VBITSELP(%tr,$Vars{%i}{val},%2v,%3v,$VarAttrs{%i}{lsb});',
rnd=>'%i=next_id(%tw); $VarAttrs{%i}{lsb} = 0&&rnd_lsb();'
.' my $wid=min(128,(%tw+rnd_width()|3)); %3r=val_leaf(%tw); my $maxval = $wid-%tw; %2r=(($maxval<4)?val_leaf($maxval):gen_leaf(width=>(log2($maxval)-1),signed=>0));'
.' $Vars{%i}=gen_leaf(width=>$wid);'},
'VBITSELM'=> {pl=>'VBITSELM(%tr,$Vars{%i}{val},%2v,%3v,$VarAttrs{%i}{lsb});',
rnd=>'%i=next_id(%tw); $VarAttrs{%i}{lsb} = 0&&rnd_lsb();'
.' my $wid=min(128,(%tw+rnd_width()|3)); %3r=val_leaf(%tw); my $maxval = $wid-1; my $minval=%tw-1; %2r=val_leaf(rnd($maxval-$minval)+$minval);'
.' $Vars{%i}=gen_leaf(width=>$wid);'}, # No easy way to make expr with specified minimum
# Unary
'VEXTEND'=> {pl=>'VRESIZE (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>rnd_width(%tw-1));'},
'VLOGNOT'=> {pl=>'VLOGNOT (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
'VREDAND'=> {pl=>'VREDAND (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
'VREDOR'=> {pl=>'VREDOR (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
'VREDNAND'=> {pl=>'VREDNAND (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
'VREDNOR'=> {pl=>'VREDNOR (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
'VREDXOR'=> {pl=>'VREDXOR (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
'VREDXNOR'=> {pl=>'VREDXNOR (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
'VNOT'=> {pl=>'VNOT (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg);'},
'VNEGATE'=> {pl=>'VNEGATE (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg);'},
'VCOUNTONES'=> {pl=>'VCOUNTONES(%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
'VONEHOT'=> {pl=>'VONEHOT (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
'VONEHOT0'=> {pl=>'VONEHOT0 (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
'VEXTEND'=> {pl=>'VRESIZE (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>rnd_width(%tw-1));'},
'VLOGNOT'=> {pl=>'VLOGNOT (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
'VREDAND'=> {pl=>'VREDAND (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
'VREDOR'=> {pl=>'VREDOR (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
'VREDNAND'=> {pl=>'VREDNAND (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
'VREDNOR'=> {pl=>'VREDNOR (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
'VREDXOR'=> {pl=>'VREDXOR (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
'VREDXNOR'=> {pl=>'VREDXNOR (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
'VNOT'=> {pl=>'VNOT (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg);'},
'VNEGATE'=> {pl=>'VNEGATE (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg);'},
'VCOUNTONES'=> {pl=>'VCOUNTONES(%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
'VONEHOT'=> {pl=>'VONEHOT (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
'VONEHOT0'=> {pl=>'VONEHOT0 (%tr,%1v);', rnd=>'%1r=gen_leaf(width=>0);'},
# Binary
'VAND'=> {pl=>'VAND (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'},
'VOR'=> {pl=>'VOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'},
'VNAND'=> {pl=>'VNAND (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'},
'VNOR'=> {pl=>'VNOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'},
'VXOR'=> {pl=>'VXOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'},
'VXNOR'=> {pl=>'VXNOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'},
'VEQ'=> {pl=>'VEQ (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'},
'VNEQ'=> {pl=>'VNE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'},
'VGT'=> {pl=>'VGT (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'},
'VGTE'=> {pl=>'VGE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'},
'VLT'=> {pl=>'VLT (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'},
'VLTE'=> {pl=>'VLE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'},
'VEQCASE'=> {pl=>'VEQ (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'},
'VNEQCASE'=> {pl=>'VNE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'},
'VLOGOR'=> {pl=>'VLOGOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>0);'},
'VLOGAND'=> {pl=>'VLOGAND(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>0);'},
'VADD'=> {pl=>'VADD (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);', trunc=>1,},
'VSUB'=> {pl=>'VSUB (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);', trunc=>1,},
'VMUL'=> {pl=>'VMUL (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);', trunc=>1,}, # Multiply generates larger width, so need truncate for safety
'VDIV'=> {pl=>'VDIV (%tr,%1r,%2r,0);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'},
'VMODDIV'=> {pl=>'VDIV (%tr,%1r,%2r,1);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'},
#'VPOW'=> {pl=>'VPOW (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>min(%tw,6),signed=>%tg); %2r=gen_leaf(width=>min(%tw,8),signed=>%tg);', trunc=>1,}, # Generates larger width, so need truncate for safety
'VSHIFTL'=> {pl=>'VSHIFTL(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>log2(%tw)+1,signed=>%tg);'},
'VSHIFTLS'=> {pl=>'VSHIFTL(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>log2(%tw)+1,signed=>%tg);'},
'VSHIFTR'=> {pl=>'VSHIFTR(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>log2(%tw)+1,signed=>%tg);'},
'VSHIFTRS'=> {pl=>'VSHIFTRS(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>log2(%tw)+1,signed=>%tg);'},
'VCONCAT'=> {pl=>'VCONCAT(%tr,%1v,%2v);', rnd=>'my $d=(rnd(%tw-2)+1); %1r=gen_leaf(width=>$d,signed=>0); %2r=gen_leaf(width=>(%tw-$d),signed=>0);'},
'VREPLIC'=> {pl=>'VREPLIC(%tr,%1v,%2v);', rnd=>'my $d=rnd_rep_width(%tw); %1r=val_leaf($d); %2r=gen_leaf(width=>(%tw/$d),signed=>0);'},
'VREPLIC1W'=> {pl=>'VREPLIC(%tr,%1v,%2v);', rnd=>'%1r=val_leaf(%tw); %2r=gen_leaf(width=>1,signed=>0);'},
'VSIGNED'=> {pl=>'VCLONE (%tr,%1v,0);', rnd=>'%1r=gen_leaf(width=>%tw);'},
'VUNSIGNED'=> {pl=>'VCLONE (%tr,%1v,0);', rnd=>'%1r=gen_leaf(width=>%tw);'},
'VAND'=> {pl=>'VAND (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'},
'VOR'=> {pl=>'VOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'},
'VNAND'=> {pl=>'VNAND (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'},
'VNOR'=> {pl=>'VNOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'},
'VXOR'=> {pl=>'VXOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'},
'VXNOR'=> {pl=>'VXNOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'},
'VEQ'=> {pl=>'VEQ (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'},
'VNEQ'=> {pl=>'VNE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'},
'VGT'=> {pl=>'VGT (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'},
'VGTE'=> {pl=>'VGE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'},
'VLT'=> {pl=>'VLT (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'},
'VLTE'=> {pl=>'VLE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'},
'VEQCASE'=> {pl=>'VEQ (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'},
'VNEQCASE'=> {pl=>'VNE (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>%1w,signed=>%1g);'},
'VLOGOR'=> {pl=>'VLOGOR (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>0);'},
'VLOGAND'=> {pl=>'VLOGAND(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>0); %2r=gen_leaf(width=>0);'},
'VADD'=> {pl=>'VADD (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);', trunc=>1,},
'VSUB'=> {pl=>'VSUB (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);', trunc=>1,},
'VMUL'=> {pl=>'VMUL (%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);', trunc=>1,}, # Multiply generates larger width, so need truncate for safety
'VDIV'=> {pl=>'VDIV (%tr,%1r,%2r,0);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'},
'VMODDIV'=> {pl=>'VDIV (%tr,%1r,%2r,1);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>%tw,signed=>%tg);'},
#'VPOW'=> {pl=>'VPOW (%tr,%1r,%2r);', rnd=>'%1r=gen_leaf(width=>min(%tw,6),signed=>%tg); %2r=gen_leaf(width=>min(%tw,8),signed=>%tg);', trunc=>1,}, # Generates larger width, so need truncate for safety
'VSHIFTL'=> {pl=>'VSHIFTL(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>log2(%tw)+1,signed=>%tg);'},
'VSHIFTLS'=> {pl=>'VSHIFTL(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>log2(%tw)+1,signed=>%tg);'},
'VSHIFTR'=> {pl=>'VSHIFTR(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>log2(%tw)+1,signed=>%tg);'},
'VSHIFTRS'=> {pl=>'VSHIFTRS(%tr,%1v,%2v);', rnd=>'%1r=gen_leaf(width=>%tw,signed=>%tg); %2r=gen_leaf(width=>log2(%tw)+1,signed=>%tg);'},
'VCONCAT'=> {pl=>'VCONCAT(%tr,%1v,%2v);', rnd=>'my $d=(rnd(%tw-2)+1); %1r=gen_leaf(width=>$d,signed=>0); %2r=gen_leaf(width=>(%tw-$d),signed=>0);'},
'VREPLIC'=> {pl=>'VREPLIC(%tr,%1v,%2v);', rnd=>'my $d=rnd_rep_width(%tw); %1r=val_leaf($d); %2r=gen_leaf(width=>(%tw/$d),signed=>0);'},
'VREPLIC1W'=> {pl=>'VREPLIC(%tr,%1v,%2v);', rnd=>'%1r=val_leaf(%tw); %2r=gen_leaf(width=>1,signed=>0);'},
'VSIGNED'=> {pl=>'VCLONE (%tr,%1v,0);', rnd=>'%1r=gen_leaf(width=>%tw);'},
'VUNSIGNED'=> {pl=>'VCLONE (%tr,%1v,0);', rnd=>'%1r=gen_leaf(width=>%tw);'},
# Triops
'VCOND'=> {pl=>'VCOND(%tr,%1v,%2v,%3v);', rnd=>'%1r=gen_leaf(width=>1); %2r=gen_leaf(width=>%tw,signed=>%tg); %3r=gen_leaf(width=>%tw,signed=>%tg);'},
'VCOND'=> {pl=>'VCOND(%tr,%1v,%2v,%3v);', rnd=>'%1r=gen_leaf(width=>1); %2r=gen_leaf(width=>%tw,signed=>%tg); %3r=gen_leaf(width=>%tw,signed=>%tg);'},
);
foreach my $op (keys %ops2) {
while ((my $key,my $val) = each %{$ops2{$op}}) {
$Ops{$op}{$key} = $val;
$Ops{$op}{$key} = $val;
}
}
@ -207,17 +207,17 @@ our $Opt_BlockStmts = 2;
our $Signed_Pct = 60;
$Debug = 0;
if (! GetOptions (
"help" => \&usage,
"debug" => \&debug,
"depth=i" => \$Opt_Depth,
"blockstmts=i"=> \$Opt_BlockStmts,
"numops=i" => \$Opt_NumOps,
"o=s" => \$Opt_Output,
"raise=i" => \$Opt_Raise,
"seed=i" => \$opt_seed,
"signed!" => \$Opt_Signed,
"<>" => \&parameter,
)) {
"help" => \&usage,
"debug" => \&debug,
"depth=i" => \$Opt_Depth,
"blockstmts=i"=> \$Opt_BlockStmts,
"numops=i" => \$Opt_NumOps,
"o=s" => \$Opt_Output,
"raise=i" => \$Opt_Raise,
"seed=i" => \$opt_seed,
"signed!" => \$Opt_Signed,
"<>" => \&parameter,
)) {
usage();
}
@ -238,7 +238,7 @@ write_output_v($Opt_Output);
sub usage {
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
exit (1);
exit(1);
}
sub debug {
@ -258,31 +258,31 @@ sub parameter {
sub init {
for my $op (keys %Ops) {
my $opref = $Ops{$op};
$opref->{name} = $op;
gen_v($opref);
gen_pl($opref);
gen_rnd($opref);
my $opref = $Ops{$op};
$opref->{name} = $op;
gen_v($opref);
gen_pl($opref);
gen_rnd($opref);
}
raise();
}
sub raise {
for (my $i=0; $i<($Opt_Raise||0); $i++) {
my @ops = (values %Ops);
while (1) {
my $rndop = $ops[rnd($#ops + 1)];
next if !$rndop->{weight}; # Don't turn on disabled ops
$rndop->{weight} += rnd($Raise_Weight_Max);
printf "\tWeight %-15s +%d\n",$rndop->{name},$rndop->{weight};
last;
}
my @ops = (values %Ops);
while (1) {
my $rndop = $ops[rnd($#ops + 1)];
next if !$rndop->{weight}; # Don't turn on disabled ops
$rndop->{weight} += rnd($Raise_Weight_Max);
printf "\tWeight %-15s +%d\n",$rndop->{name},$rndop->{weight};
last;
}
}
}
sub gentest {
for (my $opn=0; $opn<$Opt_NumOps/$Opt_BlockStmts; $opn++) {
do_a_test();
do_a_test();
}
}
@ -293,20 +293,20 @@ sub _rnd_op_ok {
my $opref = shift;
my $paramref = shift;
return (($opref->{width} == 0
|| $opref->{width} == $paramref->{width}
# Note -2 means >, while -32 means <!
|| ($opref->{width}==-31 && $paramref->{width}<=31) # -31... must be <31 bits
|| ($opref->{width}==-32 && $paramref->{width}<=32) # -32... must be <32 bits
|| ($opref->{width}==-63 && $paramref->{width}<=63) # -63... must be <63 bits
|| ($opref->{width}==-64 && $paramref->{width}<=64) # -64... must be <64 bits
|| ($opref->{width}==-2 && $paramref->{width}>=2) # -2... must be >2 bits
)
&& (!$opref->{ok_id_width} || $IdWidth{$paramref->{width}}{$paramref->{signed}||0})
&& (!defined $opref->{signed} || ($opref->{signed} == ($paramref->{signed}||0)))
&& (!$opref->{trunc} || $paramref->{trunc})
&& (!$opref->{opt_signed} || $Opt_Signed)
&& (($Depth < $Opt_Depth && !$paramref->{need_terminal})
|| $opref->{terminal}));
|| $opref->{width} == $paramref->{width}
# Note -2 means >, while -32 means <!
|| ($opref->{width}==-31 && $paramref->{width}<=31) # -31... must be <31 bits
|| ($opref->{width}==-32 && $paramref->{width}<=32) # -32... must be <32 bits
|| ($opref->{width}==-63 && $paramref->{width}<=63) # -63... must be <63 bits
|| ($opref->{width}==-64 && $paramref->{width}<=64) # -64... must be <64 bits
|| ($opref->{width}==-2 && $paramref->{width}>=2) # -2... must be >2 bits
)
&& (!$opref->{ok_id_width} || $IdWidth{$paramref->{width}}{$paramref->{signed}||0})
&& (!defined $opref->{signed} || ($opref->{signed} == ($paramref->{signed}||0)))
&& (!$opref->{trunc} || $paramref->{trunc})
&& (!$opref->{opt_signed} || $Opt_Signed)
&& (($Depth < $Opt_Depth && !$paramref->{need_terminal})
|| $opref->{terminal}));
}
sub rnd_op {
@ -314,19 +314,19 @@ sub rnd_op {
my $totweight = 0;
foreach my $opref (values %Ops) {
if (_rnd_op_ok($opref,$paramref)) {
$totweight += $opref->{weight};
}
if (_rnd_op_ok($opref,$paramref)) {
$totweight += $opref->{weight};
}
}
my $chooseweight = rnd($totweight);
$totweight = 0;
foreach my $opref (values %Ops) {
if (_rnd_op_ok($opref,$paramref)) {
$totweight += $opref->{weight};
if ($chooseweight < $totweight) {
return $opref;
}
}
if (_rnd_op_ok($opref,$paramref)) {
$totweight += $opref->{weight};
if ($chooseweight < $totweight) {
return $opref;
}
}
}
die "%Error: No instructions match,";
}
@ -335,15 +335,15 @@ sub rnd_width {
my $max = shift;
my $v = rnd(100);
my $n = (0
|| (($v<20) && 1)
|| (($v<25) && 2)
|| (($v<30) && 31)
|| (($v<35) && 32)
|| (($v<40) && 63)
|| (($v<45) && 64)
|| (($v<50) && 95)
|| (($v<55) && 96)
|| (rnd(128)+1));
|| (($v<20) && 1)
|| (($v<25) && 2)
|| (($v<30) && 31)
|| (($v<35) && 32)
|| (($v<40) && 63)
|| (($v<45) && 64)
|| (($v<50) && 95)
|| (($v<55) && 96)
|| (rnd(128)+1));
if ($max && $n>=$max) { $n = rnd($max-1)+1; }
return $n;
}
@ -354,9 +354,9 @@ sub rnd_rep_width {
# We'd like to pick any divisor that works.
my @factors;
for (my $div=1; $div<$out; $div++) {
if (int($out/$div)==($out/$div)) {
push @factors, $div;
}
if (int($out/$div)==($out/$div)) {
push @factors, $div;
}
}
my $fac = $factors[rnd($#factors+1)];
#print "RND REP $out -> $fac (@factors)\n" if $Debug;
@ -369,17 +369,17 @@ sub rnd_const {
my $v = rnd(100);
my $val = Bit::Vector->new($width);
if ($v<25) { # zero
} elsif ($v<50) { # ones
for (my $w=0; $w<$val->Word_Size; ++$w) {
$val->Word_Store(0,~0);
}
} elsif ($v<60) { # one
$val->Word_Store(0,1);
} else { #random
for (my $w=0; $w<$val->Word_Size; ++$w) {
$val->Word_Store($w,rnd_int());
}
if ($v<25) { # zero
} elsif ($v<50) { # ones
for (my $w=0; $w<$val->Word_Size; ++$w) {
$val->Word_Store(0,~0);
}
} elsif ($v<60) { # one
$val->Word_Store(0,1);
} else { # random
for (my $w=0; $w<$val->Word_Size; ++$w) {
$val->Word_Store($w,rnd_int());
}
}
$treeref->{val} = $val;
}
@ -403,7 +403,7 @@ sub rnd {
}
sub rnd32 {
my $vp = int(rand(1<<16));
$vp ^= (int(rand(1<<8)))<<16;# Single 1<<16 doesn't work
$vp ^= (int(rand(1<<8)))<<16; # Single 1<<16 doesn't work
$vp ^= (int(rand(1<<8)))<<24;
return ($vp);
}
@ -423,10 +423,10 @@ sub id_commit {
my $signed = $treeref->{signed};
my $id = shift;
push @Commit, sub {
$IdWidth{$width}{$signed} = [] if !$IdWidth{$width}{$signed};
push @{$IdWidth{$width}{$signed}}, $id;
$VarsBlock{$id}{set} = 1;
1;
$IdWidth{$width}{$signed} = [] if !$IdWidth{$width}{$signed};
push @{$IdWidth{$width}{$signed}}, $id;
$VarsBlock{$id}{set} = 1;
1;
};
}
@ -449,15 +449,15 @@ sub id_same {
my @possible;
foreach my $id (keys %VarsBlock) {
next if !$VarsBlock{$id}{used};
my $varref = $Vars{$id};
next if $varref->{signed} != $signed;
next if $varref->{width} != $width;
push @possible, $id;
next if !$VarsBlock{$id}{used};
my $varref = $Vars{$id};
next if $varref->{signed} != $signed;
next if $varref->{width} != $width;
push @possible, $id;
}
my $n = $#possible + 1;
if ($n<1) { # Nothing, grab another!
return id_old($treeref,$width,$signed);
if ($n<1) { # Nothing, grab another!
return id_old($treeref,$width,$signed);
}
my $idn = rnd($n);
my $id = $possible[$idn];
@ -484,41 +484,41 @@ sub write_output_v {
my $cycles = 2;
foreach my $var (sort (keys %Vars)) {
print $fh "",decl_text ($var),"\n";
print $fh "",decl_text ($var),"\n";
}
foreach my $block (@Blocks) {
print $fh "\t//".('='x60)."\n";
my $style = rnd(100);
if ($style < 15) {
# This allows statements to get split up, and constants to propagate
print $fh " always @(", join(" or ", ('check', @{$block->{inputs}}));
print $fh ") begin : $block->{name}\n";
print $fh @{$block->{preass}};
print $fh " end\n";
print $fh " always @(posedge clk) begin : $block->{name}Check\n";
print $fh @{$block->{body}};
print $fh " end\n";
}
elsif ($style < 40) {
print $fh " always @(", join(" or ", ('check', @{$block->{inputs}}));
print $fh ") begin : $block->{name}\n";
print $fh @{$block->{preass}};
print $fh @{$block->{body}};
print $fh " end\n";
}
else {
foreach my $stmt (@{$block->{preass}}) {
$cycles++;
print $fh " always @(posedge clk) begin\n";
$stmt =~ s/ = / <= /mg;
print $fh $stmt;
print $fh " end\n";
}
print $fh " always @(posedge clk) begin\n";
print $fh @{$block->{body}};
print $fh " end\n";
}
print $fh "\t//".('='x60)."\n";
my $style = rnd(100);
if ($style < 15) {
# This allows statements to get split up, and constants to propagate
print $fh " always @(", join(" or ", ('check', @{$block->{inputs}}));
print $fh ") begin : $block->{name}\n";
print $fh @{$block->{preass}};
print $fh " end\n";
print $fh " always @(posedge clk) begin : $block->{name}Check\n";
print $fh @{$block->{body}};
print $fh " end\n";
}
elsif ($style < 40) {
print $fh " always @(", join(" or ", ('check', @{$block->{inputs}}));
print $fh ") begin : $block->{name}\n";
print $fh @{$block->{preass}};
print $fh @{$block->{body}};
print $fh " end\n";
}
else {
foreach my $stmt (@{$block->{preass}}) {
$cycles++;
print $fh " always @(posedge clk) begin\n";
$stmt =~ s/ = / <= /mg;
print $fh $stmt;
print $fh " end\n";
}
print $fh " always @(posedge clk) begin\n";
print $fh @{$block->{body}};
print $fh " end\n";
}
}
print $fh "\n";
@ -551,9 +551,9 @@ sub write_output_v {
sub callers {
for (my $i=0; ; $i++) {
my @c = caller($i);
last if !$c[0];
print "Caller $i: ",join(' ',@c[0..3]),"\n";
my @c = caller($i);
last if !$c[0];
print "Caller $i: ",join(' ',@c[0..3]),"\n";
}
}
@ -569,35 +569,35 @@ sub do_a_test {
%VarsBlock = ();
my $block = {
name=>"Block".($#Blocks+2),
body=>[],
preass=>[],
inputs=>[],
outputs=>[],
name=>"Block".($#Blocks+2),
body=>[],
preass=>[],
inputs=>[],
outputs=>[],
};
for (my $i=0; $i<$Opt_BlockStmts; $i++) {
my $treeref = gen_leaf(width=>0);
push @{$block->{body}},
"\tif ($treeref->{text} != ".$treeref->val_to_text().") if (check) ".stop_text().";\n";
my $treeref = gen_leaf(width=>0);
push @{$block->{body}},
"\tif ($treeref->{text} != ".$treeref->val_to_text().") if (check) ".stop_text().";\n";
}
foreach my $var (keys %VarsBlock) {
push @{$block->{inputs}}, $var
if $VarsBlock{$var}{used} && !$VarsBlock{$var}{set};
push @{$block->{inputs}}, $var
if $VarsBlock{$var}{used} && !$VarsBlock{$var}{set};
}
foreach my $var (reverse (sort (keys %Vars))) {
my $varref = $Vars{$var};
next if $varref->{printedit};
$varref->{printedit} = 1;
push @{$block->{outputs}}, $var;
push @{$block->{preass}}, sprintf ("\t$var = %s;\n"
,$varref->{text});
my $varref = $Vars{$var};
next if $varref->{printedit};
$varref->{printedit} = 1;
push @{$block->{outputs}}, $var;
push @{$block->{preass}}, sprintf ("\t$var = %s;\n"
,$varref->{text});
}
foreach my $com (@Commit) {
&{$com} or die "%Error: Can't eval:\n$com\n $@ ";
&{$com} or die "%Error: Can't eval:\n$com\n $@ ";
}
push @Blocks, $block;
@ -605,22 +605,22 @@ sub do_a_test {
sub gen_leaf {
my $inforef = {width=>0, # Anything
need_terminal=>0,
#trunc=>undef, # Allow multiply op
@_};
need_terminal=>0,
#trunc=>undef, # Allow multiply op
@_};
$inforef->{width} ||= rnd_width();
$inforef->{signed} = ($Opt_Signed && $inforef->{width}>1 && (rnd(100)<$Signed_Pct))?1:0
if !defined $inforef->{signed};
if !defined $inforef->{signed};
print +((" "x$Depth)."Leaf of width $inforef->{width}\n") if $Debug;
my $op = rnd_op($inforef);
my $treeref = new Vg::Base;
while ((my $key,my $val) = each %{$op}) {
$treeref->{$key} = $val;
$treeref->{$key} = $val;
}
while ((my $key,my $val) = each %{$inforef}) {
$treeref->{$key} = $val;
$treeref->{$key} = $val;
}
local $Depth = $Depth+1;
@ -636,11 +636,11 @@ sub gen_leaf {
print " Value ",$treeref->{val}," = ",$treeref->val_to_text(),"\n" if $Debug;
#$treeref->tree_dump() if $Debug;
$treeref->{val_size} = $treeref->{val}->Size; #Debugging
$treeref->{val_text} = $treeref->{val}->to_Hex; #Debugging
$treeref->{val_size} = $treeref->{val}->Size; # Debugging
$treeref->{val_text} = $treeref->{val}->to_Hex; # Debugging
($treeref->{val}->Size == $treeref->{width})
or die "%Error: Size mismatch ",$treeref->{val}->Size,"!=",$treeref->{width},"\n",Dumper($treeref);
or die "%Error: Size mismatch ",$treeref->{val}->Size,"!=",$treeref->{width},"\n",Dumper($treeref);
return $treeref;
}
@ -659,23 +659,23 @@ sub gen_v {
my $argl = $opref->{v};
my @args;
while ($argl =~ s/(%x.|%.)//) {
my $arg = $1;
push @args, '$treeref->{op1}{text}' if $arg =~ /%1/;
push @args, '$treeref->{op2}{text}' if $arg =~ /%2/;
push @args, '$treeref->{op3}{text}' if $arg =~ /%3/;
push @args, '$treeref->val_to_text' if $arg =~ /%v/;
push @args, '$treeref->{id}' if $arg =~ /%i/;
push @args, '$treeref->{signed}?"s":""' if $arg =~ /%xs/;
push @args, '$treeref->{width}' if $arg =~ /%xw/;
push @args, '$treeref->{width}-$treeref->{op1}{width}' if $arg =~ /%xd/;
my $arg = $1;
push @args, '$treeref->{op1}{text}' if $arg =~ /%1/;
push @args, '$treeref->{op2}{text}' if $arg =~ /%2/;
push @args, '$treeref->{op3}{text}' if $arg =~ /%3/;
push @args, '$treeref->val_to_text' if $arg =~ /%v/;
push @args, '$treeref->{id}' if $arg =~ /%i/;
push @args, '$treeref->{signed}?"s":""' if $arg =~ /%xs/;
push @args, '$treeref->{width}' if $arg =~ /%xw/;
push @args, '$treeref->{width}-$treeref->{op1}{width}' if $arg =~ /%xd/;
}
my $func = ("sub { "
." my \$treeref = shift;"
." sprintf(\"$fmt\",".join(',',@args).");"
."}");
." my \$treeref = shift;"
." sprintf(\"$fmt\",".join(',',@args).");"
."}");
my $set = ("\$opref->{v_sub} = $func; 1;");
$opref->{v_sub_text} = $func; # For seeing it in debugging dumps
$opref->{v_sub_text} = $func; # For seeing it in debugging dumps
#print "Op V $opref->{name} $set\n";
eval($set) or die "%Error: Can't eval:\n$set\n $@ ";
}
@ -716,11 +716,11 @@ sub gen_pl {
my $str = escapes($opref->{pl}, $opref->{name});
my $func = ("sub { "
." my \$treeref = shift;"
." $str;"
."}");
." my \$treeref = shift;"
." $str;"
."}");
my $set = ("\$opref->{pl_sub} = $func; 1;");
$opref->{pl_sub_text} = $func; # For seeing it in debugging dumps
$opref->{pl_sub_text} = $func; # For seeing it in debugging dumps
#print "Op PL $opref->{name} $set\n";
eval($set) or die "%Error: Can't eval:\n$set\n $@ ";
}
@ -731,11 +731,11 @@ sub gen_rnd {
my $str = escapes($opref->{rnd}, $opref->{name});
my $func = ("sub { "
." my \$treeref = shift;"
." $str;"
."}");
." my \$treeref = shift;"
." $str;"
."}");
my $set = ("\$opref->{rnd_sub} = $func; 1;");
$opref->{rnd_sub_text} = $func; # For seeing it in debugging dumps
$opref->{rnd_sub_text} = $func; # For seeing it in debugging dumps
#print "Op RND $opref->{name} $set\n";
eval($set) or die "%Error: Can't eval:\n$set\n $@ ";
}
@ -749,14 +749,14 @@ sub decl_text {
my $decl_with = shift;
my $varref = $Vars{$var};
return sprintf (" reg %s [%3d:%3d] %s %s; //=%d'h%s"
, ($varref->{signed}?"signed":" ")
, ($varref->{val}->Size)-1+$VarAttrs{$var}{lsb},
, $VarAttrs{$var}{lsb}
, $var
, (rnd(100)<30 ? "/*verilator public*/":(" "x length("/*verilator public*/")))
, $varref->{val}->Size
, lc $varref->{val}->to_Hex);
return sprintf(" reg %s [%3d:%3d] %s %s; //=%d'h%s"
, ($varref->{signed}?"signed":" ")
, ($varref->{val}->Size)-1+$VarAttrs{$var}{lsb},
, $VarAttrs{$var}{lsb}
, $var
, (rnd(100)<30 ? "/*verilator public*/":(" "x length("/*verilator public*/")))
, $varref->{val}->Size
, lc $varref->{val}->to_Hex);
}
#######################################################################
@ -789,7 +789,7 @@ sub min { return $_[0]>$_[1] ? $_[1] : $_[0]; }
sub log2 {
for (my $i=31; $i>=0; $i--) {
return $i+1 if $_[0]>(1<<$i);
return $i+1 if $_[0]>(1<<$i);
}
return 0;
}
@ -797,7 +797,7 @@ sub log2 {
sub countones {
my $out = 0;
for (my $bit=0; $bit < $_[0]->Size; $bit++) {
$out ++ if $_[0]->bit_test($bit);
$out ++ if $_[0]->bit_test($bit);
}
return $out;
}
@ -820,20 +820,20 @@ sub VREDNOR { $_[0]{val} = makebool(($_[1]->is_empty)?1:0); }
sub VREDXOR {
my $out = 0;
for (my $bit=0; $bit < $_[1]->Size; $bit++) {
$out ^= $_[1]->bit_test($bit);
$out ^= $_[1]->bit_test($bit);
}
$_[0]{val} = makebool($out);
}
sub VREDXNOR {
my $out = 1;
for (my $bit=0; $bit < $_[1]->Size; $bit++) {
$out ^= $_[1]->bit_test($bit);
$out ^= $_[1]->bit_test($bit);
}
$_[0]{val} = makebool($out);
}
sub eithercompare { ($_[1]->{signed} && $_[2]->{signed})
? $_[1]{val}->Compare($_[2]{val})
: $_[1]{val}->Lexicompare($_[2]{val}); }
? $_[1]{val}->Compare($_[2]{val})
: $_[1]{val}->Lexicompare($_[2]{val}); }
sub VEQ { $_[0]{val} = makebool( (eithercompare($_[0],$_[1],$_[2])==0) ?1:0); }
sub VNE { $_[0]{val} = makebool( (eithercompare($_[0],$_[1],$_[2])!=0) ?1:0); }
sub VLT { $_[0]{val} = makebool( (eithercompare($_[0],$_[1],$_[2])< 0) ?1:0); }
@ -858,8 +858,8 @@ sub VNOT { $_[0]{val}=my $o=newsized($_[1]); $o->Complement($_[1]); }
sub VSHIFTL{ $_[0]{val}=my $o=$_[1]->Clone; $o->Move_Left ($_[2]->Word_Read(0)); }
sub VSHIFTR{ $_[0]{val}=my $o=$_[1]->Clone; $o->Move_Right($_[2]->Word_Read(0)); }
sub VSHIFTRS{$_[0]{val}=my $o=$_[1]->Clone; $o->Move_Right($_[2]->Word_Read(0));
if ($_[1]->msb() && $_[2]->Word_Read(0)>0) {$o->Interval_Fill(max(0,$o->Size-1-$_[2]->Word_Read(0)), $o->Size-1); }
#print (" SHI ",$_[0]{val}->to_Hex,' = ',$_[1]->to_Hex,' >>> ',$_[2]->Word_Read(0),"\n");
if ($_[1]->msb() && $_[2]->Word_Read(0)>0) {$o->Interval_Fill(max(0,$o->Size-1-$_[2]->Word_Read(0)), $o->Size-1); }
#print (" SHI ",$_[0]{val}->to_Hex,' = ',$_[1]->to_Hex,' >>> ',$_[2]->Word_Read(0),"\n");
}
sub VCLONE { $_[0]{val}=$_[1]->Clone; }
sub VRESIZE {
@ -880,21 +880,21 @@ sub VMUL {
sub VDIV {
my $is_mod = $_[3];
if ($_[2]{val}->is_empty) { # Avoid divide by zero
$_[0]{val}=newsized($_[1]{val});
return;
$_[0]{val}=newsized($_[1]{val});
return;
}
my $a=$_[1]{val}->Clone; if (!$_[1]->{signed}) { $a->Resize($a->Size + 1); }
my $b=$_[2]{val}->Clone; if (!$_[2]->{signed}) { $b->Resize($b->Size + 1); }
#print ("//DIVpp ",$_[1]->to_Hex,' ',$_[2]->to_Hex,' ',$_[1]->Size,'.',$_[2]->Size," \n");
#print ("//DIVpp ",$a->to_Hex,' ',$b->to_Hex,' ',$a->Size,'.',$b->Size," \n");
my $quo=newsized($a); my $rem=newsized($a);
$quo->Divide($a,$b,$rem); # No division by zero - handled by if above
$quo->Divide($a,$b,$rem); # No division by zero - handled by if above
my $o=newsized($_[1]{val});
$o->Interval_Copy($is_mod ? $rem : $quo,0,0,$_[1]{val}->Size);
#print "//DIV",($_[1]->{signed}?"S":" "),' w',$a->Size,' ',$_[1]{val}->to_Hex,' ',$_[2]{val}->to_Hex,' =',$quo->to_Hex,'.',$rem->to_Hex," \n";
$_[0]{val}=$o;
}
sub VPOW { # Power is a signed operation
sub VPOW { # Power is a signed operation
my $a=$_[1]{val}->Clone; if (!$_[1]->{signed}) { $a->Resize($_[1]{val}->Size + 1); }
my $b=$_[2]{val}->Clone; if (!$_[2]->{signed}) { $b->Resize($_[2]{val}->Size + 1); }
print "VVpow = ",$_[1]{val}->to_Hex," ** ",$_[2]{val}->to_Hex,"\n";
@ -904,19 +904,26 @@ sub VPOW { # Power is a signed operation
$_[0]{val}=$o;
print "VV = $o\n";
}
sub VRANGE { #print "RANGE ",$_[1]->to_Hex,' ',$_[2]->to_Hex,' ',$_[3]->to_Hex," \n";
return VRANGE_CONST($_[0],$_[1],$_[2]->Word_Read(0),$_[3]->Word_Read(0), $_[4]); }
sub VRANGE {
#print "RANGE ",$_[1]->to_Hex,' ',$_[2]->to_Hex,' ',$_[3]->to_Hex," \n";
return VRANGE_CONST($_[0], $_[1], $_[2]->Word_Read(0),
$_[3]->Word_Read(0), $_[4]);
}
sub VBITSELP {
return VRANGE_CONST($_[0],$_[1],$_[2]->Word_Read(0)+$_[3]->Word_Read(0)-1, $_[2]->Word_Read(0), $_[4]); }
return VRANGE_CONST($_[0], $_[1], $_[2]->Word_Read(0)+$_[3]->Word_Read(0)-1,
$_[2]->Word_Read(0), $_[4]);
}
sub VBITSELM {
return VRANGE_CONST($_[0],$_[1],$_[2]->Word_Read(0), $_[2]->Word_Read(0)-$_[3]->Word_Read(0)+1, $_[4]); }
return VRANGE_CONST($_[0],$_[1],$_[2]->Word_Read(0),
$_[2]->Word_Read(0)-$_[3]->Word_Read(0)+1, $_[4]);
}
sub VRANGE_CONST {
# to, from, msb, lsb, variable_lsb_to_subtract
#print "RANGE ",$_[1]->to_Hex,' ',$_[2],' ',$_[3],' ',$_[4]," \n";
my $size = $_[2] - $_[3] + 1;
my $o=Bit::Vector->new($size);
if ($_[3] < $_[1]->Size) {
$o->Interval_Copy($_[1],0,$_[3]-$_[4],$size);
$o->Interval_Copy($_[1],0,$_[3]-$_[4],$size);
}
$_[0]{val}=$o; }
sub VCONCAT {
@ -929,8 +936,8 @@ sub VREPLIC {
my $o=Bit::Vector->new($_[1]->Word_Read(0) * $_[2]->Size);
my $pos = 0;
for (my $time=0; $time<($_[1]->Word_Read(0)); $time++) {
$o->Interval_Copy($_[2],$pos,0,$_[2]->Size);
$pos += $_[2]->Size;
$o->Interval_Copy($_[2],$pos,0,$_[2]->Size);
$pos += $_[2]->Size;
}
$_[0]{val}=$o;
}
@ -949,9 +956,9 @@ use strict;
sub new {
my $class = shift;
my $self = {
width=>0, # Width of expression, 0=Pick a width
#signed=>0/1, # Undef = pick a sign
@_};
width=>0, # Width of expression, 0=Pick a width
#signed=>0/1, # Undef = pick a sign
@_};
bless $self, $class;
return $self;
}
@ -966,8 +973,8 @@ sub val_to_text {
my $val = lc $treeref->{val}->to_Hex();
$val = "0" if $treeref->{val}->is_empty;
return ($treeref->{width}
.($treeref->{signed}?"'sh":"'h")
.$val);
.($treeref->{signed}?"'sh":"'h")
.$val);
}
sub tree_dump {