if ( $INPUT_DATA =~ /module (\w+) /) { my $circuit_name = $1; print "circuit name = $circuit_name\n"; } #### if ( $INPUT_DATA =~ /module (\w+) /) { print "circuit name = $1\n"; } #### #!/usr/bin/perl #levelization.plx use warnings; use Data::Dumper; use strict; #Test netlist file my $bench_file = $ARGV[0]; if ( $bench_file !~ /(.*).v/ ) { print "Format of bench file name: circuit_name.v \n example : s1423.v\n"; } #Read Netlist File my @input_array; my @gates; while (<>) { my $INPUT_DATA = $_; chomp($INPUT_DATA); #MODULE NAME if ( $INPUT_DATA =~ /module (\w+) / ) { print "circuit name = $1\n"; } #INPUT OUTPUT WIRES if ( $INPUT_DATA =~ /input (.*);/ ) { @input_array = split /,/, $1; } #AND, OR, NAND, NOR, XOR if ( ( $INPUT_DATA =~ /(.*) (.*) \((.*),(.*),(.*)\);/ ) && ( $INPUT_DATA !~ /module/ ) ) { push @gates, { num_inputs => 2, gate_type => "$1", gate_name => "$2", output => { wire_name => "$3", sa0 => 1, sa1 => 1, level => 0, }, input_1 => { wire_name => "$2_$4", CC0 => 1, CC1 => 1, level => 0, }, input_2 => { wire_name => "$2_$5", CC0 => 1, CC1 => 1, level => 0, }, processed => 0, processed_ip1 => 0, processed_ip2 => 0, gate_level => -1, shifted => 0 }; } #INV, BUF #DE - Doesnt Exist #renaming the gates at inputs of the gates for fanouts if ( $INPUT_DATA =~ /(INVX1|BUFX1) (.*) \((.*),(.*),(.*)\);$/ ) { push @gates, { num_inputs => 1, gate_type => "$1", gate_name => "$2", output => { wire_name => "$3", sa0 => 1, sa1 => 1, level => 0, }, input_1 => { wire_name => "$2_$4", sa0 => 1, sa1 => 1, level => 0, }, processed => 0, processed_ip1 => 0, gate_level => -1, shifted => 0 }; } } #File Read complete #input_list_struct is used for levelization my @input_list_struct; for my $element (@input_array) { print "input: $element\n"; push @input_list_struct, { wire_name => "$element", sa0 => 1, sa1 => 1, level => 0 }; } print "Initial inputs\n"; for my $href (@input_list_struct) { print "{ "; for my $role ( keys %$href ) { print "$role=$href->{$role} "; } print "}\n"; } my $num_gates = scalar @gates; #gate_processed = 2 then all inputs are processed #shift gate into the queue if even one of the inputs processed my @gate_queue; while ( $num_gates != 0 ) { for my $gate (@gates) { for my $inp (@input_list_struct) { my $inp_test = $inp->{wire_name}; if ( ( $gate->{input_1} )->{wire_name} =~ m/$inp_test$/ ) { $gate->{processed_ip1} = 1; if ( $gate->{num_inputs} == 1 ) { print "NOTE: $gate->{gate_name}:$gate->{processed}\n"; getc(); if ( $gate->{processed} != $gate->{num_inputs} ) { unshift( @gate_queue, $gate ); } } elsif ( $gate->{processed_ip2} == 1 ) { $gate->{processed} = $gate->{num_inputs}; } elsif ( $gate->{processed} != $gate->{num_inputs} ) { if ( $gate->{shifted} == 0 ) { print "1. shifting $gate->{gate_name} to gate queue\n"; getc(); unshift( @gate_queue, $gate ); } } } if ( ( $gate->{num_inputs} != 1 ) ) { if ( ( $gate->{input_2} )->{wire_name} =~ m/$inp_test$/ ) { $gate->{processed_ip2} = 1; if ( $gate->{processed_ip1} == 1 ) { $gate->{processed} = $gate->{num_inputs}; } if ( $gate->{processed} != $gate->{num_inputs} ) { if ( $gate->{shifted} == 0 ) { print "2. shifting $gate->{gate_name} to gate queue\n"; getc(); unshift( @gate_queue, $gate ); } } } } } } print "Gates in gate queue\n"; for my $line (@gate_queue) { for my $role ( keys %$line ) { if ( $role =~ m/^input_1$/ ) { print "$role: $line->{$role}->{wire_name},"; print "lvl: $line->{$role}->{level},"; } elsif ( $role =~ m/^input_2$/ ) { print "$role: $line->{$role}->{wire_name},"; print "lvl: $line->{$role}->{level},"; } elsif ( $role =~ m/^output$/ ) { print "$role: $line->{$role}->{wire_name},"; print "lvl: $line->{$role}->{level},"; } else { print "$role:$line->{$role},"; } } print "\n"; } getc(); # if both inputs of the gates are processed, then calculate the level of the gate # if only one of the inputs are processed, then add the gate to the end my $num_gate_queue = scalar @gate_queue; while ( $num_gate_queue != 0 ) { my $gate = pop(@gate_queue); if ( $gate->{num_inputs} == 1 ) { print "Number of gates in queue: $num_gate_queue"; if ( $gate->{processed_ip1} == 1 ) { $gate->{processed} = $gate->{num_inputs}; } } if ( $gate->{processed} == $gate->{num_inputs} ) { if ( $gate->{num_inputs} == 2 ) { if ( ( $gate->{input_1}->{level} ) > ( $gate->{input_2}->{level} ) ) { $gate->{gate_level} = ( $gate->{input_1}->{level} ); } else { $gate->{gate_level} = ( $gate->{input_2}->{level} ); } $gate->{gate_level}++; $gate->{output}->{level} = $gate->{gate_level}; unshift( @input_list_struct, $gate->{output} ); $num_gate_queue--; $num_gates--; print "Number of gates left $num_gates"; getc(); } elsif ( $gate->{num_inputs} == 1 ) { print "input level: $gate->{input_1}->{level}\n"; getc(); $gate->{gate_level} = $gate->{input_1}->{level}; $gate->{gate_level}++; $gate->{output}->{level} = $gate->{gate_level}; print "$gate->{gate_name}: $gate->{gate_level}"; unshift( @input_list_struct, $gate->{output} ); $num_gate_queue--; $num_gates--; print "Number of gates left $num_gates"; getc(); } } else { print "3. shifting $gate->{gate_name} to gate queue\n"; getc(); unshift( @gate_queue, $gate ); $num_gate_queue--; # gates that are not processed because of lack of second input # being processed are shifted in here, they need not be shifted again $gate->{shifted} = 1; } } print "updated input list\n"; for my $href (@input_list_struct) { print "{ "; for my $role ( keys %$href ) { print "$role=$href->{$role} "; } print "}\n"; } #the updated levels of the wires are present in input_list_struct #update the fanouts of the gate with the levels from this struct print "modifying gate: level input of gate\n"; for my $gate (@gates) { for my $inp (@input_list_struct) { my $inp_test = $inp->{wire_name}; if ( ( $gate->{input_1} )->{wire_name} =~ m/$inp_test$/ ) { $gate->{input_1}->{level} = $inp->{level}; print "$gate->{gate_name}: $gate->{input_1}->{wire_name} " . "- $gate->{input_1}->{level}\n"; } if ( $gate->{num_inputs} != 1 ) { if ( ( $gate->{input_2} )->{wire_name} =~ m/$inp_test$/ ) { $gate->{input_2}->{level} = $inp->{level}; } } } } } print "gate: level\n"; for my $gate (@gates) { print "$gate->{gate_name}: $gate->{gate_level}\n"; } #### my @array; # Push the value 1 onto @array push @array, 1; # Push the values 3, 4 and 5 onto @array push @array, 3, 4, 5; # Push an array reference (containing two strings) onto @array push @array, ['bill', 'bob']; # Push a hash reference onto @array push @array, {type=>'AND', inp_1=>'net_7', inp_2=>'net_8'}; # We can access the various values: print $array[0], "\n"; # 1 print $array[2], "\n"; # 4 print $array[4][1], "\n"; # bob print $array[5]{inp_1}, "\n"; # net_7