mirror of
https://github.com/RTimothyEdwards/magic.git
synced 2026-08-29 17:39:28 +02:00
a routine that should have been called with a NULL argument, but instead was called with no argument, making the behavior system- dependent. Revised the parsing of the "defaultareacap" and "defaultperimeter" statements in the tech file, such that the short version of both statements gets automatic handling of the substrate and isolated substrate areas; this goes back to the recent change in extraction behavior to redefine the "substrate type" (e.g., pwell) during extraction as defining isolated substrate areas, and not the default substrate. The earlier code change dealt with problems related to extracting nodes and regions, but did not consider how parasitic capacitance was affected. This commit resolves that issue.
174 lines
4.7 KiB
C
174 lines
4.7 KiB
C
/*
|
|
* extcheck.c --
|
|
*
|
|
* Program to check .ext files for consistency without producing
|
|
* any output. Checks for disconnected global nodes as well as
|
|
* for version consistency. Counts the number of interesting
|
|
* things in the circuit (devices, capacitors, resistors, nodes).
|
|
*
|
|
* Flattens the tree rooted at file.ext, reading in additional .ext
|
|
* files as specified by "use" lines in file.ext.
|
|
*
|
|
* *********************************************************************
|
|
* * Copyright (C) 1985, 1990 Regents of the University of California. *
|
|
* * Permission to use, copy, modify, and distribute this *
|
|
* * software and its documentation for any purpose and without *
|
|
* * fee is hereby granted, provided that the above copyright *
|
|
* * notice appear in all copies. The University of California *
|
|
* * makes no representations about the suitability of this *
|
|
* * software for any purpose. It is provided "as is" without *
|
|
* * express or implied warranty. Export of this software outside *
|
|
* * of the United States of America may require an export license. *
|
|
* *********************************************************************
|
|
*/
|
|
|
|
#ifndef lint
|
|
static char rcsid[] = "$Header: /usr/cvsroot/magic-8.0/extcheck/extcheck.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
|
#endif /* not lint */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <ctype.h>
|
|
|
|
#include "utils/magic.h"
|
|
#include "utils/paths.h"
|
|
#include "utils/geometry.h"
|
|
#include "utils/hash.h"
|
|
#include "utils/utils.h"
|
|
#include "utils/pathvisit.h"
|
|
#include "extflat/extflat.h"
|
|
#include "utils/runstats.h"
|
|
|
|
int ecNumDevs;
|
|
int ecNumCaps;
|
|
int ecNumResists;
|
|
int ecNumThreshCaps;
|
|
int ecNumThreshResists;
|
|
int ecNumNodes;
|
|
int ecNumGlobalNodes;
|
|
int ecNumNodeCaps;
|
|
int ecNumNodeResists;
|
|
|
|
/* Forward declarations */
|
|
int nodeVisit(), devVisit(), capVisit(), resistVisit();
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* main --
|
|
*
|
|
* Top level of extcheck.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
main(argc, argv)
|
|
char *argv[];
|
|
{
|
|
char *inName;
|
|
|
|
/* Process command line arguments */
|
|
EFInit();
|
|
inName = EFArgs(argc, argv, NULL, (int (*)()) NULL, (ClientData) NULL);
|
|
if (inName == NULL)
|
|
exit (1);
|
|
|
|
/* Read the hierarchical description of the input circuit */
|
|
EFReadFile(inName, FALSE, FALSE, FALSE);
|
|
if (EFArgTech) EFTech = StrDup((char **) NULL, EFArgTech);
|
|
if (EFScale == 0.0) EFScale = 1.0;
|
|
|
|
/* Convert the hierarchical description to a flat one */
|
|
EFFlatBuild(inName, EF_FLATNODES|EF_FLATCAPS|EF_FLATRESISTS);
|
|
|
|
EFVisitDevs(devVisit, (ClientData) NULL);
|
|
if (IS_FINITE_F(EFCapThreshold))
|
|
EFVisitCaps(capVisit, (ClientData) NULL);
|
|
if (EFResistThreshold != INFINITE_THRESHOLD)
|
|
EFVisitResists(resistVisit, (ClientData) NULL);
|
|
EFVisitNodes(nodeVisit, (ClientData) NULL);
|
|
|
|
#ifdef free_all_mem
|
|
EFFlatDone(NULL);
|
|
EFDone();
|
|
#endif /* free_all_mem */
|
|
|
|
printf("Memory used: %s\n", RunStats(RS_MEM, NULL, NULL));
|
|
printf("%d devices\n", ecNumDevs);
|
|
printf("%d nodes (%d global, %d local)\n",
|
|
ecNumNodes, ecNumGlobalNodes, ecNumNodes - ecNumGlobalNodes);
|
|
printf("%d nodes above capacitance threshold\n", ecNumNodeCaps);
|
|
printf("%d nodes above resistance threshold\n", ecNumNodeResists);
|
|
printf("%d internodal capacitors (%d above threshold)\n",
|
|
ecNumCaps, ecNumThreshCaps);
|
|
printf("%d explicit resistors (%d above threshold)\n",
|
|
ecNumResists, ecNumThreshResists);
|
|
exit (0);
|
|
}
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* nodeVisit --
|
|
* devVisit --
|
|
* capVisit --
|
|
* resistVisit --
|
|
*
|
|
* Called once for each of the appropriate type of object.
|
|
* Each updates various counts.
|
|
*
|
|
* Results:
|
|
* Returns 0 always.
|
|
*
|
|
* Side effects:
|
|
* See above.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
int
|
|
nodeVisit(node, res, cap)
|
|
EFNode *node;
|
|
int res;
|
|
double cap;
|
|
{
|
|
cap = (cap + 500) / 1000;
|
|
res = (res + 500) / 1000;
|
|
|
|
ecNumNodes++;
|
|
if (EFHNIsGlob(node->efnode_name->efnn_hier))
|
|
ecNumGlobalNodes++;
|
|
if (res > EFResistThreshold) ecNumNodeResists++;
|
|
if (cap > (double) EFCapThreshold) ecNumNodeCaps++;
|
|
return 0;
|
|
}
|
|
|
|
int
|
|
devVisit()
|
|
{
|
|
ecNumDevs++;
|
|
return 0;
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
int
|
|
capVisit(hn1, hn2, cap)
|
|
HierName *hn1, *hn2; /* UNUSED */
|
|
double cap;
|
|
{
|
|
ecNumCaps++;
|
|
if ((cap / 1000.) > (double) EFCapThreshold) ecNumThreshCaps++;
|
|
return 0;
|
|
}
|
|
|
|
/*ARGSUSED*/
|
|
int
|
|
resistVisit(hn1, hn2, res)
|
|
HierName *hn1, *hn2; /* UNUSED */
|
|
float res;
|
|
{
|
|
ecNumResists++;
|
|
if ((res / 1000.) > EFResistThreshold) ecNumThreshResists++;
|
|
return 0;
|
|
}
|