utils.pl,v #1

  • //
  • guest/
  • robert_yu/
  • autochar-1.5.3/
  • src/
  • RCS/
  • utils.pl,v
  • View
  • Commits
  • Open Download .zip Download (31 KB)
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
@
# Change User Description Committed
#1 6489 robert_yu Saved here.