Commit 0c9547b4 authored by Stefan Tauner's avatar Stefan Tauner
Browse files

Big refinement of FIJI settings validation

 - validate nets and respective drivers like everything else
 - load the netlist earlier (in the user scripts) to make it available while
   loading settings
 - add a FIJI::Netlist parameter to respective FIJI::Settings's functions
 - add a new type 'driver' for FIU elements to distinguish its string
   representation from nets'
 - add new net validation function to FIJI::Netlist
 - use this to make net and FIU validation more generic to simplify FIJISettingsViewer
 - refine and correct handling of the tool phases
 - distinguish fatal errors, missing fields and less important anomalies when
   validating settings depending on the phase etc
 - notify user about validation problems in more detailed messages and tooltips
 - refine FIJI::VHDL to not load settings all the time and receive parameters
   directly instead of via hashes
 - use a global constant ONLY_LOAD in fiji_setup instead of a local variable
 - add a 'show_warning' function to ease opening warning dialogs
 - various other usability/GUI-related improvements
 - allow the deletion of nets
parent 6caa4313
...@@ -160,7 +160,8 @@ logo_end ...@@ -160,7 +160,8 @@ logo_end
# FIXME: complete docs # FIXME: complete docs
# - values (optional) used to restrict valid values. Can be... # - values (optional) used to restrict valid values. Can be...
# - an array reference listing all valid values (emulates an enum) # - an array reference listing all valid values (emulates an enum)
# - a code reference to a function that gets the new and old values and # - a code reference to a function that gets the new plus old values
# (as well as the value of the dependency if there is one) and
# returns true if the new value is allowed, or false otherwise. # returns true if the new value is allowed, or false otherwise.
# - phases_opt (optional) list of phases (subset of "setup", "instrument", "download") # - phases_opt (optional) list of phases (subset of "setup", "instrument", "download")
# where no value must be present in input (e.g. ID is only necessary while downloading). # where no value must be present in input (e.g. ID is only necessary while downloading).
...@@ -301,6 +302,7 @@ BEGIN { ...@@ -301,6 +302,7 @@ BEGIN {
ini_name => "LFSR_POLY", ini_name => "LFSR_POLY",
default => 0x2D, default => 0x2D,
type => 'lfsrpoly', type => 'lfsrpoly',
unit => 'hex',
depends_on => 'LFSR_WIDTH', depends_on => 'LFSR_WIDTH',
values => sub { values => sub {
my ($val, $old, $top) = @_; my ($val, $old, $top) = @_;
...@@ -316,6 +318,7 @@ BEGIN { ...@@ -316,6 +318,7 @@ BEGIN {
ini_name => "LFSR_SEED", ini_name => "LFSR_SEED",
default => 0xCAFE, default => 0xCAFE,
type => 'hexadecimal', type => 'hexadecimal',
unit => 'hex',
depends_on => 'LFSR_WIDTH', depends_on => 'LFSR_WIDTH',
values => sub { values => sub {
my ($val, $old, $top) = @_; my ($val, $old, $top) = @_;
...@@ -331,8 +334,9 @@ BEGIN { ...@@ -331,8 +334,9 @@ BEGIN {
description => "Use external reset", description => "Use external reset",
help => "If enabled, the FIJI logic can be reset using an FPGA pin.", help => "If enabled, the FIJI logic can be reset using an FPGA pin.",
ini_name => "RST_EXT_EN", ini_name => "RST_EXT_EN",
default => 0,
type => 'boolean', type => 'boolean',
default => 0,
phases_opt => ['setup'],
group => 'reset_external', group => 'reset_external',
order => 10, order => 10,
}, },
...@@ -366,8 +370,9 @@ BEGIN { ...@@ -366,8 +370,9 @@ BEGIN {
description => "Enable DUT-to-FIJI reset", description => "Enable DUT-to-FIJI reset",
help => "If enabled, a net in the DUT is used as a reset source for the FIJI logic.", help => "If enabled, a net in the DUT is used as a reset source for the FIJI logic.",
ini_name => "RST_DUT_OUT_EN", ini_name => "RST_DUT_OUT_EN",
default => 0,
type => 'boolean', type => 'boolean',
default => 0,
phases_opt => ['setup'],
group => 'reset_from_dut', group => 'reset_from_dut',
forbidden_by => 'RST_DUT_IN_EN', forbidden_by => 'RST_DUT_IN_EN',
order => 10, order => 10,
...@@ -379,7 +384,7 @@ BEGIN { ...@@ -379,7 +384,7 @@ BEGIN {
depends_on => 'RST_DUT_OUT_EN', depends_on => 'RST_DUT_OUT_EN',
type => 'net', type => 'net',
default => "", default => "",
phases_opt => ['setup'], phases_opt => [qw(setup download)],
group => 'reset_from_dut', group => 'reset_from_dut',
order => 30, order => 30,
}, },
...@@ -401,8 +406,9 @@ BEGIN { ...@@ -401,8 +406,9 @@ BEGIN {
description => "Enable FIJI-to-DUT reset", description => "Enable FIJI-to-DUT reset",
help => "If enabled, the DUT will be reset from the FIJI logic.", help => "If enabled, the DUT will be reset from the FIJI logic.",
ini_name => "RST_DUT_IN_EN", ini_name => "RST_DUT_IN_EN",
default => 0,
type => 'boolean', type => 'boolean',
default => 0,
phases_opt => ['setup'],
group => 'reset_to_dut', group => 'reset_to_dut',
forbidden_by => 'RST_DUT_OUT_EN', forbidden_by => 'RST_DUT_OUT_EN',
order => 10, order => 10,
...@@ -412,6 +418,7 @@ BEGIN { ...@@ -412,6 +418,7 @@ BEGIN {
help => "The specified DUT reset input will be connected\n to the FIJI logic's reset output.", help => "The specified DUT reset input will be connected\n to the FIJI logic's reset output.",
ini_name => "RST_DUT_IN_NAME", ini_name => "RST_DUT_IN_NAME",
default => "", default => "",
phases_opt => [qw(setup download)],
depends_on => 'RST_DUT_IN_EN', depends_on => 'RST_DUT_IN_EN',
type => 'toplevel_port', type => 'toplevel_port',
group => 'reset_to_dut', group => 'reset_to_dut',
...@@ -451,16 +458,17 @@ BEGIN { ...@@ -451,16 +458,17 @@ BEGIN {
description => "Enable DUT-to-FIJI trigger", description => "Enable DUT-to-FIJI trigger",
help => "If enabled, a signal in the DUT can be selected to trigger fault injection operations.\n" . "Once a pattern is downloaded with the INTERNAL trigger enabled, the FIJI logic waits for\n" . "an inactive-to-active transition on this signal before starting to count down duration t1.", help => "If enabled, a signal in the DUT can be selected to trigger fault injection operations.\n" . "Once a pattern is downloaded with the INTERNAL trigger enabled, the FIJI logic waits for\n" . "an inactive-to-active transition on this signal before starting to count down duration t1.",
ini_name => "TRIG_DUT_EN", ini_name => "TRIG_DUT_EN",
default => 0,
type => 'boolean', type => 'boolean',
default => 0,
phases_opt => ['setup'],
group => 'trigger', group => 'trigger',
order => 10, order => 10,
}, },
TRIG_DUT_ACT => { TRIG_DUT_ACT => {
description => "Active level of DUT-to-FIJI trigger", description => "Active level of DUT-to-FIJI trigger",
ini_name => "TRIG_DUT_ACT",
help => "Select the signal level to trigger fault injection.", help => "Select the signal level to trigger fault injection.",
ini_name => "TRIG_DUT_ACT",
type => 'bit', type => 'bit',
values => [qw(0 1)], values => [qw(0 1)],
phases_opt => ['setup'], phases_opt => ['setup'],
...@@ -475,7 +483,7 @@ BEGIN { ...@@ -475,7 +483,7 @@ BEGIN {
help => "Select the net in the DUT which shall be used to trigger fault injection operations.", help => "Select the net in the DUT which shall be used to trigger fault injection operations.",
ini_name => "TRIG_DUT_NAME", ini_name => "TRIG_DUT_NAME",
default => "", default => "",
phases_opt => ['setup'], phases_opt => [qw(setup download)],
depends_on => 'TRIG_DUT_EN', depends_on => 'TRIG_DUT_EN',
type => 'net', type => 'net',
group => 'trigger', group => 'trigger',
...@@ -487,8 +495,9 @@ BEGIN { ...@@ -487,8 +495,9 @@ BEGIN {
description => "Enable external trigger", description => "Enable external trigger",
help => "If enabled, an I/O port can be selected to trigger fault injection operations.\n" . "Once a pattern is downloaded with the EXTERNAL trigger enabled, the FIJI logic waits for \n" . "an inactive-to-active transition on this port before starting to count down duration t1. \n" . "The port is synchronized to the FIJI logic's clock, thus introducing a few clock cycles delay.", help => "If enabled, an I/O port can be selected to trigger fault injection operations.\n" . "Once a pattern is downloaded with the EXTERNAL trigger enabled, the FIJI logic waits for \n" . "an inactive-to-active transition on this port before starting to count down duration t1. \n" . "The port is synchronized to the FIJI logic's clock, thus introducing a few clock cycles delay.",
ini_name => "TRIG_EXT_EN", ini_name => "TRIG_EXT_EN",
default => 0,
type => 'boolean', type => 'boolean',
default => 0,
phases_opt => ['setup'],
group => 'trigger', group => 'trigger',
order => 40, order => 40,
}, },
...@@ -521,6 +530,7 @@ BEGIN { ...@@ -521,6 +530,7 @@ BEGIN {
ini_name => "FD_1_EN", ini_name => "FD_1_EN",
type => 'boolean', type => 'boolean',
default => 0, default => 0,
phases_opt => ['setup'],
group => 'fault_detect', group => 'fault_detect',
order => 10, order => 10,
}, },
...@@ -530,7 +540,7 @@ BEGIN { ...@@ -530,7 +540,7 @@ BEGIN {
ini_name => "FD_1_NAME", ini_name => "FD_1_NAME",
type => 'net', type => 'net',
default => "", default => "",
phases_opt => ['setup'], phases_opt => [qw(setup download)],
depends_on => 'FD_1_EN', depends_on => 'FD_1_EN',
group => 'fault_detect', group => 'fault_detect',
order => 20, order => 20,
...@@ -553,6 +563,7 @@ BEGIN { ...@@ -553,6 +563,7 @@ BEGIN {
ini_name => "FD_2_EN", ini_name => "FD_2_EN",
type => 'boolean', type => 'boolean',
default => 0, default => 0,
phases_opt => ['setup'],
group => 'fault_detect', group => 'fault_detect',
order => 40, order => 40,
}, },
...@@ -562,7 +573,7 @@ BEGIN { ...@@ -562,7 +573,7 @@ BEGIN {
ini_name => "FD_2_NAME", ini_name => "FD_2_NAME",
type => 'net', type => 'net',
default => "", default => "",
phases_opt => ['setup'], phases_opt => [qw(setup download)],
depends_on => 'FD_2_EN', depends_on => 'FD_2_EN',
group => 'fault_detect', group => 'fault_detect',
order => 50, order => 50,
...@@ -688,7 +699,7 @@ BEGIN { ...@@ -688,7 +699,7 @@ BEGIN {
general_control => { general_control => {
title => "General settings", title => "General settings",
subtitle => "", subtitle => "",
description => "Settings concerning miscellanous features of FIJI", description => "Settings concerning miscellaneous features of FIJI",
order => 10, order => 10,
}, },
clock => { clock => {
...@@ -720,6 +731,7 @@ use constant DISPLAYGROUPS_FIU_KEY => 'fius'; ...@@ -720,6 +731,7 @@ use constant DISPLAYGROUPS_FIU_KEY => 'fius';
# - hexadecimal: values must be hexadecimal numbers. # - hexadecimal: values must be hexadecimal numbers.
# - boolean: will be convert to a truth value by Perl semantics # - boolean: will be convert to a truth value by Perl semantics
# - net: hierarchical path of a net from the input netlist # - net: hierarchical path of a net from the input netlist
# - driver: driver-specific hierarchical path of a net from the input netlist
# - values (optional) used to restrict valid values. Can be... # - values (optional) used to restrict valid values. Can be...
# - an array reference listing all valid values (emulates an enum) # - an array reference listing all valid values (emulates an enum)
# - a code reference to a function that gets the new and old values and # - a code reference to a function that gets the new and old values and
...@@ -743,7 +755,7 @@ BEGIN { ...@@ -743,7 +755,7 @@ BEGIN {
default => "", default => "",
type => 'net', type => 'net',
help => "String representation of the instrumented net.", help => "String representation of the instrumented net.",
phases_opt => [qw(setup)], phases_opt => [qw(setup download)], # Either FIU or net name is strongly recommended during download
}, },
FIU_DRIVER_TYPE => { FIU_DRIVER_TYPE => {
ini_name => "DRIVER_TYPE", ini_name => "DRIVER_TYPE",
...@@ -754,9 +766,9 @@ BEGIN { ...@@ -754,9 +766,9 @@ BEGIN {
FIU_DRIVER_PATH => { FIU_DRIVER_PATH => {
ini_name => "DRIVER_PATH", ini_name => "DRIVER_PATH",
default => "", default => "",
type => 'net', type => 'driver',
help => "String representation of a driver.", help => "String representation of a driver.",
phases_opt => [qw(setup)], phases_opt => [qw(setup download)], # Either FIU or net name is strongly recommended during download
}, },
FIU_MODEL => { FIU_MODEL => {
ini_name => "FAULT_MODEL", ini_name => "FAULT_MODEL",
...@@ -799,7 +811,7 @@ use constant FIUMAP => \%fiumap; ...@@ -799,7 +811,7 @@ use constant FIUMAP => \%fiumap;
# The respective constant is only relevant (and thuse required as input) # The respective constant is only relevant (and thuse required as input)
# if the value of the referenced constant is true. # if the value of the referenced constant is true.
# - order (optional) specifies how to sort this value in output group # - order (optional) specifies how to sort this value in output group
# - default (optional) default value if not given in file and not determinable otherwise, # - default (optional) default value if not given in file and not determinable otherwise.
# Can either be a scalar or a function pointer expecting a FIJI settings reference. # Can either be a scalar or a function pointer expecting a FIJI settings reference.
# - help (optional) short help text, e.g. to be displayed via Tk:Balloon # - help (optional) short help text, e.g. to be displayed via Tk:Balloon
# The respective constant may not be enabled if the value # The respective constant may not be enabled if the value
......
...@@ -32,7 +32,7 @@ use Clone 'clone'; ...@@ -32,7 +32,7 @@ use Clone 'clone';
use threads; use threads;
use threads::shared; use threads::shared;
# FIXME: fix documentation # FIXME: fix documentation, possibly refine settings_from_file and existing_settings
## @function public new ($testsname,%$existing_tests,$cfgname,%$existing_cfg) ## @function public new ($testsname,%$existing_tests,$cfgname,%$existing_cfg)
# #
# @param testsname (optional) Name of a FIJI::Tests configuration file # @param testsname (optional) Name of a FIJI::Tests configuration file
...@@ -82,11 +82,12 @@ sub settings_from_file { ...@@ -82,11 +82,12 @@ sub settings_from_file {
my $logger = get_logger(""); my $logger = get_logger("");
my $rv; my $rv;
my ($self, $cfgname) = @_; my ($self, $cfgname) = @_;
my ($fiji_settings, $warn) = FIJI::Settings->new("download", $cfgname); my ($fiji_settings, $errors, $warnings) = FIJI::Settings->new('download', $cfgname); # fixme
if (!defined($fiji_settings)) { if (!defined($fiji_settings)) {
$rv = $warn; $rv = $errors;
} else { } else {
$logger->warn($warn) if defined $warn; $logger->warn($errors) if defined $errors;
$logger->warn($warnings) if defined $warnings;
$rv = $self->{'fiji_settings'} = $fiji_settings; $rv = $self->{'fiji_settings'} = $fiji_settings;
} }
return $rv; return $rv;
......
...@@ -81,6 +81,9 @@ sub read_file { ...@@ -81,6 +81,9 @@ sub read_file {
$logger->info("Reading in netlist from file \"$filename\"."); $logger->info("Reading in netlist from file \"$filename\".");
eval { eval {
# Stop croak and friends from printing stuff to stderr
# FIXME: how to capture the messages?
$SIG{__WARN__} = sub {};
$self->{'nl'}->read_file(filename => $filename); # read Verilog file $self->{'nl'}->read_file(filename => $filename); # read Verilog file
$self->{'nl'}->link(); # Read in any sub-modules $self->{'nl'}->link(); # Read in any sub-modules
}; };
...@@ -125,8 +128,8 @@ sub get_toplevel_module { ...@@ -125,8 +128,8 @@ sub get_toplevel_module {
my @m = $self->{'nl'}->top_modules_sorted; my @m = $self->{'nl'}->top_modules_sorted;
my $n = @m; my $n = @m;
return $m[0] if ($n == 1); return $m[0] if ($n == 1);
return "More than one toplevel module present in netlist." if ($n > 1); return "More than one toplevel module present in netlist" if ($n > 1);
return "No toplevel module found."; return "No toplevel module found";
} }
## @method public get_nets () ## @method public get_nets ()
...@@ -791,39 +794,61 @@ sub instrument_net { ...@@ -791,39 +794,61 @@ sub instrument_net {
return undef; return undef;
} }
## @method public validate_net($net_path)
# @brief Check if the given net path is valid (i.e., referring to an existing net)
#
# @param net_path The hierarchical path of the net, separated by HIERSEP
#
# @returns STRING if an error occurred
# @returns undef if successful
sub validate_net {
my ($self, $net_path,) = @_;
if ($net_path eq "") {
return "Net path is empty";
}
my $net_descriptor = $self->get_netdescriptor_from_path($net_path);
if (ref($net_descriptor) ne "HASH") {
return $net_descriptor;
}
return undef;
}
## @method public validate_driver($net_path, $driver_path, $driver_type) ## @method public validate_driver($net_path, $driver_path, $driver_type)
# @brief Check if the given driver is valid for the given net # @brief Check if the given driver is valid for the given net
# #
# Check if the driver specified by $driver_type and $driver_path # Check if the driver specified by $driver_type and $driver_path
# is actually connected to the net specified by $net_path # is actually connected to the net specified by $net_path
# #
# @param net_path The hierarchical path of the net, separeted by HIERSEP # @param net_path The hierarchical path of the net, separated by HIERSEP
# @param driver_path The hierarchical path of the driver object, separated by HIERSEP # @param driver_path The hierarchical path of the driver object, separated by HIERSEP
# @param driver_type The type of the driver object, one of {PIN, PORT, ASSIGN} # @param driver_type The type of the driver object, one of {PIN, PORT, ASSIGN}
# #
# @returns STRING if an error occurred # @returns STRING if an error occurred
# @returns undef if successfull # @returns undef if successful
sub _validate_driver { sub validate_driver {
my $logger = get_logger(""); my $logger = get_logger("");
my ($self, $net_path, $driver_path, $driver_type) = @_; my ($self, $net_path, $driver_path, $driver_type) = @_;
return "Net path is empty" if (!defined($net_path) || ($net_path eq ""));
return "Driver path is empty" if (!defined($driver_path) || ($driver_path eq ""));
return "Driver type is empty" if (!defined($driver_type) || ($driver_type eq ""));
my $connection_object = $self->get_connection_object($driver_path, $driver_type); my $connection_object = $self->get_connection_object($driver_path, $driver_type);
my $connections = {}; return "Specified driver not found in netlist" if (!defined $connection_object);
$self->_get_net_connections_from_path($net_path, $connections);
goto FAIL if (!defined $connection_object); my $connections = {};
my $rv = $self->_get_net_connections_from_path($net_path, $connections);
return $rv if defined($rv);
my @in_drivers = grep { $_ == $connection_object } @{$connections->{'drivers'}}; my @in_drivers = grep { $_ == $connection_object } @{$connections->{'drivers'}};
my @in_connections = grep { $_ == $connection_object } @{$connections->{'connected'}}; my @in_connections = grep { $_ == $connection_object } @{$connections->{'connected'}};
goto FAIL if (@in_drivers == 0 && @in_connections == 0); return "Driver \"$driver_path\" exists in netlist but is not connected to net \"$net_path\" at all" if (@in_drivers == 0 && @in_connections == 0);
return undef; return undef;
FAIL:
my $msg = "No possible driver found";
$logger->error($msg);
return $msg;
} }
## @function private _select_driver($connected,$net) ## @function private _select_driver($connected,$net)
...@@ -936,11 +961,9 @@ sub get_connection_object { ...@@ -936,11 +961,9 @@ sub get_connection_object {
my $logger = get_logger(""); my $logger = get_logger("");
my ($self, $connection_path, $connection_type) = @_; my ($self, $connection_path, $connection_type) = @_;
my $rv;
my $SEP = HIERSEP;
my @path_elements = _split_path($connection_path); my @path_elements = _split_path($connection_path);
my $rv;
if ($connection_type eq "PIN") { if ($connection_type eq "PIN") {
if (@path_elements == 3) { if (@path_elements == 3) {
...@@ -985,6 +1008,9 @@ sub get_connection_object { ...@@ -985,6 +1008,9 @@ sub get_connection_object {
$rv = $assign; $rv = $assign;
} }
} }
} else {
$logger->error("Unknown connection type \"$connection_type\"!");
return undef;
} }
$logger->warn("Could not find $connection_type \"$connection_path\"!") if !defined($rv); $logger->warn("Could not find $connection_type \"$connection_path\"!") if !defined($rv);
return $rv; return $rv;
...@@ -1002,6 +1028,8 @@ sub get_connection_object { ...@@ -1002,6 +1028,8 @@ sub get_connection_object {
# connection_hashref->{'driven'} contains a list of driven cells # connection_hashref->{'driven'} contains a list of driven cells
# connection_hashref->{'connected'} contains a list cells connected to the # connection_hashref->{'connected'} contains a list cells connected to the
# net but driver/driven cannot be decided # net but driver/driven cannot be decided
# @returns STRING if an error occurred
# @returns undef if successful
sub _get_net_connections_from_path { sub _get_net_connections_from_path {
my $logger = get_logger(""); my $logger = get_logger("");
my ($self, $net_path, $connection_hashref, $sorted) = @_; my ($self, $net_path, $connection_hashref, $sorted) = @_;
...@@ -1107,6 +1135,9 @@ sub _handle_connection_statement { ...@@ -1107,6 +1135,9 @@ sub _handle_connection_statement {
# @param bit one bit of the net to check for connections (optional, only useful for vectored nets) # @param bit one bit of the net to check for connections (optional, only useful for vectored nets)
# @param driver_path the path to the driver of this net (optional but depends on driver_type) # @param driver_path the path to the driver of this net (optional but depends on driver_type)
# @param driver_type the type of the driver (can be PIN, PORT, ASSIGN) (optional but depends on driver_path) # @param driver_type the type of the driver (can be PIN, PORT, ASSIGN) (optional but depends on driver_path)
#
# @returns STRING if an error occurred
# @returns undef if successful
sub _get_net_connections { sub _get_net_connections {
my $logger = get_logger(""); my $logger = get_logger("");
my ($self, $net, $connection_hashref, $bit, $driver_path, $driver_type) = @_; my ($self, $net, $connection_hashref, $bit, $driver_path, $driver_type) = @_;
...@@ -1351,7 +1382,7 @@ sub _extract_netpath_elements { ...@@ -1351,7 +1382,7 @@ sub _extract_netpath_elements {
my ($self, $netpath, $netpath_elements) = @_; my ($self, $netpath, $netpath_elements) = @_;
if (!defined($netpath) || "$netpath" eq "") { if (!defined($netpath) || "$netpath" eq "") {
return "Can not parse an empty net."; return "Can not parse an empty net";
} }
my $hiersep = HIERSEP; my $hiersep = HIERSEP;
...@@ -1373,10 +1404,11 @@ sub _extract_netpath_elements { ...@@ -1373,10 +1404,11 @@ sub _extract_netpath_elements {
for ($i = 1; $i < @net_split-1; $i++) { for ($i = 1; $i < @net_split-1; $i++) {
my $cell = $mod->find_cell($net_split[$i]); my $cell = $mod->find_cell($net_split[$i]);
if (!(defined $cell && $cell->isa("Verilog::Netlist::Cell"))) { if (!(defined $cell && $cell->isa("Verilog::Netlist::Cell"))) {
return "Could not find cell ".$net_split[$i]." in $netpath in netlist $self->{'filename'}'"; return "Could not find cell ".$net_split[$i]." in $netpath in netlist $self->{'filename'}";
} }
$mod = $cell->submod(); $mod = $cell->submod();
} }
my $mod_name = $mod->name;
my $netstring_elements = $self->_extract_netstring_elements($net_split[$i]); my $netstring_elements = $self->_extract_netstring_elements($net_split[$i]);
...@@ -1385,10 +1417,9 @@ sub _extract_netpath_elements { ...@@ -1385,10 +1417,9 @@ sub _extract_netpath_elements {
my $net = $mod->find_net($netstring_elements->{'net_name'}); my $net = $mod->find_net($netstring_elements->{'net_name'});
if (!(defined $net && $net->isa("Verilog::Netlist::Net"))) { if (!(defined $net && $net->isa("Verilog::Netlist::Net"))) {
return "Could not find net ".$netstring_elements->{'net_name'}." in $netpath in netlist $self->{'filename'}'"; return "Could not find net ".$netstring_elements->{'net_name'}." in $mod_name in netlist $self->{'filename'}";
} }
my $mod_name = $mod->name;
my $net_string = $net_split[$i]; my $net_string = $net_split[$i];
if (defined($netpath_elements)) { if (defined($netpath_elements)) {
...@@ -1415,7 +1446,7 @@ sub _extract_netstring_elements { ...@@ -1415,7 +1446,7 @@ sub _extract_netstring_elements {
my ($self, $net_string, $net_descriptor) = @_; my ($self, $net_string, $net_descriptor) = @_;
if (!defined($net_string) || "$net_string" eq "") { if (!defined($net_string) || "$net_string" eq "") {
return "Can not parse an empty net."; return "Can not parse an empty net";
} }
$net_string =~ /(~)?(.*?)(\[([^:]+)(:(.*))?\])?$/; $net_string =~ /(~)?(.*?)(\[([^:]+)(:(.*))?\])?$/;
...@@ -1451,7 +1482,7 @@ sub get_netdescriptor_from_path { ...@@ -1451,7 +1482,7 @@ sub get_netdescriptor_from_path {
my $netpath_elements = $self->_extract_netpath_elements($netpath); my $netpath_elements = $self->_extract_netpath_elements($netpath);
if (!defined($netpath_elements)) { if (!defined($netpath_elements)) {
return "$netpath is not a valid net path."; return "$netpath is not a valid net path";
} }
if (ref($netpath_elements) ne "HASH") { if (ref($netpath_elements) ne "HASH") {
...@@ -1477,7 +1508,7 @@ sub get_netdescriptor_from_path { ...@@ -1477,7 +1508,7 @@ sub get_netdescriptor_from_path {
if (defined($net->lsb) || defined($net->msb)) { if (defined($net->lsb) || defined($net->msb)) {
# must contain a net range, i.e. have msb and lsb set... # must contain a net range, i.e. have msb and lsb set...
if (!defined($lsb) || !defined($msb)) { if (!defined($lsb) || !defined($msb)) {
return sprintf("Net '%s%s%s' in netlist %s has a defined pin range but requested net does not.", $mod->name, HIERSEP, $net_name, $self->{'filename'}); return sprintf("Net '%s%s%s' in netlist %s has a defined pin range but requested net does not", $mod->name, HIERSEP, $net_name, $self->{'filename'});
} }
if (-1 == _offset_of_bit_in_netrange($msb, $net)) { if (-1 == _offset_of_bit_in_netrange($msb, $net)) {
return sprintf("Bit [%s] is not in net '%s%s%s' in netlist %s", $msb, $mod->name, HIERSEP, $net_name, $self->{'filename'}); return sprintf("Bit [%s] is not in net '%s%s%s' in netlist %s", $msb, $mod->name, HIERSEP, $net_name, $self->{'filename'});
......
This diff is collapsed.
...@@ -436,7 +436,7 @@ sub _set_defaults { ...@@ -436,7 +436,7 @@ sub _set_defaults {
# \param v_ref scalar reference to the proposed value (that may be modified) # \param v_ref scalar reference to the proposed value (that may be modified)
# \param old (optional) previously valid value # \param old (optional) previously valid value
# \param log_func (optional) the (log4perl) log function to use # \param log_func (optional) the (log4perl) log function to use
# (defaul is \&Log::Log4perl::Logger::trace) # (default is \&Log::Log4perl::Logger::trace)
sub validate_value { sub validate_value {