common.pl,v #1

  • //
  • guest/
  • robert_yu/
  • autochar-1.5.3/
  • src/
  • RCS/
  • common.pl,v
  • View
  • Commits
  • Open Download .zip Download (15 KB)
head	1.9;
access;
symbols;
locks; strict;
comment	@# @;


1.9
date	99.01.29.05.38.33;	author ryu;	state Exp;
branches;
next	1.8;

1.8
date	99.01.26.18.22.22;	author ryu;	state Exp;
branches;
next	1.7;

1.7
date	99.01.20.07.44.59;	author ryu;	state Exp;
branches;
next	1.6;

1.6
date	99.01.19.11.20.05;	author ryu;	state Exp;
branches;
next	1.5;

1.5
date	99.01.14.10.19.02;	author ryu;	state Exp;
branches;
next	1.4;

1.4
date	99.01.13.07.18.42;	author ryu;	state Exp;
branches;
next	1.3;

1.3
date	98.09.13.03.33.19;	author ryu;	state Exp;
branches;
next	1.2;

1.2
date	98.09.13.03.31.44;	author ryu;	state Exp;
branches;
next	1.1;

1.1
date	98.09.13.03.29.12;	author ryu;	state Exp;
branches;
next	;


desc
@#! /usr/local/bin/perl
@


1.9
log
@Getting port directions will search for the correct subckt first.
@
text
@#	$Id: common.pl,v 1.8 1999/01/26 18:22:22 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';

#   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_cell, $found_ports, $count, %tlist);

    open(FA, $filename) || die "ERROR: Cannot open spice file '$filename'.\n"; 

    $found_cell = 0;
    $found_ports = 0;
    $count = 0;

    while (<FA>) {
	if (/^.subckt\s+$cellname\s+(.*)/i) {
	    $found_cell = 1 ;
	    next;
	}
	if (/\* Begin port declarations/) {
	    $found_ports = 1 ;
	    next;
	}
	if ($found_cell && $found_ports) {
	    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;
}

#   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);
}


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`;
    }
}


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 trig_word {
    if ($spice_type eq 'smartspice') {
	return 'delay';
    } else {
	return 'trig=';
    }
}


1;
@


1.8
log
@smartspice trig_word
@
text
@d1 1
a1 1
#	$Id: common.pl,v 1.7 1999/01/20 07:44:59 ryu Exp ryu $
d196 1
a196 1
    my($found, $count, %tlist);
d200 2
a201 1
    $found = 0;
d205 4
d210 1
a210 1
	    $found = 1 ;
d213 1
a213 1
	if ($found) {
@


1.7
log
@No perl header
@
text
@d1 1
a1 1
#	$Id: common.pl,v 1.6 1999/01/19 11:20:05 ryu Exp ryu $
d347 9
@


1.6
log
@wip
@
text
@d1 1
a1 3
#! /usr/bin/perl

#	$Id: common.pl,v 1.5 1999/01/14 10:19:02 ryu Exp ryu $
@


1.5
log
@Using /usr/bin/perl
@
text
@d3 1
a3 1
#	$Id: common.pl,v 1.4 1999/01/13 07:18:42 ryu Exp ryu $
d206 1
a206 1
	if (/\* Terminals for cell $cellname/i) {
d265 1
@


1.4
log
@GPL
@
text
@d1 1
a1 1
#! /usr/local/bin/perl
d3 1
a3 1
#	$Id$
@


1.3
log
@*** empty log message ***
@
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: common.pl,v 1.2 1998/09/13 03:31:44 ryu Exp ryu $
#	Common routines
#	Author: Robert K. Yu
d8 16
@


1.2
log
@common stuff
@
text
@d9 2
a10 2
#	$Id: common.pl,v 1.1 1998/09/13 03:29:12 ryu Exp ryu $
#	Utilities
d325 12
@


1.1
log
@entered into RCS
@
text
@d9 1
a9 1
#	$Id: utils.pl,v 1.26 1998/09/12 19:54:02 ryu Exp ryu $
a15 184
#   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";
}


#   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);
}


#   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;
    }
    if ($units eq 'FF') {
	$number *= 1e-15;
    }
    if ($units eq 'PF') {
	$number *= 1e-12;
    }
    if ($units eq 'PS') {
	$number *= 1e-12;
    }
    if ($units eq 'NS') {
	$number *= 1e-9;
    }
    if ($units eq 'K') {
	$number *= 1e3;
    }
    return ($number);
}


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);
}


d254 8
d263 2
a264 2
sub max {
    my ($a, $b) = @@_;
d266 5
a270 2
    return ($a) if ($a > $b); 
    return ($b);
d272 7
d280 3
a282 8
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;
d284 24
@
# Change User Description Committed
#1 6489 robert_yu Saved here.