(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:
parent
8d08cb2f2f
commit
1a3caee376
|
|
@ -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" */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue