(1) Added a check for unclosed boundaries when reading GDS.

This is diagnostic only and does not change the read-in
    behavior.
(2) ext2spice:  Corrected an error that had been introduced
    into version 8.3.171 that accidentally marks all devices
    as visited which causes all source/drain areas and
    perimeters to be output as zero.
(3) extract:  Sweeping changes to handling of fringe
    capacitance.  Removed the (recently added) "fringeshieldhalo"
    parameter from the tech file.  Reworked the fringe
    capacitance models based on results from the "capiche"
    project (github/RTimothyEdwards/capiche).  Fringe shielding
    is now done by clipping fringe at the boundary of a
    shielding shape, rather than trying to calculate the
    amount of shielding (as the "capiche" project proved this
    to be equivalent).  Values for partial fringing are modeled
    by atan(x), which like the sidewall (1/x) curve, extends to
    infinity and values are limited by the halo but do not
    otherwise depend on the halo.  Because of this, the halo can
    be made variable and controlled by the user for deciding on
    the tradeoff between accuracy and run time.  A new command
    option "extract halo" was added to allow this control over
    the halo distance.
This commit is contained in:
Tim Edwards 2023-01-27 11:47:37 -05:00
parent 8d08cb2f2f
commit 1a3caee376
10 changed files with 341 additions and 499 deletions

View File

@ -1 +1 @@
8.3.363
8.3.364

View File

@ -283,7 +283,7 @@ calmaElementBoundary()
/* Convert the polygon to rectangles. */
rp = CIFPolyToRects(pathheadp, plane, CIFPaintTable, (PaintUndoInfo *)NULL);
rp = CIFPolyToRects(pathheadp, plane, CIFPaintTable, (PaintUndoInfo *)NULL, TRUE);
CIFFreePath(pathheadp);
/* If the input layer is designated for ports by a "label" */

View File

@ -29,6 +29,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "database/database.h"
#include "cif/CIFint.h"
#include "cif/CIFread.h"
#include "calma/calma.h"
#include "utils/malloc.h"
#define HEDGE 0 /* Horizontal edge */
@ -222,11 +223,12 @@ cifCross(edge, dir, ybot, ytop)
*/
LinkedRect *
CIFPolyToRects(path, plane, resultTbl, ui)
CIFPolyToRects(path, plane, resultTbl, ui, isCalma)
CIFPath *path; /* Path describing a polygon. */
Plane *plane; /* Plane to draw on */
PaintResultType *resultTbl;
PaintUndoInfo *ui;
bool isCalma; /* TRUE for Calma, FALSE for CIF */
{
int npts = 0, n, *dir, curr, wrapno;
int xbot, xtop, ybot, ytop;
@ -240,6 +242,9 @@ CIFPolyToRects(path, plane, resultTbl, ui)
if ((tail->cifp_x != path->cifp_x) || (tail->cifp_y != path->cifp_y))
{
if (isCalma)
CalmaReadError("Boundary is not closed.\n" );
p = (CIFPath *) mallocMagic ((unsigned) sizeof (CIFPath));
p->cifp_x = path->cifp_x;
p->cifp_y = path->cifp_y;

View File

@ -481,7 +481,7 @@ CIFPaintWirePath(pathheadp, width, endcap, plane, ptable, ui)
/* Slow draw for non-Manhattan paths: */
/* Break the area up into triangles and rectangles */
rectp = CIFPolyToRects(polypath, plane, ptable, ui);
rectp = CIFPolyToRects(polypath, plane, ptable, ui, FALSE);
CIFFreePath(polypath);
for (; rectp != NULL ; rectp = rectp->r_next)
@ -583,7 +583,7 @@ PaintPolygon(pointlist, number, plane, ptable, ui, keep)
cifpath = newpath;
}
rectlist = CIFPolyToRects(cifpath, plane, ptable, ui);
rectlist = CIFPolyToRects(cifpath, plane, ptable, ui, FALSE);
CIFFreePath(cifpath);
for (rectp = rectlist; rectp != NULL ; rectp = rectp->r_next)
@ -807,7 +807,7 @@ CIFParsePoly()
/* Convert the polygon to rectangles. */
rectp = CIFPolyToRects(pathheadp, cifReadPlane, CIFPaintTable,
(PaintUndoInfo *)NULL);
(PaintUndoInfo *)NULL, FALSE);
CIFFreePath(pathheadp);
if (rectp == NULL)
{

View File

@ -2907,7 +2907,7 @@ CmdCorner(w, cmd)
ui.pu_pNum = pNum;
rectp = CIFPolyToRects(cmdPathList.pathlist->pathhead, plane,
resultTbl, &ui);
resultTbl, &ui, FALSE);
for (; rectp != NULL; rectp = rectp->r_next)
{
DBPaintPlane(plane, &rectp->r_r, resultTbl, &ui);

View File

@ -42,6 +42,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "drc/drc.h"
#include "textio/txcommands.h"
#include "extract/extract.h"
#include "extract/extractInt.h"
#include "select/select.h"
/* C99 compat */
@ -860,14 +861,15 @@ cmdExpandFunc(use, windowMask)
#define EXTALL 0
#define EXTCELL 1
#define EXTDO 2
#define EXTHELP 3
#define EXTLENGTH 4
#define EXTNO 5
#define EXTPARENTS 6
#define EXTSHOWPARENTS 7
#define EXTSTYLE 8
#define EXTUNIQUE 9
#define EXTWARN 10
#define EXTHALO 3
#define EXTHELP 4
#define EXTLENGTH 5
#define EXTNO 6
#define EXTPARENTS 7
#define EXTSHOWPARENTS 8
#define EXTSTYLE 9
#define EXTUNIQUE 10
#define EXTWARN 11
#define WARNALL 0
#define WARNDUP 1
@ -900,6 +902,7 @@ CmdExtract(w, cmd)
{
char **msg, *namep, *arg;
int option, warn, len, n, all;
int dist;
bool no;
CellUse *selectedUse;
CellDef *selectedDef;
@ -953,6 +956,7 @@ CmdExtract(w, cmd)
"all extract root cell and all its children",
"cell name extract selected cell into file \"name\"",
"do [option] enable extractor option",
"halo [value] print or set the sidewall halo distance",
"help print this help information",
"length [option] control pathlength extraction information",
"no [option] disable extractor option",
@ -1060,6 +1064,36 @@ CmdExtract(w, cmd)
ExtractOneCell(selectedUse->cu_def, namep, FALSE);
return;
case EXTHALO:
if (ExtCurStyle == NULL)
{
TxError("No extraction style set.\n");
return;
}
else if (argc == 2)
{
#ifdef MAGIC_WRAPPER
Tcl_Obj *tobj;
tobj = Tcl_NewIntObj(ExtCurStyle->exts_sideCoupleHalo);
Tcl_SetObjResult(magicinterp, tobj);
#else
TxPrintf("Side overlap halo is %d\n", ExtCurStyle->exts_sideCoupleHalo);
#endif
return;
}
else if (argc != 3) goto wrongNumArgs;
/* argv[2] is a halo distance */
dist = cmdParseCoord(w, argv[2], TRUE, TRUE);
if (dist <= 0)
{
TxError("Bad halo distance. Halo must be strictly positive.");
return;
}
else
ExtCurStyle->exts_sideCoupleHalo = dist;
break;
case EXTPARENTS:
selectedUse = CmdGetSelectedCell((Transform *) NULL);
if (selectedUse == NULL)

View File

@ -1093,7 +1093,7 @@ runexttospice:
TTMaskZero(&initMask);
if (!esDistrJunct)
TTMaskCom(&initMask);
TTMaskSetType(&initMask, efNumResistClasses);
if (esMergeDevsA || esMergeDevsC)
{
@ -1271,7 +1271,7 @@ main(argc, argv)
TTMaskZero(&initMask);
if (!esDistrJunct)
TTMaskCom(&initMask);
TTMaskSetType(&initMask, efNumResistClasses);
if ( esMergeDevsA || esMergeDevsC ) {
EFVisitDevs(devMergeVisit, (ClientData) NULL);

File diff suppressed because it is too large Load Diff

View File

@ -62,6 +62,12 @@ void extTechFinalStyle();
void ExtLoadStyle();
void ExtTechScale(int, int);
/* This is a placeholder value; it may be approximately
* constant across processes, or it may need to be set
* per process.
*/
#define FRINGE_MULT 0.02
/*
* Table used for parsing the extract section of a .tech file
* Each line in the extract section is of a type determined by
@ -767,6 +773,7 @@ extTechStyleInit(style)
style->exts_sideOverlapCap[r][s] = (EdgeCap *) NULL;
style->exts_perimCap[r][s] = (CapValue) 0;
style->exts_overlapCap[r][s] = (CapValue) 0;
style->exts_overlapMult[r][s] = (float) 0;
TTMaskZero(&style->exts_overlapShieldTypes[r][s]);
style->exts_overlapShieldPlanes[r][s] = 0;
@ -815,7 +822,6 @@ extTechStyleInit(style)
}
style->exts_sideCoupleHalo = 0;
style->exts_fringeShieldHalo = 0;
style->exts_stepSize = 100;
style->exts_unitsPerLambda = 100.0;
style->exts_resistScale = 1000;
@ -1064,6 +1070,7 @@ ExtTechSimpleAreaCap(argc, argv)
TileType s, t;
TileTypeBitMask types, subtypes, shields;
CapValue capVal;
float multVal;
int plane1, plane2, plane3, pnum1, pnum2, pnum3;
PlaneMask pshield;
@ -1096,7 +1103,11 @@ ExtTechSimpleAreaCap(argc, argv)
/* Part 1: Area cap */
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
if (TTMaskHasType(&types, t))
{
ExtCurStyle->exts_areaCap[t] = capVal;
ExtCurStyle->exts_overlapMult[t][0] = (float) capVal * FRINGE_MULT;
ExtCurStyle->exts_overlapMult[0][t] = (float) capVal * FRINGE_MULT;
}
if ((plane2 == -1) && (ExtCurStyle->exts_globSubstratePlane == -1)) return;
else if (plane1 == plane2) return; /* shouldn't happen */
@ -1182,6 +1193,8 @@ ExtTechSimpleAreaCap(argc, argv)
continue; /* redundant overlap */
ExtCurStyle->exts_overlapCap[s][t] = capVal;
ExtCurStyle->exts_overlapMult[s][t] = (float)capVal * FRINGE_MULT;
ExtCurStyle->exts_overlapMult[t][s] = (float)capVal * FRINGE_MULT;
ExtCurStyle->exts_overlapPlanes |= PlaneNumToMaskBit(plane1);
if (plane2 != -1)
ExtCurStyle->exts_overlapOtherPlanes[s] |= PlaneNumToMaskBit(plane2);
@ -1561,6 +1574,8 @@ ExtTechSimpleOverlapCap(argv)
continue; /* redundant overlap */
ExtCurStyle->exts_overlapCap[s][t] = capVal;
ExtCurStyle->exts_overlapMult[s][t] = (float)capVal * FRINGE_MULT;
ExtCurStyle->exts_overlapMult[t][s] = (float)capVal * FRINGE_MULT;
ExtCurStyle->exts_overlapPlanes |= PlaneNumToMaskBit(plane1);
ExtCurStyle->exts_overlapOtherPlanes[s] |= PlaneNumToMaskBit(plane2);
TTMaskSetType(&ExtCurStyle->exts_overlapTypes[plane1], s);
@ -2109,7 +2124,11 @@ ExtTechLine(sectionName, argc, argv)
capVal = aToCap(argv[2]);
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
if (TTMaskHasType(&types1, t))
{
ExtCurStyle->exts_areaCap[t] = capVal;
ExtCurStyle->exts_overlapMult[t][0] = (float) capVal * FRINGE_MULT;
ExtCurStyle->exts_overlapMult[0][t] = (float) capVal * FRINGE_MULT;
}
break;
case CONTACT:
/* Contact size, border, spacing deprecated (now taken from */
@ -2825,6 +2844,8 @@ ExtTechLine(sectionName, argc, argv)
continue;
}
ExtCurStyle->exts_overlapCap[s][t] = capVal;
ExtCurStyle->exts_overlapMult[s][t] = (float)capVal * FRINGE_MULT;
ExtCurStyle->exts_overlapMult[t][s] = (float)capVal * FRINGE_MULT;
ExtCurStyle->exts_overlapPlanes |= PlaneNumToMaskBit(p1);
ExtCurStyle->exts_overlapOtherPlanes[s]
|= PlaneNumToMaskBit(p2);
@ -3012,11 +3033,7 @@ ExtTechLine(sectionName, argc, argv)
ExtCurStyle->exts_sideCoupleHalo = (int)dhalo;
break;
case FRINGESHIELDHALO:
/* Allow floating-point and increase by factor of 1000 */
/* to accommodate "units microns". */
sscanf(argv[1], "%lg", &dhalo);
dhalo *= (double)1000.0;
ExtCurStyle->exts_fringeShieldHalo = (int)dhalo;
/* This is deprecated. . . Ignore */
break;
case PERIMC:
DBTechNoisyNameMask(argv[2], &types2);
@ -3471,6 +3488,7 @@ zinit:
style->exts_perimCap[r][s] *= scalefac;
style->exts_overlapCap[r][s] *= sqfac;
style->exts_overlapMult[r][s] *= scalefac;
for (ec = style->exts_sideOverlapCap[r][s]; ec != NULL;
ec = ec->ec_next)
ec->ec_cap *= scalefac;
@ -3512,8 +3530,6 @@ zinit:
style->exts_sideCoupleHalo = (int)(((float)style->exts_sideCoupleHalo
/ dscale) + 0.5);
style->exts_fringeShieldHalo = (int)(((float)style->exts_fringeShieldHalo
/ dscale) + 0.5);
style->exts_stepSize = (int)(((float)style->exts_stepSize
/ dscale) + 0.5);
}
@ -3530,7 +3546,6 @@ zinit:
/* needed, so normalize it back to lambda units. */
style->exts_sideCoupleHalo /= 1000;
style->exts_fringeShieldHalo /= 1000;
}
/*
@ -3559,7 +3574,6 @@ ExtTechScale(scalen, scaled)
style->exts_unitsPerLambda = style->exts_unitsPerLambda * (float)scalen
/ (float)scaled;
DBScaleValue(&style->exts_sideCoupleHalo, scaled, scalen);
DBScaleValue(&style->exts_fringeShieldHalo, scaled, scalen);
DBScaleValue(&style->exts_stepSize, scaled, scalen);
for (i = 0; i < DBNumTypes; i++)
@ -3591,6 +3605,8 @@ ExtTechScale(scalen, scaled)
style->exts_perimCap[i][j] /= scaled;
style->exts_overlapCap[i][j] *= sqn;
style->exts_overlapCap[i][j] /= sqd; /* Typo fixed in 7.2.57 */
style->exts_overlapMult[i][j] *= scalen;
style->exts_overlapMult[i][j] /= scaled;
// Do not scale sidewall cap, for while the value is
// per distance, the distance is referred to a separation

View File

@ -726,6 +726,15 @@ typedef struct extstyle
*/
CapValue exts_overlapCap[NT][NT];
/*
* exts_overlapMult is needed for modeling fringe shielding and
* partial fringing, whose models have multiplier coefficients
* that are proportional to area capacitance referred to some
* constant length (so that it scales with the internal grid,
* not with the internal grid squared).
*/
float exts_overlapMult[NT][NT];
/* Specifies an ordering of the planes, so we can determine which
* tile is above another one. This is used only when determining
* if we should subtract capacitance to substrate for overlap and
@ -780,19 +789,13 @@ typedef struct extstyle
* This value determines how much extra gets yanked when
* computing hierarchical adjustments, so should be kept
* small to insure reasonable performance.
*
* To be done: Set this as a per-plane value with a
* corresponding method in the tech file to declare the value
* for each plane separately.
*/
int exts_sideCoupleHalo;
/*
* Search out a distance exts_fringeShieldHalo from each edge
* for types on the same plane that partially shield fringe
* capacitance. The shielding is modeled as an ellipse equation
* and the shield halo should be approximately 10x the distance
* where half the fringe capacitance is shielded. If not specified,
* then it is set to be equal to exts_sideCoupleHalo.
*/
int exts_fringeShieldHalo;
/*
* Sidewall-overlap coupling capacitance.
* This is between an edge on one plane and a type on another plane