Internals: Detab and fix spacing style issues in tests and scripts. No functional change.
This commit is contained in:
parent
37c8cc82b2
commit
f818ddc71c
|
@ -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
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
"<>" => \¶meter,
|
||||
"lineno!" => \$Opt_Lineno,
|
||||
if (! GetOptions(
|
||||
"help" => \&usage,
|
||||
"debug" => \&debug,
|
||||
"<>" => \¶meter,
|
||||
"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";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
if (! GetOptions(
|
||||
"help" => \&usage,
|
||||
"debug" => \&debug,
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,11 +24,11 @@ $Debug = 0;
|
|||
my $opt_filename;
|
||||
autoflush STDOUT 1;
|
||||
autoflush STDERR 1;
|
||||
if (! GetOptions (
|
||||
"help" => \&usage,
|
||||
"debug" => \&debug,
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
if (! GetOptions(
|
||||
"help" => \&usage,
|
||||
"debug" => \&debug,
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
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");
|
||||
}
|
||||
|
|
|
@ -26,12 +26,12 @@ my $opt_filename;
|
|||
my $opt_circle;
|
||||
autoflush STDOUT 1;
|
||||
autoflush STDERR 1;
|
||||
if (! GetOptions (
|
||||
"help" => \&usage,
|
||||
"debug" => \&debug,
|
||||
"<>" => \¶meter,
|
||||
"circle=s" => \$opt_circle,
|
||||
)) {
|
||||
if (! GetOptions(
|
||||
"help" => \&usage,
|
||||
"debug" => \&debug,
|
||||
"<>" => \¶meter,
|
||||
"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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -23,11 +23,11 @@ $Debug = 0;
|
|||
my $opt_filename;
|
||||
autoflush STDOUT 1;
|
||||
autoflush STDERR 1;
|
||||
if (! GetOptions (
|
||||
"help" => \&usage,
|
||||
"debug" => \&debug,
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
if (! GetOptions(
|
||||
"help" => \&usage,
|
||||
"debug" => \&debug,
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
582
src/astgen
582
src/astgen
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
474
src/bisonpre
474
src/bisonpre
|
@ -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,
|
||||
"<>" => \¶meter,
|
||||
Getopt::Long::config("no_auto_abbrev");
|
||||
if (! GetOptions(
|
||||
# Local options
|
||||
"help" => \&usage,
|
||||
"version" => sub { print "Version $VERSION\n"; exit(0); },
|
||||
"yacc=s" => \$Opt_Yacc,
|
||||
# Passed to Bison
|
||||
"t|debug" => sub { $Opt_Debug = 1; },
|
||||
"b|file-prefix=s" => \$Opt_File_Prefix,
|
||||
"d" => \$Opt_Definitions,
|
||||
"k|token-table" => \$Opt_Token_Table,
|
||||
"o=s" => \$Opt_Output,
|
||||
"p|name-prefix=s" => \$Opt_Name_Prefix,
|
||||
"v|verbose" => \$Opt_Verbose,
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
die "%Error: Bad usage, try 'bisonpre --help'\n";
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
104
src/vlcovgen
104
src/vlcovgen
|
@ -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
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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); }
|
||||
|
||||
//======================================================================
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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););
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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`;
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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});
|
||||
|
||||
|
|
|
@ -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});
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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,
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
"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,
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
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 {
|
||||
|
|
Loading…
Reference in New Issue