[qflow] 04/16: Removed an unused backup file.

Ruben Undheim rubund-guest at moszumanska.debian.org
Thu Jul 23 08:22:47 UTC 2015


This is an automated email from the git hooks/post-receive script.

rubund-guest pushed a commit to tag upstream/1.1.7
in repository qflow.

commit c4354acd7aaced1af2469464cea323dd9a697d7d
Author: Tim Edwards <tim at opencircuitdesign.com>
Date:   Sun May 31 19:36:20 2015 -0400

    Removed an unused backup file.
---
 src/vesta.c.xxx | 3527 -------------------------------------------------------
 1 file changed, 3527 deletions(-)

diff --git a/src/vesta.c.xxx b/src/vesta.c.xxx
deleted file mode 100644
index a7990b9..0000000
--- a/src/vesta.c.xxx
+++ /dev/null
@@ -1,3527 +0,0 @@
-/*--------------------------------------------------------------*/
-/* vesta.c ---							*/
-/*								*/
-/*	This file reads two files:  (1) A verilog netlist file	*/
-/*	of a circuit (structural verilog, that is, gate-level	*/
-/*	information only), and (2) a liberty format file 	*/
-/*	containing timing information for the standard cell 	*/
-/*	macros instantiated in the verilog netlist.  In		*/
-/*	addition, it may take an optional third file containing	*/
-/*	information about the resistance and capacitance of the	*/
-/*	wiring (see below).					*/
-/*								*/
-/*	Options are supplied as command-line arguments:		*/
-/*								*/
-/*		-d <delay_file>	Wiring delays (see below)	*/
-/*		-p <value>  	Clock period, in ps		*/
-/*		-l <value>	Output load, in fF		*/
-/*		-v <level>	set verbose mode		*/
-/*		-V		report version number		*/
-/*		-e		exhaustive search		*/
-/*								*/
-/*	Currently the only output this tool generates is a	*/
-/*	list of paths with negative slack.  If no paths have	*/
-/*	negative slack, then the 20 paths with the smallest	*/
-/*	positive slack are output, following a "success"	*/
-/*	message.  If no clock period is supplied, then the	*/
-/*	clock period is set to equal the delay of the longest	*/
-/*	delay path, and the 20 paths with the smallest positive	*/
-/*	slack are output, following a statement indicated the	*/
-/*	computed minimum clock period.				*/
-/*--------------------------------------------------------------*/
-
-/*--------------------------------------------------------------*/
-/*	Wiring delay file:					*/
-/*	For qflow, the wiring delay is generated by the tool	*/
-/*	"def2delays".  The file format is as follows:		*/
-/*								*/
-/*	<net_name>						*/
-/*	<output_terminal> [<net_capacitance>]			*/
-/*	<input_terminal_1> <delay_1>				*/
-/*	...							*/
-/*	<input_terminal_N> <delay_N>				*/
-/*								*/
-/*	Optional value <net_capacitance> is in fF		*/
-/*	Values <delay_i> are in ps				*/
-/*--------------------------------------------------------------*/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <string.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <math.h>	// Temporary, for fabs()
-#include "hash.h"	// For net hash table
- 
-#define LIB_LINE_MAX  65535
-
-int fileCurrentLine;
-
-// Analysis types --- note that maximum flop-to-flop delay
-// requires calculating minimum clock skew time, and vice
-// versa, so it is necessary that these have TRUE/FALSE
-// values.
-
-#define MINIMUM_TIME	0
-#define MAXIMUM_TIME	1
-
-// Multiple-use definition
-#define	UNKNOWN		-1
-
-// Sections of liberty file
-#define INIT		0
-#define LIBBLOCK	1
-#define CELLDEF		2
-#define PINDEF		3
-#define FLOPDEF		4
-#define LATCHDEF	5
-#define TIMING		6
-
-// Sections of verilog file
-#define MODULE		0
-#define IOLIST		1
-#define GATELIST	2
-#define INSTANCE	3
-#define INSTPIN		4
-#define PINCONN		5
-
-// Pin types (these are masks---e.g., a pin can be an INPUT and a CLOCK)
-#define INPUT		0x01	// The default
-#define OUTPUT		0x02
-#define DFFCLK		0x04
-#define DFFIN		0x08	// Flop input
-#define DFFOUT		0x10	// Flop output
-#define DFFSET		0x20	// Flop set (preset)
-#define DFFRST		0x40	// Flop reset (clear)
-#define LATCHIN		0x80	// Latch input
-#define LATCHEN		0x100	// Latch enable
-
-// Timing type (for tables)
-
-#define TIMING_PROP_TRANS	0
-#define TIMING_HOLD		1
-#define TIMING_SETUP		2
-#define TIMING_SET_RESET	3
-#define TIMING_RECOVERY		4
-#define TIMING_REMOVAL		5
-#define TIMING_TRISTATE		6
-
-// A few short-hand definitions
-#define DFF_ALL_IN	(DFFCLK | DFFIN | DFFSET | DFFRST)	
-#define LATCH_ALL_IN	(LATCHIN | LATCHEN)
-
-#define DFF_IN_NOT_CLK	(DFFIN | DFFSET | DFFRST)	
-#define LATCH_IN_NOT_EN	(LATCHIN)
-
-#define REGISTER_IN	(DFF_ALL_IN | LATCH_ALL_IN)
-#define REG_IN_NOT_CLK	(DFF_IN_NOT_CLK | LATCH_IN_NOT_EN)
-
-#define IOMASK		0x03
-#define DFFMASK		0x7c
-#define LATCHMASK	0x180
-
-// Pin sense
-#define SENSE_UNKNOWN	0	// Sense unknown
-#define SENSE_NONE	1	// Non-unate
-#define SENSE_POSITIVE	2	// Positive-unate
-#define SENSE_NEGATIVE	3	// Negative-unate
-
-// Signal transition direction
-#define EDGE_UNKNOWN	0
-#define RISING		1
-#define FALLING		2
-#define EITHER		3
-
-// Function translation
-#define GROUPBEGIN	1
-#define GROUPEND	2
-#define SIGNAL		3
-#define OPERATOR	4
-#define XOPERATOR	5
-#define SEPARATOR	6
-
-// Net types
-#define	NET		0x00	// Ordinary net (default)
-#define	CLOCK		0x01	// Clock net (path start)
-#define OUTTERM		0x02	// Module output
-#define	ASYNC		0x04	// Asynchronous set/reset
-#define TERMINAL	0x08	// DFF input (path terminal)
-#define LATCHTERM	0x10	// Latch input (dependent path terminal)
-#define ENABLE		0x20	// Latch enable (path start)
-
-// Cell types
-#define GATE		0x00	// Combinatorial gate (default)
-#define DFF		0x01	// Flip-flop (shared bit field)
-#define CLK_SENSE_MASK	0x02	// Clock edge mask (0=positive, 1=negative)
-#define RST_MASK	0x04	// Reset mask (0=no reset, 1=reset)
-#define RST_SENSE_MASK	0x08	// Reset edge mask (0=positive, 1=negative)
-#define SET_MASK	0x10	// Set mask (0=no set, 1=set)
-#define SET_SENSE_MASK	0x20	// Set edge mask (0=positive, 1=negative)
-#define LATCH		0x40	// Latch type
-#define EN_SENSE_MASK	0x80	// Latch enable edge mask (0=positive, 1=negative)
-
-// Some names for cell types based on masks
-
-#define DFFCP		0x01	// Pos clock
-#define DFFCN		0x03	// Neg clock
-#define DFFCPRP		0x05	// Pos clock, Pos reset
-#define DFFCNRP		0x07	// Neg clock, Pos reset
-#define DFFCPRN		0x0d	// Pos clock, Neg reset
-#define DFFCNRN		0x0f	// Neg clock, Neg reset
-#define DFFCPSP		0x11	// Pos clock, Pos set
-#define DFFCNSP		0x13	// Neg clock, Pos set
-#define DFFCPRPSP	0x15	// Pos clock, Pos reset, Pos set
-#define DFFCNRPSP	0x17	// Neg clock, Pos reset, Pos set
-#define DFFCPRNSP	0x1d	// Pos clock, Neg reset, Pos set
-#define DFFCNRNSP	0x1f	// Neg clock, Neg reset, Pos set
-#define DFFCPSN		0x31	// Pos clock, Neg set
-#define DFFCNSN		0x33	// Neg clock, Neg set
-#define DFFCPRPSN	0x35	// Pos clock, Pos reset, Neg set
-#define DFFCNRPSN	0x37	// Neg clock, Pos reset, Neg set
-#define DFFCPRNSN	0x3d	// Pos clock, Neg reset, Neg set
-#define DFFCNRNSN	0x3f	// Neg clock, Neg reset, Neg set
-
-/*--------------------------------------------------------------*/
-/* Liberty file database					*/
-/*--------------------------------------------------------------*/
-
-// Types of array
-
-// Array type 1:  Propagation time
-#define OUTPUT_CAP		0	
-#define TRANSITION_TIME		1
-
-// Array type 2:  Setup, hold, recovery, removal times
-#define RELATED_TIME		2
-#define CONSTRAINED_TIME	3
-
-typedef struct _lutable *lutableptr;
-
-typedef struct _lutable {
-    char *name;
-    char invert;	// 0 if times x caps, 1 if caps x times
-    int  var1;		// Type of array in index1
-    int  var2;		// Type of array in index2
-    int  size1;		// Number of entries in time array
-    int  size2;		// Number of entries in cap (or constrained timing) array
-    union {
-        double *times;	// Time array (units ps)
-        double *rel;	// Related pin transition time array (units ps)
-    } idx1;
-    union {
-        double *caps;	// Cap array (units fF)
-        double *cons;	// Constrained pin transition time array (units ps)
-    } idx2;
-    double *values;	// Matrix of values (used locally, not for templates)
-    lutableptr next;
-} lutable;
-
-typedef struct _pin *pinptr;
-typedef struct _cell *cellptr;
-
-typedef struct _pin {
-    char *name;
-    short type;
-
-    double capr;	// Capacitance for rising input
-    double capf;	// Capacitance for falling input (optional)
-
-    short sense;	// Sense (positive-unate, negative-unate, non-unate)
-    lutable *propdelr;	// Reference table for rising output prop delay relative to driver
-    lutable *propdelf;	// Reference table for falling output prop delay relative to driver
-    lutable *transr;	// Reference table for transition rise time
-    lutable *transf;	// Reference table for transition fall time
-
-    cellptr refcell;	// Pointer back to parent cell
-
-    pinptr next;
-} pin;
-
-typedef struct _cell {
-    short type;
-    char *name;
-    char *function;
-    pin	 *pins;		/* List of input pins with timing info */
-    double area;
-    double maxtrans;	/* Maximum transition time */
-    double maxcap;	/* Maximum allowable load */
-    cellptr next;
-} cell;
-
-/*--------------------------------------------------------------*/
-/* Verilog netlist database					*/
-/*--------------------------------------------------------------*/
-
-typedef struct _net *netptr;
-typedef struct _connect *connptr;
-typedef struct _delaydata *ddataptr;
-
-typedef struct _net {
-   char *name;
-   connptr driver;
-   short type;
-   int fanout;
-   connptr *receivers;
-   double loadr;	/* Total load capacitance for rising input */
-   double loadf;	/* Total load capacitance for falling input */
-} net;
-
-typedef struct _instance *instptr;
-
-typedef struct _connect {
-   double   metric;		/* Delay metric at connection */
-   instptr  refinst;
-   pinptr   refpin;
-   netptr   refnet;
-   ddataptr tag;		/* Tag value for checking for loops and endpoints */
-   double   *prvector;		/* Prop delay rising (at load condition) vector */
-   double   *pfvector;		/* Prop delay falling (at load condition) vector */
-   double   *trvector;		/* Transition time rising (at load condition) vector */
-   double   *tfvector;		/* Transition time falling (at load condition) vector */
-   connptr  next;
-} connect;
-
-typedef struct _instance {
-   char *name;
-   cellptr refcell;
-   connptr in_connects;
-   connptr out_connects;
-   instptr next;
-} instance;
-
-// Linked list of delays (backtrace to source)
-
-typedef struct _btdata *btptr;
-
-typedef struct _btdata {
-   double  delay;	/* Propagation delay to this point */
-   double  trans;	/* Transition time at this point */
-   short   dir;		/* Edge direction at this point */
-   connptr receiver;	/* Receiver connection at end of path */
-   int	   refcnt;	/* Reference counter for backtrace data */
-   btptr   next;	/* Path of propagation */
-} btdata;
-
-// Linked list of backtrace records
-
-typedef struct _delaydata {
-   double delay;	/* Total delay, including setup and clock skew */
-   double trans;	/* Transition time at destination, used to find setup */
-   btptr backtrace;
-   ddataptr  next;
-} delaydata;
-
-// Linked list of connection pointers
-// (Much like delaydata, but without all the timing information)
-
-typedef struct _connlist *connlistptr;
-
-typedef struct _connlist {
-   connptr connection;
-   connlistptr next;
-} connlist;
-
-/* Global variables */
-
-unsigned char verbose;		/* Level of debug output generated */
-unsigned char exhaustive;	/* Exhaustive search mode */
-
-/*--------------------------------------------------------------*/
-/* Grab a token from the input					*/
-/* Return the token, or NULL if we have reached end-of-file.	*/
-/*--------------------------------------------------------------*/
-
-char *
-advancetoken(FILE *flib, char delimiter)
-{
-    static char token[LIB_LINE_MAX];
-    static char line[LIB_LINE_MAX];
-    static char *linepos = NULL;
-
-    char *lineptr = linepos;
-    char *lptr, *tptr;
-    char *result;
-    int commentblock, concat, nest;
-
-    commentblock = 0;
-    concat = 0;
-    nest = 0;
-    while (1) {		/* Keep processing until we get a token or hit EOF */
-
-	if (lineptr != NULL && *lineptr == '/' && *(lineptr + 1) == '*') {
-	    commentblock = 1;
-	}
-
-	if (commentblock == 1) {
-	    if ((lptr = strstr(lineptr, "*/")) != NULL) {
-		lineptr = lptr + 2;
-		commentblock = 0;
-	    }
-	    else lineptr = NULL;
-	}
-
-	if (lineptr == NULL || *lineptr == '\n' || *lineptr == '\0') {
-	    result = fgets(line, LIB_LINE_MAX, flib);
-	    fileCurrentLine++;
-	    if (result == NULL) return NULL;
-
-	    /* Keep pulling stuff in if the line ends with a continuation character */
- 	    lptr = line;
-	    while (*lptr != '\n' && *lptr != '\0') {
-		if (*lptr == '\\') {
-		    // To be considered a line continuation marker, there must be
-		    // only whitespace or newline between the backslash and the
-		    // end of the string.
-		    char *eptr = lptr + 1;
-		    while (isspace(*eptr)) eptr++;
-		    if (*eptr == '\0') {
-		        result = fgets(lptr, LIB_LINE_MAX - (lptr - line), flib);
-		        fileCurrentLine++;
-		        if (result == NULL) break;
-		    }
-		    else
-			lptr++;
-		}
-		else
-		    lptr++;
-	    }	
-	    if (result == NULL) return NULL;
-	    lineptr = line;
-	}
-
-	if (commentblock == 1) continue;
-
-	while (isspace(*lineptr)) lineptr++;
-	if (concat == 0)
-	    tptr = token;
-
-	// Find the next token and return just the token.  Update linepos
-	// to the position just beyond the token.  All delimiters like
-	// parentheses, quotes, etc., are returned as single tokens
-
-	// If delimiter is declared, then we stop when we reach the
-	// delimiter character, and return all the text preceding it
-	// as the token.  If delimiter is 0, then we look for standard
-	// delimiters, and separate them out and return them as tokens
-	// if found.
-
-	while (1) {
-	    if (*lineptr == '\n' || *lineptr == '\0')
-		break;
-	    if (*lineptr == '/' && *(lineptr + 1) == '*')
-		break;
-	    if (delimiter != 0 && *lineptr == delimiter) {
-		if (nest > 0)
-		    nest--;
-		else
-		    break;
-	    }
-
-	    // Watch for nested delimiters!
-	    if (delimiter == '}' && *lineptr == '{') nest++;
-	    if (delimiter == ')' && *lineptr == '(') nest++;
-
-	    if (delimiter == 0)
-		if (*lineptr == ' ' || *lineptr == '\t')
-		    break;
-
-	    if (delimiter == 0) {
-		if (*lineptr == '(' || *lineptr == ')') {
-		    if (tptr == token) *tptr++ = *lineptr++;
-		    break;
-		}
-		if (*lineptr == '{' || *lineptr == '}') {
-		    if (tptr == token) *tptr++ = *lineptr++;
-		    break;
-		}
-		if (*lineptr == '\"' || *lineptr == ':' || *lineptr == ';') {
-		    if (tptr == token) *tptr++ = *lineptr++;
-		    break;
-		}
-	    }
-
-	    *tptr++ = *lineptr++;
-	}
-	*tptr = '\0';
-	if ((delimiter != 0) && (*lineptr != delimiter))
-	    concat = 1;
-	else if ((delimiter != 0) && (*lineptr == delimiter))
-	    break;
-	else if (tptr > token)
-	    break;
-    }
-    if (delimiter != 0) lineptr++;
-
-    while (isspace(*lineptr)) lineptr++;
-    linepos = lineptr;
-
-    // Final:  Remove trailing whitespace
-    tptr = token + strlen(token) - 1;
-    while (isspace(*tptr)) {
-	*tptr = '\0';
-	tptr--;
-    }
-    return token;
-}
-
-/*--------------------------------------------------------------*/
-/* Parse a pin name.  Check if the cell has a pin of that name,	*/
-/* and if not, add the pin to the cell, giving it default	*/
-/* values.  The pin name may contain quotes, parentheses, or	*/
-/* negations ("!" or "'");  these should be ignored.		*/
-/*--------------------------------------------------------------*/
-
-pinptr parse_pin(cellptr newcell, char *token, short sense_predef)
-{
-    pinptr newpin, lastpin;
-    char *pinname, *sptr;
-
-    // Advance to first legal pin name character
-
-    pinname = token;
-    while (isspace(*pinname) || (*pinname == '\'') || (*pinname == '\"') ||
-		(*pinname == '!') || (*pinname == '(') || (*pinname == ')'))
-	pinname++;
-
-    sptr = pinname;
-    while (*sptr != '\0') {
-	if (isspace(*sptr) || (*sptr == '\'') || (*sptr == '\"') ||
-		(*sptr == '!') || (*sptr == '(') || (*sptr == ')')) {
-	    *sptr = '\0';
-	    break;
-	}
-	sptr++;
-    }
-
-    // Check if pin was already defined
-
-    lastpin = NULL;
-    newpin = newcell->pins;
-    while (newpin) {
-	lastpin = newpin;
-	if (!strcmp(newpin->name, pinname))
-	    return newpin;
-	newpin = newpin->next;
-    }
-
-    // Pin was not defined, so create a new one and add it to the cell
-    // at the end of the cell's pin list.
-
-    newpin = (pin *)malloc(sizeof(pin));
-    newpin->name = strdup(pinname);
-    newpin->next = NULL;
-
-    if (lastpin != NULL)
-	lastpin->next = newpin;
-    else
-	newcell->pins = newpin;
-
-    newpin->type = INPUT;	// The default; modified later, if not an input
-    newpin->capr = 0.0;
-    newpin->capf = 0.0;
-    newpin->sense = sense_predef;  // Again, modified later if not true.
-    newpin->propdelr = NULL;
-    newpin->propdelf = NULL;
-    newpin->transr = NULL;
-    newpin->transf = NULL;
-    newpin->refcell = newcell;	// Create link back to cell
-    return newpin;
-}
-
-/*--------------------------------------------------------------*/
-/* Create a new net record					*/
-/*--------------------------------------------------------------*/
-
-netptr create_net() {
-
-    netptr newnet;
-
-    newnet = (netptr)malloc(sizeof(net));
-    newnet->name = NULL;
-    newnet->driver = NULL;
-    newnet->fanout = 0;
-    newnet->receivers = NULL;
-    newnet->loadr = 0.0;
-    newnet->loadf = 0.0;
-    newnet->type = NET;
-    return newnet;
-}
-
-/*----------------------------------------------------------------------*/
-/* Create and hash a net record (unless it's already in the hash table)	*/
-/*----------------------------------------------------------------------*/
-
-netptr hash_net(struct hashlist *nethash[], char *name)
-{
-    netptr np;
-
-    np = (netptr)HashLookup(name, nethash);
-
-    if (np == NULL)
-    {
-	np = create_net();
-	HashPtrInstall(name, np, nethash);
-	np->name = strdup(name);
-    }
-    return np;
-}
-
-/*----------------------------------------------------------------------*/
-/* Interpolate or extrapolate a vector from a time vs. capacitance	*/
-/* lookup table.							*/
-/*----------------------------------------------------------------------*/
-
-double *table_collapse(lutableptr tableptr, double load)
-{
-    double *vector;
-    double cfrac, vlow, vhigh;
-    int i, j;
-
-    vector = (double *)malloc(tableptr->size1 * sizeof(double));
-
-    // If the table is 1-dimensional, then just return a copy of the table.
-    if (tableptr->size2 <= 1) {
-       for (i = 0; i < tableptr->size1; i++) {
-	  *(vector + i) = *(tableptr->values + i);
-       }
-       return vector;
-    }
-
-    // Find cap load index entries bounding  "load", or the two nearest
-    // entries, if extrapolating
-
-    if (load < tableptr->idx2.caps[0])
-	j = 1;
-    else if (load >= tableptr->idx2.caps[tableptr->size2 - 1])
-	j = tableptr->size2 - 1;
-    else {
-	for (j = 0; j < tableptr->size2; j++)
-	    if (tableptr->idx2.caps[j] > load)
-		break;
-    }
-
-    cfrac = (load - tableptr->idx2.caps[j - 1]) /
-			(tableptr->idx2.caps[j] - tableptr->idx2.caps[j - 1]);
-
-    for (i = 0; i < tableptr->size1; i++) {
-
-	// Interpolate value at cap load for each transition value
-
-	vlow = *(tableptr->values + i * tableptr->size1 + (j - 1));
-	vhigh = *(tableptr->values + i * tableptr->size1 + j);
-	*(vector + i) = vlow + (vhigh - vlow) * cfrac;
-    }
-    return vector;
-}
-
-/*----------------------------------------------------------------------*/
-/* Interpolate/extrapolate a delay or transition value from a vector of	*/
-/* values at a known output load.  The original full 2D table contains	*/
-/* the transition time index values.					*/
-/*----------------------------------------------------------------------*/
-
-double vector_get_value(lutableptr tableptr, double *vector, double trans)
-{
-    int i;
-    double tfrac, vlow, vhigh, value;
-
-    // Find time index entries bounding  "trans", or the two nearest
-    // entries, if extrapolating
-
-    if (trans < tableptr->idx1.times[0])
-	i = 1;
-    else if (trans >= tableptr->idx1.times[tableptr->size1 - 1])
-	i = tableptr->size1 - 1;
-    else {
-	for (i = 0; i < tableptr->size1; i++)
-	    if (tableptr->idx1.times[i] > trans)
-		break;
-    }
-
-    // Compute transition time as a fraction of the nearest table indexes
-    // for transition times
-
-    tfrac = (trans - tableptr->idx1.times[i - 1]) /
-		(tableptr->idx1.times[i] - tableptr->idx1.times[i - 1]);
-
-    // Interpolate value
-    vlow = *(vector + (i - 1));
-    vhigh = *(vector + i);
-    value = vlow + (vhigh - vlow) * tfrac;
-    return value;
-}
-
-/*----------------------------------------------------------------------*/
-/* Interpolate or extrapolate a value from a related time vs.		*/
-/* constrained time lookup table.					*/
-/*----------------------------------------------------------------------*/
-
-double binomial_get_value(lutableptr tableptr, double rtrans, double ctrans)
-{
-    int i, j;
-    double rfrac, cfrac, vlow, vhigh, valuel, valueh, value;
-
-    /* Tables have been arranged such that idx1 is related time,	*/
-    /* idx2 is constrained time */
-
-    // Find time index entries bounding  "rtrans", or the two nearest
-    // entries, if extrapolating
-
-    if (rtrans < tableptr->idx1.rel[0])
-	i = 1;
-    else if (rtrans >= tableptr->idx1.rel[tableptr->size1 - 1])
-	i = tableptr->size1 - 1;
-    else {
-	for (i = 0; i < tableptr->size1; i++)
-	    if (tableptr->idx1.rel[i] > rtrans)
-		break;
-    }
-
-    // Compute transition time as a fraction of the nearest table indexes
-    // for transition times
-
-    rfrac = (rtrans - tableptr->idx1.rel[i - 1]) /
-		(tableptr->idx1.rel[i] - tableptr->idx1.rel[i - 1]);
-
-    // 1-dimensional computation, if this table is 1-dimensional
-
-    if (tableptr->size2 == 0) {
-	vlow = *(tableptr->values + (i - 1));
-	vhigh = *(tableptr->values + i);
-	value = vlow + (vhigh - vlow) * rfrac;
-	return value;
-    }
-
-    // Find cons index entries bounding  "ctrans", or the two nearest
-    // entries, if extrapolating
-
-    if (ctrans < tableptr->idx2.cons[0])
-	j = 1;
-    else if (ctrans >= tableptr->idx2.cons[tableptr->size2 - 1])
-	j = tableptr->size2 - 1;
-    else {
-	for (j = 0; j < tableptr->size2; j++)
-	    if (tableptr->idx2.cons[j] > ctrans)
-		break;
-    }
-
-    // Compute cons transition as a fraction of the nearest table indexes for cons
-
-    cfrac = (ctrans - tableptr->idx2.cons[j - 1]) /
-			(tableptr->idx2.cons[j] - tableptr->idx2.cons[j - 1]);
-
-    // Interpolate value at cons lower bound
-    vlow = *(tableptr->values + (i - 1) * tableptr->size1 + (j - 1));
-    vhigh = *(tableptr->values + i * tableptr->size1 + (j - 1));
-    valuel = vlow + (vhigh - vlow) * rfrac;
-
-    // Interpolate value at cons upper bound
-    vlow = *(tableptr->values + (i - 1) * tableptr->size1 + j);
-    vhigh = *(tableptr->values + i * tableptr->size1 + j);
-    valueh = vlow + (vhigh - vlow) * rfrac;
-
-    // Final interpolation (binomial interpolation)
-    value = valuel + (valueh - valuel) * cfrac;
-    return value;
-}
-
-/*----------------------------------------------------------------------*/
-/* Determine how the sense of a signal changes going from a gate's 	*/
-/* input to its output.  If the gate's input pin is positive unate	*/
-/* relative to the gate output, then the signal sense remains the same.	*/
-/* If it is negative unate, then the signal sense inverts.  If it is	*/
-/* non-unate, then the signal sense becomes non-unate, and we calculate	*/
-/* timing for both edges from that point forward, always accepting the	*/
-/* maximum time.							*/
-/*----------------------------------------------------------------------*/
-
-short calc_dir(pinptr testpin, short dir)
-{
-    short outdir;
-
-    outdir = UNKNOWN;
-    if (testpin == NULL) return dir;
-
-    switch(dir) {
-	case RISING:
-	    if (testpin->sense == SENSE_POSITIVE)
-		outdir = RISING;	/* rising input, rising output */
-	    else if (testpin->sense = SENSE_NEGATIVE)
-		outdir = FALLING;	/* rising input, falling output */
-	    else
-		outdir = EITHER;	/* output can be rising or falling */
-	    break;
-	case FALLING:
-	    if (testpin->sense == SENSE_POSITIVE)
-		outdir = FALLING;	/* falling input, falling output */
-	    else if (testpin->sense = SENSE_NEGATIVE)
-		outdir = RISING;	/* falling input, rising output */
-	    else
-		outdir = EITHER;		/* output can be rising or falling */
-	    break;
-	case EITHER:
-	    outdir = EITHER;		/* output can be rising or falling */
-	    break;
-    }
-    return outdir;
-}
-
-/*----------------------------------------------------------------------*/
-/* Calculate the propagation delay from "testpin" to the output		*/
-/* of the gate to which "testpin" is an input.				*/
-/*									*/
-/* "sense" is a pointer to the sense at the input.  SENSE_POSITIVE	*/
-/* indicates a rising edge at the pin, SENSE_NEGATIVE indicates a	*/
-/* falling edge at the pin.  "sense" is updated to indicate if the	*/
-/* output transition is rising, falling, or unknown (SENSE_NONE).	*/
-/*									*/
-/* "loadnet" is a pointer to the net connected to the cell instance's	*/
-/* output pin.  Load values will be taken from this net, depending on	*/
-/* the sense of the output.						*/
-/*									*/
-/* "testpin" is the pin receiving the input signal, and the pin	record	*/
-/* containing the relevant timing tables.				*/
-/*----------------------------------------------------------------------*/
-
-double calc_prop_delay(double trans, connptr testconn, short sense, char minmax)
-{
-    pinptr testpin;
-    double propdelayr, propdelayf;
-
-    propdelayr = 0.0;
-    propdelayf = 0.0;
-
-    testpin = testconn->refpin;
-    if (testpin == NULL) return 0.0;
-
-    if (sense != SENSE_NEGATIVE) {
-	if (testconn->prvector)
-	    propdelayr = vector_get_value(testpin->propdelr, testconn->prvector, trans);
-	if (sense == SENSE_POSITIVE) return propdelayr;
-    }
-
-    if (sense != SENSE_POSITIVE) {
-	if (testconn->pfvector)
-	    propdelayf = vector_get_value(testpin->propdelf, testconn->pfvector, trans);
-	if (sense == SENSE_NEGATIVE) return propdelayf;
-    }
-
-    if (minmax == MAXIMUM_TIME)
-	return (propdelayr > propdelayf) ? propdelayr : propdelayf;
-    else
-	return (propdelayr < propdelayf) ? propdelayr : propdelayf;
-}
-
-/*----------------------------------------------------------------------*/
-/* Calculate the transition time from "testpin" to the output		*/
-/* of the gate to which "testpin" is an input.	This is equivalent to	*/
-/* the propagation delay calculation routine above, apart from using	*/
-/* the lookup tables for transition time instead of propagation delay.	*/
-/*----------------------------------------------------------------------*/
-
-double calc_transition(double trans, connptr testconn, short sense, char minmax)
-{
-    pinptr testpin;
-    double transr, transf;
-
-    testpin = testconn->refpin;
-    if (testpin == NULL) return 0.0;
-
-    transr = 0.0;
-    transf = 0.0;
-
-    if (sense != SENSE_NEGATIVE) {
-	if (testconn->trvector)
-	    transr = vector_get_value(testpin->transr, testconn->trvector, trans);
-	if (sense == SENSE_POSITIVE) return transr;
-    }
-
-    if (sense != SENSE_POSITIVE) {
-	if (testconn->tfvector)
-	    transf = vector_get_value(testpin->transf, testconn->tfvector, trans);
-	if (sense == SENSE_NEGATIVE) return transf;
-    }
-
-    if (minmax == MAXIMUM_TIME)
-	return (transr > transf) ? transr : transf;
-    else
-	return (transr < transf) ? transr : transf;
-}
-
-/*----------------------------------------------------------------------*/
-/* Calculate the hold time for a flop input "testpin" relative to the	*/
-/* flop clock, where "trans" is the transition time of the signal at	*/
-/* "testpin", and "clktrans" is the transition time of the clock	*/
-/* signal at the clock pin.  "sense" is the sense of the input signal	*/
-/* at "testpin".							*/
-/*----------------------------------------------------------------------*/
-
-double calc_hold_time(double trans, pinptr testpin, double clktrans, short sense,
-		char minmax)
-{
-    double holdr, holdf;
-
-    if (testpin == NULL) return 0.0;
-
-    holdr = 0.0;
-    holdf = 0.0;
-
-    if (sense != SENSE_NEGATIVE) {
-	if (testpin->transr)
-	    holdr = binomial_get_value(testpin->transr, trans, clktrans);
-	if (sense == SENSE_POSITIVE) return holdr;
-    }
-
-    if (sense != SENSE_POSITIVE) {
-	if (testpin->transf)
-	    holdf = binomial_get_value(testpin->transf, trans, clktrans);
-	if (sense == SENSE_NEGATIVE) return holdf;
-    }
-
-    if (minmax == MAXIMUM_TIME)
-	return (holdr > holdf) ? holdr : holdf;
-    else
-	return (holdr < holdf) ? holdr : holdf;
-}
-
-/*----------------------------------------------------------------------*/
-/* Calculate the setup time for a flop input "testpin" relative to the	*/
-/* flop clock, where "trans" is the transition time of the signal at	*/
-/* "testpin", and "clktrans" is the transition time of the clock	*/
-/* signal at the clock pin.  "sense" is the sense of the input signal	*/
-/* at "testpin".							*/
-/*----------------------------------------------------------------------*/
-
-double calc_setup_time(double trans, pinptr testpin, double clktrans, short sense,
-		char minmax)
-{
-    double setupr, setupf;
-
-    if (testpin == NULL) return 0.0;
-
-    setupr = 0.0;
-    setupf = 0.0;
-
-    if (sense != SENSE_NEGATIVE) {
-	if (testpin->propdelr)
-	    setupr = binomial_get_value(testpin->propdelr, trans, clktrans);
-	if (sense == SENSE_POSITIVE) return setupr;
-    }
-
-    if (sense != SENSE_POSITIVE) {
-	if (testpin->propdelf)
-	    setupf = binomial_get_value(testpin->propdelf, trans, clktrans);
-	if (sense == SENSE_NEGATIVE) return setupf;
-    }
-
-    if (minmax == MAXIMUM_TIME)
-	return (setupr > setupf) ? setupr : setupf;
-    else
-	return (setupr < setupf) ? setupr : setupf;
-}
-
-/*--------------------------------------------------------------*/
-/* Find the path from a clock back to all inputs or flop	*/
-/* outputs.  This list will be used to find nodes that are	*/
-/* common to other clocks.					*/
-/*--------------------------------------------------------------*/
-
-void
-find_clock_source(connptr testlink, btptr *clocklist, short dir)
-{
-    netptr clknet;
-    connptr driver, iinput;
-    instptr iupstream;
-    btptr newclock;
-    short newdir;
-
-    /* Add this connection record to clocklist */
-
-    newclock = (btptr)malloc(sizeof(btdata));
-    newclock->delay = 0.0;
-    newclock->trans = 0.0;
-    newclock->dir = dir;
-    newclock->refcnt = 1;
-    newclock->receiver = testlink;
-    newclock->next = *clocklist;
-    *clocklist = newclock;
-
-    clknet = testlink->refnet;
-    driver = clknet->driver;
-    if (driver == NULL) return;			/* Reached a module input */
-    iupstream = driver->refinst;
-
-    if (iupstream == NULL) return;		/* Not supposed to happen? */
-    if (driver->refpin->type & DFFOUT) return;	/* Reached a flop output */
-
-    for (iinput = iupstream->in_connects; iinput; iinput = iinput->next) {
-	newdir = calc_dir(iinput->refpin, dir);
-	find_clock_source(iinput, clocklist, newdir);
-    }
-}
-
-/*--------------------------------------------------------------*/
-/* Find a net that is common to both "clocklist" and		*/
-/* "clock2list".  If one exists, return a pointer to the	*/
-/* connection.							*/
-/*--------------------------------------------------------------*/
-
-netptr find_common_clock(btptr clocklist, btptr clock2list)
-{
-    btptr srch1ptr, srch2ptr;
-
-    for (srch1ptr = clocklist; srch1ptr; srch1ptr = srch1ptr->next)
-        for (srch2ptr = clock2list; srch2ptr; srch2ptr = srch2ptr->next)
-	    if (srch1ptr->receiver->refnet == srch2ptr->receiver->refnet)
-		return srch1ptr->receiver->refnet;
-
-    return NULL;
-}
-
-/*--------------------------------------------------------------*/
-/* Determine the delay to a clock pin from the farthest point	*/
-/* back in the network, either to an input pin or the output of	*/
-/* another flop (e.g., a ripple counter).  If there is more	*/
-/* than one such source (which can happen with, say, a gated	*/
-/* clock, because this routine will not differentiate between	*/
-/* the clock signal and the gating signal), then all sources	*/
-/* recorded (it is only necessary to find a common root of all	*/
-/* other related clocks downstream).				*/
-/*								*/
-/* This is a recursive routine, continuing to find all delays	*/
-/* through the circuit until it reaches "terminal".  The 	*/
-/* "delaylist" linked list is not modified by this routine.	*/
-/*--------------------------------------------------------------*/
-
-void
-find_clock_delay(int dir, double delay, double trans, connptr receiver,
-		btptr clocklist, connptr terminal, char minmax) {
-
-    pinptr  testpin;
-    netptr  loadnet;
-    cellptr testcell;
-    instptr testinst;
-    btptr   testbtdata, newbtdata;
-    double  newdelayr, newdelayf, newtransr, newtransf;
-    short   outdir;
-    int	    i;
-
-    testpin = receiver->refpin;
-
-    // Stop when receiver matches terminal.
-
-    if (receiver != terminal) {
-
-	testinst = receiver->refinst;
-	testcell = (testpin) ? testpin->refcell : NULL;
-
-	// Don't follow signal through any DFF pins
-	if (testcell && (testcell->type & DFF)) return;
-
-	// Compute delay from gate input to output
-
-	outdir = calc_dir(testpin, dir);
-	if (outdir & RISING) {
-	    newdelayr = delay + calc_prop_delay(trans, receiver, RISING, minmax);
-	    newtransr = calc_transition(trans, receiver, RISING, minmax);
-	}
-	if (outdir & FALLING) {
-	    newdelayf = delay + calc_prop_delay(trans, receiver, FALLING, minmax);
-	    newtransf = calc_transition(trans, receiver, FALLING, minmax);
-	}
-
-	loadnet = (testinst) ? testinst->out_connects->refnet : NULL;
-	if (loadnet != NULL) {
-	    for (i = 0; i < loadnet->fanout; i++) {
-		if (outdir & RISING)
-		    find_clock_delay(RISING, newdelayr, newtransr, loadnet->receivers[i],
-				clocklist, terminal, minmax);
-		if (outdir & FALLING)
-		    find_clock_delay(FALLING, newdelayf, newtransf, loadnet->receivers[i],
-				clocklist, terminal, minmax);
-	    }
-	}
-    }
-    else {
-
-	/* Determine if receiver is in clocklist */
-	for (testbtdata = clocklist; testbtdata; testbtdata = testbtdata->next) {
-	    if (testbtdata->receiver == receiver) {
-		/* Is delay greater than that already recorded?  If so, replace it */
-		if (minmax == MAXIMUM_TIME) {
-		    if (delay > testbtdata->delay) {
-			testbtdata->delay = delay;
-			testbtdata->trans = trans;
-			testbtdata->dir = dir;
-		    }
-		}
-		else {
-		    if (delay < testbtdata->delay) {
-			testbtdata->delay = delay;
-			testbtdata->trans = trans;
-			testbtdata->dir = dir;
-		    }
-		}
-		break;
-	    }
-	}
-    }
-}
-
-/*--------------------------------------------------------------*/
-/* Determine the delay from input to output through a gate	*/
-/*								*/
-/* This is a recursive routine, continuing to find all delays	*/
-/* through the circuit until it reaches a terminal or flop	*/
-/* input.  It is similar to find_clock_delay, but stops on all	*/
-/* terminal points found in the path, rather than stopping on	*/
-/* a specific connection.					*/
-/*								*/
-/* Also unlike find_clock_delay, the routine keeps a running	*/
-/* record of the path followed from the source, as a character	*/
-/* string.  When a terminal is found, the path and delay are	*/
-/* saved and added to "delaylist".  After the recursive search,	*/
-/* "delaylist" contains a list of all paths starting from the	*/
-/* original connection "receiver" and ending on a clock or an	*/
-/* output pin.  Where multiple paths exist between source and	*/
-/* destination, only the path with the longest delay is kept.	*/
-/*								*/
-/* Return the number of new paths recorded.			*/
-/*--------------------------------------------------------------*/
-
-int find_path_delay(int dir, double delay, double trans, connptr receiver,
-		btptr backtrace, ddataptr *delaylist, char minmax) {
-
-    pinptr   testpin;
-    netptr   loadnet;
-    cellptr  testcell;
-    instptr  testinst;
-    btptr    newbtdata, freebt, testbt;
-    ddataptr testddata, newddata;
-    double   newdelayr, newdelayf, newtransr, newtransf;
-    short    outdir;
-    char     replace;
-    int	     i, numpaths;
-
-    numpaths = 0;
-    testpin = receiver->refpin;
-
-    // Prevent exhaustive search by stopping on a metric.  Note that the
-    // nonlinear table-based delay data requires an exhaustive search;
-    // generally, the tables can be assumed to be monotonic, in which case
-    // we can stop if the delay is less than the greatest delay recorded
-    // at this point AND the transition time is less than the transition
-    // time recorded along with that delay.  A more relaxed metric is to
-    // use the delay plus the transition time, and an even more relaxed
-    // metric is to use only the delay.  Any relaxing of the metric
-    // implies that the final result may not be the absolute maximum delay,
-    // although it will typically vary by less than an average gate delay.
-
-    if (!exhaustive) {
-	if (minmax == MAXIMUM_TIME) {
-	    if (delay <= receiver->metric)
-		return numpaths;
-	}
-	else {
-	    if (delay >= receiver->metric)
-		return numpaths;
-	}
-    }
-
-    // Check for a logic loop, and truncate the path to avoid infinite
-    // looping in the path search.
-
-    if (receiver->tag == (ddataptr)(-1)) return numpaths;
-    else if (receiver->tag == NULL) receiver->tag = (ddataptr)(-1);
-
-    // Record this position and delay/transition information
-
-    newbtdata = (btptr)malloc(sizeof(btdata));
-    newbtdata->delay = delay;
-    newbtdata->trans = trans;
-    newbtdata->dir = dir;
-    newbtdata->receiver = receiver;
-    newbtdata->refcnt = 1;
-    newbtdata->next = backtrace;
-
-    // Stop when we hit a module output pin or any flop/latch input.
-    // We must allow the routine to pass through the 1st register clock (on the first
-    // time through, backtrace is NULL).
-
-    if ((backtrace == NULL) || (testpin && ((testpin->type & REGISTER_IN) == 0))) {
-
-	testinst = receiver->refinst;
-	testcell = (testpin) ? testpin->refcell : NULL;
-
-	// Compute delay from gate input to output
-
-	outdir = calc_dir(testpin, dir);
-	if (outdir & RISING) {
-	    newdelayr = delay + calc_prop_delay(trans, receiver, RISING, minmax);
-	    newtransr = calc_transition(trans, receiver, RISING, minmax);
-	}
-	if (outdir & FALLING) {
-	    newdelayf = delay + calc_prop_delay(trans, receiver, FALLING, minmax);
-	    newtransf = calc_transition(trans, receiver, FALLING, minmax);
-	}
-
-	loadnet = (testinst) ? testinst->out_connects->refnet : receiver->refnet;
-	for (i = 0; i < loadnet->fanout; i++) {
-	    if (outdir & RISING)
-		numpaths += find_path_delay(RISING, newdelayr, newtransr,
-			loadnet->receivers[i], newbtdata, delaylist, minmax);
-	    if (outdir & FALLING)
-		numpaths += find_path_delay(FALLING, newdelayf, newtransf,
-			loadnet->receivers[i], newbtdata, delaylist, minmax);
-	}
-	receiver->tag = NULL;
-    }
-    else {
-
-	/* Is receiver already in delaylist? */
-	if ((receiver->tag != (ddataptr)(-1)) && (receiver->tag != NULL)) {
-
-	    /* Position in delaylist is recorded in tag field */
-	    testddata = receiver->tag;
-
-	    if (testddata->backtrace->receiver == receiver) {
-		replace = 0;
-		if (minmax == MAXIMUM_TIME) {
-		    /* Is delay greater than that already recorded?  If so, replace it */
-		    if (delay > testddata->backtrace->delay)
-			replace = 1;
-		}
-		else {
-		    /* Is delay less than that already recorded?  If so, replace it */
-		    if (delay < testddata->backtrace->delay)
-			replace = 1;
-		}
-		if (replace) {
-	
-		    /* Remove the existing path record and replace it */
-		    while (testddata->backtrace != NULL) {
-			freebt = testddata->backtrace;
-			testddata->backtrace = testddata->backtrace->next;
-		 	freebt->refcnt--;
-			if (freebt->refcnt <= 0) free(freebt);
-		    }
-		    testddata->backtrace = newbtdata;
-
-		    /* Increment the refcounts along the backtrace */
-		    for (testbt = newbtdata; testbt; testbt = testbt->next)
-			testbt->refcnt++;
-		}
-	    }
-	    else
-		fprintf(stderr, "ERROR:  Bad endpoint tag!\n");
-	}
-	else
-	    testddata = NULL;
-
-	// If we have found a propagation path from source to dest,
-	// record it in delaylist.
-
-	if (testddata == NULL) {
-	    numpaths++;
-	    newddata = (ddataptr)malloc(sizeof(delaydata));
-	    newddata->delay = 0.0;
-	    newddata->trans = 0.0;
-	    newddata->backtrace = newbtdata;
-	    newddata->next = *delaylist;
-	    *delaylist = newddata;
-
-	    /* Mark the receiver as having been visited */
-	    receiver->tag = *delaylist;
-
-	    /* Increment the refcounts along the backtrace */
-	    for (testbt = newbtdata; testbt; testbt = testbt->next)
-		testbt->refcnt++;
-	}
-
-    }
-
-    receiver->metric = delay;
-    newbtdata->refcnt--;
-    if (newbtdata->refcnt <= 0) free(newbtdata);
-    return numpaths;
-}
-
-/*--------------------------------------------------------------*/
-/* Search the list "clocklist" for all points that are module	*/
-/* inputs or flop outputs, and compute the worst-case		*/
-/* transition time downstream at testlink.			*/
-/* 								*/
-/* Return a pointer to the ddataptr entry that contains the	*/
-/* worst-case transition time.					*/
-/*--------------------------------------------------------------*/
-
-btptr find_clock_transition(btptr clocklist, connptr testlink, short dir, char minmax)
-{
-    btptr testclock, testlinkptr, resetclock;
-    connptr testconn;
-    double tdriver;
-
-    // Find out where testlink is in clocklist, and save the position.
-
-    for (testclock = clocklist; testclock; testclock = testclock->next) {
-	if (testclock->receiver == testlink) {
-	    testlinkptr = testclock;
-	    break;
-	}
-    }
-    if (testclock == NULL) return NULL;	// Error---testlink wasn't in clocklist!
-
-    for (testclock = clocklist; testclock; testclock = testclock->next) {
-	testconn = testclock->receiver;
-	tdriver = 0.0;		// to-do:  set to default input transition time
-	find_clock_delay(testlinkptr->dir, 0.0, tdriver, testconn, clocklist, testlink,
-			minmax);
-    }
-
-    // Return the linkptr containing the recorded transition time from
-    // source to destination clock pins
-
-    return testlinkptr;
-}
-
-/*--------------------------------------------------------------*/
-/* Given an instance record, find the pin of the instance that	*/
-/* is the clock, if the instance is a flop.  If the instance is	*/
-/* not a flop, return NULL.					*/
-/*--------------------------------------------------------------*/
-
-connptr find_register_clock(instptr testinst)
-{
-    connptr testconn;
-
-    for (testconn = testinst->in_connects; testconn; testconn = testconn->next)
-	if (testconn->refpin && (testconn->refpin->type & DFFCLK))
-	    return testconn;
-
-    return NULL;
-}
-
-/*--------------------------------------------------------------*/
-/* Given an edge direction (RISING or FALLING) at a source net,	*/
-/* and given a destination net, find the sense of the signal	*/
-/* when it arrives at the destination net.			*/
-/*--------------------------------------------------------------*/
-
-short find_edge_dir(short dir, netptr sourcenet, netptr destnet) {
-    int i;
-    short outdir, rdir;
-    connptr testconn, nextconn;
-    instptr testinst;
-    netptr nextnet;
-
-    for (i = 0; i < sourcenet->fanout; i++) {
-	testconn = sourcenet->receivers[i];
-	testinst = testconn->refinst;
-	if (testinst == NULL) continue;
-	if (testconn->refpin == NULL) continue;
-	if ((testconn->refpin->type & REGISTER_IN) != 0) continue;
-	nextconn = testinst->out_connects;
-	nextnet  = nextconn->refnet;
-	outdir = calc_dir(testconn->refpin, dir);
-	if (nextnet == destnet) return outdir;
-
-	rdir = find_edge_dir(outdir, nextnet, destnet);
-	if (rdir != 0) return rdir;
-    }
-    return 0;
-}
-
-/*--------------------------------------------------------------*/
-/* Search all paths from the clocked data outputs of		*/
-/* "clockedlist" to either output pins or data inputs of other	*/
-/* flops.							*/
-/*								*/
-/* Return a master list of all backtraces in "masterlist".	*/
-/*								*/
-/* Return value is the number of paths recorded in masterlist.	*/
-/*								*/
-/* If minmax == MAXIMUM_TIME, return the maximum delay.		*/
-/* If minmax == MINIMUM_TIME, return the minimum delay.		*/
-/*--------------------------------------------------------------*/
-
-int find_clock_to_term_paths(connlistptr clockedlist, ddataptr *masterlist,
-		struct hashlist *nethash[], char minmax)
-{
-    netptr	commonclock, testnet;
-    connptr     testconn, thisconn;
-    connlistptr testlink;
-    pinptr      testpin;
-    cellptr     testcell;
-    instptr     testinst;
-    btptr 	clocklist, clock2list, backtrace, freebt;
-    btptr	selectedsource, selecteddest;
-    ddataptr    delaylist, testddata;
-    ddataptr	freeddata;
-
-    short	srcdir, destdir;		// Signal direction in/out
-    double	tdriver, setupdelay, holddelay;
-    char	clk_sense_inv, clk_invert;
-    int		numpaths, n, i;
-
-    delaylist = NULL;
-    clocklist = NULL;
-    clock2list = NULL;
-
-    numpaths = 0;
-    for (testlink = clockedlist; testlink; testlink = testlink->next) {
-
-	// Remove all tags and reset delay metrics before each run
-
-	testnet = (netptr)HashFirst(nethash);
-	while (testnet != NULL) {
-	    for (i = 0; i < testnet->fanout; i++) {
-		testconn = testnet->receivers[i];
-		testconn->tag = NULL;
-		if (minmax == MAXIMUM_TIME)
-		    testconn->metric = -1.0;
-		else
-		    testconn->metric = 1E50;
-	    }
-	    testnet = (netptr)HashNext(nethash);
-	}
-
-	thisconn = testlink->connection;
-	testpin = thisconn->refpin;
-	if (testpin) {
-	    testcell = testpin->refcell;
-
-	    // Sense is positive for rising edge-triggered flops, negative for
-	    // falling edge-triggered flops
-	    srcdir = (testcell->type & CLK_SENSE_MASK) ? FALLING : RISING;
-
-	    // Find the sources of the clock at the path start
-	    find_clock_source(thisconn, &clocklist, srcdir);
-
-	    // Find the clock source with the worst-case transition time at testlink
-	    // (Note:  For maximum path delay, find minimum clock transistion, and vice versa)
-	    selectedsource = find_clock_transition(clocklist, thisconn, srcdir, ~minmax);
-	    if (selectedsource == NULL)
-		tdriver = 0.0;
-	    else
-		tdriver = selectedsource->trans;
-
-	    // Report on paths and their maximum delays
-	    if (verbose > 0)
-		fprintf(stdout, "Paths starting at flop \"%s\" clock:\n\n",
-				thisconn->refinst->name);
-
-	}
-	else {
-	    // Connection is an input pin;  must calculate both rising and falling edges.
-	    srcdir = EITHER;
-	    tdriver = 0.0;	// To-do: use designated input transition time
-
-	    // Report on paths and their maximum delays
-	    if (verbose > 0)
-		fprintf(stdout, "Paths starting at input pin \"%s\"\n\n",
-				thisconn->refnet->name);
-	}
-
-	if (verbose > 0) fflush(stdout);
-
-	// Find all paths from "thisconn" to output or a flop input, and compute delay
-	n = find_path_delay(srcdir, 0.0, tdriver, thisconn, NULL, &delaylist, minmax);
-	numpaths += n;
-
-	if (verbose > 0) fprintf(stdout, "%d paths traced (%d total).\n\n", n, numpaths);
-
-	for (testddata = delaylist; testddata; testddata = testddata->next) {
-	    // Copy last backtrace delay to testddata.
-	    testddata->delay = testddata->backtrace->delay;
-	    testddata->trans = testddata->backtrace->trans;
-	    testinst = testddata->backtrace->receiver->refinst;
-
-	    if (testinst != NULL) {
-		// Find the sources of the clock at the path end
-		destdir = (testinst->refcell->type & CLK_SENSE_MASK) ? FALLING : RISING;
-		testconn = find_register_clock(testinst);
-		find_clock_source(testconn, &clock2list, destdir);
-		selecteddest = find_clock_transition(clock2list, testconn, destdir, ~minmax);
-
-		// Find the connection that is common to both clocks
-		commonclock = find_common_clock(clocklist, clock2list);
-		if (commonclock == NULL) {
-		    // Warn about asynchronous clock sources
-		    if (verbose > 0) {
-			fflush(stdout);
-			fprintf(stderr, "Independent clock nets \"%s\" and \"%s\""
-				" drive related gates!\n",
-				testconn->refnet->name, thisconn->refnet->name);
-		    }
-		    clk_invert = -1;
-		}
-		else {
-		    // Add or subtract difference in arrival times between source and
-		    // destination clocks
-
-		    if (selecteddest != NULL && selectedsource != NULL) {
-			testddata->delay += selecteddest->delay;
-			testddata->delay -= selectedsource->delay;
-
-			/* Check if the clock signal arrives at both flops with the	*/
-			/* same edge type (both rising or both falling).		*/
-
-			clk_invert = (find_edge_dir(RISING, commonclock,
-						selectedsource->receiver->refnet) ==
-					find_edge_dir(RISING, commonclock,
-						selecteddest->receiver->refnet)) ? 0 : 1;
-		    }
-
-		    if (minmax == MAXIMUM_TIME) {
-			// Add setup time for destination clocks
-			setupdelay = calc_setup_time(testddata->trans,
-					testddata->backtrace->receiver->refpin,
-					selecteddest->trans,
-					testddata->backtrace->dir, minmax);
-			testddata->delay += setupdelay;
-		    }
-		    else {
-			// Subtract hold time for destination clocks
-			holddelay = calc_hold_time(testddata->trans,
-					testddata->backtrace->receiver->refpin,
-					selecteddest->trans,
-					testddata->backtrace->dir, minmax);
-			testddata->delay -= holddelay;
-		    }
-
-		    if (verbose > 0)
-			fprintf(stdout, "Path terminated on flop \"%s\" input with max delay %g ps\n",
-				testconn->refinst->name, testddata->delay);
-
-		    for (backtrace = testddata->backtrace; backtrace->next;
-				backtrace = backtrace->next) {
-			if (verbose > 0)
-			    fprintf(stdout, "   %g (%s) %s/%s -> %s/%s\n",
-					backtrace->delay,
-					backtrace->receiver->refnet->name,
-					backtrace->receiver->refnet->driver->refinst->name,
-					backtrace->receiver->refnet->driver->refpin->name,
-					backtrace->receiver->refinst->name,
-					backtrace->receiver->refpin->name);
-		    }
-		    if (verbose > 0)
-			fprintf(stdout, "   000.000 (%s) %s/%s -> %s/%s\n",
-				backtrace->receiver->refnet->name,
-				backtrace->receiver->refinst->name,
-				backtrace->receiver->refpin->name,
-				backtrace->receiver->refinst->name,
-				backtrace->receiver->refinst->out_connects->refpin->name);
-
-		    if (selecteddest != NULL && selectedsource != NULL) {
-			if (verbose > 0) {
-			    if (selectedsource->receiver->refnet != selecteddest->receiver->refnet) {
-				fprintf(stdout, "   %g %s to %s clock skew\n",
-					selecteddest->delay - selectedsource->delay,
-					selectedsource->receiver->refnet->name,
-					selecteddest->receiver->refnet->name);
-			    }
-			}
-
-			/* Check if the flops have the same clock sense */
-			/* (both are clock rising edge or both are clock falling edge type) */
-
-			if ((testinst->refcell->type & CLK_SENSE_MASK) !=
-					(backtrace->receiver->refinst->refcell->type
-					& CLK_SENSE_MASK))
-			    clk_sense_inv = 1;
-			else
-			    clk_sense_inv = 0;
-
-			/* If the two flops don't clock at the same time, then issue a	*/
-			/* warning that the slack time loses half a clock period.	*/
-
-			if ((verbose > 0) && (clk_invert != -1) && (clk_sense_inv != clk_invert)) {
-			    fprintf(stdout, "   Clocks are inverted relative to one another,\n");
-			    fprintf(stdout, "   implying a maximum propagation delay of 1/2 period.\n");
-			}
-		    }
-		    if (selecteddest != NULL && selectedsource != NULL) {
-			if (verbose > 0) {
-			    if (minmax == MAXIMUM_TIME)
-				fprintf(stdout, "   %g setup time at destination\n", setupdelay);
-			    else
-				fprintf(stdout, "   %g hold time at destination\n", holddelay);
-			}
-		    }
-
-		    if (verbose > 0) fprintf(stdout, "\n");
-		}
-	    }
-	    else if (verbose > 0) {
-		fprintf(stdout, "Path terminated on output \"%s\" with max delay %g ps\n",
-				testddata->backtrace->receiver->refnet->name, testddata->delay);
-
-		backtrace = testddata->backtrace;
-		fprintf(stdout, "   %g (%s) %s/%s -> [output pin]\n",
-			backtrace->delay,
-			backtrace->receiver->refnet->name,
-			backtrace->receiver->refnet->driver->refinst->name,
-			backtrace->receiver->refnet->driver->refpin->name);
-
-		for (backtrace = backtrace->next; backtrace->next; backtrace = backtrace->next) {
-		    fprintf(stdout, "   %g (%s) %s/%s -> %s/%s\n",
-				backtrace->delay,
-				backtrace->receiver->refnet->name,
-				backtrace->receiver->refnet->driver->refinst->name,
-				backtrace->receiver->refnet->driver->refpin->name,
-				backtrace->receiver->refinst->name,
-				backtrace->receiver->refpin->name);
-		}
-		fprintf(stdout, "   000.000 (%s) %s/%s -> %s/%s\n\n",
-			backtrace->receiver->refnet->name,
-			backtrace->receiver->refinst->name,
-			backtrace->receiver->refpin->name,
-			backtrace->receiver->refinst->name,
-			backtrace->receiver->refinst->out_connects->refpin->name);
-	    }
-
-	    // Clean up clock2list
-	    while (clock2list != NULL) {
-		freebt = clock2list;
-		clock2list = clock2list->next;
-		free(freebt);
-	    }
-	}
-
-	// Link delaylist data to the beginning of masterlist, and null out
-	// delaylist for the next set of paths.
-
-	if (delaylist) {
-	    for (testddata = delaylist; testddata->next; testddata = testddata->next);
-	    testddata->next = *masterlist;
-	    *masterlist = delaylist;
-	    delaylist = NULL;
-	}
-
-	// Free up clocklist
-	while (clocklist != NULL) {
-	    freebt = clocklist;
-	    clocklist = clocklist->next;
-	    free(freebt);
-	}
-    }
-    return numpaths;
-}
-
-/*--------------------------------------------------------------*/
-/* Parse a table variable type from a liberty format file	*/
-/*--------------------------------------------------------------*/
-
-int get_table_type(char *token) {
-    if (!strcasecmp(token, "input_net_transition"))
-	return TRANSITION_TIME;
-    else if (!strcasecmp(token, "total_output_net_capacitance"))
-	return OUTPUT_CAP;
-    else if (!strcasecmp(token, "related_pin_transition"))
-	return RELATED_TIME;
-    else if (!strcasecmp(token, "constrained_pin_transition"))
-	return CONSTRAINED_TIME;
-    else
-	return UNKNOWN;
-}
-
-/*--------------------------------------------------------------*/
-/* Read a liberty format file and collect information about	*/
-/* the timing properties of each standard cell.			*/
-/*--------------------------------------------------------------*/
-
-void
-libertyRead(FILE *flib, lutable **tablelist, cell **celllist)
-{
-    char *token;
-    char *libname = NULL;
-    int section = INIT;
-
-    double time_unit = 1.0;	// Time unit multiplier, to get ps
-    double cap_unit = 1.0;	// Capacitive unit multiplier, to get fF
-
-    pinptr testpin;
-    lutable *tableptr;
-
-    int i, j;
-    double gval;
-    char *iptr;
-    short timing_type, sense_type;
-
-    lutable *newtable, *reftable;
-    cell *newcell, *lastcell;
-    pin *newpin;
-
-    lastcell = NULL;
-    timing_type = UNKNOWN;
-
-    /* Read tokens off of the line */
-    token = advancetoken(flib, 0);
-
-    while (token != NULL) {
-
-	switch (section) {
-	    case INIT:
-		if (!strcasecmp(token, "library")) {
-		    token = advancetoken(flib, 0);
-		    if (strcmp(token, "("))
-			fprintf(stderr, "Library not followed by name\n");
-		    else
-			token = advancetoken(flib, ')');
-		    fprintf(stderr, "Parsing library \"%s\"\n", token);
-		    libname = strdup(token);
-		    token = advancetoken(flib, 0);
-		    if (strcmp(token, "{")) {
-			fprintf(stderr, "Did not find opening brace "
-					"on library block\n");
-			exit(1);
-		    }
-		    section = LIBBLOCK;
-		}
-		else
-		    fprintf(stderr, "Unknown input \"%s\", looking for "
-					"\"library\"\n", token);
-		break;
-
-	    case LIBBLOCK:
-		// Here we check for the main blocks, again not rigorously. . .
-
-		if (!strcasecmp(token, "}")) {
-		    fprintf(stdout, "End of library at line %d\n", fileCurrentLine);
-		    section = INIT;			// End of library block
-		}
-		else if (!strcasecmp(token, "delay_model")) {
-		    token = advancetoken(flib, 0);
-		    if (strcmp(token, ":"))
-			fprintf(stderr, "Input missing colon\n");
-		    token = advancetoken(flib, ';');
-		    if (strcasecmp(token, "table_lookup")) {
-			fprintf(stderr, "Sorry, only know how to "
-					"handle table lookup!\n");
-			exit(1);
-		    }
-		}
-		else if (!strcasecmp(token, "lu_table_template") ||
-			 !strcasecmp(token, "power_lut_template")) {
-		    // Read in template information;
-		    newtable = (lutable *)malloc(sizeof(lutable));
-		    newtable->name = NULL;
-		    newtable->invert = 0;
-		    newtable->var1 = UNKNOWN;
-		    newtable->var2 = UNKNOWN;
-		    newtable->size1 = 0;
-		    newtable->size2 = 0;
-		    newtable->idx1.times = NULL;
-		    newtable->idx2.caps = NULL;
-		    newtable->values = NULL;
-		    newtable->next = *tablelist;
-		    *tablelist = newtable;
-
-		    token = advancetoken(flib, 0);
-		    if (strcmp(token, "("))
-			fprintf(stderr, "Input missing open parens\n");
-		    else
-			token = advancetoken(flib, ')');
-		    newtable->name = strdup(token);
-		    while (*token != '}') {
-			token = advancetoken(flib, 0);
-			if (!strcasecmp(token, "variable_1")) {
-			    token = advancetoken(flib, 0);
-			    token = advancetoken(flib, ';');
-			    newtable->var1 = get_table_type(token);
-			    if (newtable->var1 == OUTPUT_CAP || newtable->var1 == CONSTRAINED_TIME)
-				newtable->invert = 1;
-			}
-			else if (!strcasecmp(token, "variable_2")) {
-			    token = advancetoken(flib, 0);
-			    token = advancetoken(flib, ';');
-			    newtable->var2 = get_table_type(token);
-			    if (newtable->var2 == TRANSITION_TIME || newtable->var2 == RELATED_TIME)
-				newtable->invert = 1;
-			}
-			else if (!strcasecmp(token, "index_1")) {
-			    token = advancetoken(flib, 0);	// Open parens
-			    token = advancetoken(flib, 0);	// Quote
-			    if (!strcmp(token, "\""))
-				token = advancetoken(flib, '\"');
-
-			    if (newtable->invert == 1) {
-				// Count entries
-				iptr = token;
-				newtable->size2 = 1;
-				while ((iptr = strchr(iptr, ',')) != NULL) {
-				    iptr++;
-				    newtable->size2++;
-				}
-				newtable->idx2.caps = (double *)malloc(newtable->size2 *
-					sizeof(double));
-				newtable->size2 = 0;
-				iptr = token;
-				sscanf(iptr, "%lg", &newtable->idx2.caps[0]);
-				if (newtable->var2 == OUTPUT_CAP)
-				    newtable->idx2.caps[0] *= cap_unit;
-				else
-				    newtable->idx2.caps[0] *= time_unit;
-
-				while ((iptr = strchr(iptr, ',')) != NULL) {
-				    iptr++;
-				    newtable->size2++;
-				    sscanf(iptr, "%lg",
-						&newtable->idx2.caps[newtable->size2]);
-				    if (newtable->var2 == OUTPUT_CAP)
-					newtable->idx2.caps[newtable->size2] *= cap_unit;
-				    else
-					newtable->idx2.cons[newtable->size2] *= time_unit;
-				}
-				newtable->size2++;
-			    }
-			    else {	// newtable->invert = 0
-				// Count entries
-				iptr = token;
-				newtable->size1 = 1;
-				while ((iptr = strchr(iptr, ',')) != NULL) {
-				    iptr++;
-				    newtable->size1++;
-				}
-				newtable->idx1.times = (double *)malloc(newtable->size1 *
-					sizeof(double));
-				newtable->size1 = 0;
-				iptr = token;
-				sscanf(iptr, "%lg", &newtable->idx1.times[0]);
-				newtable->idx1.times[0] *= time_unit; 
-				while ((iptr = strchr(iptr, ',')) != NULL) {
-				    iptr++;
-				    newtable->size1++;
-				    sscanf(iptr, "%lg",
-						&newtable->idx1.times[newtable->size1]);
-				    newtable->idx1.times[newtable->size1] *= time_unit;
-				}
-				newtable->size1++;
-			    }
-
-			    token = advancetoken(flib, ';'); // EOL semicolon
-			}
-			else if (!strcasecmp(token, "index_2")) {
-			    token = advancetoken(flib, 0);	// Open parens
-			    token = advancetoken(flib, 0);	// Quote
-			    if (!strcmp(token, "\""))
-				token = advancetoken(flib, '\"');
-
-			    if (newtable->invert == 0) {
-				// Count entries
-				iptr = token;
-				newtable->size2 = 1;
-				while ((iptr = strchr(iptr, ',')) != NULL) {
-				    iptr++;
-				    newtable->size2++;
-				}
-				newtable->idx2.caps = (double *)malloc(newtable->size2 *
-					sizeof(double));
-				newtable->size2 = 0;
-				iptr = token;
-				sscanf(iptr, "%lg", &newtable->idx2.caps[0]);
-				if (newtable->var2 == OUTPUT_CAP)
-				    newtable->idx2.caps[0] *= cap_unit;
-				else
-				    newtable->idx2.cons[0] *= time_unit;
-				while ((iptr = strchr(iptr, ',')) != NULL) {
-				    iptr++;
-				    newtable->size2++;
-				    sscanf(iptr, "%lg",
-						&newtable->idx2.caps[newtable->size2]);
-				    if (newtable->var2 == OUTPUT_CAP)
-					newtable->idx2.caps[newtable->size2] *= cap_unit;
-				    else
-					newtable->idx2.cons[newtable->size2] *= time_unit;
-				}
-				newtable->size2++;
-			    }
-			    else { 	// newtable->invert == 1
-				// Count entries
-				iptr = token;
-				newtable->size1 = 1;
-				while ((iptr = strchr(iptr, ',')) != NULL) {
-				    iptr++;
-				    newtable->size1++;
-				}
-				newtable->idx1.times = (double *)malloc(newtable->size1 *
-					sizeof(double));
-				newtable->size1 = 0;
-				iptr = token;
-				sscanf(iptr, "%lg", &newtable->idx1.times[0]);
-				newtable->idx1.times[0] *= time_unit;
-				while ((iptr = strchr(iptr, ',')) != NULL) {
-				    iptr++;
-				    newtable->size1++;
-				    sscanf(iptr, "%lg",
-						&newtable->idx1.times[newtable->size1]);
-				    newtable->idx1.times[newtable->size1] *= time_unit;
-				}
-				newtable->size1++;
-			    }
-
-			    token = advancetoken(flib, ';'); // EOL semicolon
-			}
-		    }
-		}
-		else if (!strcasecmp(token, "cell")) {
-		    newcell = (cell *)malloc(sizeof(cell));
-		    newcell->next = NULL;
-		    if (lastcell != NULL)
-			lastcell->next = newcell;
-		    else
-			*celllist = newcell;
-		    lastcell = newcell;
-		    token = advancetoken(flib, 0);	// Open parens
-		    if (!strcmp(token, "("))
-			token = advancetoken(flib, ')');	// Cellname
-		    newcell->name = strdup(token);
-		    token = advancetoken(flib, 0);	// Find start of block
-		    if (strcmp(token, "{"))
-			fprintf(stderr, "Error: failed to find start of block\n");
-		    newcell->type = GATE;		// Default type
-		    newcell->function = NULL;
-		    newcell->pins = NULL;
-		    newcell->area = 1.0;
-		    newcell->maxtrans = 0.0;
-		    newcell->maxcap = 0.0;
-		    section = CELLDEF;
-		}
-		else if (!strcasecmp(token, "time_unit")) {
-		   char *metric;
-
-		   token = advancetoken(flib, 0);
-		   if (token == NULL) break;
-		   if (!strcmp(token, ":")) {
-		      token = advancetoken(flib, 0);
-		      if (token == NULL) break;
-		   }
-		   if (!strcmp(token, "\"")) {
-		      token = advancetoken(flib, '\"');
-		      if (token == NULL) break;
-		   }
-		   time_unit = strtod(token, &metric);
-		   if (*metric != '\0') {
-		      if (!strcmp(metric, "ns"))
-			 time_unit *= 1E3;
-		      else if (!strcmp(metric, "us"))
-			 time_unit *= 1E6;
-		      else if (!strcmp(metric, "fs"))
-			 time_unit *= 1E-3;
-		      else if (strcmp(metric, "ps"))
-			 fprintf(stderr, "Don't understand time units \"%s\"\n",
-				token);
-		   }
-		   else {
-		      token = advancetoken(flib, 0);
-		      if (token == NULL) break;
-		      if (!strcmp(token, "ns"))
-			 time_unit *= 1E3;
-		      else if (!strcmp(token, "us"))
-			 time_unit *= 1E6;
-		      else if (!strcmp(token, "fs"))
-			 time_unit *= 1E-3;
-		      else if (strcmp(token, "ps"))
-			 fprintf(stderr, "Don't understand time units \"%s\"\n",
-				token);
-		   }
-		   token = advancetoken(flib, ';');
-		}
-		else if (!strcasecmp(token, "capacitive_load_unit")) {
-		   char *metric;
-
-		   token = advancetoken(flib, 0);
-		   if (token == NULL) break;
-		   if (!strcmp(token, "(")) {
-		      token = advancetoken(flib, ')');
-		      if (token == NULL) break;
-		   }
-		   cap_unit = strtod(token, &metric);
-		   if (*metric != '\0') {
-		      while (isspace(*metric)) metric++;
-		      if (*metric == ',') metric++;
-		      while ((*metric != '\0') && isspace(*metric)) metric++;
-		      if (!strcasecmp(metric, "af"))
-			 cap_unit *= 1E-3;
-		      else if (!strcasecmp(metric, "pf"))
-			 cap_unit *= 1000;
-		      else if (!strcasecmp(metric, "nf"))
-			 cap_unit *= 1E6;
-		      else if (!strcasecmp(metric, "uf"))
-			 cap_unit *= 1E9;
-		      else if (strcasecmp(metric, "ff"))
-			 fprintf(stderr, "Don't understand capacitive units \"%s\"\n",
-				token);
-		   }
-		   else {
-		      token = advancetoken(flib, 0);
-		      if (token == NULL) break;
-		      if (!strcasecmp(token, "af"))
-			 cap_unit *= 1E-3;
-		      else if (!strcasecmp(token, "pf"))
-			 cap_unit *= 1000;
-		      else if (!strcasecmp(token, "nf"))
-			 cap_unit *= 1E6;
-		      else if (!strcasecmp(token, "uf"))
-			 cap_unit *= 1E9;
-		      else if (strcasecmp(token, "ff"))
-			 fprintf(stderr, "Don't understand capacitive units \"%s\"\n",
-				token);
-		   }
-		   token = advancetoken(flib, ';');
-		}
-		else {
-		    // For unhandled tokens, read in tokens.  If it is
-		    // a definition or function, read to end-of-line.  If
-		    // it is a block definition, read to end-of-block.
-		    while (1) {
-			token = advancetoken(flib, 0);
-			if (token == NULL) break;
-			if (!strcmp(token, ";")) break;
-			if (!strcmp(token, "\""))
-			    token = advancetoken(flib, '\"');
-			if (!strcmp(token, "{")) {
-			    token = advancetoken(flib, '}');
-			    break;
-			}
-		    }
-		}
-		break;
-
-	    case CELLDEF:
-
-		if (!strcmp(token, "}")) {
-		    section = LIBBLOCK;			// End of cell def
-		}
-		else if (!strcasecmp(token, "pin")) {
-		    token = advancetoken(flib, 0);	// Open parens
-		    if (!strcmp(token, "("))
-			token = advancetoken(flib, ')');	// Close parens
-
-		    newpin = parse_pin(newcell, token, SENSE_NONE);
-
-		    token = advancetoken(flib, 0);	// Find start of block
-		    if (strcmp(token, "{"))
-			fprintf(stderr, "Error: failed to find start of block\n");
-		    section = PINDEF;
-		}		
-		else if (!strcasecmp(token, "area")) {
-		    token = advancetoken(flib, 0);	// Colon
-		    token = advancetoken(flib, ';');	// To end-of-statement
-		    sscanf(token, "%lg", &newcell->area);
-		}
-		else if (!strcasecmp(token, "ff")) {
-		    newcell->type |= DFF;
-		    token = advancetoken(flib, '{');
-		    section = FLOPDEF;
-		}
-		else if (!strcasecmp(token, "latch")) {
-		    newcell->type |= LATCH;
-		    token = advancetoken(flib, '{');
-		    section = LATCHDEF;
-		}
-		else {
-		    // For unhandled tokens, read in tokens.  If it is
-		    // a definition or function, read to end-of-line.  If
-		    // it is a block definition, read to end-of-block.
-		    while (1) {
-			token = advancetoken(flib, 0);
-			if (token == NULL) break;
-			if (!strcmp(token, ";")) break;
-			if (!strcmp(token, "\""))
-			    token = advancetoken(flib, '\"');
-			if (!strcmp(token, "("))
-			    token = advancetoken(flib, ')');
-			if (!strcmp(token, "{")) {
-			    token = advancetoken(flib, '}');
-			    break;
-			}
-		    }
-		}
-		break;
-
-	    case FLOPDEF:
-
-		if (!strcmp(token, "}")) {
-		    section = CELLDEF;			// End of flop def
-		}
-		else if (!strcasecmp(token, "next_state")) {
-		    token = advancetoken(flib, 0);	// Colon
-		    token = advancetoken(flib, ';');	// To end-of-statement
-		    newpin = parse_pin(newcell, token, SENSE_NONE);
-		    newpin->type |= DFFIN;
-		}
-		else if (!strcasecmp(token, "clocked_on")) {
-		    token = advancetoken(flib, 0);	// Colon
-		    token = advancetoken(flib, ';');	// To end-of-statement
-		    if (strchr(token, '\'') != NULL)
-			newcell->type |= CLK_SENSE_MASK;
-		    else if (strchr(token, '!') != NULL)
-			newcell->type |= CLK_SENSE_MASK;
-		    newpin = parse_pin(newcell, token, SENSE_NONE);
-		    newpin->type |= DFFCLK;
-		}
-		else if (!strcasecmp(token, "clear")) {
-		    newcell->type |= RST_MASK;
-		    token = advancetoken(flib, 0);	// Colon
-		    token = advancetoken(flib, ';');	// To end-of-statement
-		    if (strchr(token, '\'') != NULL)
-			newcell->type |= RST_SENSE_MASK;
-		    else if (strchr(token, '!') != NULL)
-			newcell->type |= RST_SENSE_MASK;
-		    newpin = parse_pin(newcell, token, SENSE_NONE);
-		    newpin->type |= DFFRST;
-		}
-		else if (!strcasecmp(token, "preset")) {
-		    newcell->type |= SET_MASK;
-		    token = advancetoken(flib, 0);	// Colon
-		    token = advancetoken(flib, ';');	// To end-of-statement
-		    if (strchr(token, '\'') != NULL)
-			newcell->type |= SET_SENSE_MASK;
-		    else if (strchr(token, '!') != NULL)
-			newcell->type |= SET_SENSE_MASK;
-		    newpin = parse_pin(newcell, token, SENSE_NONE);
-		    newpin->type |= DFFSET;
-		}
-		else
-		    token = advancetoken(flib, ';');	// Read to end-of-statement
-
-		break;
-
-	    case LATCHDEF:
-
-		if (!strcmp(token, "}")) {
-		    section = CELLDEF;			// End of flop def
-		}
-		else if (!strcasecmp(token, "data_in")) {
-		    token = advancetoken(flib, 0);	// Colon
-		    token = advancetoken(flib, ';');	// To end-of-statement
-		    newpin = parse_pin(newcell, token, SENSE_NONE);
-		    newpin->type |= LATCHIN;
-		}
-		else if (!strcasecmp(token, "enable")) {
-		    token = advancetoken(flib, 0);	// Colon
-		    token = advancetoken(flib, ';');	// To end-of-statement
-		    if (strchr(token, '\'') != NULL)
-			newcell->type |= EN_SENSE_MASK;
-		    else if (strchr(token, '!') != NULL)
-			newcell->type |= EN_SENSE_MASK;
-		    newpin = parse_pin(newcell, token, SENSE_NONE);
-		    newpin->type |= LATCHEN;
-		}
-		else
-		    token = advancetoken(flib, ';');	// Read to end-of-statement
-
-		break;
-
-	    case PINDEF:
-
-		if (!strcmp(token, "}")) {
-		    section = CELLDEF;			// End of pin def
-		}
-		else if (!strcasecmp(token, "capacitance")) {
-		    token = advancetoken(flib, 0);	// Colon
-		    token = advancetoken(flib, ';');	// To end-of-statement
-		    sscanf(token, "%lg", &newpin->capr);
-		    newpin->capr *= cap_unit;
-		}
-		else if (!strcasecmp(token, "rise_capacitance")) {
-		    token = advancetoken(flib, 0);	// Colon
-		    token = advancetoken(flib, ';');	// To end-of-statement
-		    sscanf(token, "%lg", &newpin->capr);
-		    newpin->capr *= cap_unit;
-		}
-		else if (!strcasecmp(token, "fall_capacitance")) {
-		    token = advancetoken(flib, 0);	// Colon
-		    token = advancetoken(flib, ';');	// To end-of-statement
-		    sscanf(token, "%lg", &newpin->capf);
-		    newpin->capf *= cap_unit;
-		}
-		else if (!strcasecmp(token, "function")) {
-		    token = advancetoken(flib, 0);	// Colon
-		    token = advancetoken(flib, 0);	// Open quote
-		    if (!strcmp(token, "\""))
-			token = advancetoken(flib, '\"');	// Find function string
-		    if (newpin->type & OUTPUT) {
-			newcell->function = strdup(token);
-		    }
-		    token = advancetoken(flib, 0);
-		    if (strcmp(token, ";"))
-			fprintf(stderr, "Expected end-of-statement.\n");
-		}
-		else if (!strcasecmp(token, "direction")) {
-		    token = advancetoken(flib, 0);	// Colon
-		    token = advancetoken(flib, ';');
-		    if (!strcasecmp(token, "input")) {
-			newpin->type |= INPUT;
-		    }
-		    else if (!strcasecmp(token, "output")) {
-			newpin->type |= OUTPUT;
-		    }
-		}
-		else if (!strcasecmp(token, "max_transition")) {
-		    token = advancetoken(flib, 0);	// Colon
-		    token = advancetoken(flib, ';');	// To end-of-statement
-		    sscanf(token, "%lg", &newcell->maxtrans);
-		    newcell->maxtrans *= time_unit;
-		}
-		else if (!strcasecmp(token, "max_capacitance")) {
-		    token = advancetoken(flib, 0);	// Colon
-		    token = advancetoken(flib, ';');	// To end-of-statement
-		    sscanf(token, "%lg", &newcell->maxcap);
-		    newcell->maxcap *= cap_unit;
-		}
-		else if (!strcasecmp(token, "timing")) {
-		    token = advancetoken(flib, 0);	// Arguments, if any
-		    if (strcmp(token, "("))
-			fprintf(stderr, "Error: failed to find start of block\n");
-		    else
-		       token = advancetoken(flib, ')');	// Arguments, if any
-		    token = advancetoken(flib, 0);	// Find start of block
-		    if (strcmp(token, "{"))
-			fprintf(stderr, "Error: failed to find start of block\n");
-		    testpin = NULL;
-		    sense_type = SENSE_NONE;
-		    section = TIMING;
-		}
-		else {
-		    // For unhandled tokens, read in tokens.  If it is
-		    // a definition or function, read to end-of-line.  If
-		    // it is a block definition, read to end-of-block.
-		    while (1) {
-			token = advancetoken(flib, 0);
-			if (token == NULL) break;
-			if (!strcmp(token, ";")) break;
-			if (!strcmp(token, "\""))
-			    token = advancetoken(flib, '\"');
-			if (!strcmp(token, "{")) {
-			    token = advancetoken(flib, '}');
-			    break;
-			}
-		    }
-		}
-		break;
-
-	    case TIMING:
-
-		if (!strcmp(token, "}")) {
-		    section = PINDEF;			// End of timing def
-		}
-		else if (!strcasecmp(token, "related_pin")) {
-		    token = advancetoken(flib, 0);	// Colon
-		    token = advancetoken(flib, ';');	// Read to end of statement
-		    // Create the related pin if needed
-		    testpin = parse_pin(newcell, token, sense_type);
-		}
-		else if (!strcasecmp(token, "timing_sense")) {
-		    token = advancetoken(flib, 0);	// Colon
-		    token = advancetoken(flib, ';');	// Read to end of statement
-		    if (!strcasecmp(token, "positive_unate")) {
-			if (testpin)
-			   testpin->sense = SENSE_POSITIVE;
-			else
-			   sense_type = SENSE_POSITIVE;
-		    }
-		    else if (!strcasecmp(token, "negative_unate")) {
-			if (testpin)
-			   testpin->sense = SENSE_NEGATIVE;
-			else
-			   sense_type = SENSE_NEGATIVE;
-		    }
-		    else if (!strcasecmp(token, "non_unate")) {
-			if (testpin)
-			   testpin->sense = SENSE_NONE;
-			else
-			   sense_type = SENSE_NONE;
-		    }
-		}
-		else if (!strcasecmp(token, "timing_type")) {
-		    token = advancetoken(flib, 0);	// Colon
-		    token = advancetoken(flib, ';');	// Read to end of statement
-
-		    // Note:  Timing type is apparently redundant information;
-		    // e.g., "falling_edge" can be determined by "clocked_on : !CLK"
-		    // in the ff {} block.  How reliable is this?
-
-		    if (!strcasecmp(token, "rising_edge"))
-			timing_type = TIMING_PROP_TRANS;
-		    else if (!strcasecmp(token, "falling_edge"))
-			timing_type = TIMING_PROP_TRANS;
-		    else if (!strcasecmp(token, "hold_rising"))
-			timing_type = TIMING_HOLD;
-		    else if (!strcasecmp(token, "hold_falling"))
-			timing_type = TIMING_HOLD;
-		    else if (!strcasecmp(token, "setup_rising"))
-			timing_type = TIMING_SETUP;
-		    else if (!strcasecmp(token, "setup_falling"))
-			timing_type = TIMING_SETUP;
-		    else if (!strcasecmp(token, "clear"))
-			timing_type = TIMING_SET_RESET;
-		    else if (!strcasecmp(token, "preset"))
-			timing_type = TIMING_SET_RESET;
-		    else if (!strcasecmp(token, "recovery_rising"))
-			timing_type = TIMING_RECOVERY;
-		    else if (!strcasecmp(token, "recovery_falling"))
-			timing_type = TIMING_RECOVERY;
-		    else if (!strcasecmp(token, "removal_rising"))
-			timing_type = TIMING_REMOVAL;
-		    else if (!strcasecmp(token, "removal_falling"))
-			timing_type = TIMING_REMOVAL;
-		    else if (!strcasecmp(token, "three_state_enable"))
-			timing_type = TIMING_TRISTATE;
-		    else if (!strcasecmp(token, "three_state_disable"))
-			timing_type = TIMING_TRISTATE;
-		}
-		else if ((!strcasecmp(token, "cell_rise")) ||
-			(!strcasecmp(token, "cell_fall")) ||
-			(!strcasecmp(token, "rise_transition")) ||
-			(!strcasecmp(token, "fall_transition")) ||
-			(!strcasecmp(token, "rise_constraint")) ||
-			(!strcasecmp(token, "fall_constraint"))) {
-
-		    tableptr = (lutable *)malloc(sizeof(lutable));
-		    tableptr->name = NULL;	// Not used
-		    tableptr->invert = 0;
-		    tableptr->var1 = UNKNOWN;
-		    tableptr->var2 = UNKNOWN;
-		    tableptr->size1 = 0;
-		    tableptr->size2 = 0;
-		    tableptr->idx1.times = NULL;
-		    tableptr->idx2.caps = NULL;
-		    tableptr->values = NULL;
-		    tableptr->next = NULL;	// Not used
-
-		    // Note that propagation delays (cell rise, cell fall) and
-		    // transition times (rise transition, fall transition) have
-		    // their lookup tables stored in the "related pin" pin record.
-		    // Setup and hold times (rise constraint, fall constraint)
-		    // have their lookup tables stored in the original pin record.
-		    // These should not overlap.
-
-		    // Recovery and removal tables are not yet handled. . .
-
-		    if (!strcasecmp(token, "cell_rise"))
-			testpin->propdelr = tableptr;
-		    else if (!strcasecmp(token, "cell_fall"))
-			testpin->propdelf = tableptr;
-		    else if (!strcasecmp(token, "rise_transition"))
-			testpin->transr = tableptr;
-		    else if (!strcasecmp(token, "fall_transition"))
-			testpin->transf = tableptr;
-		    else if (!strcasecmp(token, "rise_constraint")) {
-			if (timing_type == TIMING_SETUP)
-			    newpin->propdelr = tableptr;
-			else if (timing_type == TIMING_HOLD)
-			    newpin->transr = tableptr;
-		    }
-		    else if (!strcasecmp(token, "fall_constraint")) {
-			if (timing_type == TIMING_SETUP)
-			    newpin->propdelf = tableptr;
-			else if (timing_type == TIMING_HOLD)
-			    newpin->transf = tableptr;
-		    }
-
-		    token = advancetoken(flib, 0);	// Open parens
-		    if (!strcmp(token, "("))
-			token = advancetoken(flib, ')');
-			
-		    for (reftable = *tablelist; reftable; reftable = reftable->next)
-			if (!strcmp(reftable->name, token))
-			    break;
-		    if (reftable == NULL)
-			fprintf(stderr, "Failed to find a valid table \"%s\"\n",
-				    token);
-		    else {
-			// Fill in default values from template reftable
-			tableptr->invert = reftable->invert;
-			if (reftable->size1 > 0) {
-			    tableptr->var1 = reftable->var1;
-			    tableptr->size1 = reftable->size1;
-			    tableptr->idx1.times = (double *)malloc(tableptr->size1 * sizeof(double));
-			    memcpy(tableptr->idx1.times, reftable->idx1.times,
-						tableptr->size1 * sizeof(double));
-			}
-			if (reftable->size2 > 0) {
-			    tableptr->var2 = reftable->var2;
-			    tableptr->size2 = reftable->size2;
-			    tableptr->idx2.caps = (double *)malloc(tableptr->size2 * sizeof(double));
-			    memcpy(tableptr->idx2.caps, reftable->idx2.caps,
-						tableptr->size2 * sizeof(double));
-			}
-		    }
-
-		    token = advancetoken(flib, 0);
-		    if (strcmp(token, "{"))
-			fprintf(stderr, "Failed to find start of timing block\n");
-
-		    while (*token != '}') {
-		        token = advancetoken(flib, 0);
-		        if (!strcasecmp(token, "index_1")) {
-
-			    // Local index values override those in the template
-
-			    token = advancetoken(flib, 0);	// Open parens
-			    token = advancetoken(flib, 0);	// Quote
-			    if (!strcmp(token, "\""))
-				token = advancetoken(flib, '\"');
-
-			    //-------------------------
-
-			    if (reftable && (reftable->invert == 1)) {
-				// Entries had better match the ref table
-				iptr = token;
-				i = 0;
-				sscanf(iptr, "%lg", &tableptr->idx2.caps[0]);
-				if (tableptr->var2 == OUTPUT_CAP)
-				    tableptr->idx2.caps[0] *= cap_unit;
-				else
-				    tableptr->idx2.cons[0] *= time_unit;
-				while ((iptr = strchr(iptr, ',')) != NULL) {
-				    iptr++;
-				    i++;
-				    sscanf(iptr, "%lg", &tableptr->idx2.caps[i]);
-				    if (tableptr->var2 == OUTPUT_CAP)
-					tableptr->idx2.caps[i] *= cap_unit;
-				    else
-					tableptr->idx2.cons[i] *= time_unit;
-				}
-			    }
-			    else if (reftable && (reftable->invert == 0)) {
-				iptr = token;
-				i = 0;
-				sscanf(iptr, "%lg", &tableptr->idx1.times[0]);
-				tableptr->idx1.times[0] *= time_unit;
-				while ((iptr = strchr(iptr, ',')) != NULL) {
-				    iptr++;
-				    i++;
-				    sscanf(iptr, "%lg", &tableptr->idx1.times[i]);
-				    tableptr->idx1.times[i] *= time_unit;
-				}
-			    }
-
-			    token = advancetoken(flib, ')'); 	// Close paren
-			    token = advancetoken(flib, ';');	// EOL semicolon
-			}
-		        else if (!strcasecmp(token, "index_2")) {
-
-			    // Local index values override those in the template
-
-			    token = advancetoken(flib, 0);	// Open parens
-			    token = advancetoken(flib, 0);	// Quote
-			    if (!strcmp(token, "\""))
-				token = advancetoken(flib, '\"');
-
-			    //-------------------------
-
-			    if (reftable && (reftable->invert == 1)) {
-				// Entries had better match the ref table
-				iptr = token;
-				i = 0;
-				sscanf(iptr, "%lg", &tableptr->idx1.times[0]);
-				tableptr->idx1.times[0] *= time_unit;
-				while ((iptr = strchr(iptr, ',')) != NULL) {
-				    iptr++;
-				    i++;
-				    sscanf(iptr, "%lg", &tableptr->idx1.times[i]);
-				    tableptr->idx1.times[i] *= time_unit;
-				}
-			    }
-			    else if (reftable && (reftable->invert == 0)) {
-				iptr = token;
-				i = 0;
-				sscanf(iptr, "%lg", &tableptr->idx2.caps[0]);
-				tableptr->idx2.caps[0] *= cap_unit;
-				while ((iptr = strchr(iptr, ',')) != NULL) {
-				    iptr++;
-				    i++;
-				    sscanf(iptr, "%lg", &tableptr->idx2.caps[i]);
-				    tableptr->idx2.caps[i] *= cap_unit;
-				}
-			    }
-
-			    token = advancetoken(flib, ')'); 	// Close paren
-			    token = advancetoken(flib, ';');	// EOL semicolon
-			}
-			else if (!strcasecmp(token, "values")) {
-			    token = advancetoken(flib, 0);	
-			    if (strcmp(token, "("))
-				fprintf(stderr, "Failed to find start of"
-						" value table\n");
-			    token = advancetoken(flib, ')');
-
-			    // Parse the string of values and enter it into the
-			    // table "values", which is size size2 x size1
-
-			    if (reftable && reftable->size1 > 0) {
-				int locsize2;
-			        locsize2 = (reftable->size2 > 0) ? reftable->size2 : 1;
-				if (reftable->invert) {
-				    tableptr->values = (double *)malloc(locsize2 *
-						reftable->size1 * sizeof(double));
-				    iptr = token;
-				    for (i = 0; i < reftable->size1; i++) {
-					for (j = 0; j < locsize2; j++) {
-					    while (*iptr == ' ' || *iptr == '\"' ||
-							*iptr == ',')
-						iptr++;
-					    sscanf(iptr, "%lg", &gval);
-					    *(tableptr->values + j * reftable->size1
-							+ i) = gval * time_unit;
-					    while (*iptr != ' ' && *iptr != '\"' &&
-							*iptr != ',')
-						iptr++;
-					}
-				    }
-				}
-				else {
-				    tableptr->values = (double *)malloc(locsize2 *
-						reftable->size1 * sizeof(double));
-				    iptr = token;
-				    for (j = 0; j < locsize2; j++) {
-					for (i = 0; i < reftable->size1; i++) {
-					    while (*iptr == ' ' || *iptr == '\"' ||
-							*iptr == ',')
-						iptr++;
-					    sscanf(iptr, "%lg", &gval);
-					    *(tableptr->values + j * reftable->size1
-							+ i) = gval * time_unit;
-					    while (*iptr != ' ' && *iptr != '\"' &&
-							*iptr != ',')
-						iptr++;
-					}
-				    }
-				}
-			    }
-
-			    token = advancetoken(flib, 0);
-			    if (strcmp(token, ";"))
-				fprintf(stderr, "Failed to find end of value table\n");
-			    token = advancetoken(flib, 0);
-
-			}
-			else if (strcmp(token, "{"))
-			    fprintf(stderr, "Failed to find end of timing block\n");
-		    }
-		}
-		else {
-		    // For unhandled tokens, read in tokens.  If it is
-		    // a definition or function, read to end-of-line.  If
-		    // it is a block definition, read to end-of-block.
-		    while (1) {
-			token = advancetoken(flib, 0);
-			if (token == NULL) break;
-			if (!strcmp(token, ";")) break;
-			if (!strcmp(token, "\""))
-			    token = advancetoken(flib, '\"');
-			if (!strcmp(token, "{")) {
-			    token = advancetoken(flib, '}');
-			    break;
-			}
-		    }
-		}
-		break;
-	}
-	token = advancetoken(flib, 0);
-    }
-}
-
-/*--------------------------------------------------------------*/
-/* Read a verilog netlist and collect information about the	*/
-/* cells instantiated and the network structure			*/
-/*--------------------------------------------------------------*/
-
-void
-verilogRead(FILE *fsrc, cell *cells, struct hashlist *nethash[],
-		instance **instlist, connect **inputlist,
-		connect **outputlist)
-{
-    char *token;
-    char *modname = NULL;
-    int section = MODULE;
-
-    instptr newinst;
-    netptr newnet, testnet;
-    cellptr testcell;
-    connptr newconn, testconn;
-    pinptr testpin;
-
-    int vstart, vend, vtarget, isinput;
-
-    /* Read tokens off of the line */
-    token = advancetoken(fsrc, 0);
-
-    while (token != NULL) {
-
-	switch (section) {
-	    case MODULE:
-		if (!strcasecmp(token, "module")) {
-		    token = advancetoken(fsrc, 0);
-		    fprintf(stderr, "Parsing module \"%s\"\n", token);
-
-		    token = advancetoken(fsrc, 0);
-		    if (strcmp(token, "("))
-			fprintf(stderr, "Module not followed by pin list\n");
-		    else
-			token = advancetoken(fsrc, ')');
-		    token = advancetoken(fsrc, ';');	// Get end-of-line
-
-		    // Ignore the pin list, go straight to the input/output declarations
-		    section = IOLIST;
-		}
-		break;
-
-	    case IOLIST:
-		if (!strcasecmp(token, "input") || !strcasecmp(token, "output")) {
-
-		    testconn = NULL;
-		    vstart = vend = 0;
-
-		    if (!strcasecmp(token, "input")) {
-			isinput = 1;
-		    }
-		    else { 	// output
-			isinput = 0;
-		    }
-
-		    token = advancetoken(fsrc, 0);
-		    if (*token == '[') {
-			sscanf(token + 1, "%d", &vstart);
-			token = advancetoken(fsrc, ':');
-			token = advancetoken(fsrc, ']');	// Read to end of vector
-			sscanf(token, "%d", &vend);
-			token = advancetoken(fsrc, 0);		// Read signal name
-		    }
-
-		    // Create a net entry for the input or output, add to the list of nets
-
-		    if (vstart == 0 && vend == 0) {
-			newnet = hash_net(nethash, token);
-
-			testconn = (connptr)malloc(sizeof(connect));
-			testconn->refnet = newnet;
-			testconn->refpin = NULL;	// No associated pin
-			testconn->refinst = NULL;	// No associated instance
-			testconn->tag = NULL;
-			testconn->metric = -1.0;
-			testconn->prvector = NULL;
-			testconn->pfvector = NULL;
-			testconn->trvector = NULL;
-			testconn->tfvector = NULL;
-
-			if (isinput) {			// driver (input)
-			    testconn->next = *inputlist;
-			    *inputlist = testconn;
-			}
-			else {				// receiver (output)
-			    testconn->next = *outputlist;
-			    *outputlist = testconn;
-			}
-		    }
-		    else {
-			vtarget = vend + (vstart < vend) ? 1 : -1;
-			while (vstart != vtarget) {
-			    char *netname;
-			    netname = (char *)malloc(strlen(token) + 6);
-			    sprintf(netname, "%s[%d]", token, vstart);
-			    newnet = hash_net(nethash, netname);
-			    free(netname);
-
-			    vstart += (vtarget > vend) ? 1 : -1;
-
-			    testconn = (connptr)malloc(sizeof(connect));
-			    testconn->refnet = newnet;
-			    testconn->refpin = NULL;	// No associated pin
-			    testconn->refinst = NULL;	// No associated instance
-			    testconn->tag = NULL;
-			    testconn->metric = -1.0;
-			    testconn->prvector = NULL;
-			    testconn->pfvector = NULL;
-			    testconn->trvector = NULL;
-			    testconn->tfvector = NULL;
-
-			    if (isinput) {		// driver (input)
-				testconn->next = *inputlist;
-				*inputlist = testconn;
-			    }
-			    else {			// receiver (output)
-				testconn->next = *outputlist;
-				*outputlist = testconn;
-			    }
-			}
-		    }
-		    token = advancetoken(fsrc, ';');	// Get rest of input/output entry
-		    break;
-		}
-
-		/* Drop through on anything that isn't an input, output, or blank line */
-
-	    case GATELIST:
-
-		if (!strcasecmp(token, "endmodule")) {
-		    section = MODULE;
-		    break;    
-		}
-
-		/* Confirm that the token is a known cell, and continue parsing line if so */
-		/* Otherwise, parse to semicolon line end and continue */
-
-		for (testcell = cells; testcell; testcell = testcell->next)
-		    if (!strcasecmp(testcell->name, token))
-			break;
-
-		if (testcell != NULL) {
-		    section = INSTANCE;
-		    newinst = (instptr)malloc(sizeof(instance));
-		    newinst->next = *instlist;
-		    *instlist = newinst;
-		    newinst->refcell = testcell;
-		    newinst->in_connects = NULL;
-		    newinst->out_connects = NULL;
-		}
-		else {
-		    /* Ignore all wire and assign statements	*/
-		    /* Qflow does not generate these, but other	*/
-		    /* synthesis tools may.			*/
-
-		    if (!strcasecmp(token, "assign") && (verbose > 0)) {
-			fprintf(stdout, "Wire assignments are not handled!\n");
-		    }
-		    else if (strcasecmp(token, "wire") && (verbose > 0)) {
-			fprintf(stdout, "Unknown cell \"%s\" instanced.\n",
-				token);
-		    }
-		    token = advancetoken(fsrc, ';');	// Get rest of entry, and ignore
-		}
-		break;
-
-	    case INSTANCE:
-		newinst->name = strdup(token);
-		token = advancetoken(fsrc, '(');	// Find beginning of pin list
-		section = INSTPIN;
-		break;
-
-	    case INSTPIN:
-		if (*token == '.') {
-		    newconn = (connptr)malloc(sizeof(connect));
-		    // Pin name is in (token + 1)
-		    for (testpin = testcell->pins; testpin; testpin = testpin->next) {
-			if (!strcmp(testpin->name, token + 1))
-			    break;
-		    }
-		    // Sanity check
-		    if (testpin == NULL) {
-			fprintf(stderr, "No such pin \"%s\" in cell \"%s\"!\n",
-				token + 1, testcell->name);
-		    }
-		    else {
-			if (testpin->type & OUTPUT) {
-			    newconn->next = newinst->out_connects;
-			    newinst->out_connects = newconn;
-			}
-			else {
-			    newconn->next = newinst->in_connects;
-			    newinst->in_connects = newconn;
-			}
-		    }
-		    newconn->refinst = newinst;
-		    newconn->refpin = testpin;
-		    newconn->refnet = NULL;
-		    newconn->tag = NULL;
-		    newconn->metric = -1.0;
-		    newconn->prvector = NULL;
-		    newconn->pfvector = NULL;
-		    newconn->trvector = NULL;
-		    newconn->tfvector = NULL;
-		    token = advancetoken(fsrc, '(');	// Read to beginning of pin name
-		    section = PINCONN;
-		}
-		else if (*token == ';') {
-		    // End of instance record
-		    section = GATELIST;
-		}
-		else if (*token != ',' && *token != ')') {
-		    fprintf(stderr, "Unexpected entry in instance pin connection list!\n");
-		    token = advancetoken(fsrc, ';');	// Read to end-of-line
-		    section = GATELIST;
-		}
-		break;
-
-	    case PINCONN:
-		// Token is net name
-		testnet = (netptr)HashLookup(token, nethash);
-		if (testnet == NULL) {
-		    // This is a new net, and we need to record it
-		    newnet = hash_net(nethash, token);
-		    newconn->refnet = newnet;
-		}
-		else
-		    newconn->refnet = testnet;
-		section = INSTPIN;
-		break;
-	}
-	if (section == PINCONN)
-	    token = advancetoken(fsrc, ')');	// Name token parsing
-	else
-	    token = advancetoken(fsrc, 0);
-    }
-}
-
-/*--------------------------------------------------------------*/
-/* For each net, go through the list of receivers and add the	*/
-/* contributions of each to the total load.  This is either	*/
-/* the input pin capacitance, if the receiver is a pin, or the	*/
-/* designated output load (given on the command line), if the	*/
-/* receiver is an output pin.					*/
-/*--------------------------------------------------------------*/
-
-void
-computeLoads(struct hashlist *nethash[], instptr instlist, double out_load)
-{
-    instptr testinst;
-    pinptr testpin;
-    netptr testnet, driver, loadnet;
-    connptr testconn;
-    int i;
-
-    testnet = (netptr)HashFirst(nethash);
-    while (testnet != NULL) {
-	for (i = 0; i < testnet->fanout; i++) {
-	    testconn = testnet->receivers[i];
-	    testpin = testconn->refpin;
-	    if (testpin == NULL) {
-		testnet->loadr += out_load;
-		testnet->loadf += out_load;
-	    }
-	    else {
-		testnet->loadr += testpin->capr;
-		testnet->loadf += testpin->capf;
-	    }
-	}
-	testnet = (netptr)HashNext(nethash);
-    }
-
-    // For each instance input pin, collapse the pin's lookup table
-    // to a vector by interpolating/extrapolating the table at the
-    // calculated output load.  Save this vector in the connection
-    // record for the pin.
-
-    for (testinst = instlist; testinst; testinst = testinst->next) {
-	loadnet = testinst->out_connects->refnet;
-	for (testconn = testinst->in_connects; testconn; testconn = testconn->next) {
-	    testpin = testconn->refpin;
-
-	    if (testpin->propdelr)
-		testconn->prvector = table_collapse(testpin->propdelr, loadnet->loadr);
-	    if (testpin->propdelf)
-		testconn->pfvector = table_collapse(testpin->propdelf, loadnet->loadf);
-	    if (testpin->transr)
-		testconn->trvector = table_collapse(testpin->transr, loadnet->loadr);
-	    if (testpin->transf)
-		testconn->tfvector = table_collapse(testpin->transf, loadnet->loadf);
-	}
-    }
-}
-
-/*--------------------------------------------------------------*/
-/* Assign types to each net.  This identifies which nets are	*/
-/* clock inputs, which are latch enable inputs, and which are	*/
-/* asynchronous set/reset inputs,.				*/
-/*								*/
-/* Whenever a clock input to a flop is found, add the		*/
-/* connection record to clockedlist				*/
-/*								*/
-/* For diagnostics, return the number of entries in clockedlist	*/
-/*--------------------------------------------------------------*/
-
-int assign_net_types(struct hashlist *nethash[], connlistptr *clockedlist)
-{
-    int i, numterms;
-    netptr testnet;
-    connptr testrcvr;
-    pinptr testpin;
-    connlistptr newclocked;
-
-    numterms = 0;
-
-    testnet = (netptr)HashFirst(nethash);
-    while (testnet != NULL) {
-	for (i = 0; i < testnet->fanout; i++) {
-	    testrcvr = testnet->receivers[i];
-	    testpin = testrcvr->refpin;
-	    if (testpin == NULL)
-		testnet->type |= OUTTERM;
-	    else {
-		switch (testpin->type & (DFFMASK | LATCHMASK)) {
-		    case DFFCLK:
-			testnet->type |= CLOCK;
-			newclocked = (connlistptr)malloc(sizeof(connlist));
-			newclocked->connection = testrcvr;
-			newclocked->next = *clockedlist;
-			*clockedlist = newclocked;
-			numterms++;
-			break;
-		    case DFFIN:
-			testnet->type |= TERMINAL;
-			break;
-		    case DFFSET:
-		    case DFFRST:
-			testnet->type |= ASYNC;
-			break;
-		    case LATCHIN:
-			testnet->type |= LATCHTERM;
-			break;
-		    case LATCHEN:
-			testnet->type |= ENABLE;
-			break;
-		}
-	    }
-	}
-	testnet = (netptr)HashNext(nethash);
-    }
-    return numterms;
-}
-
-/*--------------------------------------------------------------*/
-/* Create the links representing the netlist connections.	*/
-/*								*/
-/* The verilogRead() routine added all nets and instances, and	*/
-/* for each instance, generated a list of net connections to	*/
-/* each pin.  To make the netlist easily traversible, this	*/
-/* routine does the following:					*/
-/*								*/
-/* For each instance, work through the list of pin		*/
-/*	connections.  If the pin is an output, then add the	*/
-/*	connection as the net's driver entry.  If the pin is	*/
-/*	an input, then add the connection to the list of the	*/
-/*	net's receivers, and increment the net's fanout.	*/
-/*								*/
-/* For each module input, add the input connection as the	*/
-/*	net's driver (flag an error if the net already has a	*/
-/*	driver).						*/
-/*								*/
-/* For each module output, add the output connection as one of	*/
-/*	the net's receivers (it may be the only one).		*/
-/*								*/
-/*--------------------------------------------------------------*/
-
-void
-createLinks(instptr instlist, connptr inputlist, connptr outputlist)
-{
-    netptr testnet;
-    instptr testinst;
-    connptr testconn;
-
-    for (testinst = instlist; testinst; testinst = testinst->next) {
-	for (testconn = testinst->in_connects; testconn; testconn = testconn->next) {
-	    testnet = testconn->refnet;
-	    testnet->fanout++;
-	    if (testnet->receivers == NULL)
-		testnet->receivers = (connptr *)malloc(sizeof(connptr));
-
-	    else
-		testnet->receivers = (connptr *)realloc(testnet->receivers,
-				testnet->fanout * sizeof(connptr));
-
-	    testnet->receivers[testnet->fanout - 1] = testconn;
-	} 
-
-	for (testconn = testinst->out_connects; testconn; testconn = testconn->next) {
-	    testnet = testconn->refnet;
-	    testnet->driver = testconn;
-	} 
-    }
-
-    for (testconn = inputlist; testconn; testconn = testconn->next) {
-	testnet = testconn->refnet;
-	if (testnet->driver != NULL)
-	    fprintf(stderr, "Error:  Input pin \"%s\" has an internal driver!\n",
-			testnet->name);
-	// else
-	//    testnet->driver = testconn;	// Don't do this, makes connectivity circular
-    }
-
-    for (testconn = outputlist; testconn; testconn = testconn->next) {
-	testnet = testconn->refnet;
-	testnet->fanout++;
-	if (testnet->receivers == NULL)
-	    testnet->receivers = (connptr *)malloc(sizeof(connptr));
-
-	else 
-	    testnet->receivers = (connptr *)realloc(testnet->receivers,
-			testnet->fanout * sizeof(connptr));
-
-	testnet->receivers[testnet->fanout - 1] = testconn;
-    }
-}
-
-/*--------------------------------------------------------------*/
-/* Delay comparison used by qsort() to sort paths in order from	*/
-/* longest to shortest propagation delay.			*/
-/*--------------------------------------------------------------*/
-
-int
-compdelay(ddataptr *a, ddataptr *b)
-{
-    ddataptr p = *a;
-    ddataptr q = *b;
-
-    if (p->delay < q->delay)
-	return (1);
-    if (p->delay > q->delay)
-	return (-1);
-    return (0);
-}
-
-/*--------------------------------------------------------------*/
-/* Main program							*/
-/*--------------------------------------------------------------*/
-
-int
-main(int objc, char *argv[])
-{
-    FILE *flib;
-    FILE *fsrc;
-    double period = 0.0;
-    double outLoad = 0.0;
-    double inTrans = 0.0;
-    char *delayfile = NULL;
-    int ival, firstarg = 1;
-
-    // Liberty database
-
-    lutable *tables = NULL;
-    cell *cells = NULL;
-    lutable *scalar;
-
-    // Verilog netlist database
-
-    instptr     instlist = NULL;
-    connlistptr clockconnlist = NULL;
-    connlistptr newinputconn, inputconnlist = NULL;
-    connptr     testconn, inputlist = NULL;
-    connptr     outputlist = NULL;
-
-    // Net hashtable
-    struct hashlist *Nethash[OBJHASHSIZE];
-
-    // Timing path database
-    ddataptr	pathlist = NULL;
-    ddataptr	freeddata, testddata, *orderedpaths;
-    btptr	freebt, testbt;
-    int		numpaths, numterms, i;
-    char	badtiming;
-    double	slack;
-
-    verbose = 0;
-    exhaustive = 0;
-
-    InitializeHashTable(Nethash);
-
-    while ((firstarg < objc) && (*argv[firstarg] == '-')) {
-       if (!strcmp(argv[firstarg], "-d") || !strcmp(argv[firstarg], "--delay")) {
-	  delayfile = strdup(argv[firstarg + 1]);
-	  firstarg += 2;
-       }
-       else if (!strcmp(argv[firstarg], "-p") || !strcmp(argv[firstarg], "--period")) {
-	  period = strtod(argv[firstarg + 1], NULL);
-	  firstarg += 2;
-       }
-       else if (!strcmp(argv[firstarg], "-l") || !strcmp(argv[firstarg], "--load")) {
-	  outLoad = strtod(argv[firstarg + 1], NULL);
-	  firstarg += 2;
-       }
-       else if (!strcmp(argv[firstarg], "-t") || !strcmp(argv[firstarg], "--trans")) {
-	  inTrans = strtod(argv[firstarg + 1], NULL);
-	  firstarg += 2;
-       }
-       else if (!strcmp(argv[firstarg], "-v") || !strcmp(argv[firstarg], "--verbose")) {
-	  sscanf(argv[firstarg + 1], "%d", &ival);
-	  verbose = (unsigned char)ival;
-	  firstarg += 2;
-       }
-       else if (!strcmp(argv[firstarg], "-e") || !strcmp(argv[firstarg], "--exhaustive")) {
-	  exhaustive = 1;
-	  firstarg++;
-       }
-       else if (!strcmp(argv[firstarg], "-V") || !strcmp(argv[firstarg], "--version")) {
-	  fprintf(stderr, "Vesta Static Timing Analzyer version 0.2\n");
-	  exit(0);
-       }
-       else {
-	  fprintf(stderr, "Unknown option \"%s\"\n", argv[firstarg]);
-	  firstarg++;
-       }
-    }
-
-    if (objc - firstarg != 2) {
-	fprintf(stderr, "Usage:  vesta [options] <name.v> <name.lib>\n");
-	fprintf(stderr, "Options:\n");
-	fprintf(stderr, "--delay <delay_file>	or	-d <delay_file>\n");
-	fprintf(stderr, "--period <period>	or	-p <period>\n");
-	fprintf(stderr, "--load <load>		or	-l <load>\n");
-	fprintf(stderr, "--verbose <level>	or	-v <level>\n");
-	fprintf(stderr, "--exhaustive		or 	-e\n");
-	fprintf(stderr, "--version		or	-V\n");
-	exit (1);
-    }
-    else {
-	fflush(stdout);
-	fprintf(stdout, "-----------------------------------------\n");
-	fprintf(stdout, "Vesta static timing analysis tool\n");
-	fprintf(stdout, "(c) 2013 Tim Edwards, Open Circuit Design\n");
-	fprintf(stdout, "-----------------------------------------\n\n");
-	fflush(stdout);
-    }
-
-    fsrc = fopen(argv[firstarg], "r");
-    if (fsrc == NULL) {
-	fprintf(stderr, "Cannot open %s for reading\n", argv[firstarg]);
-	exit (1);
-    }
-
-    flib = fopen(argv[firstarg + 1], "r");
-    if (flib == NULL) {
-	fprintf(stderr, "Cannot open %s for reading\n", argv[firstarg + 1]);
-	exit (1);
-    }
-
-    /*------------------------------------------------------------------*/
-    /* Generate one table template for the "scalar" case		*/
-    /*------------------------------------------------------------------*/
-
-    scalar = (lutable *)malloc(sizeof(lutable));
-    scalar->name = strdup("scalar");
-    scalar->invert = 0;
-    scalar->var1 = CONSTRAINED_TIME;
-    scalar->var2 = OUTPUT_CAP;
-    scalar->size1 = 1;
-    scalar->size2 = 1;
-    scalar->idx1.times = (double *)malloc(sizeof(double));
-    scalar->idx2.caps = (double *)malloc(sizeof(double));
-    scalar->values = (double *)malloc(sizeof(double));
-
-    scalar->idx1.times[0] = 0.0;
-    scalar->idx2.caps[0] = 0.0;
-    scalar->values[0] = 0.0;
-
-    scalar->next = NULL;
-    tables = scalar;
-
-    /*------------------------------------------------------------------*/
-    /* Read the liberty format file.  This is not a rigorous parser!	*/
-    /*------------------------------------------------------------------*/
-
-    fileCurrentLine = 0;
-    libertyRead(flib, &tables, &cells);
-    fflush(stdout);
-    fprintf(stdout, "Lib Read:  Processed %d lines.\n", fileCurrentLine);
-    if (flib != NULL) fclose(flib);
-
-    /*--------------------------------------------------*/
-    /* Debug:  Print summary of liberty database	*/
-    /*--------------------------------------------------*/
-
-    if (verbose > 2) {
-
-	lutable *newtable;
-	cell *newcell;
-	pin *newpin;
-
-	for (newtable = tables; newtable; newtable = newtable->next) {
-	    fprintf(stdout, "Table: %s\n", newtable->name);
-	}
-
-	for (newcell = cells; newcell; newcell = newcell->next) {
-	    fprintf(stdout, "Cell: %s\n", newcell->name);
-	    fprintf(stdout, "   Function: %s\n", newcell->function);
-	    for (newpin = newcell->pins; newpin; newpin = newpin->next) {
-		if (newpin->type == INPUT)
-		    fprintf(stdout, "   Pin: %s  cap=%g\n", newpin->name, newpin->capr);
-	    }
-	    fprintf(stdout, "\n");
-	}
-    }
-
-    /*------------------------------------------------------------------*/
-    /* Read verilog netlist.  This is also not a rigorous parser!	*/
-    /*------------------------------------------------------------------*/
-
-    fileCurrentLine = 0;
-    verilogRead(fsrc, cells, Nethash, &instlist, &inputlist, &outputlist);
-    fflush(stdout);
-    fprintf(stdout, "Verilog netlist read:  Processed %d lines.\n", fileCurrentLine);
-    if (fsrc != NULL) fclose(fsrc);
-
-    /*--------------------------------------------------*/
-    /* Debug:  Print summary of verilog source		*/
-    /*--------------------------------------------------*/
-
-    if (verbose > 1) {
-	connect *testoutput;
-	connect *testinput;
-	instance *testinst;
-	netptr testnet;
-
-	for (testinput = inputlist; testinput; testinput = testinput->next) {
-	    if (testinput->refnet)
-		fprintf(stdout, "   Input: %s\n", testinput->refnet->name);
-	}
-	for (testoutput = outputlist; testoutput; testoutput = testoutput->next) {
-	    if (testoutput->refnet)
-		fprintf(stdout, "   Output: %s\n", testoutput->refnet->name);
-	}
-	testnet = (netptr)HashFirst(Nethash);
-	while (testnet != NULL) {
-	    fprintf(stdout, "   Net: %s\n", testnet->name);
-	    testnet = (netptr)HashNext(Nethash);
-	}
-	for (testinst = instlist; testinst; testinst = testinst->next) {
-	    fprintf(stdout, "   Gate: %s\n", testinst->name);
-	}
-    }
-
-    /*--------------------------------------------------*/
-    /* Generate internal links representing the network	*/
-    /*--------------------------------------------------*/
-
-    createLinks(instlist, inputlist, outputlist);
-
-    /* Generate a connection list from inputlist */
-
-    for (testconn = inputlist; testconn; testconn = testconn->next) {
-	newinputconn = (connlistptr)malloc(sizeof(connlist));
-	newinputconn->connection = testconn;
-	newinputconn->next = inputconnlist;
-	inputconnlist = newinputconn;
-    }
-
-    /*--------------------------------------------------*/
-    /* Calculate total load on each net			*/
-    /* To do:  Add wire models or computed wire delays	*/
-    /*--------------------------------------------------*/
-
-    computeLoads(Nethash, instlist, outLoad);
-
-    /*--------------------------------------------------*/
-    /* Assign net types, mainly to identify clocks	*/
-    /* Return a list of clock nets			*/
-    /*--------------------------------------------------*/
-
-    numterms = assign_net_types(Nethash, &clockconnlist);
-
-    if (verbose > 1) 
-	fprintf(stdout, "Number of terminals to check: %d\n", numterms);
-
-    /*--------------------------------------------------*/
-    /* Identify all clock-to-terminal paths		*/
-    /*--------------------------------------------------*/
-
-    numpaths = find_clock_to_term_paths(clockconnlist, &pathlist, Nethash, MAXIMUM_TIME);
-    fprintf(stdout, "Number of paths analyzed:  %d\n", numpaths);
-
-    /*--------------------------------------------------*/
-    /* Collect paths into a non-linked array so that	*/
-    /* they can be sorted by delay time			*/
-    /*--------------------------------------------------*/
-
-    orderedpaths = (ddataptr *)malloc(numpaths * sizeof(ddataptr));
-
-    i = 0;
-    for (testddata = pathlist; testddata; testddata = testddata->next) {
-       orderedpaths[i] = testddata;
-       i++;
-    }
-
-    qsort(orderedpaths, numpaths, sizeof(ddataptr), (__compar_fn_t)compdelay);
-
-    /*--------------------------------------------------*/
-    /* Report on top 20 maximum delay paths		*/
-    /*--------------------------------------------------*/
-
-    fprintf(stdout, "\nTop %d maximum delay paths:\n", (numpaths >= 20) ? 20 : numpaths);
-    badtiming = 0;
-    for (i = 0; ((i < 20) && (i < numpaths)); i++) {
-	testddata = orderedpaths[i];
-	for (testbt = testddata->backtrace; testbt->next; testbt = testbt->next);
-		
-	if (testddata->backtrace->receiver->refinst != NULL) {
-	    fprintf(stdout, "Path %s/%s to %s/%s delay %g ps",
-			testbt->receiver->refinst->name,
-			testbt->receiver->refpin->name,
-			testddata->backtrace->receiver->refinst->name,
-			testddata->backtrace->receiver->refpin->name,
-			testddata->delay);
-	}
-	else {
-	    fprintf(stdout, "Path %s/%s to output pin %s delay %g ps",
-			testbt->receiver->refinst->name,
-			testbt->receiver->refpin->name,
-			testddata->backtrace->receiver->refnet->name,
-			testddata->delay);
-	}
-
-	if (period > 0.0) {
-	    slack = period - testddata->delay;
-	    fprintf(stdout, "   Slack = %g ps", slack);
-	    if (slack < 0.0) badtiming = 1;
-	}
-	fprintf(stdout, "\n");
-    }
-
-    if (period > 0.0) {
-	if (badtiming) {
-	    fprintf(stdout, "ERROR:  Design fails timing requirements.\n");
-	}
-	else {
-	    fprintf(stdout, "Design meets timing requirements.\n");
-	}
-    }
-    else if (orderedpaths[0] != NULL) {
-	fprintf(stdout, "Computed maximum clock frequency (zero slack) = %g MHz\n",
-		(1.0E6 / orderedpaths[0]->delay));
-    }
-    fprintf(stdout, "-----------------------------------------\n\n");
-    fflush(stdout);
-
-    /*--------------------------------------------------*/
-    /* Clean up the path list				*/
-    /*--------------------------------------------------*/
-
-    while (pathlist != NULL) {
-	freeddata = pathlist;
-	pathlist = pathlist->next;
-	while (freeddata->backtrace != NULL) {
-	    freebt = freeddata->backtrace;
-	    freeddata->backtrace = freeddata->backtrace->next;
-	    freebt->refcnt--;
-	    if (freebt->refcnt == 0) free(freebt);
-	}
-	free(freeddata);
-    }
-
-    free(orderedpaths);
-
-    /*--------------------------------------------------*/
-    /* Now calculate minimum delay paths		*/
-    /*--------------------------------------------------*/
-
-    numpaths = find_clock_to_term_paths(clockconnlist, &pathlist, Nethash, MINIMUM_TIME);
-    fprintf(stdout, "Number of paths analyzed:  %d\n", numpaths);
-
-    /*--------------------------------------------------*/
-    /* Collect paths into a non-linked array so that	*/
-    /* they can be sorted by delay time			*/
-    /*--------------------------------------------------*/
-
-    orderedpaths = (ddataptr *)malloc(numpaths * sizeof(ddataptr));
-
-    i = 0;
-    for (testddata = pathlist; testddata; testddata = testddata->next) {
-       orderedpaths[i] = testddata;
-       i++;
-    }
-
-    qsort(orderedpaths, numpaths, sizeof(ddataptr), (__compar_fn_t)compdelay);
-
-    /*--------------------------------------------------*/
-    /* Report on top 20 minimum delay paths		*/
-    /*--------------------------------------------------*/
-
-    fprintf(stdout, "\nTop %d minimum delay paths:\n", (numpaths >= 20) ? 20 : numpaths);
-    badtiming = 0;
-    for (i = numpaths; (i > (numpaths - 20)) && (i > 0); i--) {
-	testddata = orderedpaths[i - 1];
-	for (testbt = testddata->backtrace; testbt->next; testbt = testbt->next);
-		
-	if (testddata->backtrace->receiver->refinst != NULL) {
-	    fprintf(stdout, "Path %s/%s to %s/%s delay %g ps\n",
-			testbt->receiver->refinst->name,
-			testbt->receiver->refpin->name,
-			testddata->backtrace->receiver->refinst->name,
-			testddata->backtrace->receiver->refpin->name,
-			testddata->delay);
-	}
-	else {
-	    fprintf(stdout, "Path %s/%s to output pin %s delay %g ps\n",
-			testbt->receiver->refinst->name,
-			testbt->receiver->refpin->name,
-			testddata->backtrace->receiver->refnet->name,
-			testddata->delay);
-	}
-
-	if (testddata->delay < 0.0) badtiming = 1;
-    }
-    if (badtiming)
-	fprintf(stdout, "ERROR:  Design fails minimum hold timing.\n");
-    else
-	fprintf(stdout, "Design meets minimum hold timing.\n");
-
-    fprintf(stdout, "-----------------------------------------\n\n");
-    fflush(stdout);
-
-    /*--------------------------------------------------*/
-    /* Clean up the path list				*/
-    /*--------------------------------------------------*/
-
-    while (pathlist != NULL) {
-	freeddata = pathlist;
-	pathlist = pathlist->next;
-	while (freeddata->backtrace != NULL) {
-	    freebt = freeddata->backtrace;
-	    freeddata->backtrace = freeddata->backtrace->next;
-	    freebt->refcnt--;
-	    if (freebt->refcnt == 0) free(freebt);
-	}
-	free(freeddata);
-    }
-
-    free(orderedpaths);
-
-    for (testconn = inputlist; testconn; testconn = testconn->next) {
-	testconn->tag = NULL;
-	testconn->metric = -1;
-    }
-
-    /*--------------------------------------------------*/
-    /* Identify all input-to-terminal paths		*/
-    /*--------------------------------------------------*/
-
-    numpaths = find_clock_to_term_paths(inputconnlist, &pathlist, Nethash, MAXIMUM_TIME);
-    fprintf(stdout, "Number of paths analyzed:  %d\n", numpaths);
-
-    /*--------------------------------------------------*/
-    /* Collect paths into a non-linked array so that	*/
-    /* they can be sorted by delay time			*/
-    /*--------------------------------------------------*/
-
-    orderedpaths = (ddataptr *)malloc(numpaths * sizeof(ddataptr));
-
-    i = 0;
-    for (testddata = pathlist; testddata; testddata = testddata->next) {
-       orderedpaths[i] = testddata;
-       i++;
-    }
-
-    qsort(orderedpaths, numpaths, sizeof(ddataptr), (__compar_fn_t)compdelay);
-
-    /*--------------------------------------------------*/
-    /* Report on top 20 maximum delay paths		*/
-    /*--------------------------------------------------*/
-
-    fprintf(stdout, "\nTop %d maximum delay paths:\n", (numpaths >= 20) ? 20 : numpaths);
-    for (i = 0; ((i < 20) && (i < numpaths)); i++) {
-	testddata = orderedpaths[i];
-	for (testbt = testddata->backtrace; testbt->next; testbt = testbt->next);
-		
-	if (testddata->backtrace->receiver->refinst != NULL) {
-	    fprintf(stdout, "Path input pin %s to %s/%s delay %g ps\n",
-			testbt->receiver->refnet->name,
-			testddata->backtrace->receiver->refinst->name,
-			testddata->backtrace->receiver->refpin->name,
-			testddata->delay);
-	}
-	else {
-	    fprintf(stdout, "Path input pin %s to output pin %s delay %g ps\n",
-			testbt->receiver->refnet->name,
-			testddata->backtrace->receiver->refnet->name,
-			testddata->delay);
-	}
-    }
-
-    fprintf(stdout, "-----------------------------------------\n\n");
-    fflush(stdout);
-
-    /*--------------------------------------------------*/
-    /* Clean up the path list				*/
-    /*--------------------------------------------------*/
-
-    while (pathlist != NULL) {
-	freeddata = pathlist;
-	pathlist = pathlist->next;
-	while (freeddata->backtrace != NULL) {
-	    freebt = freeddata->backtrace;
-	    freeddata->backtrace = freeddata->backtrace->next;
-	    freebt->refcnt--;
-	    if (freebt->refcnt == 0) free(freebt);
-	}
-	free(freeddata);
-    }
-
-    free(orderedpaths);
-
-    for (testconn = inputlist; testconn; testconn = testconn->next) {
-	testconn->tag = NULL;
-	testconn->metric = 1E50;
-    }
-
-    /*--------------------------------------------------*/
-    /* Now calculate minimum delay paths from inputs	*/
-    /*--------------------------------------------------*/
-
-    numpaths = find_clock_to_term_paths(inputconnlist, &pathlist, Nethash, MINIMUM_TIME);
-    fprintf(stdout, "Number of paths analyzed:  %d\n", numpaths);
-
-    /*--------------------------------------------------*/
-    /* Collect paths into a non-linked array so that	*/
-    /* they can be sorted by delay time			*/
-    /*--------------------------------------------------*/
-
-    orderedpaths = (ddataptr *)malloc(numpaths * sizeof(ddataptr));
-
-    i = 0;
-    for (testddata = pathlist; testddata; testddata = testddata->next) {
-       orderedpaths[i] = testddata;
-       i++;
-    }
-
-    qsort(orderedpaths, numpaths, sizeof(ddataptr), (__compar_fn_t)compdelay);
-
-    /*--------------------------------------------------*/
-    /* Report on top 20 minimum delay paths		*/
-    /*--------------------------------------------------*/
-
-    fprintf(stdout, "\nTop %d minimum delay paths:\n", (numpaths >= 20) ? 20 : numpaths);
-    for (i = numpaths; (i > (numpaths - 20)) && (i > 0); i--) {
-	testddata = orderedpaths[i - 1];
-	for (testbt = testddata->backtrace; testbt->next; testbt = testbt->next);
-		
-	if (testddata->backtrace->receiver->refinst != NULL) {
-	    fprintf(stdout, "Path input pin %s to %s/%s delay %g ps\n",
-			testbt->receiver->refnet->name,
-			testddata->backtrace->receiver->refinst->name,
-			testddata->backtrace->receiver->refpin->name,
-			testddata->delay);
-	}
-	else {
-	    fprintf(stdout, "Path input pin %s to output pin %s delay %g ps\n",
-			testbt->receiver->refnet->name,
-			testddata->backtrace->receiver->refnet->name,
-			testddata->delay);
-	}
-    }
-
-    fprintf(stdout, "-----------------------------------------\n\n");
-    fflush(stdout);
-
-    /*--------------------------------------------------*/
-    /* Clean up the path list				*/
-    /*--------------------------------------------------*/
-
-    while (pathlist != NULL) {
-	freeddata = pathlist;
-	pathlist = pathlist->next;
-	while (freeddata->backtrace != NULL) {
-	    freebt = freeddata->backtrace;
-	    freeddata->backtrace = freeddata->backtrace->next;
-	    freebt->refcnt--;
-	    if (freebt->refcnt == 0) free(freebt);
-	}
-	free(freeddata);
-    }
-
-    free(orderedpaths);
-
-    // Should free netlist memory and HashKill(Nethash) here. . .
-    return 0;
-}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/qflow.git



More information about the debian-science-commits mailing list