#!/usr/local/bin/perl -w
#====================================================================================
# Design unit  : SEUs Simulation Tool (SST)
#
# File name    : SST_bit_flip.pl
#
# Purpose      : This script is used by the modelsim macro spt.do (which at the same 
#                time is created by SST_upset_generator.pl). It is used to change the 
#                value of a wire and emulate the presence of a Single Event Upset. 
#                If the length of the wire is one bit, it negates it. If the length 
#                of the wire is greater than one, it changes the value of one of its 
#                bits.
#
# Authors      : Daniel González Gutiérrez TEC-EDM
#
# Contact      : mailto:microelectronics@estec.esa.int
#                http://www.estec.esa.int/microelectronics
#
# Copyright (C): European Space Agency (ESA) 2004. No part may be reproduced
#                in any form without the prior written permission of ESA.
#
# Disclaimer   : All information is provided "as is", there is no warranty that
#                the information is correct or suitable for any purpose,
#                neither implicit nor explicit. This information does not
#                necessarily reflect the policy of the European Space Agency.
#====================================================================================
#====================================================================================
# Revision control
#
###Version 1.0	31/10/03 --DGG
#
###Revision 1.1	22/03/04 --DGG
#  
###Revision 1.2	27/07/04 --DGG
#
###Revision 1.3	25/11/04 --DGG
#====================================================================================

#----------------------------------------------------------------------------
# Imported modules
#---------------------------------------------------------------------------- 
use POSIX;       # Import floor function                       

#----------------------------------------------------------------------------
# My variables
#---------------------------------------------------------------------------- 

my($index);
my($input_line);
my($upset_bus);

my(@bits);

#----------------------------------------------------------------------------
# Script main body
#---------------------------------------------------------------------------- 

$input_line = $ARGV[0]; # keep here the input command 

if ($input_line =~ /[^01]+/) {
  print ('undefined');
}
else {
  @bits = split(//,$input_line);
  # if it is a bit, invert it
  if (@bits == 1) {
    if ($input_line eq '0') {
      print ('1');
    }
    else {
      print ('0');
    }  
  }
  # if it's a bus, invert one of its bits (randomly selected)
  else {
    $index = POSIX::floor(rand @bits);
    if ($bits[$index] eq '0') {
      $bits[$index] = '1';
    }
    else {
      $bits[$index] = '0';
    }  
    $upset_bus = "@bits";
    $upset_bus =~ s/ //g; #remove white spaces
    print ("$upset_bus");
  }
}