Commit c00f2daf authored by Christian Fibich's avatar Christian Fibich Committed by Stefan Tauner
Browse files

Simplified random test generation

Simplified assignment import into Quartus in Demo
parent 7e372d3a
......@@ -323,7 +323,9 @@ sub instrument_net ($$;$) {
my %connections;
$self->_get_net_connections($net,\%connections);
# if _get_net_connections() could not determine a driver
# the user must choose manually
if(!defined $driver && @{$connections{'drivers'}} == 0) {
$driver = _select_driver($connections{'connected'},$net);
......@@ -332,6 +334,8 @@ sub instrument_net ($$;$) {
}
}
# if _get_net_connections() could not determine a driver
# take the one chosen by the user
if(@{$connections{'drivers'}} == 0) {
foreach my $connection (@{$connections{'connected'}}) {
if($connection == $driver) {
......@@ -340,7 +344,9 @@ sub instrument_net ($$;$) {
push @{$connections{'driven'}},$connection;
}
}
# if _get_net_connections() determined a driver
} elsif(@{$connections{'drivers'}} == 1) {
# and the user supplied a driver, check if they both match
if(defined $driver && @{$connections{'drivers'}}[0] != $driver) {
$msg = "Driver mismatch on net ".$net->name;
return $msg;
......@@ -357,8 +363,8 @@ sub instrument_net ($$;$) {
}
# VHDL signals must not contain multiple subsequent underscores
my $output_name = (($FIJI_PORT_PREFIX.$net->name.$FIJI_PORT_OUT_POSTFIX) =~ s/_+/_/gr);
my $input_name = (($FIJI_PORT_PREFIX.$net->name.$FIJI_PORT_IN_POSTFIX) =~ s/_+/_/gr);
my $output_name = (($FIJI_PORT_PREFIX.$net->name.$FIJI_PORT_OUT_POSTFIX) =~ s/__+/_/gr);
my $input_name = (($FIJI_PORT_PREFIX.$net->name.$FIJI_PORT_IN_POSTFIX) =~ s/__+/_/gr);
$msg = _check_name_in_hierarchy($net->module,$output_name);
return $msg if defined $msg;
......@@ -376,12 +382,14 @@ sub instrument_net ($$;$) {
foreach my $connection (@{$connections{'drivers'}}) {
my $log = "Original: Connecting ";
if(ref($connection) eq "Verilog::Netlist::Pin") {
# if it is a pin of a cell, connect this pin to the newly created net
$log .= "(output) pin ".$connection->cell->name.$HIERSEP.$connection->name;
$connection->netname($op->net->name);
$connection->portname($op->name);
$connection->net(undef); # resolved by link
$connection->port(undef); # resolved by link
} elsif (ref($connection) eq "Verilog::Netlist::Port") {
# if it is a port of a module, connect this port to the newly created net
$log .= "(input) port ".$connection->name;
$connection->net($op->net);
$net->module->new_contassign (keyword => "assign",
......@@ -400,6 +408,7 @@ sub instrument_net ($$;$) {
# $net->module->link;
}
# exactly the same for the input
# connecting newly created input to driven cells
foreach my $connection (@{$connections{'driven'}}) {
my $log = "Modified: Connecting ";
......@@ -433,6 +442,10 @@ sub instrument_net ($$;$) {
return undef;
}
# Prompt the user to select a driver for a net from a set of given cells/outputs
# Params:
# connected list reference containing connected Verilog::Perl instances
# net the Verilog::Perl::Net instance to select the driver for
sub _select_driver($$) {
my ($connected,$net) = @_;
......@@ -480,6 +493,11 @@ sub _connection_tostr($) {
# params
# net the net to be examined
# connection_hashref a hashref where the results can be placed
# -> connection_hashref->{'drivers'} contains a list of driver cells
# -> connection_hashref->{'driven'} contains a list of driven cells
# -> connection_hashref->{'connected'} contains a list cells connected to the
# net but driver/driven cannot be decided
sub _get_net_connections ($$) {
my $logger = get_logger();
my ($self,$net,$connection_hashref) = @_;
......@@ -507,6 +525,10 @@ sub _get_net_connections ($$) {
my @netnames_list = ();
# This generates a list of net names for buses e.g.
# wire [3:0] bus
# netnames = (bus[0],bus[1],bus[2],bus[3])
# FIXME there must be a cleaner alternative
if ((defined $net->msb && defined $net->lsb)) {
for (my $i = $net->lsb; $i <= $net->msb; $i++) {
push @netnames_list,$net->name."[$i]";
......@@ -515,13 +537,15 @@ sub _get_net_connections ($$) {
push @netnames_list,$net->name;
}
# check each netname
foreach my $netname (@netnames_list) {
if($netname =~ m/.+\[([0-9]+)\]/) {
my $idx = $1;
}
my $bn = $net->name;
$logger->debug("Net ".$mod->name.$HIERSEP.$netname.", connections:");
if($netname =~ m/.+\[([0-9]+)\]/) {
my $idx = $1;
}
my $bn = $net->name;
$logger->debug("Net ".$mod->name.$HIERSEP.$netname.", connections:");
# find nets driven by continuous assignment (e.g., constant or inverter)
foreach my $statement ($mod->statements) {
if($statement->lhs eq $netname) {
......@@ -532,30 +556,31 @@ sub _get_net_connections ($$) {
push @driven,$statement;
}
}
# find nets driven by this module's input ports
foreach my $port ($mod->ports_sorted) {
if (defined $port->net && ($port->net->name eq $netname)) {
$logger->debug(" port: ".$mod->name.$HIERSEP.$port->name) ;
$logger->debug(" port: ".$mod->name.$HIERSEP.$port->name) ;
# driven from an input, there can't be another driver
if ($port->direction eq "in") {
push @drivers,$port;
} elsif ($port->direction eq "out") {
push @driven,$port;
} elsif ($port->direction eq "inout") {
push @connected,$port;
}
if ($port->direction eq "in") {
push @drivers,$port;
} elsif ($port->direction eq "out") {
push @driven,$port;
} elsif ($port->direction eq "inout") {
push @connected,$port;
}
}
}
# find nets driven by other cells output pins
foreach my $cell ($mod->cells_sorted) {
foreach my $pin ($cell->pins_sorted) {
if ($pin->netname eq $netname) {
$logger->debug(" pin ".$pin->cell->name.$HIERSEP.$pin->name);
push @connected,$pin;
}
if ($pin->netname eq $netname) {
$logger->debug(" pin ".$pin->cell->name.$HIERSEP.$pin->name);
push @connected,$pin;
}
}
}
}
$connections->{'drivers'} = \@drivers;
$connections->{'driven'} = \@driven;
......@@ -659,7 +684,7 @@ sub _export_module($) {
$logger->info("Generating assigns for module ".$mod->name);
# need to separate assigns from defparams - see later...
# need to separate assigns from defparams - see below...
foreach my $statement ($mod->statements_sorted) {
if(ref($statement) eq "Verilog::Netlist::ContAssign") {
push @contassigns, $statement;
......@@ -669,7 +694,6 @@ sub _export_module($) {
# FIXME this regex might break with other synthesis tool because of other delimiters (?)
my $k = (split(/\./,$statement->lhs))[0];
push @{$defparams{$k}}, $statement;
#$defparam_indent = length $statement->lhs if (length $statement->lhs > $defparam_indent);
}
}
......
......@@ -853,24 +853,15 @@ sub make_random_test {
# cfg[FIJI::FIUENUM->{'DELAY'}] Probability of delay error
# cfg[FIJI::FIUENUM->{'SEU'}] Probability of seu error
# cfg[FIJI::FIUENUM->{'STUCK_OPEN'}] Probability of stuck-open error
#
# thank you http://www.perlmonks.org/?node_id=22094
sub choose_random_fault {
my ($cfg) = @_;
my $random = rand(1);
my ($sum_old, $sum_new);
$sum_old = 0;
$sum_new = 0;
my $fault = 0;
# loop through fault probabilities and accumulate
# check if $random is in the current range
for (my $ti = 0; $ti <= [FIJI::FIUENUM->{'STUCK_OPEN'}]; $ti++) {
$sum_new = $sum_old + @$cfg[$ti];
if ($random >= $sum_old && $random < $sum_new) {
$fault = $ti;
last;
}
$sum_old = $sum_new;
my ($mark,$fault) = (0,undef);
for (my $idx = FIJI::FIUENUM->{'NONE'}; $idx <= FIJI::FIUENUM->{'STUCK_OPEN'}; $idx++) {
$mark += @$cfg[ $idx ];
$fault = $idx if rand($mark) < @$cfg[ $idx ];
}
return REVERSE_FIU_ENUM($fault);
......
use FIJI::VHDL;
use Log::Log4perl qw(get_logger);
use Verilog::Netlist;
use Verilog::Getopt;
exit(main(@ARGV));
sub main ($) {
my $logger = get_logger();
Log::Log4perl::init_and_watch('logger.conf', 'HUP');
my $name = $0;
$name =~ s/\.p[lm]//;
my $cfgname = $name . ".cfg";
$logger->debug("=== Starting new execution of $name ===");
$logger->debug(sprintf("%d argument(s)%s", scalar(@_), scalar(@_) > 0 ? ": @_" : ""));
$logger->debug("Generating FIJI public config package");
FIJI::VHDL->generate_config_package("fiji.cfg", "fiji_public_config_pkg.vhd");
$logger->debug("Generating FIJI wrapper");
my %wrapper_config;
$wrapper_config{'dut_toplevel_module_name'} = "i2c_master_top";
$wrapper_config{'fiji_settings_filename'} = "fiji.cfg";
$wrapper_config{'vhdl_filename'} = "fiji_wrapper.vhd";
my $vqm_netlist = new Verilog::Netlist (options => $opt,
keep_comments=>1, # include comments in netlist
link_read_nonfatal=>1); # do not fail if module description not found
# read vqm file
$vqm_netlist->read_file (filename=>"test/synplify_i2c_mod.v") or die ("Could not read netlist.\n");
# Read in any sub-modules
$vqm_netlist->link();
#$vqm_netlist->lint(); # Optional, see docs; probably not wanted
$vqm_netlist->exit_if_error();
my $vqm_toplevel_module = $vqm_netlist->find_module($wrapper_config{'dut_toplevel_module_name'});
my $injected_idx = 0;
my $original_idx = 0;
foreach my $vqm_port ($vqm_toplevel_module->ports_ordered) {
if($vqm_port->name =~ m/.+inj_i$/) {
$vqm_port->userdata(FIJI::VHDL->FIJI_USERDATA_PORTTYPE,FIJI::VHDL->FIJI_PORTTYPE_MODIFIED);
$vqm_port->userdata(FIJI::VHDL->FIJI_USERDATA_FIU_INDEX,$injected_idx);
$injected_idx += 1;
} elsif($vqm_port->name =~ m/.+ori_o$/) {
$vqm_port->userdata(FIJI::VHDL->FIJI_USERDATA_PORTTYPE,FIJI::VHDL->FIJI_PORTTYPE_ORIGINAL);
$vqm_port->userdata(FIJI::VHDL->FIJI_USERDATA_FIU_INDEX,$original_idx);
$original_idx += 1;
}
}
my $clkport = $vqm_toplevel_module->find_port("dut_clk_o");
my $rstport = $vqm_toplevel_module->find_port("dut_rst_o");
print "bla ".FIJI::VHDL->FIJI_PORTTYPE_RESET_FROM_DUT."\n";
$clkport->userdata(FIJI::VHDL->FIJI_USERDATA_PORTTYPE,FIJI::VHDL->FIJI_PORTTYPE_CLOCK);
$rstport->userdata(FIJI::VHDL->FIJI_USERDATA_PORTTYPE,FIJI::VHDL->FIJI_PORTTYPE_RESET_FROM_DUT);
$vqm_netlist->link();
# END generate test netlist
$wrapper_config{'netlist'} = $vqm_netlist;
FIJI::VHDL->generate_wrapper_module(\%wrapper_config);
$logger->trace("=== Stopping execution ===");
}
perl fiji_instrument.pl --fiji_settings_file=fiji.cfg --netlist_file=input.v --toplevel_module=i2c_master_top --file_prefix=i2c_master_fiji
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment