Files
magic/extract/ExtTest.c
T
Darryl L. Miles e88dcba1c5 CodeQL File{MayNot,Never}BeClosed.ql file-handle resource leaks
Guided by CodeQL static code analyser.

FileMayNotBeClosed.ql
FileMayNeverBeClosed.ql

The trick with "if(fp != stdout)" is problematic (to analyser) as
technically 'stdout' can be a global pointer that COULD be modified any
time, so it might have changed between the fopen() and fclose() calls so
the close MAY NEVER occurs (which is problem the analyzer can see).

So local state is maintained as a bool which will also clarify to the
compiler see the intention without concern for external stdout
modification.

Some items appear to be out and out leaks when certain commands are use.
2025-02-22 21:02:49 -05:00

1446 lines
36 KiB
C

/*
* ExtTest.c --
*
* Circuit extraction.
* Interface for testing.
*
* *********************************************************************
* * 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[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/extract/ExtTest.c,v 1.3 2009/05/13 15:03:16 tim Exp $";
#endif /* not lint */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "utils/magic.h"
#include "utils/utils.h"
#include "utils/geometry.h"
#include "utils/styles.h"
#include "tiles/tile.h"
#include "utils/hash.h"
#include "database/database.h"
#include "utils/malloc.h"
#include "windows/windows.h"
#include "graphics/graphics.h"
#include "dbwind/dbwind.h"
#include "utils/main.h"
#include "commands/commands.h"
#include "textio/textio.h"
#include "textio/txcommands.h"
#include "debug/debug.h"
#include "extract/extract.h"
#include "extract/extractInt.h"
int extDebAreaEnum;
int extDebArray;
int extDebHardWay;
int extDebHierCap;
int extDebHierAreaCap;
int extDebLabel;
int extDebNeighbor;
int extDebNoArray;
int extDebNoFeedback;
int extDebNoHard;
int extDebNoSubcell;
int extDebLength;
int extDebPerim;
int extDebResist;
int extDebVisOnly;
int extDebYank;
/*
* The following are used for selective redisplay while debugging
* the circuit extractor.
*/
Rect extScreenClip;
CellDef *extCellDef;
MagWindow *extDebugWindow;
/* The width of an edge in pixels when it is displayed */
int extEdgePixels = 4;
/* Forward declarations */
int extShowInter();
void extShowTech();
void extDispInit();
bool extShowRect();
void extMore();
void extShowTrans(char *, TileTypeBitMask *, FILE *);
void extShowMask(TileTypeBitMask *, FILE *);
void extShowPlanes(PlaneMask, FILE *);
void extShowConnect(char *, TileTypeBitMask *, FILE *);
/*
* ----------------------------------------------------------------------------
*
* ExtractTest --
*
* Command interface for testing circuit extraction.
* Usage:
* *extract
*
* Results:
* None.
*
* Side effects:
* Extracts the current cell, writing a file named
* currentcellname.ext.
*
* ----------------------------------------------------------------------------
*/
void
ExtractTest(w, cmd)
MagWindow *w;
TxCommand *cmd;
{
extern long extSubtreeTotalArea;
extern long extSubtreeInteractionArea;
extern long extSubtreeClippedArea;
static Plane *interPlane = (Plane *) NULL;
static long areaTotal = 0, areaInteraction = 0, areaClipped = 0;
long a1, a2;
int n, halo, bloat;
CellUse *selectedCell;
Rect editArea;
char *addr, *name;
typedef enum { CLRDEBUG, CLRLENGTH, DRIVER, DUMP, INTERACTIONS,
INTERCOUNT, EXTPARENTS, RECEIVER, SETDEBUG, SHOWDEBUG,
SHOWPARENTS, SHOWTECH, STATS, STEP, TIME } cmdType;
static const struct
{
const char *cmd_name;
cmdType cmd_val;
} cmds[] = {
{"clrdebug", CLRDEBUG},
{"clrlength", CLRLENGTH},
{"driver", DRIVER},
{"dump", DUMP},
{"interactions", INTERACTIONS},
{"intercount", INTERCOUNT},
{"parents", EXTPARENTS},
{"receiver", RECEIVER},
{"setdebug", SETDEBUG},
{"showdebug", SHOWDEBUG},
{"showparents", SHOWPARENTS},
{"showtech", SHOWTECH},
{"stats", STATS},
{"step", STEP},
{"times", TIME},
{0}
};
if (cmd->tx_argc == 1)
{
Plane *savePlane;
selectedCell = CmdGetSelectedCell((Transform *) NULL);
if (selectedCell == NULL)
{
TxError("No cell selected\n");
return;
}
extDispInit(selectedCell->cu_def, w);
savePlane = ExtCell(selectedCell->cu_def, selectedCell->cu_def->cd_name, FALSE);
ExtRevertSubstrate(selectedCell->cu_def, savePlane);
return;
}
n = LookupStruct(cmd->tx_argv[1], (const LookupTable *) cmds, sizeof cmds[0]);
if (n < 0)
{
TxError("Unrecognized subcommand: %s\n", cmd->tx_argv[1]);
TxError("Valid subcommands:");
for (n = 0; cmds[n].cmd_name; n++)
TxError(" %s", cmds[n].cmd_name);
TxError("\n");
return;
}
switch (cmds[n].cmd_val)
{
case STATS:
areaTotal += extSubtreeTotalArea;
areaInteraction += extSubtreeInteractionArea;
areaClipped += extSubtreeClippedArea;
TxPrintf("Extraction statistics (recent/total):\n");
TxPrintf("Total area of all cells = %ld / %ld\n",
extSubtreeTotalArea, areaTotal);
a1 = extSubtreeTotalArea;
a2 = areaTotal;
if (a1 == 0) a1 = 1;
if (a2 == 0) a2 = 1;
TxPrintf(
"Total interaction area processed = %ld (%.2f%%) / %ld (%.2f%%)\n",
extSubtreeInteractionArea,
((double) extSubtreeInteractionArea) / ((double) a1) * 100.0,
areaInteraction,
((double) areaInteraction) / ((double) a2) * 100.0);
TxPrintf(
"Clipped interaction area= %ld (%.2f%%) / %ld (%.2f%%)\n",
extSubtreeClippedArea,
((double) extSubtreeClippedArea) / ((double) a1) * 100.0,
areaClipped,
((double) areaClipped) / ((double) a2) * 100.0);
extSubtreeTotalArea = 0;
extSubtreeInteractionArea = 0;
extSubtreeClippedArea = 0;
break;
case INTERACTIONS:
if (interPlane == NULL)
interPlane = DBNewPlane((ClientData) TT_SPACE);
halo = 1, bloat = 0;
if (cmd->tx_argc > 2) halo = atoi(cmd->tx_argv[2]) + 1;
if (cmd->tx_argc > 3) bloat = atoi(cmd->tx_argv[3]);
ExtFindInteractions(EditCellUse->cu_def, halo, bloat, interPlane);
(void) DBSrPaintArea((Tile *) NULL, interPlane, &TiPlaneRect,
&DBAllButSpaceBits, extShowInter, (ClientData) NULL);
DBClearPaintPlane(interPlane);
break;
case INTERCOUNT:
halo = 1;
if (cmd->tx_argc > 2)
halo = atoi(cmd->tx_argv[2]);
if (cmd->tx_argc > 3)
{
FILE *f = fopen(cmd->tx_argv[3], "w");
if (f == NULL)
{
perror(cmd->tx_argv[3]);
break;
}
ExtInterCount((CellUse *) w->w_surfaceID, halo, f);
fclose(f);
}
else
{
ExtInterCount((CellUse *) w->w_surfaceID, halo, stdout);
}
break;
case TIME:
if (cmd->tx_argc > 2)
{
FILE *f = fopen(cmd->tx_argv[2], "w");
if (f == NULL)
{
perror(cmd->tx_argv[2]);
break;
}
ExtTimes((CellUse *) w->w_surfaceID, f);
fclose(f);
}
else
{
ExtTimes((CellUse *) w->w_surfaceID, stdout);
}
break;
case EXTPARENTS:
if (ToolGetEditBox(&editArea))
ExtParentArea(EditCellUse, &editArea, TRUE);
break;
case DUMP:
if (cmd->tx_argc != 2 && cmd->tx_argc != 3)
{
TxError("Usage: *extract dump filename|-\n");
break;
}
ExtDumpCaps(cmd->tx_argc > 2 ? cmd->tx_argv[2] : "-");
break;
case DRIVER:
if (cmd->tx_argc != 3)
{
TxError("Usage: *extract driver terminalname\n");
break;
}
ExtSetDriver(cmd->tx_argv[2]);
break;
case RECEIVER:
if (cmd->tx_argc != 3)
{
TxError("Usage: *extract receiver terminalname\n");
break;
}
ExtSetReceiver(cmd->tx_argv[2]);
break;
case CLRLENGTH:
TxPrintf("Clearing driver/receiver length list\n");
ExtLengthClear();
break;
case SHOWPARENTS:
if (ToolGetEditBox(&editArea))
ExtParentArea(EditCellUse, &editArea, FALSE);
break;
case SETDEBUG:
DebugSet(extDebugID, cmd->tx_argc - 2, &cmd->tx_argv[2], TRUE);
break;
case CLRDEBUG:
DebugSet(extDebugID, cmd->tx_argc - 2, &cmd->tx_argv[2], FALSE);
break;
case SHOWDEBUG:
DebugShow(extDebugID);
break;
case SHOWTECH:
extShowTech(cmd->tx_argc > 2 ? cmd->tx_argv[2] : "-");
break;
case STEP:
TxPrintf("Current interaction step size is %d\n",
ExtCurStyle->exts_stepSize);
if (cmd->tx_argc > 2)
{
ExtCurStyle->exts_stepSize = atoi(cmd->tx_argv[2]);
TxPrintf("New interaction step size is %d\n",
ExtCurStyle->exts_stepSize);
}
break;
}
}
int
extShowInter(tile)
Tile *tile;
{
Rect r;
TiToRect(tile, &r);
DBWFeedbackAdd(&r, "interaction", EditCellUse->cu_def,
1, STYLE_MEDIUMHIGHLIGHTS);
return (0);
}
/*
* ----------------------------------------------------------------------------
*
* extShowTech --
*
* Display the technology-specific tables maintained for circuit
* extraction in a human-readable format. Intended mainly for
* debugging technology files. If the argument 'name' is "-",
* the output is to the standard output; otherwise, it is to
* the file whose name is 'name'.
*
* Results:
* None.
*
* Side effects:
* None.
*
* ----------------------------------------------------------------------------
*/
void
extShowTech(name)
char *name;
{
FILE *out;
TileType t, s;
int p;
EdgeCap *e;
if (strcmp(name, "-") == 0)
out = stdout;
else
{
out = fopen(name, "w");
if (out == NULL)
{
perror(name);
return;
}
}
extShowTrans("Transistor", &ExtCurStyle->exts_deviceMask, out);
fprintf(out, "\nNode resistance and capacitance:\n");
fprintf(out, "type R-ohm/sq AreaC-ff/l**2\n");
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
fprintf(out, "%-8.8s %8d %9lf\n",
DBTypeShortName(t),
ExtCurStyle->exts_resistByResistClass[
ExtCurStyle->exts_typeToResistClass[t]],
ExtCurStyle->exts_areaCap[t]);
fprintf(out, "\nTypes contributing to resistive perimeter:\n");
fprintf(out, "type R-type boundary types\n");
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
{
fprintf(out, "%-8.8s ", DBTypeShortName(t));
fprintf(out, "%7d ", ExtCurStyle->exts_typeToResistClass[t]);
extShowMask(&ExtCurStyle->exts_typesResistChanged[t], out);
fprintf(out, "\n");
}
fprintf(out, "\nSidewall capacitance:\n");
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
for (s = 0; s < DBNumTypes; s++)
if (ExtCurStyle->exts_perimCap[t][s] != (CapValue) 0)
fprintf(out, " %-8.8s %-8.8s %8lf\n",
DBTypeShortName(t), DBTypeShortName(s),
ExtCurStyle->exts_perimCap[t][s]);
fprintf(out, "\nInternodal overlap capacitance:\n");
fprintf(out, "\n (by plane)\n");
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
{
if (PlaneMaskHasPlane(ExtCurStyle->exts_overlapPlanes , p))
{
fprintf(out, " %-10.10s: types=", DBPlaneShortName(p));
extShowMask(&ExtCurStyle->exts_overlapTypes [p], out);
fprintf(out, "\n");
}
}
fprintf(out, "\n (by type)\n");
for (t = 0; t < DBNumTypes; t++)
if (!TTMaskIsZero(&ExtCurStyle->exts_overlapOtherTypes[t]))
{
fprintf(out, " %-10.10s: planes=", DBTypeShortName(t));
extShowPlanes(ExtCurStyle->exts_overlapOtherPlanes[t], out);
fprintf(out, "\n overlapped types=");
extShowMask(&ExtCurStyle->exts_overlapOtherTypes[t], out);
fprintf(out, "\n");
for (s = 0; s < DBNumTypes; s++)
if (ExtCurStyle->exts_overlapCap[t][s] != (CapValue) 0)
fprintf(out, " %-10.10s: %8lf\n",
DBTypeShortName(s), ExtCurStyle->exts_overlapCap[t][s]);
}
fprintf(out, "\nSidewall-coupling/sidewall-overlap capacitance:\n");
fprintf(out, "\n (by plane)\n");
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
{
if (PlaneMaskHasPlane(ExtCurStyle->exts_sidePlanes, p))
{
fprintf(out, " %-10.10s: ", DBPlaneShortName(p));
extShowMask(&ExtCurStyle->exts_sideTypes[p], out);
fprintf(out, "\n");
}
}
fprintf(out, "\n (by type)\n");
for (s = 0; s < DBNumTypes; s++)
if (!TTMaskIsZero(&ExtCurStyle->exts_sideEdges[s]))
{
fprintf(out, " %-10.10s: ", DBTypeShortName(s));
extShowMask(&ExtCurStyle->exts_sideEdges[s], out);
fprintf(out, "\n");
for (t = 0; t < DBNumTypes; t++)
{
if (!TTMaskIsZero(&ExtCurStyle->exts_sideCoupleOtherEdges[s][t]))
{
fprintf(out, " edge mask=");
extShowMask(&ExtCurStyle->exts_sideCoupleOtherEdges[s][t], out);
fprintf(out, "\n");
}
if (!TTMaskIsZero(&ExtCurStyle->exts_sideOverlapOtherTypes[s][t]))
{
fprintf(out, " overlap mask=");
extShowMask(&ExtCurStyle->exts_sideOverlapOtherTypes[s][t],
out);
fprintf(out, "\n");
}
if ((e = ExtCurStyle->exts_sideCoupleCap[s][t]))
for ( ; e; e = e->ec_next)
{
fprintf(out, " COUPLE: ");
extShowMask(&e->ec_near, out);
fprintf(out, " || ");
extShowMask(&e->ec_far, out);
fprintf(out, ": %lf\n", e->ec_cap);
}
if ((e = ExtCurStyle->exts_sideOverlapCap[s][t]))
for ( ; e; e = e->ec_next)
{
fprintf(out, " OVERLAP: ");
extShowMask(&e->ec_near, out);
fprintf(out, ": %lf\n", e->ec_cap);
}
}
}
fprintf(out, "\n\nSidewall coupling halo = %d\n", ExtCurStyle->exts_sideCoupleHalo );
extShowConnect("\nNode connectivity", ExtCurStyle->exts_nodeConn, out);
extShowConnect("\nResistive region connectivity", ExtCurStyle->exts_resistConn, out);
extShowConnect("\nTransistor connectivity", ExtCurStyle->exts_deviceConn, out);
if (out != stdout)
(void) fclose(out);
}
void
extShowTrans(name, mask, out)
char *name;
TileTypeBitMask *mask;
FILE *out;
{
TileType t;
fprintf(out, "%s types: ", name);
extShowMask(mask, out);
fprintf(out, "\n");
for (t = 0; t < DBNumTypes; t++)
if (TTMaskHasType(mask, t))
{
ExtDevice *devptr;
for (devptr = ExtCurStyle->exts_device[t]; devptr; devptr = devptr->exts_next)
{
fprintf(out, " %-8.8s %d terminals: ",
DBTypeShortName(t), devptr->exts_deviceSDCount);
extShowMask(&devptr->exts_deviceSDTypes[0], out);
fprintf(out, "\n\tcap (gate-sd/gate-ch) = %lf/%lf\n",
devptr->exts_deviceSDCap,
devptr->exts_deviceGateCap);
}
}
}
void
extShowConnect(hdr, connectsTo, out)
char *hdr;
TileTypeBitMask *connectsTo;
FILE *out;
{
TileType t;
fprintf(out, "%s\n", hdr);
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
if (!TTMaskEqual(&connectsTo[t], &DBZeroTypeBits))
{
fprintf(out, " %-8.8s: ", DBTypeShortName(t));
extShowMask(&connectsTo[t], out);
fprintf(out, "\n");
}
}
void
extShowMask(m, out)
TileTypeBitMask *m;
FILE *out;
{
TileType t;
bool first = TRUE;
for (t = 0; t < DBNumTypes; t++)
if (TTMaskHasType(m, t))
{
if (!first)
fprintf(out, ",");
first = FALSE;
fprintf(out, "%s", DBTypeShortName(t));
}
}
void
extShowPlanes(m, out)
PlaneMask m;
FILE *out;
{
int pNum;
bool first = TRUE;
for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++)
if (PlaneMaskHasPlane(m, pNum))
{
if (!first)
fprintf(out, ",");
first = FALSE;
fprintf(out, "%s", DBPlaneShortName(pNum));
}
}
/*
* ----------------------------------------------------------------------------
*
* extDispInit --
*
* Initialize the screen information to be used during
* extraction debugging.
*
* Results:
* None.
*
* Side effects:
* Initializes extDebugWindow, extScreenClip, and extCellDef.
*
* ----------------------------------------------------------------------------
*/
void
extDispInit(def, w)
CellDef *def;
MagWindow *w;
{
extDebugWindow = w;
extCellDef = def;
extScreenClip = w->w_screenArea;
GeoClip(&extScreenClip, &GrScreenRect);
}
/*
* ----------------------------------------------------------------------------
*
* extShowEdge --
*
* Display the edge described by the Boundary 'bp' on the display,
* with text string 's' on the text terminal. Prompt with '--next--'
* to allow a primitive sort of 'more' processing.
*
* Results:
* None.
*
* Side effects:
* Updates the display.
*
* ----------------------------------------------------------------------------
*/
void
extShowEdge(s, bp)
char *s;
Boundary *bp;
{
Rect extScreenRect, edgeRect;
int style = STYLE_PURPLE1;
edgeRect = bp->b_segment;
WindSurfaceToScreen(extDebugWindow, &edgeRect, &extScreenRect);
if (extScreenRect.r_ybot == extScreenRect.r_ytop)
{
extScreenRect.r_ybot -= extEdgePixels/2;
extScreenRect.r_ytop += extEdgePixels - extEdgePixels/2;
}
else /* extScreenRect.r_xtop == extScreenRect.r_xbot */
{
extScreenRect.r_xbot -= extEdgePixels/2;
extScreenRect.r_xtop += extEdgePixels - extEdgePixels/2;
}
if (DebugIsSet(extDebugID, extDebVisOnly))
{
Rect r;
r = extScreenRect;
GeoClip(&r, &extScreenClip);
if (r.r_xtop <= r.r_xbot || r.r_ytop <= r.r_ybot)
return;
}
TxPrintf("%s: ", s);
GrLock(extDebugWindow, TRUE);
GrClipBox(&extScreenRect, style);
GrUnlock(extDebugWindow);
(void) GrFlush();
extMore();
GrLock(extDebugWindow, TRUE);
GrClipBox(&extScreenRect, STYLE_ORANGE1);
GrUnlock(extDebugWindow);
(void) GrFlush();
}
/*
* ----------------------------------------------------------------------------
*
* extShowTile --
*
* Display the tile 'tp' on the display by highlighting it. Also show
* the text string 's' on the terminal. Prompt with '--next--' to allow
* a primitive sort of more processing.
*
* Results:
* None.
*
* Side effects:
* Updates the display.
*
* ----------------------------------------------------------------------------
*/
void
extShowTile(tile, s, style_index)
Tile *tile;
char *s;
int style_index;
{
Rect tileRect;
static int styles[] = { STYLE_PALEHIGHLIGHTS, STYLE_DOTTEDHIGHLIGHTS };
TiToRect(tile, &tileRect);
if (!extShowRect(&tileRect, styles[style_index]))
return;
TxPrintf("%s: ", s);
extMore();
(void) extShowRect(&tileRect, STYLE_ERASEHIGHLIGHTS);
}
bool
extShowRect(r, style)
Rect *r;
int style;
{
Rect extScreenRect;
WindSurfaceToScreen(extDebugWindow, r, &extScreenRect);
if (DebugIsSet(extDebugID, extDebVisOnly))
{
Rect rclip;
rclip = extScreenRect;
GeoClip(&rclip, &extScreenClip);
if (rclip.r_xtop <= rclip.r_xbot || rclip.r_ytop <= rclip.r_ybot)
return (FALSE);
}
GrLock(extDebugWindow, TRUE);
GrClipBox(&extScreenRect, style);
GrUnlock(extDebugWindow);
(void) GrFlush();
return (TRUE);
}
void
extMore()
{
char line[100];
TxPrintf("--next--"); (void) fflush(stdout);
(void) TxGetLine(line, sizeof line);
}
void
extNewYank(name, puse, pdef)
char *name;
CellUse **puse;
CellDef **pdef;
{
DBNewYank(name, puse, pdef);
}
/*
* ----------------------------------------------------------------------------
* Dump parasitic capacitance extraction information to a file
* ----------------------------------------------------------------------------
*/
void
ExtDumpCapsToFile(f)
FILE *f;
{
TileType t, s, r;
EdgeCap *e;
int p, found;
fprintf(f, "Parasitic extraction capacitance values\n");
fprintf(f, "\n1) Area caps\n");
for (t = 0; t < DBNumTypes; t++)
{
if (ExtCurStyle->exts_areaCap[t] > 0.0)
fprintf(f, "%s %3.3f\n",
DBTypeLongNameTbl[t],
ExtCurStyle->exts_areaCap[t]);
}
fprintf(f, "\n2) Perimeter caps\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
if (ExtCurStyle->exts_perimCap[t][s] > 0.0)
fprintf(f, "%s | %s %3.3f\n",
DBTypeLongNameTbl[t],
DBTypeLongNameTbl[s],
ExtCurStyle->exts_perimCap[t][s]);
}
}
fprintf(f, "\n3) Overlap caps\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
if (ExtCurStyle->exts_overlapCap[t][s] > 0.0)
fprintf(f, "%s | %s %3.3f\n",
DBTypeLongNameTbl[t],
DBTypeLongNameTbl[s],
ExtCurStyle->exts_overlapCap[t][s]);
}
}
fprintf(f, "\n4) Side coupling caps\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
for (e = ExtCurStyle->exts_sideCoupleCap[t][s]; e; e = e->ec_next) {
fprintf(f, "%s | %s: %3.3f\n",
DBTypeLongNameTbl[t],
DBTypeLongNameTbl[s],
e->ec_cap);
fprintf(f, " near: ");
for (r = 0; r < DBNumTypes; r++)
if (TTMaskHasType(&e->ec_near, r))
fprintf(f, " %s", DBTypeLongNameTbl[r]);
fprintf(f, "\n far: ");
for (r = 0; r < DBNumTypes; r++)
if (TTMaskHasType(&e->ec_far, r))
fprintf(f, " %s", DBTypeLongNameTbl[r]);
fprintf(f, "\n planes: ");
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
if (PlaneMaskHasPlane(e->ec_pmask, p))
fprintf(f, " %s", DBPlaneLongNameTbl[p]);
fprintf(f, "\n");
}
}
}
fprintf(f, "\n5) Side overlap caps\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
for (e = ExtCurStyle->exts_sideOverlapCap[t][s]; e; e = e->ec_next) {
fprintf(f, "%s | %s: %3.3f\n",
DBTypeLongNameTbl[t],
DBTypeLongNameTbl[s],
e->ec_cap);
fprintf(f, " near: ");
for (r = 0; r < DBNumTypes; r++)
if (TTMaskHasType(&e->ec_near, r))
fprintf(f, " %s", DBTypeLongNameTbl[r]);
fprintf(f, "\n far: ");
for (r = 0; r < DBNumTypes; r++)
if (TTMaskHasType(&e->ec_far, r))
fprintf(f, " %s", DBTypeLongNameTbl[r]);
fprintf(f, "\n planes: ");
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
if (PlaneMaskHasPlane(e->ec_pmask, p))
fprintf(f, " %s", DBPlaneLongNameTbl[p]);
fprintf(f, "\n");
}
}
}
fprintf(f, "\n6) (Check) Perimeter cap mask\n");
for (t = 0; t < DBNumTypes; t++)
{
found = 0;
for (s = 0; s < DBNumTypes; s++)
if (TTMaskHasType(&ExtCurStyle->exts_perimCapMask[t], s))
{
if (found == 0)
{
fprintf(f, " %s: ", DBTypeLongNameTbl[t]);
found = 1;
}
fprintf(f, " %s", DBTypeLongNameTbl[s]);
}
if (found != 0) fprintf(f, "\n");
}
fprintf(f, "\n7) (Check) Overlap plane mask\n");
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
if (PlaneMaskHasPlane(ExtCurStyle->exts_overlapPlanes, p))
fprintf(f, " %s", DBPlaneLongNameTbl[p]);
fprintf(f, "\n");
fprintf(f, "\n8) (Check) Overlap types mask\n");
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
{
found = 0;
for (s = 0; s < DBNumTypes; s++)
if (TTMaskHasType(&ExtCurStyle->exts_overlapTypes[p], s))
{
if (found == 0)
{
found = 1;
fprintf(f, " %s: ", DBPlaneLongNameTbl[p]);
}
fprintf(f, " %s", DBTypeLongNameTbl[s]);
}
if (found != 0) fprintf(f, "\n");
}
fprintf(f, "\n9) (Check) Overlap other types mask\n");
for (t = 0; t < DBNumTypes; t++)
{
found = 0;
for (s = 0; s < DBNumTypes; s++)
if (TTMaskHasType(&ExtCurStyle->exts_overlapOtherTypes[t], s))
{
if (found == 0)
{
fprintf(f, " %s: ", DBTypeLongNameTbl[t]);
found = 1;
}
fprintf(f, " %s", DBTypeLongNameTbl[s]);
}
if (found != 0) fprintf(f, "\n");
}
fprintf(f, "\n10) (Check) Overlap other planes mask\n");
for (t = 0; t < DBNumTypes; t++)
{
found = 0;
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
if (PlaneMaskHasPlane(ExtCurStyle->exts_overlapOtherPlanes[t], p))
{
if (found == 0)
{
fprintf(f, " %s: ", DBTypeLongNameTbl[t]);
found = 1;
}
fprintf(f, " %s", DBPlaneLongNameTbl[p]);
}
if (found != 0) fprintf(f, "\n");
}
fprintf(f, "\n11) (Check) Overlap shield types mask\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
found = 0;
for (r = 0; r < DBNumTypes; r++)
if (TTMaskHasType(&ExtCurStyle->exts_overlapShieldTypes[t][s], r))
{
if (found == 0)
{
fprintf(f, " %s | %s: ",
DBTypeLongNameTbl[t], DBTypeLongNameTbl[s]);
found = 1;
}
fprintf(f, " %s", DBTypeLongNameTbl[r]);
}
if (found != 0) fprintf(f, "\n");
}
}
fprintf(f, "\n12) (Check) Overlap shield planes mask\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
found = 0;
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
if (PlaneMaskHasPlane(ExtCurStyle->exts_overlapShieldPlanes[t][s], p))
{
if (found == 0)
{
fprintf(f, " %s | %s: ",
DBTypeLongNameTbl[t], DBTypeLongNameTbl[s]);
found = 1;
}
fprintf(f, " %s", DBPlaneLongNameTbl[p]);
}
if (found != 0) fprintf(f, "\n");
}
}
fprintf(f, "\n13) (Check) Side couple other edges mask\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
found = 0;
for (r = 0; r < DBNumTypes; r++)
if (TTMaskHasType(&ExtCurStyle->exts_sideCoupleOtherEdges[t][s], r))
{
if (found == 0)
{
fprintf(f, " %s | %s: ",
DBTypeLongNameTbl[t], DBTypeLongNameTbl[s]);
found = 1;
}
fprintf(f, " %s", DBTypeLongNameTbl[r]);
}
if (found != 0) fprintf(f, "\n");
}
}
fprintf(f, "\n14) (Check) Side overlap other planes mask\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
found = 0;
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
if (PlaneMaskHasPlane(ExtCurStyle->exts_sideOverlapOtherPlanes[t][s], p))
{
if (found == 0)
{
fprintf(f, " %s | %s: ",
DBTypeLongNameTbl[t], DBTypeLongNameTbl[s]);
found = 1;
}
fprintf(f, " %s", DBPlaneLongNameTbl[p]);
}
if (found != 0) fprintf(f, "\n");
}
}
fprintf(f, "\n15) (Check) Side overlap other types mask\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
found = 0;
for (r = 0; r < DBNumTypes; r++)
if (TTMaskHasType(&ExtCurStyle->exts_sideOverlapOtherTypes[t][s], r))
{
if (found == 0)
{
fprintf(f, " %s | %s: ",
DBTypeLongNameTbl[t], DBTypeLongNameTbl[s]);
found = 1;
}
fprintf(f, " %s", DBTypeLongNameTbl[r]);
}
if (found != 0) fprintf(f, "\n");
}
}
fprintf(f, "\n16) (Check) Side overlap shield planes mask\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
found = 0;
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
if (PlaneMaskHasPlane(ExtCurStyle->exts_sideOverlapShieldPlanes[t][s], p))
{
if (found == 0)
{
fprintf(f, " %s | %s: ",
DBTypeLongNameTbl[t], DBTypeLongNameTbl[s]);
found = 1;
}
fprintf(f, " %s", DBPlaneLongNameTbl[p]);
}
if (found != 0) fprintf(f, "\n");
}
}
fprintf(f, "\n17) (Check) Side planes mask\n");
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
if (PlaneMaskHasPlane(ExtCurStyle->exts_sidePlanes, p))
fprintf(f, " %s", DBPlaneLongNameTbl[p]);
fprintf(f, "\n");
fprintf(f, "\n18) (Check) Side types mask\n");
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
{
found = 0;
for (s = 0; s < DBNumTypes; s++)
if (TTMaskHasType(&ExtCurStyle->exts_sideTypes[p], s))
{
if (found == 0)
{
fprintf(f, " %s: ", DBPlaneLongNameTbl[p]);
found = 1;
}
fprintf(f, " %s", DBTypeLongNameTbl[s]);
}
if (found != 0) fprintf(f, "\n");
}
fprintf(f, "\n19) (Check) Side edges mask\n");
for (t = 0; t < DBNumTypes; t++)
{
found = 0;
for (s = 0; s < DBNumTypes; s++)
if (TTMaskHasType(&ExtCurStyle->exts_sideTypes[t], s))
{
if (found == 0)
{
fprintf(f, " %s: ", DBTypeLongNameTbl[t]);
found = 1;
}
fprintf(f, " %s", DBTypeLongNameTbl[s]);
}
if (found != 0) fprintf(f, "\n");
}
}
/*
* ----------------------------------------------------------------------------
* ExtDumpCaps ---
* Debugging tool. Dump information about all parasitics
* ----------------------------------------------------------------------------
*/
void
ExtDumpCaps(filename)
char *filename;
{
TileType t, s, r;
EdgeCap *e;
int p, found;
if (strcmp(filename, "-"))
{
FILE *f;
f = fopen(filename, "w");
if (f == NULL)
{
TxError("Cannot open file %s for writing\n", filename);
return;
}
ExtDumpCapsToFile(f);
fclose(f);
return;
}
TxPrintf("Parasitic extraction capacitance values\n");
TxPrintf("\n1) Area caps\n");
for (t = 0; t < DBNumTypes; t++)
{
if (ExtCurStyle->exts_areaCap[t] > 0.0)
TxPrintf("%s %3.3f\n",
DBTypeLongNameTbl[t],
ExtCurStyle->exts_areaCap[t]);
}
TxPrintf("\n2) Perimeter caps\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
if (ExtCurStyle->exts_perimCap[t][s] > 0.0)
TxPrintf("%s | %s %3.3f\n",
DBTypeLongNameTbl[t],
DBTypeLongNameTbl[s],
ExtCurStyle->exts_perimCap[t][s]);
}
}
TxPrintf("\n3) Overlap caps\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
if (ExtCurStyle->exts_overlapCap[t][s] > 0.0)
TxPrintf("%s | %s %3.3f\n",
DBTypeLongNameTbl[t],
DBTypeLongNameTbl[s],
ExtCurStyle->exts_overlapCap[t][s]);
}
}
TxPrintf("\n4) Side coupling caps\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
for (e = ExtCurStyle->exts_sideCoupleCap[t][s]; e; e = e->ec_next) {
TxPrintf("%s | %s: %3.3f\n",
DBTypeLongNameTbl[t],
DBTypeLongNameTbl[s],
e->ec_cap);
TxPrintf(" near: ");
for (r = 0; r < DBNumTypes; r++)
if (TTMaskHasType(&e->ec_near, r))
TxPrintf(" %s", DBTypeLongNameTbl[r]);
TxPrintf("\n far: ");
for (r = 0; r < DBNumTypes; r++)
if (TTMaskHasType(&e->ec_far, r))
TxPrintf(" %s", DBTypeLongNameTbl[r]);
TxPrintf("\n planes: ");
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
if (PlaneMaskHasPlane(e->ec_pmask, p))
TxPrintf(" %s", DBPlaneLongNameTbl[p]);
TxPrintf("\n");
}
}
}
TxPrintf("\n5) Side overlap caps\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
for (e = ExtCurStyle->exts_sideOverlapCap[t][s]; e; e = e->ec_next) {
TxPrintf("%s | %s: %3.3f\n",
DBTypeLongNameTbl[t],
DBTypeLongNameTbl[s],
e->ec_cap);
TxPrintf(" near: ");
for (r = 0; r < DBNumTypes; r++)
if (TTMaskHasType(&e->ec_near, r))
TxPrintf(" %s", DBTypeLongNameTbl[r]);
TxPrintf("\n far: ");
for (r = 0; r < DBNumTypes; r++)
if (TTMaskHasType(&e->ec_far, r))
TxPrintf(" %s", DBTypeLongNameTbl[r]);
TxPrintf("\n planes: ");
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
if (PlaneMaskHasPlane(e->ec_pmask, p))
TxPrintf(" %s", DBPlaneLongNameTbl[p]);
TxPrintf("\n");
}
}
}
TxPrintf("\n6) (Check) Perimeter cap mask\n");
for (t = 0; t < DBNumTypes; t++)
{
found = 0;
for (s = 0; s < DBNumTypes; s++)
if (TTMaskHasType(&ExtCurStyle->exts_perimCapMask[t], s))
{
if (found == 0)
{
TxPrintf(" %s: ", DBTypeLongNameTbl[t]);
found = 1;
}
TxPrintf(" %s", DBTypeLongNameTbl[s]);
}
if (found != 0) TxPrintf("\n");
}
TxPrintf("\n7) (Check) Overlap plane mask\n");
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
if (PlaneMaskHasPlane(ExtCurStyle->exts_overlapPlanes, p))
TxPrintf(" %s", DBPlaneLongNameTbl[p]);
TxPrintf("\n");
TxPrintf("\n8) (Check) Overlap types mask\n");
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
{
found = 0;
for (s = 0; s < DBNumTypes; s++)
if (TTMaskHasType(&ExtCurStyle->exts_overlapTypes[p], s))
{
if (found == 0)
{
found = 1;
TxPrintf(" %s: ", DBPlaneLongNameTbl[p]);
}
TxPrintf(" %s", DBTypeLongNameTbl[s]);
}
if (found != 0) TxPrintf("\n");
}
TxPrintf("\n9) (Check) Overlap other types mask\n");
for (t = 0; t < DBNumTypes; t++)
{
found = 0;
for (s = 0; s < DBNumTypes; s++)
if (TTMaskHasType(&ExtCurStyle->exts_overlapOtherTypes[t], s))
{
if (found == 0)
{
TxPrintf(" %s: ", DBTypeLongNameTbl[t]);
found = 1;
}
TxPrintf(" %s", DBTypeLongNameTbl[s]);
}
if (found != 0) TxPrintf("\n");
}
TxPrintf("\n10) (Check) Overlap other planes mask\n");
for (t = 0; t < DBNumTypes; t++)
{
found = 0;
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
if (PlaneMaskHasPlane(ExtCurStyle->exts_overlapOtherPlanes[t], p))
{
if (found == 0)
{
TxPrintf(" %s: ", DBTypeLongNameTbl[t]);
found = 1;
}
TxPrintf(" %s", DBPlaneLongNameTbl[p]);
}
if (found != 0) TxPrintf("\n");
}
TxPrintf("\n11) (Check) Overlap shield types mask\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
found = 0;
for (r = 0; r < DBNumTypes; r++)
if (TTMaskHasType(&ExtCurStyle->exts_overlapShieldTypes[t][s], r))
{
if (found == 0)
{
TxPrintf(" %s | %s: ",
DBTypeLongNameTbl[t], DBTypeLongNameTbl[s]);
found = 1;
}
TxPrintf(" %s", DBTypeLongNameTbl[r]);
}
if (found != 0) TxPrintf("\n");
}
}
TxPrintf("\n12) (Check) Overlap shield planes mask\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
found = 0;
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
if (PlaneMaskHasPlane(ExtCurStyle->exts_overlapShieldPlanes[t][s], p))
{
if (found == 0)
{
TxPrintf(" %s | %s: ",
DBTypeLongNameTbl[t], DBTypeLongNameTbl[s]);
found = 1;
}
TxPrintf(" %s", DBPlaneLongNameTbl[p]);
}
if (found != 0) TxPrintf("\n");
}
}
TxPrintf("\n13) (Check) Side couple other edges mask\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
found = 0;
for (r = 0; r < DBNumTypes; r++)
if (TTMaskHasType(&ExtCurStyle->exts_sideCoupleOtherEdges[t][s], r))
{
if (found == 0)
{
TxPrintf(" %s | %s: ",
DBTypeLongNameTbl[t], DBTypeLongNameTbl[s]);
found = 1;
}
TxPrintf(" %s", DBTypeLongNameTbl[r]);
}
if (found != 0) TxPrintf("\n");
}
}
TxPrintf("\n14) (Check) Side overlap other planes mask\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
found = 0;
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
if (PlaneMaskHasPlane(ExtCurStyle->exts_sideOverlapOtherPlanes[t][s], p))
{
if (found == 0)
{
TxPrintf(" %s | %s: ",
DBTypeLongNameTbl[t], DBTypeLongNameTbl[s]);
found = 1;
}
TxPrintf(" %s", DBPlaneLongNameTbl[p]);
}
if (found != 0) TxPrintf("\n");
}
}
TxPrintf("\n15) (Check) Side overlap other types mask\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
found = 0;
for (r = 0; r < DBNumTypes; r++)
if (TTMaskHasType(&ExtCurStyle->exts_sideOverlapOtherTypes[t][s], r))
{
if (found == 0)
{
TxPrintf(" %s | %s: ",
DBTypeLongNameTbl[t], DBTypeLongNameTbl[s]);
found = 1;
}
TxPrintf(" %s", DBTypeLongNameTbl[r]);
}
if (found != 0) TxPrintf("\n");
}
}
TxPrintf("\n16) (Check) Side overlap shield planes mask\n");
for (t = 0; t < DBNumTypes; t++)
{
for (s = 0; s < DBNumTypes; s++)
{
found = 0;
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
if (PlaneMaskHasPlane(ExtCurStyle->exts_sideOverlapShieldPlanes[t][s], p))
{
if (found == 0)
{
TxPrintf(" %s | %s: ",
DBTypeLongNameTbl[t], DBTypeLongNameTbl[s]);
found = 1;
}
TxPrintf(" %s", DBPlaneLongNameTbl[p]);
}
if (found != 0) TxPrintf("\n");
}
}
TxPrintf("\n17) (Check) Side planes mask\n");
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
if (PlaneMaskHasPlane(ExtCurStyle->exts_sidePlanes, p))
TxPrintf(" %s", DBPlaneLongNameTbl[p]);
TxPrintf("\n");
TxPrintf("\n18) (Check) Side types mask\n");
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
{
found = 0;
for (s = 0; s < DBNumTypes; s++)
if (TTMaskHasType(&ExtCurStyle->exts_sideTypes[p], s))
{
if (found == 0)
{
TxPrintf(" %s: ", DBPlaneLongNameTbl[p]);
found = 1;
}
TxPrintf(" %s", DBTypeLongNameTbl[s]);
}
if (found != 0) TxPrintf("\n");
}
TxPrintf("\n19) (Check) Side edges mask\n");
for (t = 0; t < DBNumTypes; t++)
{
found = 0;
for (s = 0; s < DBNumTypes; s++)
if (TTMaskHasType(&ExtCurStyle->exts_sideTypes[t], s))
{
if (found == 0)
{
TxPrintf(" %s: ", DBTypeLongNameTbl[t]);
found = 1;
}
TxPrintf(" %s", DBTypeLongNameTbl[s]);
}
if (found != 0) TxPrintf("\n");
}
}