eval 'exec perl -S $0 ${1+"$@"}' ########################################################################### # This confidential and proprietary software may be used only # as authorized by a licensing agreement from Synopsys Inc. # In the event of publication, the following notice is applicable: # # (C) COPYRIGHT 1994 SYNOPSYS INC. # ALL RIGHTS RESERVED # # The entire notice above must be reproduced on all authorized copies. ########################################################################### if 0; # sim2dp version v1.0.0 unshift(@INC,"."); unshift(@INC,"$ENV{'SYNOPSYS'}/auxx/syn/power/scripts"); unshift(@INC,$ENV{'POWER_SCRIPT'}); require "newgetopt.pl"; ########################################################## # This script implements a simulation conversion interface # for use with DesignPower and VSS VHDL System Simulator # both provided by Synopsys Inc. ########################################################## ############################################################# # Subroutine HEX_TO_BINARY(string) converts an ascii hex # string to a binary string. Probably better way to do this. ############################################################# $debug_hex2b = 0; sub HEX_TO_BINARY { local($hex) = pop(@_); if( $debug_hex2b == 1) { printf STDERR "HEX_TO_BINARY hex= %s \n", $hex;} local($bin_str) = ""; local($char) = ''; local($char_str) = ""; local(@char_ar) = split(//,$hex); foreach $char (@char_ar) { CHAR: { if ( $char =~ '0') { $char_str = "0000"; last CHAR;} if ( $char =~ '1') { $char_str = "0001"; last CHAR;} if ( $char =~ '2') { $char_str = "0010"; last CHAR;} if ( $char =~ '3') { $char_str = "0011"; last CHAR;} if ( $char =~ '4') { $char_str = "0100"; last CHAR;} if ( $char =~ '5') { $char_str = "0101"; last CHAR;} if ( $char =~ '6') { $char_str = "0110"; last CHAR;} if ( $char =~ '7') { $char_str = "0111"; last CHAR;} if ( $char =~ '8') { $char_str = "1000"; last CHAR;} if ( $char =~ '9') { $char_str = "1001"; last CHAR;} if ( $char =~ 'A') { $char_str = "1010"; last CHAR;} if ( $char =~ 'B') { $char_str = "1011"; last CHAR;} if ( $char =~ 'C') { $char_str = "1100"; last CHAR;} if ( $char =~ 'D') { $char_str = "1101"; last CHAR;} if ( $char =~ 'E') { $char_str = "1110"; last CHAR;} if ( $char =~ 'F') { $char_str = "1111"; last CHAR;} } $bin_str .= $char_str; if( $debug_hex2b == 1) { printf STDERR "\ HEX_TO_BINARY bin-str = %s char = %s char_str = %s \n", $bin_str,$char, $char_str; } } return $bin_str; } # end HEX_TO_BINARY ############################################################# # Get command line options $opt_units = 1; $autoabbrev = 1; (&NGetOpt("vss=s","tv=s","monitor=s","period=i","units=f","input_list=s","strip_name=s","quick=s","vantage=s","print_pin","find_pin","help")) || goto USAGE; if ($opt_help) {goto USAGE;}; if (($opt_monitor || $opt_tv || $opt_quick || $opt_vantage ) && !$opt_period) { print "Error: monitor, tv, quick or vantage options require period argument and value \n"; goto USAGE; }; goto BEGIN_STUFF; USAGE: print "$0\n"; print " -vss \$vss_tog_file : Read VSS toggle file \n"; print " -tv \$test_vector_file : Read test vector file \n"; print " -monitor \$monitor_output_file : Read Simulation Monitor Output\n"; print " -period \$integer_value : Length of Simulation (in sim time units)\n"; print " -units \$integer_value : Ratio of Simulation Units to Syn Lib Units, default=1 \n"; print " -input_list \$input_list_file : List of input ports in test vector file, default= input.list\n"; print " -strip_name \$string_value : Name of test bench name to strip, default is two levels of hierarchy\n"; print " -quick \$quick_tog_file : Read Quicksim toggle file \n"; print " -vantage \$vantage_tog_file : Read Vantage Coverage toggle file \n"; print " -find_pin : Use find(pin, \"name\") in the script\n"; print " -print_pin : Use all_connected to get name of pins\n"; exit 1; BEGIN_STUFF: ############## # Defaults ############## $debug0 = 0; $debug1 = 0; $debug2 = 0; $debug3 = 0; $debug_vss = 0; $debug_QUICK0 = 0; $debug_QUICK1 = 0; $debug_van0 = 0; $debug_vss0 = 0; $debug_mon = 0; $debug_mon2 = 0; $debug_tv = 0; ############## $start = 0; $[ = 0; # set array base to 1 $\ = "\n"; # set output record separator $FS = ' '; $test_port = 0; #################### # Try to Open Files #################### if (!$opt_input_list) { $opt_input_list = "input.list";}; if ($debug0) { printf STDERR "vss %s, tv %s, mon %s, period %d, units %f, input_file %s \n", $opt_vss, $opt_tv, $opt_monitor, $opt_period, $opt_units, $opt_input_list; }; if ($opt_vss) { open(VSSFILE,"< $opt_vss") || die "couldn't open vss file $opt_vss.\n"; } if ($opt_quick) { open(QUICKFILE,"< $opt_quick") || die "couldn't open quick file $opt_quick.\n"; } if ($opt_tv) { open(TVFILE,"< $opt_tv") || die "couldn't open tv file $opt_tv.\n"; } if ($opt_monitor) { open(MONFILE,"< $opt_monitor") || die "couldn't open monitor file $opt_monitor.\n"; } if ($opt_vantage) { open(VANFILE,"< $opt_vantage") || die "couldn't open Vantage toggle file $opt_vantage.\n"; } if (!$opt_units) { $opt_units = 1; }; # Convert units to syn library units $opt_period = $opt_period * $opt_units; # This improves performance by disabling autolink printf STDOUT "auto_link_disable = \"true\"\n"; # This prevents case conversion issues from preventing read printf STDOUT "find_ignore_case = \"true\"\n"; ############################### # Start Process VSS File ############################### if (!$opt_vss) {goto MONITOR}; # local defaults $start = 0; $khazrate = .5; $khaztime = 0; $skip_line = 0; $line_number = 0; $first_line = 1; $old_strip_name = $opt_strip_name; $opt_strip_name =~ s/(\W)/\\\1/g; if ($debug_vss0) { printf STDERR "strip name was %s is now %s \n", $opt_strip_name ,$opt_strip_name; }; line: while () { $line_number++; chop; # strip record separator if ($_ !~ /\S/) { next line; } @Fld = split(/[ \n]+/, $_, 9999); # Parse First Line as if ($first_line == 1) { $sim_period = $Fld[0]; if (($sim_period) && ($opt_period) && ($sim_period != $opt_period)) { printf STDERR "Warning: Simulation period from VSS %d, does not match period argument %d \n", $sim_period, $opt_period; }; if ($debug_vss) { printf STDERR "Simulation period is %d \n", $period ; printf STDERR "VSS period is %d \n", $sim_period ; printf STDERR "Opt period is %d \n", $opt_period ; }; if ($sim_period != 0) { if(!$opt_units) { $period = $sim_period; } else { $period = $sim_period * $opt_units; } } elsif ($opt_period != 0) { $period = $opt_period; } else { die "Error: Period not defined in VSS file \n"; }; $first_line = 0; next line; } $pin_name = $Fld[0]; $toggle = $Fld[1]; $hazard = $Fld[2]; $high_time = $Fld[3]; $low_time = $Fld[4]; $hazard_time = $Fld[5]; $test_pin = $pin_name; # Stripping off test_bench, assumes strip of 2 levels of hierarchy if (!$opt_strip_name) { $test_pin =~ s/^(\/\w+\/\w+\/)//; $match = $'; }else { $test_pin =~ s/^${opt_strip_name}//; $match = $'; }; if ( (! $match) || ($match != '')) { if ($debug_vss0) { printf STDERR "SKIPPING LINE, test_pin = %s, pin_name = %s \n", $test_pin, $pin_name; } $skip_line++; next line; } if ($debug_vss0){ printf STDERR "Pin name is %s, test_pin = %s, strip_name = %s match is %s\n", $pin_name, $test_pin, $opt_strip_name, $match; } $pin_name = $test_pin; if ($pin_name =~ /\)$/ || $pin_name !~ /\(+/) { # $pin_name =~ s/\(/\[/; # $pin_name =~ s/\)/\]/; $new_pin = $pin_name; } else { $new_pin = substr($pin_name,0,index($pin_name,"(")) . substr($pin_name,index($pin_name,")")+1); if ( index($new_pin,"/") == 1) { $new_pin = substr($new_pin, 2) }; } if ( index($new_pin, "/") == -1 ) { $test_port =1; } if ($debug_vss0) { printf STDERR "Net name is %s, toggle = %d \n", $new_pin, $toggle; } if ($period != 0.0) { $haz_time_delta = ($khaztime * ($hazard_time/$period)); } else { $haz_time_delta = 0.0; } $toggle_rate = $toggle + ($khazrate * $hazard) + $haz_time_delta; if (($high_time + $low_time) != 0.0) { $static_prob = $high_time / ($high_time + $low_time); } else { $static_prob = 0.5 }; if ($opt_find_pin) { printf STDOUT "find(pin,\"%s\") > /dev/null; \n" , $new_pin; printf STDOUT "if (dc_shell_status) {\n"; printf STDOUT "set_switching_activity -period %.2f -toggle_rate %.f -static_prob %f ", $period, $toggle_rate, $static_prob; printf STDOUT "find(pin,\"%s\"); \n" , $new_pin; printf STDOUT "};\n"; } else { if ($test_port) { printf STDOUT "set_switching_activity -period %.2f -toggle_rate %.f -static_prob %f ",$period, $toggle_rate, $static_prob; printf STDOUT " find(port,\"%s\") ;\n" , $new_pin; $test_port = 0; } else { printf STDOUT "set_switching_activity -period %.2f -toggle_rate %.f -static_prob %f ",$period, $toggle_rate, $static_prob; if ($start) { printf STDOUT "-start_point " ; } printf STDOUT " find(pin,\"%s\") ;\n" , $new_pin; } if ($opt_print_pin) { printf STDOUT "all_connected( %s ) ; \n" , $new_pin; }; } } if ($skip_line > 0.0) { printf STDERR "WARNING: Skipped $skip_line lines which did not match strip_name $strip_name\n"; }; ############################### # Start Process Monitor File ############################### MONITOR: if (!$opt_monitor) { goto TV_BLOCK; }; if ($debug_mon) {printf STDERR "####### Process Monitor File #######\n";} $new_bit = 0; $old_bit = 0; $bad_sig = (); line: while () { $bus = 0; $asynch_event = 0; if (s/\w+:[ \t]+EVENT[ \t]+//) { $asynch_event = 1;} if ($debug_mon) {printf STDERR "Next Mon Line %s",$_;} if (/([\w\(\)]+)[ \t\w\(\)\=]+'([01UZX])'/) { $sig = $1 ; $val = $2 } elsif (/([\w\(\)]+)[ \t\w\(\)]+X\"([0-9A-FU]+)\"/) { $sig = $1 ; $bus = 1; $val = $2 } else { /([\w\(\)]+)/; $bad_sig = $1; if ($debug_mon2) {printf STDERR "No Match on Line#=%d, on signal $bad_sig \n" , $. } next line; }; if (($val =~ /U/) || $asynch_event) { next line}; # if( $debug_mon == 1) { printf STDERR "Line #= %d sig = %s, val = %s , old_val = %s, bus = %d\n", $., $sig, $val, $cur_val{$sig}, $bus ; } ############################### # Initialization if Not Found ############################### if (! defined $cur_val{$sig}) { if( $debug_mon ) { printf STDERR "Init sig %s, val %s\n", $sig, $val; } if ($bus == 1) { $i = 0; $busl = length($val)*4;; loop1: while ($i < $busl) { $bus_sig= $sig . "[" . $i . "]"; $togs{$bus_sig} = 0; $sum{$bus_sig} = 0; $cycles{$bus_sig} = 0; $i++; next loop1; } } $cur_val{$sig} = $val; if ($debug_mon) { printf STDERR "set init val for %s: %s\n", $sig, $cur_val{$sig};} $togs{$sig} = 0; $sum{$sig} = 0; $cycles{$sig} = 0; $bus_flag{$sig} = $bus; next; } ############################### # Process Values ############################### if( $debug_mon == 1) { printf STDERR "Process Sig %s, val %s\n", $sig, $val; } if ( $bus == 1) { $busl = length($val)*4; $bit_str = &HEX_TO_BINARY($val); $old_str = &HEX_TO_BINARY($cur_val{$sig}); if( $debug_mon == 1) { printf STDERR "bit_vec = %s was %s, old_vec = %s was %s \n", $bit_str,$val,$old_str,$cur_val{$sig}; } @bit_vec = split(//,$bit_str); @old_vec = split(//,$old_str); if ($debug2) { printf STDERR "bit0 = %s, old_bit0 = %s \n", $bit_vec[0],$old_vec[0]; }; $i = $busl-1; loop2: while ($i >= 0) { $new_bit = $bit_vec[$i]; $old_bit = $old_vec[$i]; $bus_sig= $sig . "[" . ($busl-$i-1) . "]"; if( $debug1 == 1) { printf STDERR " Bus Sig %s Bit Vec - %d, NewBit - %d, OldBit - %d \n", $bus_sig, $i, $new_bit, $old_bit; } if ($new_bit != $old_bit) { $togs{$bus_sig}++; if( $debug3 == 1) { printf STDERR "Diff Bus Sig %s Bit Vec = %d, Val = %d \n", $bus_sig, $i, $new_bit; } } $sum{$bus_sig} += $new_bit; $i--; next loop2; } } ############################## # Handling Non-Bus Signal ############################## if ($cur_val{$sig} != $val) { $togs{$sig}++ }; $sum{$sig} += $val; $cur_val{$sig} = $val; $cycles{$sig}++; if ($debug_mon) { printf STDERR "cycles(%s) = %d \n",$sig,$cycles{$sig}; } if ($max_cycles < $cycles{$sig}) {$max_cycles = $cycles{$sig}}; } # Increment Cycles, to include reset cycle $max_cycles++; if ($debug_mon) {printf STDERR "Monitor Process max_cycles = %d \n",$max_cycles;} @sigs = keys(%togs); if ($debug1) {print STDERR "\nAll the signals = \n @sigs \n";} PRINTL: foreach $sig (sort(@sigs)) { # Don't Print Bus Signals # if ($bus_flag{$sig}) { next PRINTL;}; $port = $sig; $period = $opt_period; printf("set_switching_activity -period %.2f", $period); printf(" -toggle_rate %.f", $togs{$sig}); if (($max_cycles != 0) && ($cur_val{$sig} >= 0)) { printf(" -static_prob %f", $sum{$sig} / $max_cycles); } else { printf(" -static_prob 0.5"); } printf(" find(port, \"%s\") ;\n", $port); } if ($bad_sig) { printf STDERR "Skipped at least one signal \(may be enumerated type\) %s \n", $bad_sig}; if ($debug_mon) {printf STDERR "***** Monitor Ended ****%s\n",$_;} ################################ # Start Process Test Vector File ################################ TV_BLOCK: if (!$opt_tv) {goto QUICK_BLOCK}; if ($debug_tv) { printf STDERR "***** Process Test Vector File ****\n"; }; ########################### # local tv_block defaults ########################### $period = 0; $sim_period = 0; $line_number = 0; $init=0; $first=0; open(INFILE,"$opt_input_list") || die "couldn't open input list $opt_input_list.\n"; $num_inputs = 0; inlist: while (){ chop; # strip record separator @Fld = split(/[ \t\n]/, $_, 9999); if ($debug_tv) { printf STDERR " numinputs is %d, Fld[0] is %s\n", $num_inputs,$Fld[0];}; $input_name[$num_inputs] = $Fld[0]; if ($debug_tv) { printf STDERR " input %d is %s\n", $num_inputs, $input_name[$num_inputs];}; $num_inputs++; } close(INFILE); $cycles = 0; line: while () { $line_number++; chop; # strip record separator @Fld = split(/[ \t\n]+/, $_, 9999); $cycles++; @tmp = @last; if ($debug_tv){ printf STDERR " in_vector = %s, last = %s, out_vector = %s, cycle=%d \n", $Fld[0], join(':',@tmp),$Fld[1],$cycles;}; $iv = $Fld[0]; $ov = $Fld[1]; if ($init==0) { $i = 0; while ($i < $num_inputs) { $toggle[$i]=0; $static[$i]=0; $i++; } $init = 1; } @iva = split(/ */,$iv); $i = 0; while ($i < $num_inputs) { if (($first != 0) && ( $last[$i] != $iva[$i])) { $toggle[$i]++; }; $static[$i] = $static[$i] + $iva[$i]; if ($debug_tv) { printf STDERR " input#%d : \ last = %d, this = %d, toggle = %d, static = %d \n", $i, $last[$i] , $iva[$i], $toggle[$i], $static[$i]; } $i++; } $first = 1; @last = @iva; } $i = 0; while ($i < $num_inputs) { printf STDOUT "set_switching_activity -period %.2f -toggle_rate %.f ", $opt_period, $toggle[$i]; if ($static[$i] != 0) { printf STDOUT " -static_prob %f ", $static[$i]/$cycles; } else { printf STDOUT " -static_prob 0.5 "; } printf STDOUT " find(port,\"%s\") ; \n" , $input_name[$i]; $i++; } QUICK_BLOCK: ############################### # Start Process QUICKSIM File ############################### if (!$opt_quick) {goto VANTAGE_BLOCK}; # local defaults $start = 0; $skip_line = 0; $line_number = 0; $first_line = 1; if ($opt_strip_name =~ /^\//) { $opt_strip_name = "\\" . $opt_strip_name; if ($debug_QUICK0) { printf STDERR "Modified opt_strip_name = %s \n", $opt_strip_name; } } line: while () { $line_number++; chop; # strip record separator @Fld = split(/[ \t\n]+/, $_, 9999); # Parse First Line as Header String if ($first_line == 1) { $first_line = 0; next line; } $pin_name = $Fld[0]; $toggle = $Fld[2]; $hazard = 0; $high_time = 1; $low_time = 1; $hazard_time = 1; $test_pin = $pin_name; # Stripping off test_bench, assumes strip of 1 levels of hierarchy if (!$opt_strip_name) { $test_pin =~ s/^(\/\w+)\//\//; $match = $'; }else { $test_pin =~ s/^$opt_strip_name//; $match = $'; }; if ( (! $match) || ($match != '')) { if ($debug_QUICK1) { printf STDERR "SKIPPING LINE, test_pin = %s pin_name = %s \n", $test_pin, $pin_name ; } $skip_line++; next line; } if ($debug_QUICK0){ printf STDERR "Pin name is %s, test_pin = %s, strip_name = %s match is %s, index is %d\n", $pin_name, $test_pin, $opt_strip_name, $match, index($pin_name,"/"); } $new_pin = $test_pin; # $pin_name = $test_pin; # $new_pin = substr($pin_name,0,index($pin_name,"(")) . # substr($pin_name,index($pin_name,")")+1); # if ( index($new_pin,"/") == 0) { $new_pin = substr($new_pin, 1) }; if ($debug_QUICK0){ printf STDERR "Net name is %s, toggle = %d \n", $new_pin, $toggle; } if ($opt_period != 0.0) { $haz_time_delta = ($khaztime * ($hazard_time/$opt_period)); } else { $haz_time_delta = 0.0; } $toggle_rate = $toggle + ($khazrate * $hazard) + $haz_time_delta; if (($high_time + $low_time) != 0.0) { $static_prob = $high_time / ($high_time + $low_time); } else { $static_prob = 0.5 }; if ($opt_find_pin) { printf STDOUT " find(net,\"%s\") > /dev/null; \n" , $new_pin; printf STDOUT "if (dc_shell_status) {\n"; printf STDOUT "set_switching_activity -period %.2f -toggle_rate %.f -static_prob %f ", $opt_period, $toggle_rate, $static_prob; printf STDOUT "find(net,\"%s\"); \n" , $new_pin; printf STDOUT "}\n"; } else { printf STDOUT "set_switching_activity -period %.f -toggle_rate %.2f -static_prob %f ", $opt_period, $toggle_rate, $static_prob; if ($start) { printf STDOUT "-start_point " ; } # script can take instance pins printf STDOUT " find(net,\"%s\") ; \n" , $new_pin;} if ($opt_print_pin) { printf STDOUT "all_connected( %s ) ; \n" , $new_pin; }; } if ($skip_line > 0.0) { printf STDERR "WARNING: Skipped $skip_line lines which did not match strip_name $strip_name\n"; }; VANTAGE_BLOCK: ############################### # Start Process VANTAGE File ############################### if (!$opt_vantage) {goto NEXT_BLOCK}; # local defaults $start = 0; $skip_line = 0; $line_number = 0; $first_line = 1; $pin_found = 0; linev: while () { $line_number++; if (/[ ]*(\/[^\/]+\/.*):/) { if (!(/\/CELL\//)) { $pin_found = 1; $pin_name = $1; } } if ($pin_found) { if (/to[ ]+'0'[ ]+(\d+)[ ]+.*/) { $to_zero = $1; } if (/to[ ]+'1'[ ]+(\d+)[ ]+.*/) { $to_one = $1; $pin_found = 0; # Stripping off test_bench, assumes strip of 2 levels of hierarchy $test_pin = $pin_name; if (!$opt_strip_name) { $pin_name =~ s/^(\/\w+\/\w+\/)//; $match = $'; }else { $pin_name =~ s/^${opt_strip_name}//; $match = $'; }; if ( (! $match) || ($match =~ '') || $match =~ /\s+/) { if ($debug_van0) { printf STDERR "SKIPPING LINE, pin_name = %s test_pin = %s match = %s \n", $pin_name, $test_pin, $match; } $skip_line++; next linev; } $toggle_count = $to_zero + $to_one; $command = "set_switching_activity -toggle_rate $toggle_count -period $opt_period find(pin, \"$pin_name\");\n"; if ($opt_find_pin) { printf STDOUT "find(pin, \"$pin_name\") > /dev/null\n"; printf STDOUT "if (dc_shell_status) {\n"; printf STDOUT " $command\n"; printf STDOUT "};\n"; } else { printf STDOUT " $command"; } if ($debug_van0){ printf STDERR "Pin name is %s, test_pin = %s, strip_name = %s match is %s\n", $pin_name, $test_pin, $opt_strip_name, $match; } } } } close(TIN); close(SETSA); NEXT_BLOCK: printf STDOUT "auto_link_disable = \"false\"\n"; printf STDOUT "find_ignore_case = \"false\"\n"; #END OF PROGRAM