Wednesday, October 17, 2012

Equivalent Fault Collapsing

Here is an equivalent fault collapsing program, The aim is to  read a combinational Verilog netlist file and perform equivalent fault collapsing for the circuit.

The program does equivalent fault collapsing for the following gate types
Two-input, one-output gates or One-input, one-output gates as follows:
AND2X1
OR2X1
NAND2X1
NOR2X1
XOR2X1
INVX1
BUFX1

Upgrade: Fanouts need to be considered separately. upgrade the program to include fanouts also
 #!/usr/bin/perl  
 #fault_collapsing.plx  
 use warnings;  
 use strict;  
 my $bench_file = $ARGV[0];  
 my $file_name;  
 my $circuit_name;  
 my $element;  
 my @input_array;  
 my @output_array;  
 my @wire_array;  
 my @gates;  
 my @sorted_gates;  
 my @wire_struct;  
 #my @fanout_test;  
 my $num_inputs=0;  
 my $num_outputs=0;  
 my $num_wires=0;  
 my $num_gates=0;  
 #Test netlist file  
 if($bench_file =~ /(.*).v/)  
 {  
 $file_name = $1;  
 }   
 else  
 {  
 print "Format of bench file name: circuit_name.v \n example : s1423.v\n";  
 }  
 #Read Netlist File  
 while(<>)  
 {  
   my $INPUT_DATA = $_;  
   chomp($INPUT_DATA);  
 {  
 #MODULE NAME  
 if($INPUT_DATA =~ /module (.*) (.*);/)  
 {  
   $circuit_name = $1;  
   print "circuit name = $circuit_name\n";  
 }  
 #INPUT OUTPUT WIRES  
 if($INPUT_DATA =~ /input (.*);/)  
 {  
   @input_array = split /,/, $1;  
 }  
 if($INPUT_DATA =~ /output (.*);/)  
 {  
   @output_array = split /,/, $1;  
 }  
 if($INPUT_DATA =~ /wire (.*);/)  
 {  
   @wire_array = split /,/, $1;  
 }  
 #AND, OR, NAND, NOR, XOR  
 if($INPUT_DATA =~ /(.*) (.*) \(\.Y\((.*)\),\.A\((.*)\),\.B\((.*)\)\);/)  
 {  
   push @gates, { gate_type => "$1", gate_name => "$2", output => "$3", input_1 => "$4", input_2 => "$5", processed => 0};  
 }  
 #INV, BUF  
 #DE - Doesnt Exist  
 if($INPUT_DATA =~ /(INVX1|BUFX1) (.*) \(\.Y\((.*)\),\.A\((.*)\)\);$/)  
 {  
   push @gates, { gate_type => "$1", gate_name => "$2", output => "$3", input_1 => "$4", input_2 => "DE", processed => 0};  
 }  
 }  
 }  
 #File Read complete  
 #wire struct holds fault data for all wires  
 for $element (@input_array){  
   print "input: $element\n";  
   push @wire_struct, { wire_name => "$element", sa0 => 1, sa1 =>1};  
 }  
 for $element (@wire_array){  
   push @wire_struct, { wire_name => "$element", sa0 => 1, sa1 =>1};  
 }  
 for $element (@output_array){  
   push @wire_struct, { wire_name => "$element", sa0 => 1, sa1 =>1};  
 }  
 =pod  
 print "\n";  
 for my $href ( @wire_struct ) {  
   print "{ ";  
   for my $role ( keys %$href ) {  
      print "$role=$href->{$role} ";  
   }  
   print "}\n";  
 }   
 =cut  
 $num_gates = scalar @gates;  
 my $index=0;  
 my @remd_gates_outputs;  
 my $gate_processed_flag=0;  
 while($num_gates>0)  
 {  
   $gate_processed_flag=0;  
   print "Number of Gates = $num_gates";  
   for my $gate (@gates)  
   {  
      print "\ngate fetched: $gate->{gate_name}";  
      if($gate->{processed}==0)  
      {  
        print "\ngate under process: $gate->{gate_name}";  
 #see if any of the inputs map to a single input gate  
        if($gate->{input_2}=~ m/^DE$/)  
        {  
           print "\nsingle input";  
           print "\ngate input : $gate->{input_1}";  
           for my $inp (@input_array)  
           {  
             if($gate->{input_1} =~ m/^$inp$/)  
             {  
                print "inp matches";  
 #for 1 input gate  
                print "\n";  
                for my $role ( keys %$gate )   
                {  
                  print "$role=$gate->{$role} ";  
                }  
 #NOT GATES  
                if($gate->{gate_type} =~ m/^INVX1$/)  
                {  
                  for my $wire (@wire_struct)  
                  {  
                     if($wire->{wire_name} =~ m/^$inp$/)  
                     {  
                       $wire->{sa0} = 0;  
                       $wire->{sa1} = 0;  
                       print "\n changing $inp sa0 to 0 and sa1 to 0";  
                     }  
                  }  
                  $gate->{processed}=1;  
                  $num_gates--;  
                  push @remd_gates_outputs, $gate->{output};  
                  $gate_processed_flag=1;  
                }  
 #BUFFER GATES  
                if($gate->{gate_type} =~ m/^BUFX1$/)  
                {  
                  for my $wire (@wire_struct)  
                  {  
                     if($wire->{wire_name} =~ m/^$inp$/)  
                     {  
                       $wire->{sa0} = 0;  
                       $wire->{sa1} = 0;  
                       print "\n changing $inp sa0 to 0 and sa1 to 0";  
                     }  
                  }  
                  $gate->{processed}=1;  
                  $num_gates--;  
                  push @remd_gates_outputs, $gate->{output};  
                  $gate_processed_flag=1;  
                }  
             }  
           }  
        }  
        for my $input1 (@input_array)  
        {  
           if($gate->{processed}==0)  
           {  
             print "\nInput wire 1: $input1";  
             if($gate->{input_1} =~ m/^$input1$/)  
             {  
                print "\t$gate->{gate_name}\t";  
                for my $input2 (@input_array)  
                {       
                  print "\nInput wire 2: $input2";  
 #for two input gates  
                  if($gate->{input_2} =~ m/^$input2$/)  
                  {  
                     print "Gate under consideration: $gate->{gate_name}";              
                     print "\n";  
                     for my $role ( keys %$gate )   
                     {  
                       print "$role=$gate->{$role} ";  
                     }  
 #NAND GATES  
                     if($gate->{gate_type} =~ m/^NAND2X1$/)  
                     {  
                       for my $wire (@wire_struct)  
                       {  
                          if($wire->{wire_name} =~ m/^$input1$/)  
                          {  
                            $wire->{sa0} = 0;  
                            print "\n changing $input1 sa0 to 0";  
                          }  
                          if($wire->{wire_name} =~ m/^$input2$/)  
                          {  
                            $wire->{sa0} = 0;  
                            print "\n changing $input2 sa0 to 0";  
                          }  
                       }  
                       $gate->{processed}=1;  
                       $num_gates--;  
                       push @remd_gates_outputs, $gate->{output};  
                       $gate_processed_flag=1;  
                     }  
 #AND GATES  
                     if($gate->{gate_type} =~ m/^AND2X1$/)  
                     {  
                       print "\nhi i am inside\n";  
                       for my $wire (@wire_struct)  
                       {  
                          if($wire->{wire_name} =~ m/^$input1$/)  
                          {  
                            $wire->{sa0} = 0;  
                            print "\n changing $input1 sa0 to 0";  
                          }  
                          if($wire->{wire_name} =~ m/^$input2$/)  
                          {  
                            $wire->{sa0} = 0;  
                            print "\n changing $input2 sa0 to 0";  
                          }  
                       }  
                       $gate->{processed}=1;  
                       $num_gates--;  
                       push @remd_gates_outputs, $gate->{output};  
                       $gate_processed_flag=1;  
                     }  
 #OR GATES  
                     if($gate->{gate_type} =~ m/^OR2X1$/)  
                     {  
                       for my $wire (@wire_struct)  
                       {  
                          if($wire->{wire_name} =~ m/^$input1$/)  
                          {  
                            $wire->{sa1} = 0;  
                            print "\n changing $input1 sa1to 0";  
                          }  
                          if($wire->{wire_name} =~ m/^$input2$/)  
                          {  
                            $wire->{sa1} = 0;  
                            print "\n changing $input2 sa1 to 0";  
                          }  
                       }  
                       $gate->{processed}=1;  
                       $num_gates--;  
                       push @remd_gates_outputs, $gate->{output};  
                       $gate_processed_flag=1;  
                     }  
 #NOR GATES  
                     if($gate->{gate_type} =~ m/^NOR2X1$/)  
                     {  
                       for my $wire (@wire_struct)  
                       {  
                          if($wire->{wire_name} =~ m/^$input1$/)  
                          {  
                            $wire->{sa1} = 0;  
                            print "\n changing $input1 sa0 to 0";  
                          }  
                          if($wire->{wire_name} =~ m/^$input2$/)  
                          {  
                            $wire->{sa1} = 0;  
                            print "\n changing $input2 sa0 to 0";  
                          }  
                       }  
                       $gate->{processed}=1;  
                       $num_gates--;  
                       push @remd_gates_outputs, $gate->{output};  
                       $gate_processed_flag=1;  
                       print "\nnum gates = $num_gates";  
                     }  
                  }  
                }  
             }  
           }  
        }  
      }  
   }  
   if($gate_processed_flag==1)  
   {  
      print "\ngate outputs to be made inputs\n";  
      for $element (@remd_gates_outputs)  
      {  
        print "$element\n";  
        push @input_array, $element;            
      }  
      print "\nThe list of gates after removed\n";  
      for $element (@gates)  
      {  
        if($element->{processed}==0){  
           print "$element->{gate_name}";}  
      }  
      print "Number of gates left: $num_gates";  
   }  
   my $x = ord(getc);  
 }  
 print "\n";  
 for my $href ( @wire_struct ) {  
   print "{ ";  
   for my $role ( keys %$href ) {  
      print "$role=$href->{$role} ";  
   }  
   print "}\n";  
 }  
 =pod  
 print "\n";  
 for my $href ( @gates ) {  
   print "{ ";  
   for my $role ( keys %$href ) {  
      print "$role=$href->{$role} ";  
   }  
   print "}\n";  
 }   
 =cut  
 =pod  
 my $href1;  
 for $href1 ( @gates ) {  
   for $element (@output_array){  
   if($href1->{output} =~ m/$element/){  
      print "output_arr=$element\n";  
      print "output=$href1->{output}\n ";  
      push @sorted_gates, $href1;  
     }  
   print "output_arr=$element\n";  
   print "output=$href1->{output}\n ";  
   }   
 }  
 =cut  
 =pod  
 print "\n";  
 for my $href ( @sorted_gates ) {  
   print "{ ";  
   for my $role ( keys %$href ) {  
      print "$role=$href->{$role} ";  
   }  
   print "}\n";  
 }  
 =cut  

No comments:

Post a Comment