head 1.32; access; symbols; locks; strict; comment @# @; 1.32 date 99.01.31.09.40.13; author ryu; state Exp; branches; next 1.31; 1.31 date 99.01.20.07.44.59; author ryu; state Exp; branches; next 1.30; 1.30 date 99.01.14.10.19.02; author ryu; state Exp; branches; next 1.29; 1.29 date 99.01.13.07.18.42; author ryu; state Exp; branches; next 1.28; 1.28 date 98.09.13.04.40.51; author ryu; state Exp; branches; next 1.27; 1.27 date 98.09.13.03.33.54; author ryu; state Exp; branches; next 1.26; 1.26 date 98.09.12.19.54.02; author ryu; state Exp; branches; next 1.25; 1.25 date 98.09.11.06.19.45; author ryu; state Exp; branches; next 1.24; 1.24 date 98.09.08.13.16.49; author ryu; state Exp; branches; next 1.23; 1.23 date 98.09.07.19.24.37; author ryu; state Exp; branches; next 1.22; 1.22 date 98.09.07.09.57.10; author ryu; state Exp; branches; next 1.21; 1.21 date 98.09.06.20.43.23; author ryu; state Exp; branches; next 1.20; 1.20 date 98.09.05.22.10.32; author ryu; state Exp; branches; next 1.19; 1.19 date 98.09.03.07.32.45; author ryu; state Exp; branches; next 1.18; 1.18 date 98.09.03.06.09.52; author ryu; state Exp; branches; next 1.17; 1.17 date 98.09.01.04.49.09; author ryu; state Exp; branches; next 1.16; 1.16 date 98.08.30.19.24.00; author ryu; state Exp; branches; next 1.15; 1.15 date 98.08.29.19.50.27; author ryu; state Exp; branches; next 1.14; 1.14 date 98.08.29.17.23.56; author ryu; state Exp; branches; next 1.13; 1.13 date 98.08.24.06.16.21; author ryu; state Exp; branches; next 1.12; 1.12 date 98.08.23.22.11.24; author ryu; state Exp; branches; next 1.11; 1.11 date 98.08.23.21.59.07; author ryu; state Exp; branches; next 1.10; 1.10 date 98.08.23.06.56.57; author ryu; state Exp; branches; next 1.9; 1.9 date 98.08.18.09.33.00; author ryu; state Exp; branches; next 1.8; 1.8 date 98.08.17.16.58.24; author ryu; state Exp; branches; next 1.7; 1.7 date 98.08.17.02.41.17; author ryu; state Exp; branches; next 1.6; 1.6 date 98.08.16.13.37.40; author ryu; state Exp; branches; next 1.5; 1.5 date 98.08.15.21.23.36; author ryu; state Exp; branches; next 1.4; 1.4 date 98.08.15.11.09.38; author ryu; state Exp; branches; next 1.3; 1.3 date 98.08.15.10.11.18; author ryu; state Exp; branches; next 1.2; 1.2 date 98.08.13.09.08.03; author ryu; state Exp; branches; next 1.1; 1.1 date 98.08.13.07.17.14; author ryu; state Exp; branches; next ; desc @#! /usr/local/bin/perl @ 1.32 log @spice2float error @ text @# $Id: utils.pl,v 1.31 1999/01/20 07:44:59 ryu Exp ryu $ # Copyright (C) 1999 Robert K. Yu # email: robert@@yu.org # This file is part of Autochar. # Autochar is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # Autochar is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with Autochar; see the file COPYING. If not, write to the # Free Software Foundation, Inc., 59 Temple Place - Suite 330, # Boston, MA 02111-1307, USA. require 'ctime.pl'; # dump_list: # Prints out to STDERR the contents of a given list. # For debugging. # sub dump_list { my($name, @@l) = @@_; my($i); printf STDERR "dump_list: @@%s = (", $name; foreach $i (@@l) { printf STDERR " '$i',"; } printf STDERR ");\n"; } # dump_hash: # Prints out to STDERR the contents of a given hash list. # For debugging. # sub dump_hash { my($name, %l) = @@_; my($key); printf STDERR "dump_hash: %%%s = (\n", $name; foreach $key (keys(%l)) { printf STDERR " $key => $l{$key},\n"; } printf STDERR ");\n"; } # vary_list: # sub vary_list { my($start, $incr, $N, $units) = @@_; my($i, @@list, $value); for ($i = 0; $i <= $N; $i++) { $value = $start+$i*$incr . $units; push(@@list, $value); } return @@list; } sub convert_spice_values { my(@@list) = @@_; my(@@newlist, $value); foreach $value (@@list) { push(@@newlist, &spice2float($value)); } return (@@newlist); } sub spice2float { my($value) = @@_; my($number, $units); ($number, $units) = $value =~ /([\d\.]+)([a-zA-Z]+)/; $units =~ tr/a-z/A-Z/; if ($units eq 'AF') { $number *= 1e-18; return ($number); } if ($units eq 'FF') { $number *= 1e-15; return ($number); } if ($units eq 'PF') { $number *= 1e-12; return ($number); } if ($units eq 'PS') { $number *= 1e-12; return ($number); } if ($units eq 'NS') { $number *= 1e-9; return ($number); } if ($units eq 'K') { $number *= 1e3; return ($number); } return ($value); } sub mult_list { my($scale, @@oldvalues) = @@_; my($v, @@newvalues); if ($scale == 1) { return(@@oldvalues); } foreach $v (@@oldvalues) { push(@@newvalues, $v*$scale); } return (@@newvalues); } sub div_list { my($scale, @@oldvalues) = @@_; my($v, @@newvalues); if ($scale == 0) { die "ERROR: cannot scale by 0.\n"; } if ($scale == 1) { return(@@oldvalues); } foreach $v (@@oldvalues) { push(@@newvalues, $v/$scale); } return (@@newvalues); } sub halve_list { my(@@oldlist) = @@_; my($i, @@newlist); for ($i = 0; (2 * $i) <= $#oldlist; $i++) { push (@@newlist, @@oldlist[(2*$i)]); } return (@@newlist); } sub avg_list { my(@@list) = @@_; my($i, $sum); if ($#list == 0) { return (0); } $sum = 0; for ($i = 0; $i <= $#list; $i++) { $sum += $list[$i]; } return ($sum/$#list); } sub max { my ($a, $b) = @@_; return ($a) if ($a > $b); return ($b); } sub bigger_avg_list { local(*list1, *list2) = @@_; my($avg1, $avg2); $avg1 = &avg_list(@@list1); $avg2 = &avg_list(@@list2); if ($avg1 > $avg2) { return (@@list1); } else { return (@@list2); } } 1; @ 1.31 log @No perl header @ text @d1 1 a1 1 # $Id: utils.pl,v 1.30 1999/01/14 10:19:02 ryu Exp ryu $ d89 1 d93 1 d97 1 d101 1 d105 1 d109 1 d111 1 a111 1 return ($number); @ 1.30 log @Using /usr/bin/perl @ text @d1 1 a1 3 #! /usr/bin/perl # $Id: utils.pl,v 1.29 1999/01/13 07:18:42 ryu Exp ryu $ @ 1.29 log @GPL @ text @d1 1 a1 1 #! /usr/local/bin/perl d3 1 a3 1 # $Id$ @ 1.28 log @Added slew rate dependence on clock enable @ text @d3 1 a3 5 # Copyright (c) 1998-2001, Robert K. Yu. All Rights Reserved. # # No part of this program may be used, reproduced, stored in a # retrieval system, or transmitted in any form or by any # means without the prior permission of the author. d5 2 a6 3 # $Id: utils.pl,v 1.27 1998/09/13 03:33:54 ryu Exp ryu $ # Utilities # Author: Robert K. Yu d8 16 @ 1.27 log @Moved some stuff into common.pl @ text @d9 1 a9 1 # $Id: utils.pl,v 1.26 1998/09/12 19:54:02 ryu Exp ryu $ d140 14 d162 14 @ 1.26 log @Added slew-rate to setup and hold; support for non-linear models for clock-q @ text @d9 1 a9 1 # $Id: utils.pl,v 1.25 1998/09/11 06:19:45 ryu Exp ryu $ a47 59 # print_header: # Print out to the give $fname a standard header. The 'comment' # argument is the character(s) used to denote the beginning of # a comment, typically the "#" or "*" character. # sub print_header { my($fname, $comment) = @@_; my($user, $date); $user = $ENV{'USER'}; $date = &ctime(time); # use select(); printf $fname "$comment \$\Id\$\n\n"; printf $fname "$comment DO NOT EDIT. This file generated automagically.\n"; printf $fname "$comment Created: $date"; printf $fname "$comment User: $user\n\n"; } # uniq_run_file_name: # Removes any offensive characters that are not allowed in # unix filenames. Modifies $spice_run. # sub uniq_run_file_name { my($cellname, @@items) = @@_; my($name, $item); $name = $cellname; foreach $item (@@items) { $name = $name . '.' . $item } $name = $name . '_' . $spice_run . '.sp'; $spice_run++; # get rid of any illegal characters here. ($name = $name) =~ tr/\[\]/--/; ($name = $name) =~ tr/\<\>/--/; return $name; } # run_file_name: # sub run_file_name { my($cellname, @@items) = @@_; my($tryname); # funny, this routine fails if you use $spice_run_list{'$tryname'} do { $tryname = &uniq_run_file_name($cellname, @@items); } until $spice_run_list{$tryname} != 1; $spice_run_list{$tryname} = 1; return ($tryname); } a140 239 # lookup_input -- # GIven a term, figure out if it makes reference to # another term, or how to tie it, either to high or low. # Modifies variables $term_no and @@vcvs_list sub lookup_input { local($term, *inlist, *reflist, $tie, @@tie_list) = @@_; my($expression, $str); my($i, $in, $refname); for ($i = 0; $i <= $#inlist; $i++) { $in = $inlist[$i]; $refname = $reflist[$i]; if ($equivalent{$term} eq $in) { $str = sprintf ("e%s equiv_%s %s %s %s +1", $term_no, $term_no, $low_value, $refname, $low_value); push(@@vcvs_list, $str); return ('equiv_' . $term_no++); } if ($differential{$term} eq $in) { $str = sprintf ("e%s diff_%s %s %s %s -1", $term_no, $term_no, $low_value, $refname, $high_node); push(@@vcvs_list, $str); return ('diff_' . $term_no++); } } foreach $expression (@@tie_list) { if ($term =~ /$expression/) { if ($tie eq 'tie_high') { return $high_node; } else { return $low_node; } } } # does not match any expression, # so tie it to the opposite if ($tie eq 'tie_high') { return $low_node; } elsif ($tie eq 'tie_low') { return $high_node; } elsif ($tie eq '') { return $low_node; } else { die "ERROR: unknown tie '$tie' specified.\n"; } } # # lookup_output_load -- # Modifies variables $term_no and @@output_loads # sub lookup_output_load { my($term, $termname) = @@_; my($lookup, $load_type, $load_value); my($inc, $str); $inc = 0; # give it a name, if not provided if ($termname eq '') { $inc = 1; $termname = 'out_' . $term_no; } # lookup the load value $lookup = $load{$term}; if ($lookup eq '') { $lookup = $load{'default'}; } if ($lookup eq 'none') { $term_no++ if $inc; return ($termname); } else { ($load_type, $load_value) = split(':', $lookup); if ($load_type eq 'cap') { $str = sprintf ("c%s %s %s %s", $term_no, $termname, $low_value, $load_value); push(@@output_loads, $str); $term_no++; return ($termname); } if ($load_type eq 'res') { $str = sprintf ("r%s %s %s %s", $term_no, $termname, $low_value, $load_value); push(@@output_loads, $str); $term_no++; return ($termname); } if ($load_type eq 'subckt') { $str = sprintf ("x%s %s %s", $term_no, $termname, $load_value); push(@@output_loads, $str); $term_no++; return ($termname); } } } sub set_measure_values { local ( *input_prop_r, *input_prop_f, *output_prop_r, *output_prop_f, *trans_r1, *trans_r2, *trans_f1, *trans_f2, *slew_r1, *slew_r2, *slew_f1, *slew_f2) = @@_; # measure prop delays from inputs at these values $input_prop_r = $low_value . '+' . $input_prop_percent . '*' . $high_value; $input_prop_f = $low_value . '+(1-' . $input_prop_percent . ')*' . $high_value; # measure prop delays to outputs at these values $output_prop_r = $low_value . '+' . $output_prop_percent . '*' . $high_value; $output_prop_f = $low_value . '+(1-' . $output_prop_percent . ')*' . $high_value; # measure output rise transitions at these two points $trans_r1 = $low_value . '+' . $start_trans_percent . '*' . $high_value; $trans_r2 = $low_value . '+' . $end_trans_percent . '*' . $high_value; # measure output fall transitions at these two points $trans_f1 = $low_value . '+(1-' . $start_trans_percent . ')*' . $high_value; $trans_f2 = $low_value . '+(1-' . $end_trans_percent . ')*' . $high_value; # measure input rise slew transitions at these two points $slew_r1 = $low_value . '+' . $start_slew_percent . '*' . $high_value; $slew_r2 = $low_value . '+' . $end_slew_percent . '*' . $high_value; # measure output fall slew transitions at these two points $slew_f1 = $low_value . '+(1-' . $start_slew_percent . ')*' . $high_value; $slew_f2 = $low_value . '+(1-' . $end_slew_percent . ')*' . $high_value; } # read_spice_terms -- # Extract the terminal order and direction from the embedded comments # that may be found in the spice netlist sub read_spice_terms { my($filename, $cellname) = @@_; my(@@tlist, %dirlist, $i); @@tlist = &get_subckt_terms($filename, $cellname); %dirlist = &get_subckt_directions($filename, $cellname); for ($i = 0; $i <= $#tlist; $i++) { if ($dirlist{$tlist[$i]} eq 'input') { $tlist[$i] = $tlist[$i] . ':i'; } elsif ($dirlist{$tlist[$i]} eq 'output') { $tlist[$i] = $tlist[$i] . ':o'; } elsif ($dirlist{$tlist[$i]} eq '') { printf STDERR "WARNING: unknown direction for terminal '$tlist[$i]'.\n"; } else { printf STDERR "WARNING: unknown direction '$dirlist{$tlist[$i]}' for terminal '$tlist[$i]'.\n"; } } return @@tlist; } # get_subckt_directions -- # Look for spice comments that indicate direction sub get_subckt_directions { my($filename, $cellname) = @@_; my($found, $count, %tlist); open(FA, $filename) || die "ERROR: Cannot open spice file '$filename'.\n"; $found = 0; $count = 0; while (<FA>) { if (/\* Terminals for cell $cellname/i) { $found = 1 ; next; } if ($found) { if (($direction, $term) = /\* port (input|output) ([<>\w]+)/) { $term =~ tr/A-Z/a-z/; $tlist{$term} = $direction; $count++; next; } if (/\* End port declarations/) { last; } } } if ($count == 0) { printf STDERR "WARNING: no terminal definitions found in spice netlist.\n"; } return (%tlist); } # # get_subckt_terms -- # Return a list of terminals from the subckt in the given file. # sub get_subckt_terms { my($filename, $cellname) = @@_; my($found, @@tlist); open(FA, $filename) || die "ERROR: Cannot open spice file '$filename'.\n"; @@tlist = (); $found = 0; while (<FA>) { if (($terms) = /^.subckt\s+$cellname\s+(.*)/i) { $found = 1; $terms =~ tr/A-Z/a-z/; @@tlist = split(' ', $terms); next; } if ($found) { if (($terms) = /^\+(.*)/i) { $terms =~ tr/A-Z/a-z/; push (@@tlist, split(' ', $terms)); } elsif (/^\s*\*.*/) { # ignore comment } else { last; } } } if ($#tlist == -1) { printf STDERR "WARNING: no terminals found in spice netlist.\n"; } return @@tlist; } a145 29 } sub check_spice_run { if (/^\s*\*\*error\*\*/) { printf STDERR "ERROR: spice '$run_name' failed.\n"; return; } if (/\*\*\*\*\* job aborted/) { printf STDERR "ERROR: spice '$run_name' failed.\n"; return; } } sub run_spice { my($run_name) = @@_; my($base,$dir,$type,$spiceout); ($base,$dir,$type) = fileparse($run_name, '\.sp'); $spiceout = $base . '.out'; # Run hspice if ($skip && (-e $spiceout)) { printf STDERR "Found \"%s\", skipping run.\n", $spiceout; } else { printf STDERR "Running %s on \"%s\" ...\n", $spice_cmd, $run_name; `$spice_cmd $run_name`; } @ 1.25 log @Added slew rate to setup/hold @ text @d9 1 a9 1 # $Id: utils.pl,v 1.24 1998/09/08 13:16:49 ryu Exp ryu $ d189 11 d215 1 a215 1 $term_no, $term_no, $init{'low'}, $refname, $init{'low'}); d222 1 a222 1 $term_no, $term_no, $init{'low'}, $refname, $init{'high_node'}); d231 1 a231 1 return $init{'high_node'}; d233 1 a233 1 return $init{'low_node'}; d241 1 a241 1 return $init{'low_node'}; d243 1 a243 1 return $init{'high_node'}; d245 1 a245 1 return $init{'low_node'}; d282 1 a282 1 $term_no, $termname, $init{'low'}, $load_value); d289 1 a289 1 $term_no, $termname, $init{'low'}, $load_value); d315 2 a316 2 $input_prop_r = $init{'low'} . '+' . $trans{'input_prop_percent'} . '*' . $init{'high'}; $input_prop_f = $init{'low'} . '+(1-' . $trans{'input_prop_percent'} . ')*' . $init{'high'}; d319 2 a320 2 $output_prop_r = $init{'low'} . '+' . $trans{'output_prop_percent'} . '*' . $init{'high'}; $output_prop_f = $init{'low'} . '+(1-' . $trans{'output_prop_percent'} . ')*' . $init{'high'}; d323 2 a324 2 $trans_r1 = $init{'low'} . '+' . $trans{'start_trans_percent'} . '*' . $init{'high'}; $trans_r2 = $init{'low'} . '+' . $trans{'end_trans_percent'} . '*' . $init{'high'}; d327 2 a328 2 $trans_f1 = $init{'low'} . '+(1-' . $trans{'start_trans_percent'} . ')*' . $init{'high'}; $trans_f2 = $init{'low'} . '+(1-' . $trans{'end_trans_percent'} . ')*' . $init{'high'}; d331 2 a332 2 $slew_r1 = $init{'low'} . '+' . $trans{'start_slew_percent'} . '*' . $init{'high'}; $slew_r2 = $init{'low'} . '+' . $trans{'end_slew_percent'} . '*' . $init{'high'}; d335 2 a336 2 $slew_f1 = $init{'low'} . '+(1-' . $trans{'start_slew_percent'} . ')*' . $init{'high'}; $slew_f2 = $init{'low'} . '+(1-' . $trans{'end_slew_percent'} . ')*' . $init{'high'}; d470 2 a471 2 printf STDERR "Running %s on \"%s\" ...\n", $init{'spice_cmd'}, $run_name; `$init{'spice_cmd'} $run_name`; @ 1.24 log @slew rate at the clock input of setup_hold (wip) @ text @d9 1 a9 1 # $Id: utils.pl,v 1.23 1998/09/07 19:24:37 ryu Exp ryu $ d295 2 a296 1 local (*input_prop_r, *input_prop_f, @ 1.23 log @Added checking @ text @d3 1 a3 1 # Copyright (c) 1998, Robert K. Yu. All Rights Reserved. d9 1 a9 1 # $Id: utils.pl,v 1.22 1998/09/07 09:57:10 ryu Exp $ d442 18 @ 1.22 log @extract terminal order from the spice netlist . @ text @d9 1 a9 1 # $Id: utils.pl,v 1.21 1998/09/06 20:43:23 ryu Exp ryu $ d414 1 a414 1 } elsif (/^\*(.*)/) { d432 11 @ 1.21 log @clock enable @ text @d9 1 a9 1 # $Id: utils.pl,v 1.20 1998/09/05 22:10:32 ryu Exp ryu $ d24 1 a24 1 printf STDERR "dump_list: $name = ("; d26 1 a26 1 printf STDERR " $i"; d28 17 a44 1 printf STDERR ")\n"; d333 27 a359 1 my($found, @@tlist); a362 1 @@tlist = (); d364 1 d374 2 a375 8 if ($direction eq 'input') { $term = $term . ':i'; } elsif ($direction eq 'output') { $term = $term . ':o'; } else { die "ERROR: unknown terminal direction type '$direction'\n"; } push(@@tlist, $term); d383 38 d422 1 a422 1 printf STDERR "WARNING: no terminal definitions found in spice netlist.\n"; @ 1.20 log @Consolidate lookup_input functions into one, using list of names and refnames. @ text @d9 1 a9 1 # $Id: utils.pl,v 1.19 1998/09/03 07:32:45 ryu Exp ryu $ d52 1 a52 1 # run_file_name: d56 1 a56 1 sub run_file_name { d75 16 d352 8 @ 1.19 log @Filter out brackets @ text @d9 1 a9 1 # $Id: utils.pl,v 1.18 1998/09/03 06:09:52 ryu Exp ryu $ d163 1 a163 1 my($term, $in, $refname, $tie, @@tie_list) = @@_; d165 1 d167 16 a182 11 if ($equivalent{$term} eq $in) { $str = sprintf ("e%s equiv_%s %s %s %s +1", $term_no, $term_no, $init{'low'}, $refname, $init{'low'}); push(@@vcvs_list, $str); return ('equiv_' . $term_no++); } if ($differential{$term} eq $in) { $str = sprintf ("e%s diff_%s %s %s %s -1", $term_no, $term_no, $init{'low'}, $refname, $init{'high_node'}); push(@@vcvs_list, $str); return ('diff_' . $term_no++); a204 54 } } # lookup_input_2 -- # Same as lookup_input exept two references are given. # Modifies variables $term_no and @@vcvs_list # sub lookup_input_2 { my($term, $in1, $in2, $refname1, $refname2, $tie, @@tie_list) = @@_; my($expression, $str); if ($equivalent{$term} eq $in1) { $str = sprintf ("e%s equiv_%s %s %s %s +1", $term_no, $term_no, $init{'low'}, $refname1, $init{'low'}); push(@@vcvs_list, $str); return ('equiv_' . $term_no++); } if ($equivalent{$term} eq $in2) { $str = sprintf ("e%s equiv_%s %s %s %s +1", $term_no, $term_no, $init{'low'}, $refname2, $init{'low'}); push(@@vcvs_list, $str); return ('equiv_' . $term_no++); } if ($differential{$term} eq $in1) { $str = sprintf ("e%s diff_%s %s %s %s -1", $term_no, $term_no, $init{'low'}, $refname1, $init{'high_node'}); push(@@vcvs_list, $str); return ('diff_' . $term_no++); } if ($differential{$term} eq $in2) { $str = sprintf ("e%s diff_%s %s %s %s -1", $term_no, $term_no, $init{'low'}, $refname2, $init{'high_node'}); push(@@vcvs_list, $str); return ('diff_' . $term_no++); } foreach $expression (@@tie_list) { if ($term =~ /$expression/) { if ($tie eq 'tie_high') { return $init{'high_node'}; } else { return $init{'low_node'}; } } } # does not match any expression, # so tie it to the opposite if ($tie eq 'tie_high') { return $init{'low_node'}; } else { return $init{'high_node'}; @ 1.18 log @Using exponential ideal source for input slew rate. @ text @d9 1 a9 1 # $Id: utils.pl,v 1.17 1998/09/01 04:49:09 ryu Exp ryu $ d69 2 a70 1 # ($name = $name) =~ tr/\[\]/<>/; d275 1 d289 1 a289 1 $term_no++ if $inc; d296 1 a296 1 $term_no++ if $inc; d303 1 a303 1 $term_no++ if $inc; @ 1.17 log @Added function read_spice_terms @ text @d9 1 a9 1 # $Id: utils.pl,v 1.16 1998/08/30 19:24:00 ryu Exp ryu $ d312 3 a314 1 *trans_f1, *trans_f2) = @@_; d331 8 d363 1 a363 1 $term = $term . '.i'; d365 1 a365 1 $term = $term . '.o'; @ 1.16 log @Using term instead of port; extract all cell and terminal properties into synopsys model. @ text @d9 1 a9 1 # $Id: utils.pl,v 1.15 1998/08/29 19:50:27 ryu Exp ryu $ d331 41 @ 1.15 log @Added div_list and mult_list @ text @d9 1 a9 1 # $Id: utils.pl,v 1.14 1998/08/29 17:23:56 ryu Exp ryu $ d157 3 a159 3 # GIven a port, figure out if it makes reference to # another port, or how to tie it, either to high or low. # Modifies variables $port_no and @@vcvs_list d162 1 a162 1 my($port, $in, $refname, $tie, @@tie_list) = @@_; d165 1 a165 1 if ($equivalent{$port} eq $in) { d167 1 a167 1 $port_no, $port_no, $init{'low'}, $refname, $init{'low'}); d169 1 a169 1 return ('equiv_' . $port_no++); d171 1 a171 1 if ($differential{$port} eq $in) { d173 1 a173 1 $port_no, $port_no, $init{'low'}, $refname, $init{'high_node'}); d175 1 a175 1 return ('diff_' . $port_no++); d179 1 a179 1 if ($port =~ /$expression/) { d204 1 a204 1 # Modifies variables $port_no and @@vcvs_list d208 1 a208 1 my($port, $in1, $in2, $refname1, $refname2, $tie, @@tie_list) = @@_; d211 1 a211 1 if ($equivalent{$port} eq $in1) { d213 1 a213 1 $port_no, $port_no, $init{'low'}, $refname1, $init{'low'}); d215 1 a215 1 return ('equiv_' . $port_no++); d217 1 a217 1 if ($equivalent{$port} eq $in2) { d219 1 a219 1 $port_no, $port_no, $init{'low'}, $refname2, $init{'low'}); d221 1 a221 1 return ('equiv_' . $port_no++); d223 1 a223 1 if ($differential{$port} eq $in1) { d225 1 a225 1 $port_no, $port_no, $init{'low'}, $refname1, $init{'high_node'}); d227 1 a227 1 return ('diff_' . $port_no++); d229 1 a229 1 if ($differential{$port} eq $in2) { d231 1 a231 1 $port_no, $port_no, $init{'low'}, $refname2, $init{'high_node'}); d233 1 a233 1 return ('diff_' . $port_no++); d237 1 a237 1 if ($port =~ /$expression/) { d258 1 a258 1 # Modifies variables $port_no and @@output_loads d262 1 a262 1 my($port, $portname) = @@_; d269 1 a269 1 if ($portname eq '') { d271 1 a271 1 $portname = 'out_' . $port_no; d274 1 a274 1 $lookup = $load{$port}; d279 2 a280 2 $port_no++ if $inc; return ($portname); d285 1 a285 1 $port_no, $portname, $init{'low'}, $load_value); d287 2 a288 2 $port_no++ if $inc; return ($portname); d292 1 a292 1 $port_no, $portname, $init{'low'}, $load_value); d294 2 a295 2 $port_no++ if $inc; return ($portname); d299 1 a299 1 $port_no, $portname, $load_value); d301 2 a302 2 $port_no++ if $inc; return ($portname); @ 1.14 log @add more control of prop delay measurement @ text @d9 1 a9 1 # $Id: utils.pl,v 1.13 1998/08/24 06:16:21 ryu Exp ryu $ d126 14 a139 1 sub scale_list { @ 1.13 log @Added multivariable linear regression @ text @d9 1 a9 1 # $Id: utils.pl,v 1.12 1998/08/23 22:11:24 ryu Exp ryu $ d74 1 a74 1 # vary_cload: d76 3 a78 3 sub vary_cload { my($cstart, $cincr, $N, $units) = @@_; my($i, @@clist, $value); d81 2 a82 2 $value = $cstart+$i*$cincr . $units; push(@@clist, $value); d84 1 a84 1 return @@clist; a86 1 d292 24 @ 1.12 log @Robert K. Yu @ text @d9 1 a9 1 # $Id: utils.pl,v 1.11 1998/08/23 21:59:07 ryu Exp ryu $ a14 79 # linreg: # Perform linear regression. Given lists @@X and @@Y, # calculate a, b, and r2 for the specified type of fit: # lin: y = a + b * x # exp: y = a * exp (b * x) # pow: y = a * x^b # log: y = a + b * ln(x) # Input is a concatenated list of data points ($type, \@@X, \@@Y); # Output is a list (a, b, r2); # sub linreg { local ($type, *X, *Y) = @@_; my($x, $y, $sumx, $sumy, $sumxy, $sumx2, $sumy2, $N); my($a, $b, $r2); my($i); # init $sumx = 0.0; $sumy = 0.0; $sumxy = 0.0; $sumx2 = 0.0; $sumy2 = 0.0; $N = $#X; for ($i = 0; $i < $N; $i++) { if ($type eq 'lin') { $x = $X[$i]; $y = $Y[$i]; } elsif ($type eq 'exp') { $x = $X[$i]; $y = log($Y[$i]); } elsif ($type eq 'log') { $x = log($X[$i]); $y = $Y[$i]; } elsif ($type eq 'pow') { $x = log($X[$i]); $y = log($Y[$i]); } else { printf STDERR "ERROR: unknown regression type \'$type\".\n"; die; } $sumx += $x; $sumy += $y; $sumxy += ($x * $y); $sumx2 += ($x**2); $sumy2 += ($y**2); } # calculate a, b, r2 $a = ($sumy*$sumx2 - $sumx*$sumxy) / ($N*$sumx2 - $sumx**2); $b = ($N*$sumxy - $sumx*$sumy) / ($N*$sumx2 - $sumx**2); $r2 = ($a*$sumy + $b*$sumxy - ($sumy**2)/$N) / ($sumy2 - ($sumy**2)/$N); return ($a, $b, $r2); } # is_even: # Returns 1 if scalar value is even. 0 otherwise. # sub is_even { my($i) = @@_; return (($i % 2) == 0); } # is_odd: # Returns 1 if scalar value is odd. 0 otherwise. # sub is_odd { my($i) = @@_; return (($i % 2) == 1); } @ 1.11 log @save_data functions moved into model.pl; pass lists by reference @ text @d9 1 a9 1 # $Id: utils.pl,v 1.10 1998/08/23 06:56:57 ryu Exp ryu $ d11 1 a11 1 # Author: Robert Yu @ 1.10 log @Using my and use instead of local and require. @ text @d9 1 a9 1 # $Id: utils.pl,v 1.9 1998/08/18 09:33:00 ryu Exp ryu $ d23 1 a23 1 # Input is a concatenated list of data points ($type, @@X, @@Y); d28 1 a28 1 my($type, @@data) = @@_; d32 1 a32 1 my(@@X, @@Y, $i); a34 2 @@X = (); @@Y = (); d41 1 a41 11 if (&is_odd($#data+1)) { die "ERROR: (linreg) odd number of data entries.\n"; } $N = ($#data + 1) / 2; for ($i = 0; $i <= $N-1; $i++) { push(@@X, $data[$i]); } for ($i = $N; $i <= 2*$N-1; $i++) { push(@@Y, $data[$i]); } d271 1 @ 1.9 log @Debugged clock to q module; changed generated file convention @ text @d9 1 a9 1 # $Id: utils.pl,v 1.8 1998/08/17 16:58:24 ryu Exp ryu $ d28 1 a28 1 local($type, @@data) = @@_; d30 3 a32 3 local($x, $y, $sumx, $sumy, $sumxy, $sumx2, $sumy2, $N); local($a, $b, $r2); local(@@X, @@Y, $i); d93 2 a94 2 local($i) = @@_; return ((@@data % 2) == 0); d102 2 a103 2 local($i) = @@_; return ((@@data % 2) == 1); d112 2 a113 2 local($name, @@l) = @@_; local($i); d129 2 a130 2 local($fname, $comment) = @@_; local($user, $date); d145 1 a145 1 # unix filenames. d148 2 a149 2 local($cellname, @@items) = @@_; local($name, $item); d168 2 a169 2 local($cstart, $cincr, $N, $units) = @@_; local($i, @@clist, $value); d180 2 a181 2 local(@@list) = @@_; local(@@newlist); d191 2 a192 2 local($value) = @@_; local($number, $units); d219 2 a220 2 local($scale, @@oldvalues) = @@_; local($v, @@newvalues); d241 2 a242 2 local($port, $in, $refname, $tie, @@tie_list) = @@_; local($expression, $str); d286 2 a287 2 local($port, $in1, $in2, $refname1, $refname2, $tie, @@tie_list) = @@_; local($expression, $str); d340 3 a342 3 local($port, $portname) = @@_; local($lookup, $load_type, $load_value); local($inc, $str); @ 1.8 log @Clean up clock_q module @ text @d9 1 a9 1 # $Id: utils.pl,v 1.7 1998/08/17 02:41:17 ryu Exp ryu $ d226 1 a226 1 return(@@oldlist); d271 4 d276 1 a276 1 return $init{'high_node'}; @ 1.7 log @Debuggin @ text @d9 1 a9 1 # $Id: utils.pl,v 1.6 1998/08/16 13:37:40 ryu Exp ryu $ d136 1 a136 1 printf $fname "$comment \$\Id\n\n"; d338 3 a340 1 local($str); d344 1 d353 1 a353 1 $port_no++; d361 1 a361 1 $port_no++; d368 1 a368 1 $port_no++; d375 1 a375 1 $port_no++; @ 1.6 log @checking in @ text @d9 1 a9 1 # $Id: utils.pl,v 1.5 1998/08/15 21:23:36 ryu Exp ryu $ d252 1 a252 1 $port_no, $port_no, $init{'low'}, $refname, $init{'low'}); a263 8 } else { # does not match any expression, # so tie it to the opposite if ($tie eq 'tie_high') { return $init{'low_node'}; } else { return $init{'high_node'}; } d267 7 a273 2 # no tie list found, return default return $init{'low_node'}; d299 1 a299 1 $port_no, $port_no, $init{'low'}, $refname1, $init{'low'}); d305 1 a305 1 $port_no, $port_no, $init{'low'}, $refname2, $init{'low'}); a316 8 } else { # does not match any expression, # so tie it to the opposite if ($tie eq 'tie_high') { return $init{'low_node'}; } else { return $init{'high_node'}; } d320 7 a326 2 # no tie list found, return default return $init{'low_node'}; d340 1 a340 2 $lookup = $load{$port}; d345 1 @ 1.5 log @Renamed curve_fit to linreg; will add multivariable curve fitting later on. @ text @d9 1 a9 1 # $Id: utils.pl,v 1.4 1998/08/15 11:09:38 ryu Exp ryu $ d280 56 d342 1 a342 1 local($port) = @@_; d348 4 d356 2 a357 1 return ('nc_' . $port_no++);; d361 2 a362 2 $str = sprintf ("c%s out_%s %s %s", $port_no, $port_no, $init{'low'}, $load_value); d364 2 a365 1 return ('out_' . $port_no++); d368 2 a369 2 $str = sprintf ("r%s out_%s %s %s", $port_no, $port_no, $init{'low'}, $load_value); d371 2 a372 1 return ('out_' . $port_no++); d375 2 a376 2 $str = sprintf ("x%s out_%s %s", $port_no, $port_no, $load_value); d378 2 a379 1 return ('out_' . $port_no++); @ 1.4 log @saving work in progress @ text @d9 1 a9 1 # $Id: utils.pl,v 1.3 1998/08/15 10:11:18 ryu Exp ryu $ d16 1 a16 1 # curve_fit: d26 1 a26 1 sub curve_fit { @ 1.3 log @added input_cap sub @ text @d9 1 a9 1 # $Id: utils.pl,v 1.2 1998/08/13 09:08:03 ryu Exp ryu $ d274 3 @ 1.2 log @Added scaling of cload, delay. @ text @d9 1 a9 1 # $Id: utils.pl,v 1.1 1998/08/13 07:17:14 ryu Exp ryu $ d159 2 a160 1 #($name = $name) =~ tr/\[\]/<>/; d232 83 @ 1.1 log @entered into RCS @ text @d5 1 a5 1 # No part of this program may be reproduced, stored in a d9 1 a9 1 # $Id$ d178 1 a178 1 sub scale_values { d215 19 @