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
@