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

Moved wrapper and package VHDL generation code to VHDL.pm

todo: check if generated VHDL compiles and contains all necessary constants and assignments
todo: documentation
todo: beautify default assignments ($FIJI_DEFAULTS)
parent 74923f67
#-------------------------------------------------------------------------------
# University of Applied Sciences Technikum Wien
#
# Department of Embedded Systems
# http://embsys.technikum-wien.at
#
# Josef Ressel Center for Verification of Embedded Computing Systems
# http://vecs.technikum-wien.at
#
#-------------------------------------------------------------------------------
# File: VHDL.pm
# $Author$
# Created on: 28.05.2015
# $Date$
#
# Description:
# Contains functions to generate VHDL package and wrapper files for FIJI
# Contains enum values for marking Verilog-Perl netlist ports with userdata:
#
#
#-------------------------------------------------------------------------------
## @file
## @class FIJI::VHDL
package FIJI::VHDL;
use strict;
use warnings;
use Data::Dumper;
use Log::Log4perl qw(get_logger);
use FIJI::Settings;
# FIJI_USERDATA_xxx is intended as key for the port->userdata{} hash
# FIJI_USERDATA_PORTTYPE: type of the port (see FIJI_PORTTYPE_xxx enum)
# FIJI_USERDATA_FIU_INDEX: FIU# this FIJI_PORTTYPE_MODIFIED or FIJI_PORTTYPE_ORIGINAL should be connected to
# FIJI_USERDATA_FD_INDEX: Fault Detection channel this FIJI_PORTTYPE_FAULT_DETECTION should be connected to
use enum qw(FIJI_USERDATA_PORTTYPE FIJI_USERDATA_FIU_INDEX FIJI_USERDATA_FD_INDEX);
# FIJI_PORTTYPE_xxx is intended to be used as value for port->userdata{FIJI::VHDL->FIJI_USERDATA_PORTTYPE} to determine the special port usage
# FIJI_PORTTYPE_CLOCK: clock output to FIJI from DUT
# FIJI_PORTTYPE_MODIFIED: modified net input to DUT
# FIJI_PORTTYPE_ORIGINAL: original net output to FIJI
# FIJI_PORTTYPE_FAULT_DETECTION: fault detection net output to FIJI
# FIJI_PORTTYPE_TRIGGER_FROM_DUT: internal trigger from DUT to FIJI
# FIJI_PORTTYPE_RESET_FROM_DUT: internal reset from DUT to FIJI
# FIJI_PORTTYPE_RESET_TO_DUT: internal reset from FIJI to DUT
use enum qw(FIJI_PORTTYPE_CLOCK FIJI_PORTTYPE_MODIFIED FIJI_PORTTYPE_ORIGINAL FIJI_PORTTYPE_FAULT_DETECTION FIJI_PORTTYPE_TRIGGER_FROM_DUT FIJI_PORTTYPE_RESET_FROM_DUT FIJI_PORTTYPE_RESET_TO_DUT);
# Default values hash for signal and instantiation names, and the trigger and reset values
my %FIJI_DEFAULTS;
$FIJI_DEFAULTS{'TX_OUT_NAME'} = "s_fiji_tx_o";
$FIJI_DEFAULTS{'RX_IN_NAME'} = "s_fiji_rx_i";
$FIJI_DEFAULTS{'DUT_INST_NAME'} = "i_DUT";
$FIJI_DEFAULTS{'FIJI_INST_NAME'} = "i_FIJI";
$FIJI_DEFAULTS{'FIJI_WRAPPER_NAME'} = "fiji_top";
$FIJI_DEFAULTS{'FIJI_WRAPPER_CLOCK_SIGNAL_NAME'} = "s_fiji_clk";
$FIJI_DEFAULTS{'FIJI_WRAPPER_ORIGINAL_SIGNAL_NAME'} = "s_fiji_original";
$FIJI_DEFAULTS{'FIJI_WRAPPER_MODIFIED_SIGNAL_NAME'} = "s_fiji_modified";
$FIJI_DEFAULTS{'FIJI_WRAPPER_FAULT_SIGNAL_NAME'} = "s_fiji_fault_detect";
$FIJI_DEFAULTS{'FIJI_WRAPPER_TRIGGER_DUT_SIGNAL_NAME'} = "s_fiji_trigger_from_dut";
$FIJI_DEFAULTS{'FIJI_WRAPPER_TRIGGER_EXT_SIGNAL_NAME'} = "s_fiji_trigger_ext";
$FIJI_DEFAULTS{'FIJI_WRAPPER_RESET_FROM_DUT_SIGNAL_NAME'} = "s_fiji_reset_from_dut";
$FIJI_DEFAULTS{'FIJI_WRAPPER_RESET_TO_DUT_SIGNAL_NAME'} = "s_fiji_reset_to_dut";
$FIJI_DEFAULTS{'FIJI_WRAPPER_RESET_EXT_SIGNAL_NAME'} = "s_fiji_reset_ext";
$FIJI_DEFAULTS{'FIJI_TRIGGER_EXT_ASSIGNMENT'} = "not(c_trigger_ext_active)";
$FIJI_DEFAULTS{'FIJI_RESET_EXT_ASSIGNMENT'} = "not(c_reset_ext_active)";
## @function generate_config_package ($fiji_settings_filename, $vhdl_filename)
# @brief Generate a public_config_pkg VHDL package file for FIJI
#
# \param fiji_settings_filename the cfg file generated by fiji_setup
# \param vhdl_filename the name of the VHDL file to be generated
#
# \returns 0 if VHDL file was generated successfully.
sub generate_config_package ($$) {
my ($class, $fiji_settings_filename, $vhdl_filename) = @_;
my $logger = get_logger();
my $name = $0;
$name =~ s/\.p[lm]//;
$logger->debug("=== generate_config_package ===");
$logger->debug(sprintf("%d argument(s)%s", scalar(@_), scalar(@_) > 0 ? ": @_" : ""));
my $fiji_settings = FIJI::Settings->new('download', $fiji_settings_filename);
if (!ref($fiji_settings)) {
printf($fiji_settings . " Aborting.\n");
return 1;
}
my $fiji_consts = $fiji_settings->{'design'};
my $fius = $fiji_settings->{'FIUs'};
my $lfsr_fmt = sprintf("X\"%%0%dx\"",$fiji_consts->{'LFSR_WIDTH'}/4);
my @fiu_configs = ();
for (my $i = 0; $i < $fiji_consts->{'FIU_NUM'}; $i++) {
my $lfsr_mask = sprintf("$lfsr_fmt",@{$fius}[$i]->{'FIU_LFSR_MASK'});
my $str =<<"END_FIU";
$i => (
fault_model => @{$fius}[$i]->{'FIU_MODEL'},
lfsr_mask => $lfsr_mask
)
END_FIU
push @fiu_configs,$str;
}
my $lfsr_poly_string = sprintf($lfsr_fmt,$fiji_consts->{'LFSR_POLY'});
my $lfsr_seed_string = sprintf($lfsr_fmt,$fiji_consts->{'LFSR_SEED'});
my $fault_detect_string = "00";
my $fiu_configs_string = join(" ,\n",@fiu_configs);
my $vhdl_id = sprintf("X\"%04x\"",$fiji_consts->{'ID'});
my $gentime = localtime;
$logger->debug(sprintf("Generating VHDL text.\n"));
my $vhdl =<<"END_VHDL";
--------------------------------------------------------------------------------
-- University of Applied Sciences Technikum Wien --
-- --
-- Department of Embedded Systems --
-- http://embsys.technikum-wien.at --
-- --
-- Josef Ressel Center for Verification of Embedded Computing Systems --
-- http://vecs.technikum-wien.at --
-- --
--------------------------------------------------------------------------------
-- File: $vhdl_filename
-- Generated: $gentime
--
-- Description:
-- Public config package for $fiji_settings_filename
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.fault_selection_type_pkg.all;
package public_config_pkg is
------------------------------------------------------------------------------
-- Design configuration
------------------------------------------------------------------------------
-- The design's clock frequency
constant c_frequency : positive := $fiji_consts->{'FREQUENCY'};
-- The baud rate
constant c_baudrate : positive := $fiji_consts->{'BAUDRATE'};
-- The invert mask for the fault detection signals
constant c_fault_detect_invert_mask : std_logic_vector(1 downto 0) := $fault_detect_string;
------------------------------------------------------------------------------
-- LFSR configuration
------------------------------------------------------------------------------
-- Width of the LFSR for random FIU enable & stuck-open
constant c_lfsr_width : natural := $fiji_consts->{'LFSR_WIDTH'};
-- Polynomial for the LFSR
constant c_lfsr_poly : std_logic_vector(c_lfsr_width-1 downto 0) := $lfsr_poly_string;
-- Initial value for the LFSR
constant c_lfsr_seed : std_logic_vector(c_lfsr_width-1 downto 0) := $lfsr_seed_string;
------------------------------------------------------------------------------
-- Controller Configuration
------------------------------------------------------------------------------
-- Width of the timers in bytes.
constant c_timer_width : natural := $fiji_consts->{'TIMER_WIDTH'};
-- FIC -> DUT reset signal: active level
constant c_reset_dut_in_active : std_logic := '$fiji_consts->{'RESET_DUT_IN_ACTIVE'}';
-- reset duration
constant c_reset_dut_in_duration : positive := $fiji_consts->{'RESET_DUT_IN_DURATION'};
-- external reset signal: active level
constant c_reset_ext_active : std_logic := '$fiji_consts->{'TRIGGER_EXT_ACTIVE'}';
-- DUT -> FIC reset signal: active level
constant c_reset_dut_out_active : std_logic := '$fiji_consts->{'RESET_DUT_OUT_ACTIVE'}';
-- active level of the external and internal triggers
constant c_trigger_ext_active : std_logic := '$fiji_consts->{'TRIGGER_EXT_ACTIVE'}';
constant c_trigger_dut_active : std_logic := '$fiji_consts->{'TRIGGER_DUT_ACTIVE'}';
-- hardware id
constant c_id : std_logic_vector(15 downto 0) := $vhdl_id;
------------------------------------------------------------------------------
-- FIU Configuration
------------------------------------------------------------------------------
type t_single_fiu_record is record
fault_model : t_select_fault_models; --Select dynamic or single fault model. See fault_injection_unit
lfsr_mask : std_logic_vector(c_lfsr_width-1 downto 0); -- Select which LFSR bits to AND for Stuck-open fault
end record t_single_fiu_record;
type t_fiu_records is array (natural range <>) of t_single_fiu_record;
constant c_fiu_config : t_fiu_records := (
$fiu_configs_string
);
end package public_config_pkg;
END_VHDL
$logger->debug(sprintf("Writing public config package to $vhdl_filename.\n"));
if(open(my $fh, ">", $vhdl_filename)) {
print $fh $vhdl;
close $fh;
} else {
$logger->error("Could not open file '$vhdl_filename' $!");
return 1;
}
$logger->info(sprintf("Successfully generated public config package for $fiji_settings_filename in $vhdl_filename.\n"));
$logger->trace("=== Stopping execution ===");
return 0;
}
## @function generate_wrapper_module ($wrapper_config)
# @brief Generate a VHDL wrapper module instantiating FIJI logic and the DUT
#
# \param $wrapper_config a configuration hash ref.
# -> {'netlist'} the Verilog-Perl netlist file
# -> {'dut_toplevel_module_name'} the toplevel module in the vqm netlist
# -> {'fiji_settings_filename'} the path to the fiji.cfg file
# -> {'vhdl_filename'} the VHDL file to be generated
#
# \returns 0 if VHDL file was generated successfully.
sub generate_wrapper_module ($) {
my ($class, $wrapper_config) = @_;
my $vqm_netlist = $wrapper_config->{'netlist'};
my $dut_toplevel = $wrapper_config->{'dut_toplevel_module_name'};
my $fiji_settings_filename = $wrapper_config->{'fiji_settings_filename'};
my $vhdl_filename = $wrapper_config->{'vhdl_filename'};
my $logger = get_logger();
my $name = $0;
$name =~ s/\.p[lm]//;
$logger->debug("=== generate_wrapper_module ===");
$logger->debug(sprintf("%d argument(s)%s", scalar(@_), scalar(@_) > 0 ? ": @_" : ""));
my $fiji_settings = FIJI::Settings->new('download', $fiji_settings_filename);
if (!ref($fiji_settings)) {
printf($fiji_settings . " Aborting.\n");
return 1;
}
my $fiji_consts = $fiji_settings->{'design'};
my $fius = $fiji_settings->{'FIUs'};
$logger->debug("=== Assigning values ===");
my $tx_name = (defined $fiji_consts->{'TX_OUT_NAME'}) ? $fiji_consts->{'TX_OUT_NAME'} : $FIJI_DEFAULTS{'TX_OUT_NAME'};
my $rx_name = (defined $fiji_consts->{'RX_IN_NAME'}) ? $fiji_consts->{'RX_IN_NAME'} : $FIJI_DEFAULTS{'RX_IN_NAME'};
my $dut_inst_name = (defined $fiji_consts->{'DUT_INST_NAME'}) ? $fiji_consts->{'DUT_INST_NAME'} : $FIJI_DEFAULTS{'DUT_INST_NAME'};
my $fiji_inst_name = (defined $fiji_consts->{'FIJI_INST_NAME'}) ? $fiji_consts->{'FIJI_INST_NAME'} : $FIJI_DEFAULTS{'FIJI_INST_NAME'};
my $wrapper_name = (defined $fiji_consts->{'FIJI_WRAPPER_NAME'}) ? $fiji_consts->{'FIJI_WRAPPER_NAME'} : $FIJI_DEFAULTS{'FIJI_WRAPPER_NAME'};
my $fiji_clock_signal_name = $FIJI_DEFAULTS{'FIJI_WRAPPER_CLOCK_SIGNAL_NAME'};
my $fiji_original_signal_name = $FIJI_DEFAULTS{'FIJI_WRAPPER_ORIGINAL_SIGNAL_NAME'};
my $fiji_modified_signal_name = $FIJI_DEFAULTS{'FIJI_WRAPPER_MODIFIED_SIGNAL_NAME'};
my $fiji_fault_detection_signal_name = $FIJI_DEFAULTS{'FIJI_WRAPPER_FAULT_SIGNAL_NAME'};
my $fiji_trigger_from_dut_signal_name = $FIJI_DEFAULTS{'FIJI_WRAPPER_TRIGGER_DUT_SIGNAL_NAME'};
my $fiji_trigger_ext_signal_name = $FIJI_DEFAULTS{'FIJI_WRAPPER_TRIGGER_EXT_SIGNAL_NAME'};
my $fiji_reset_from_dut_signal_name = $FIJI_DEFAULTS{'FIJI_WRAPPER_RESET_FROM_DUT_SIGNAL_NAME'};
my $fiji_reset_to_dut_signal_name = $FIJI_DEFAULTS{'FIJI_WRAPPER_RESET_TO_DUT_SIGNAL_NAME'};
my $fiji_reset_ext_signal_name = $FIJI_DEFAULTS{'FIJI_WRAPPER_RESET_EXT_SIGNAL_NAME'};
my $trigger_ext_assignment = "not(c_trigger_ext_active)";
my $reset_ext_assignment = "not(c_reset_ext_active)";
my $vqm_toplevel_module = $vqm_netlist->find_module($dut_toplevel);
# check inputs
die ("Toplevel module $dut_toplevel not found.\n") if (!defined $vqm_toplevel_module);
die ("Module $dut_toplevel is not at the top level.\n") unless ($vqm_toplevel_module->is_top);
# create lists for vhdl declarations and maps
my @ext_ports = ();
my @dut_comp_ports = ();
my @dut_port_maps = ();
my @signal_assignments = ();
# add FIJI external ports
push @ext_ports,"--","-- FIJI ports","--";
push @ext_ports,$tx_name.": out std_logic";
push @ext_ports,$rx_name.": in std_logic";
if ($fiji_consts->{'RESET_EXT_EN'}) {
my $re_base = (defined $fiji_consts->{'RESET_EXT_IN_NAME'}) ? $fiji_consts->{'RESET_EXT_IN_NAME'} : $FIJI_DEFAULTS{'RESET_EXT_IN_NAME'};
my $re_suffix = ($fiji_consts->{'RESET_EXT_ACTIVE'} == 0) ? "n" : "";
push @ext_ports,$re_base.$re_suffix."_i : in std_logic";
$trigger_ext_assignment = $re_base.$re_suffix."_i";
}
if ($fiji_consts->{'TRIGGER_EXT_EN'}) {
my $te_base = (defined $fiji_consts->{'TRIGGER_EXT_IN_NAME'}) ? $fiji_consts->{'TRIGGER_EXT_IN_NAME'} : $FIJI_DEFAULTS{'TRIGGER_EXT_IN_NAME'};
my $te_suffix = ($fiji_consts->{'TRIGGER_EXT_ACTIVE'} == 0) ? "n" : "";
push @ext_ports,$te_base.$te_suffix."_i : in std_logic";
$trigger_ext_assignment = $te_base.$te_suffix."_i";
}
# add divider
push @ext_ports,"--","-- DUT ports","--";
foreach my $port ($vqm_toplevel_module->ports_ordered) {
# retrieve userdata from netlist
my $fiji_porttype = $port->userdata(FIJI_USERDATA_PORTTYPE);
my $fiu_idx = $port->userdata(FIJI_USERDATA_FIU_INDEX);
my $fd_idx = $port->userdata(FIJI_USERDATA_FD_INDEX);
# add to ports of vhdl component definition
push @dut_comp_ports,(($port->name)." : ".($port->direction)." ".(port2vhdtype($port)));
# if port has assigned a special FIJI function
if (defined $fiji_porttype) {
if ($fiji_porttype == FIJI_PORTTYPE_CLOCK) {
# clock from DUT to FIJI
push @dut_port_maps,(($port->name)." => $fiji_clock_signal_name");
} elsif ($fiji_porttype == FIJI_PORTTYPE_ORIGINAL) {
die ("Port ".($port->name)." has no fiji_idx assignment") unless (defined $fiu_idx);
push @dut_port_maps,(($port->name)." => $fiji_original_signal_name(".$fiu_idx.")");
} elsif ($fiji_porttype == FIJI_PORTTYPE_MODIFIED) {
die ("Port ".($port->name)." has no fiji_idx assignment") unless (defined $fiu_idx);
push @dut_port_maps,(($port->name)." => $fiji_modified_signal_name(".$fiu_idx.")");
} elsif ($fiji_porttype == FIJI_PORTTYPE_FAULT_DETECTION) {
die ("Port ".($port->name)." has no fiji_idx assignment") unless (defined $fd_idx);
push @dut_port_maps,(($port->name)." => $fiji_fault_detection_signal_name(".$fd_idx.")");
} elsif ($fiji_porttype == FIJI_PORTTYPE_TRIGGER_FROM_DUT) {
push @dut_port_maps,(($port->name)." => $fiji_trigger_from_dut_signal_name");
} elsif ($fiji_porttype == FIJI_PORTTYPE_RESET_FROM_DUT) {
push @dut_port_maps,(($port->name)." => $fiji_reset_from_dut_signal_name");
} elsif ($fiji_porttype == FIJI_PORTTYPE_RESET_TO_DUT) {
push @dut_port_maps,(($port->name)." => $fiji_reset_to_dut_signal_name");
} else {
$logger->error("Unknown fiji_porttype assignment: $fiji_porttype");
}
} else {
# add to externally connected DUT ports
push @ext_ports,(($port->name)." : ".($port->direction)." ".(port2vhdtype($port)));
push @dut_port_maps,(($port->name)." => ".($port->name));
}
}
# generate VHDL text for declaration blocks
my $ext_ports_vhdl = join(";\n ",@ext_ports);
my $dut_comp_ports_vhdl = join(";\n ",@dut_comp_ports);
my $dut_port_maps_vhdl = join(",\n ",@dut_port_maps);
my $gentime = localtime;
# generate VHDL wrapper text
my $vhdl = <<"END_VHDL";
---------------------------------------------------------------------------------
-- University of Applied Sciences Technikum Wien
--
-- Department of Embedded Systems
-- http://embsys.technikum-wien.at
--
-- Josef Ressel Center for Verification of Embedded Computing Systems
-- http://vecs.technikum-wien.at
--
---------------------------------------------------------------------------------
--
-- FIJI Wrapper generated at $gentime
-- Options:
-- toplevel = "$dut_toplevel"
-- inst_name = "$dut_inst_name"
-- fiji_name = "$fiji_inst_name"
-- wrapper = "$wrapper_name"
--
---------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.private_config_pkg.all;
use work.public_config_pkg.all;
use work.fault_injection_top_pkg.all;
entity $wrapper_name is
generic (
g_implement_fault_injection : boolean := true
);
port (
$ext_ports_vhdl
);
end entity $wrapper_name;
architecture wrap of $wrapper_name is
component $dut_toplevel is
port (
$dut_comp_ports_vhdl
);
end component $dut_toplevel;
signal $fiji_trigger_ext_signal_name : std_logic;
signal $fiji_reset_ext_signal_name : std_logic;
signal $fiji_clock_signal_name : std_logic;
signal $fiji_reset_from_dut_signal_name : std_logic := not(c_reset_dut_in_active);
signal $fiji_reset_to_dut_signal_name : std_logic;
signal $fiji_trigger_from_dut_signal_name : std_logic := not(c_trigger_dut_active);
signal $fiji_fault_detection_signal_name : std_logic_vector(c_num_fault_detect_nets-1 downto 0) := (others => '0');
signal $fiji_original_signal_name : std_logic_vector(c_fiu_config'length-1 downto 0);
signal $fiji_modified_signal_name : std_logic_vector(c_fiu_config'length-1 downto 0);
begin
$dut_inst_name : $dut_toplevel
port map(
$dut_port_maps_vhdl
);
gen_fault_injection : if g_implement_fault_injection = true generate
$fiji_trigger_ext_signal_name <= $trigger_ext_assignment;
$fiji_reset_ext_signal_name <= $reset_ext_assignment;
$fiji_inst_name : fault_injection_top
port map (
s_fiji_clk_i => $fiji_clock_signal_name,
s_fiji_reset_ext_i => $fiji_reset_ext_signal_name,
s_fiji_reset_dut_out_i => $fiji_reset_from_dut_signal_name,
s_fiji_reset_dut_in_o => $fiji_reset_to_dut_signal_name,
s_fiji_rx_i => $rx_name,
s_fiji_tx_o => $tx_name,
s_fiji_trigger_ext_i => $fiji_trigger_ext_signal_name,
s_fiji_trigger_dut_i => $fiji_trigger_from_dut_signal_name,
s_fiji_fault_detect_i => $fiji_fault_detection_signal_name,
s_fiji_original_i => $fiji_original_signal_name,
s_fiji_modified_o => $fiji_modified_signal_name
);
end generate;
gen_no_fault_injection : if g_implement_fault_injection = false generate
$fiji_modified_signal_name <= $fiji_original_signal_name;
end generate;
end wrap;
END_VHDL
$logger->debug(sprintf("Writing VHDL wrapper to $vhdl_filename.\n"));
if(open(my $fh, ">", $vhdl_filename)) {
print $fh $vhdl;
close $fh;
} else {
$logger->error("Could not open file '$vhdl_filename' $!");
return 1;
}
$logger->info(sprintf("Successfully generated VHDL wrapper for $fiji_settings_filename in $vhdl_filename.\n"));
$logger->trace("=== Stopping execution ===");
return 0;
}
# genrates a VHDL type declaration for a given port/its net
sub port2vhdtype {
my $port = shift(@_);
my $type;
if(!defined $port->net->msb || ($port->net->msb == $port->net->lsb)) {
$type = "std_logic";
} elsif ($port->net->msb > $port->net->lsb) {
$type = sprintf("std_logic_vector(%d downto %d)", $port->net->msb, $port->net->lsb);
} else {
$type = sprintf("std_logic_vector(%d to %d)", $port->net->msb, $port->net->lsb);
}
return $type;
}
1;
\ No newline at end of file
; Config::Simple 4.58
; Mon May 4 16:02:25 2015
; Thu May 28 16:06:37 2015
[FIU0]
[FIU1]
FAULT_MODEL=RUNTIME
NET_NAME=a
LFSR_MASK=0x0
FAULT_MODEL=RUNTIME
[FIU1]
[FIU0]
FAULT_MODEL=RUNTIME
NET_NAME=a
LFSR_MASK=0x0
FAULT_MODEL=RUNTIME
[CONSTS]
TRIGGER_EXT_ACTIVE=1
TIMER_WIDTH=32
LFSR_WIDTH=16
CFGS_PER_MSG=2
TRIGGER_DUT_NAME=bb
RESET_DUT_IN_ACTIVE=1
RESET_DUT_IN_EN=0
TRIGGER_DUT_ACTIVE=1
TRIGGER_EXT_EN=0
LFSR_POLY=0x2d
BAUDRATE=115200
FREQUENCY=20000000
FIU_NUM=2
RESET_EXT_EN=0
TIMER_WIDTH=32
RESET_DUT_OUT_EN=0
CFGS_PER_MSG=2
RESET_DUT_IN_DURATION=4
TRIGGER_DUT_EN=0
LFSR_SEED=0xcafe
CLOCK_NET=clk
RESET_DUT_IN_NAME=bla
FIU_CFG_BITS=3
RESET_DUT_IN_EN=0
ID=0x0123
FREQUENCY=20000000
ID=0x123
RESET_DUT_OUT_NAME=bla
RESET_EXT_ACTIVE=1
RESET_DUT_OUT_ACTIVE=1
LFSR_SEED=0xcafe
FIU_NUM=2
LFSR_POLY=0x2d
BAUDRATE=115200
RESET_DUT_OUT_EN=0
## @file
use strict;
use warnings;
use Log::Log4perl qw(get_logger);
use FIJI::Connection;
use FIJI::Settings;
sub test_fi_uart {
my ($port, $payload_ref, $t1_duration, $t2_duration, $trigger_en, $trigger_ext, $reset, $fiji_consts) = @_;
# my @payload = map hex($_), $cfg_str =~ /(..)/g; # TODO: how to do this with unpack?
my %config = (
payload => $payload_ref,
t1_duration => $t1_duration,
t2_duration => $t2_duration,
trigger_en => $trigger_en,
trigger_ext => $trigger_ext,
reset => $reset,
consts => $fiji_consts,
);
$port->send_config(\%config, 1000, 0, 1);
}
sub main {
my @ARGV = @_;
my $logger = get_logger();
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 ? ": @_" : ""));
my $fiji_settings = FIJI::Settings->new('download', $ARGV[0]);
if (!ref($fiji_settings)) {
printf($fiji_settings . " Aborting.\n");
return 1;
}
my $fiji_consts = $fiji_settings->{'design'};
my $fius = $fiji_settings->{'FIUs'};
my $lfsr_fmt = sprintf("X\"%%0%dx\"",$fiji_consts->{'LFSR_WIDTH'}/4);
my @fiu_configs = ();
for (my $i = 0; $i < $fiji_consts->{'FIU_NUM'}; $i++) {
my $lfsr_mask = sprintf("$lfsr_fmt",@{$fius}[$i]->{'FIU_LFSR_MASK'});
my $str =<<"END_FIU";
$i => (
fault_model => @{$fius}[$i]->{'FIU_MODEL'},
lfsr_mask => $lfsr_mask
)
END_FIU
push @fiu_configs,$str;
}
my $lfsr_poly_string = sprintf($lfsr_fmt,$fiji_consts->{'LFSR_POLY'});
my $lfsr_seed_string = sprintf($lfsr_fmt,$fiji_consts->{'LFSR_SEED'});
my $fault_detect_string = "00";
my $fiu_configs_string = join(" ,\n",@fiu_configs);
my $vhdl =<<"END_VHDL";
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.fault_selection_type_pkg.all;
package public_config_pkg is
------------------------------------------------------------------------------
-- Design configuration
------------------------------------------------------------------------------
-- The design's clock frequency
constant c_frequency : positive := $fiji_consts->{'FREQUENCY'};
-- The baud rate
constant c_baudrate : positive := $fiji_consts->{'BAUDRATE'};
-- The invert mask for the fault detection signals
constant c_fault_detect_invert_mask : std_logic_vector(1 downto 0) := $fault_detect_string;
------------------------------------------------------------------------------
-- LFSR configuration
------------------------------------------------------------------------------