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
@