tests: GHDL test driver support

This commit is contained in:
Wilson Snyder 2011-12-09 19:58:14 -05:00
parent 350ba264e8
commit f6fab74436
1 changed files with 182 additions and 18 deletions

View File

@ -48,6 +48,7 @@ my @opt_tests;
my $opt_gdb; my $opt_gdb;
my $opt_gdbbt; my $opt_gdbbt;
my $opt_gdbsim; my $opt_gdbsim;
my $opt_ghdl;
my $opt_iv; my $opt_iv;
my $opt_jobs = 1; my $opt_jobs = 1;
my $opt_nc; my $opt_nc;
@ -70,6 +71,7 @@ if (! GetOptions (
"gdb!" => \$opt_gdb, "gdb!" => \$opt_gdb,
"gdbbt!" => \$opt_gdbbt, "gdbbt!" => \$opt_gdbbt,
"gdbsim!" => \$opt_gdbsim, "gdbsim!" => \$opt_gdbsim,
"ghdl!" => \$opt_ghdl,
"golden!" => sub { $ENV{HARNESS_UPDATE_GOLDEN} = 1; }, "golden!" => sub { $ENV{HARNESS_UPDATE_GOLDEN} = 1; },
"help" => \&usage, "help" => \&usage,
"iverilog!" => \$opt_iv, "iverilog!" => \$opt_iv,
@ -95,7 +97,7 @@ $opt_jobs = calc_jobs() if defined $opt_jobs && $opt_jobs==0;
$Fork->max_proc($opt_jobs); $Fork->max_proc($opt_jobs);
if (!$opt_atsim && !$opt_iv && !$opt_vcs && !$opt_nc && !$opt_vlt) { if (!$opt_atsim && !$opt_ghdl && !$opt_iv && !$opt_vcs && !$opt_nc && !$opt_vlt) {
$opt_vlt = 1; $opt_vlt = 1;
} }
@ -120,6 +122,7 @@ my @fails;
foreach my $testpl (@opt_tests) { foreach my $testpl (@opt_tests) {
one_test(pl_filename => $testpl, atsim=>1) if $opt_atsim; one_test(pl_filename => $testpl, atsim=>1) if $opt_atsim;
one_test(pl_filename => $testpl, ghdl=>1) if $opt_ghdl;
one_test(pl_filename => $testpl, iv=>1) if $opt_iv; one_test(pl_filename => $testpl, iv=>1) if $opt_iv;
one_test(pl_filename => $testpl, nc=>1) if $opt_nc; one_test(pl_filename => $testpl, nc=>1) if $opt_nc;
one_test(pl_filename => $testpl, vcs=>1) if $opt_vcs; one_test(pl_filename => $testpl, vcs=>1) if $opt_vcs;
@ -306,6 +309,13 @@ sub new {
"+sv_dir+$self->{obj_dir}/.athdl_compile"], "+sv_dir+$self->{obj_dir}/.athdl_compile"],
atsim_flags2 => [], # Overridden in some sim files atsim_flags2 => [], # Overridden in some sim files
atsimrun_flags => [], atsimrun_flags => [],
# GHDL
ghdl => 0,
ghdl_work_dir => "$self->{obj_dir}/ghdl_compile",
ghdl_flags => [($::Debug?"-v":""),
"--workdir=$self->{obj_dir}/ghdl_compile", ],
ghdl_flags2 => [], # Overridden in some sim files
ghdlrun_flags => [],
# IV # IV
iv => 0, iv => 0,
iv_flags => [split(/\s+/,"+define+iverilog -o $self->{obj_dir}/simiv")], iv_flags => [split(/\s+/,"+define+iverilog -o $self->{obj_dir}/simiv")],
@ -335,6 +345,7 @@ sub new {
bless $self, $class; bless $self, $class;
$self->{mode} ||= "atsim" if $self->{atsim}; $self->{mode} ||= "atsim" if $self->{atsim};
$self->{mode} ||= "ghdl" if $self->{ghdl};
$self->{mode} ||= "vcs" if $self->{vcs}; $self->{mode} ||= "vcs" if $self->{vcs};
$self->{mode} ||= "vlt" if $self->{vlt}; $self->{mode} ||= "vlt" if $self->{vlt};
$self->{mode} ||= "nc" if $self->{nc}; $self->{mode} ||= "nc" if $self->{nc};
@ -347,11 +358,6 @@ sub new {
$self->{vcd_filename} ||= "$self->{obj_dir}/sim.vcd"; $self->{vcd_filename} ||= "$self->{obj_dir}/sim.vcd";
$self->{main_filename} ||= "$self->{obj_dir}/$self->{VM_PREFIX}__main.cpp"; $self->{main_filename} ||= "$self->{obj_dir}/$self->{VM_PREFIX}__main.cpp";
($self->{top_filename} = $self->{pl_filename}) =~ s/\.pl$/\.v/; ($self->{top_filename} = $self->{pl_filename}) =~ s/\.pl$/\.v/;
if (!$self->{make_top_shell}) {
$self->{top_shell_filename} = $self->{top_filename};
} else {
$self->{top_shell_filename} = "$self->{obj_dir}/$self->{VM_PREFIX}__top.v";
}
return $self; return $self;
} }
@ -392,7 +398,6 @@ sub read {
(-r $self->{pl_filename}) (-r $self->{pl_filename})
or return $self->error("Can't open $self->{pl_filename}\n"); or return $self->error("Can't open $self->{pl_filename}\n");
$Self = $self; $Self = $self;
$Self = $self;
delete $INC{$self->{pl_filename}}; delete $INC{$self->{pl_filename}};
require $self->{pl_filename}; require $self->{pl_filename};
} }
@ -476,6 +481,14 @@ sub compile {
compile_vlt_flags(%param); compile_vlt_flags(%param);
if (!$self->{make_top_shell}) {
$param{top_shell_filename}
= $self->{top_shell_filename} = $self->{top_filename};
} else {
$param{top_shell_filename}
= $self->{top_shell_filename} = "$self->{obj_dir}/$self->{VM_PREFIX}__top.".$self->v_suffix;
}
if ($param{atsim}) { if ($param{atsim}) {
$self->_make_top(); $self->_make_top();
$self->_run(logfile=>"$self->{obj_dir}/atsim_compile.log", $self->_run(logfile=>"$self->{obj_dir}/atsim_compile.log",
@ -490,7 +503,25 @@ sub compile {
@{$param{v_other_filenames}}, @{$param{v_other_filenames}},
]); ]);
} }
if ($param{vcs}) { elsif ($param{ghdl}) {
mkdir $self->{ghdl_work_dir};
$self->_make_top();
$self->_run(logfile=>"$self->{obj_dir}/ghdl_compile.log",
fails=>$param{fails},
cmd=>[($ENV{VERILATOR_GHDL}||"ghdl"),
# Add -c here, as having -c twice freaks it out
((($ENV{VERILATOR_GHDL}||' ') =~ / -c\b/) ? "" : "-c"),
@{$param{ghdl_flags}},
@{$param{ghdl_flags2}},
#@{$param{v_flags}}, # Not supported
#@{$param{v_flags2}}, # Not supported
$param{top_filename},
$param{top_shell_filename},
@{$param{v_other_filenames}},
"-e t",
]);
}
elsif ($param{vcs}) {
$self->_make_top(); $self->_make_top();
$self->_run(logfile=>"$self->{obj_dir}/vcs_compile.log", $self->_run(logfile=>"$self->{obj_dir}/vcs_compile.log",
fails=>$param{fails}, fails=>$param{fails},
@ -504,8 +535,14 @@ sub compile {
@{$param{v_other_filenames}}, @{$param{v_other_filenames}},
]); ]);
} }
if ($param{nc}) { elsif ($param{nc}) {
$self->_make_top(); $self->_make_top();
my @more_args;
if ($self->vhdl) {
((my $ts = $param{top_shell_filename}) =~ s!\.v!!);
$ts =~ s!.*/!!;;
push @more_args, "-vhdltop", $ts;
}
$self->_run(logfile=>"$self->{obj_dir}/nc_compile.log", $self->_run(logfile=>"$self->{obj_dir}/nc_compile.log",
fails=>$param{fails}, fails=>$param{fails},
cmd=>[($ENV{VERILATOR_NCVERILOG}||"ncverilog"), cmd=>[($ENV{VERILATOR_NCVERILOG}||"ncverilog"),
@ -516,9 +553,10 @@ sub compile {
$param{top_filename}, $param{top_filename},
$param{top_shell_filename}, $param{top_shell_filename},
@{$param{v_other_filenames}}, @{$param{v_other_filenames}},
@more_args
]); ]);
} }
if ($param{iv}) { elsif ($param{iv}) {
$self->_make_top(); $self->_make_top();
my @cmd = (($ENV{VERILATOR_IVERILOG}||"iverilog"), my @cmd = (($ENV{VERILATOR_IVERILOG}||"iverilog"),
@{$param{iv_flags}}, @{$param{iv_flags}},
@ -534,7 +572,7 @@ sub compile {
fails=>$param{fails}, fails=>$param{fails},
cmd=>\@cmd); cmd=>\@cmd);
} }
if ($param{vlt}) { elsif ($param{vlt}) {
my @cmdargs = $self->compile_vlt_flags(%param); my @cmdargs = $self->compile_vlt_flags(%param);
if ($self->sc_or_sp && !defined $ENV{SYSTEMC}) { if ($self->sc_or_sp && !defined $ENV{SYSTEMC}) {
@ -575,6 +613,9 @@ sub compile {
]); ]);
} }
} }
else {
$self->error("No compile step for this simulator");
}
return 1; return 1;
} }
@ -595,7 +636,15 @@ sub execute {
@{$param{all_run_flags}}, @{$param{all_run_flags}},
]); ]);
} }
if ($param{iv}) { elsif ($param{ghdl}) {
$self->_run(logfile=>"$self->{obj_dir}/ghdl_sim.log",
fails=>$param{fails},
cmd=>[$run_env."$self->{obj_dir}/simghdl",
@{$param{ghdlrun_flags}},
@{$param{all_run_flags}},
]);
}
elsif ($param{iv}) {
$self->_run(logfile=>"$self->{obj_dir}/iv_sim.log", $self->_run(logfile=>"$self->{obj_dir}/iv_sim.log",
fails=>$param{fails}, fails=>$param{fails},
cmd=>[$run_env."$self->{obj_dir}/simiv", cmd=>[$run_env."$self->{obj_dir}/simiv",
@ -603,7 +652,7 @@ sub execute {
@{$param{all_run_flags}}, @{$param{all_run_flags}},
]); ]);
} }
if ($param{nc}) { elsif ($param{nc}) {
$self->_run(logfile=>"$self->{obj_dir}/nc_sim.log", $self->_run(logfile=>"$self->{obj_dir}/nc_sim.log",
fails=>$param{fails}, fails=>$param{fails},
cmd=>["echo q | ".$run_env.($ENV{VERILATOR_NCVERILOG}||"ncverilog"), cmd=>["echo q | ".$run_env.($ENV{VERILATOR_NCVERILOG}||"ncverilog"),
@ -611,7 +660,7 @@ sub execute {
@{$param{all_run_flags}}, @{$param{all_run_flags}},
]); ]);
} }
if ($param{vcs}) { elsif ($param{vcs}) {
#my $fh = IO::File->new(">simv.key") or die "%Error: $! simv.key,"; #my $fh = IO::File->new(">simv.key") or die "%Error: $! simv.key,";
#$fh->print("quit\n"); $fh->close; #$fh->print("quit\n"); $fh->close;
$self->_run(logfile=>"$self->{obj_dir}/vcs_sim.log", $self->_run(logfile=>"$self->{obj_dir}/vcs_sim.log",
@ -623,7 +672,7 @@ sub execute {
expect=>undef, # vcs expect isn't the same expect=>undef, # vcs expect isn't the same
); );
} }
if ($param{vlt} elsif ($param{vlt}
#&& (!$param{needs_v4} || -r "$ENV{VERILATOR_ROOT}/src/V3Gate.cpp") #&& (!$param{needs_v4} || -r "$ENV{VERILATOR_ROOT}/src/V3Gate.cpp")
) { ) {
$param{executable} ||= "$self->{obj_dir}/$param{VM_PREFIX}"; $param{executable} ||= "$self->{obj_dir}/$param{VM_PREFIX}";
@ -636,6 +685,9 @@ sub execute {
%param, %param,
); );
} }
else {
$self->error("No execute step for this simulator");
}
} }
sub inline_checks { sub inline_checks {
@ -705,6 +757,21 @@ sub top_filename {
return $self->{top_filename}; return $self->{top_filename};
} }
sub vhdl {
my $self = (ref $_[0]? shift : $Self);
$self->{vhdl} = shift if defined $_[0];
if ($self->{vhdl}) {
$self->{top_filename} =~ s/\.v$/\.vhdl/;
}
return $self->{vhdl};
}
sub v_suffix {
my $self = (ref $_[0]? shift : $Self);
# Suffix for file type, e.g. .vhdl or .v
return $self->{vhdl} ? "vhdl" : "v";
}
sub sp { sub sp {
my $self = (ref $_[0]? shift : $Self); my $self = (ref $_[0]? shift : $Self);
return $self->{sp}; return $self->{sp};
@ -816,7 +883,11 @@ sub _run {
sub _make_main { sub _make_main {
my $self = shift; my $self = shift;
$self->_read_inputs(); if ($self->vhdl) {
$self->_read_inputs_vhdl();
} else {
$self->_read_inputs_v();
}
my $filename = $self->{main_filename}; my $filename = $self->{main_filename};
my $fh = IO::File->new(">$filename") or die "%Error: $! $filename,"; my $fh = IO::File->new(">$filename") or die "%Error: $! $filename,";
@ -959,8 +1030,17 @@ sub _print_advance_time {
sub _make_top { sub _make_top {
my $self = shift; my $self = shift;
if ($self->vhdl) {
$self->_make_top_vhdl;
} else {
$self->_make_top_v;
}
}
$self->_read_inputs(); sub _make_top_v {
my $self = shift;
$self->_read_inputs_v();
my $fh = IO::File->new(">$self->{top_shell_filename}") or die "%Error: $! $self->{top_shell_filename},"; my $fh = IO::File->new(">$self->{top_shell_filename}") or die "%Error: $! $self->{top_shell_filename},";
print $fh "module top;\n"; print $fh "module top;\n";
@ -1007,6 +1087,61 @@ sub _make_top {
$fh->close(); $fh->close();
} }
sub _make_top_vhdl {
my $self = shift;
$self->_read_inputs_vhdl();
my $fh = IO::File->new(">$self->{top_shell_filename}") or die "%Error: $! $self->{top_shell_filename},";
print $fh "library ieee;\n";
my @ports = sort (keys %{$self->{inputs}});
print $fh "entity t_ent is\n";
if ($#ports >= 0) {
print $fh " port(\n";
my $semi = "";
foreach my $inp (@ports) {
print $fh "\t${semi}${inp} : in std_logic\n";
$semi=";";
}
print $fh " );\n";
}
print $fh "end;\n";
print $fh "entity top is\n";
print $fh "end;\n";
# Inst
print $fh "architecture t_beh of t_ent is\n";
if ($#ports >= 0) {
foreach my $inp (@ports) {
print $fh "\tsignal ${inp} : std_logic := '0';\n";
}
}
print $fh " begin\n";
print $fh " t : t_ent\n";
if ($#ports >= 0) {
print $fh " port map(\n";
my $comma="";
foreach my $inp (@ports) {
print $fh "\t${comma}${inp} => ${inp}\n";
$comma=",";
}
print $fh " )\n";
}
print $fh " ;\n";
print $fh " end;\n";
# Waves TBD
# Test TBD
print $fh "end;\n";
$fh->close();
}
####################################################################### #######################################################################
sub _sp_preproc { sub _sp_preproc {
@ -1025,7 +1160,7 @@ sub _sp_preproc {
####################################################################### #######################################################################
sub _read_inputs { sub _read_inputs_v {
my $self = shift; my $self = shift;
my $filename = $self->{top_filename}; my $filename = $self->{top_filename};
$filename = "$self->{t_dir}/$filename" if !-r $filename; $filename = "$self->{t_dir}/$filename" if !-r $filename;
@ -1041,6 +1176,27 @@ sub _read_inputs {
$fh->close(); $fh->close();
} }
#######################################################################
sub _read_inputs_vhdl {
my $self = shift;
my $filename = $self->{top_filename};
$filename = "$self->{t_dir}/$filename" if !-r $filename;
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename,";
while (defined(my $line = $fh->getline)) {
# Only supports this form right now:
# signal: in ...
# signal: out ...
if ($line =~ /^\s*(\S+)\s*:\s*(in)\b\s*/) {
$self->{inputs}{$1} = $1;
}
if ($line =~ /^\s*(architecture)/) {
last;
}
}
$fh->close();
}
####################################################################### #######################################################################
# Verilator utilities # Verilator utilities
@ -1277,6 +1433,10 @@ Requires --debug.
Run Verilator generated executable under the debugger. Run Verilator generated executable under the debugger.
=item --ghdl
Run using GHDL.
=item --golden =item --golden
Update golden files, equivalent to setting HARNESS_UPDATE_GOLDEN=1. Update golden files, equivalent to setting HARNESS_UPDATE_GOLDEN=1.
@ -1329,6 +1489,10 @@ Run using Verilator.
Root directory name of SystemC kit. Root directory name of SystemC kit.
=item VERILATOR_GHDL
Command to use to invoke GHDL.
=item VERILATOR_IVERILOG =item VERILATOR_IVERILOG
Command to use to invoke Icarus Verilog. Command to use to invoke Icarus Verilog.