Finally tracked down several bugs in the sidewall walking routines

that had been causing negative capacitances to substrate to be
generated for certain complex geometries.
This commit is contained in:
Tim Edwards 2023-03-24 09:51:22 -04:00
parent f0c94d59f3
commit 30184cb506
2 changed files with 46 additions and 20 deletions

View File

@ -1 +1 @@
8.3.386
8.3.387

View File

@ -32,6 +32,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "database/database.h"
#include "extract/extract.h"
#include "extract/extractInt.h"
#include "textio/textio.h"
/* --------------------- Data local to this file ---------------------- */
@ -673,9 +674,12 @@ extSubtractSideOverlap(tile, sov)
/* coupling layer, since the fringe capacitance has a different */
/* halo than for the substrate. */
mult = ExtCurStyle->exts_overlapMult[ta][tb];
snear = 0.6366 * atan(mult * dnear);
sfar = 0.6366 * atan(mult * dfar);
if (ExtCurStyle->exts_overlapMult[ta][tb] != mult)
{
mult = ExtCurStyle->exts_overlapMult[ta][tb];
snear = 0.6366 * atan(mult * dnear);
sfar = 0.6366 * atan(mult * dfar);
}
sov->so_coupfrac += (sfar - snear) * ((double)length / (double)sov->so_length);
return (0);
@ -812,6 +816,16 @@ extAddCouple(bp, ecs)
extSidewallStruct esws;
int distFringe;
/* Check here for a zero exts_sideCoupleOtherEdges mask.
* that handles cases such as FET types not being declared in
* defaultperimeter, as the edge between poly and FET will be
* seen as a boundary. The lack of any area coupling should
* then prevent it from being checked for fringe cap.
*/
if (TTMaskIsZero(&ExtCurStyle->exts_sideCoupleOtherEdges[tin][tout]))
return 0;
/* Revert any edge contacts to their residues */
if (DBIsContact(tin))
tin = DBPlaneToResidue(tin, ecs->plane);
@ -1065,22 +1079,18 @@ extSideOverlapHalo(tp, esws)
tb = TiGetType(tp);
if (tb == TT_SPACE) return (0);
if (bp->b_segment.r_xtop == bp->b_segment.r_xbot)
{
length = MIN(bp->b_segment.r_ytop, TOP(tp))
- MAX(bp->b_segment.r_ybot, BOTTOM(tp));
}
else
{
length = MIN(bp->b_segment.r_xtop, RIGHT(tp))
- MAX(bp->b_segment.r_xbot, LEFT(tp));
}
/* Get the area of the coupling tile, and clip to the fringe area */
/* of the tile edge generating the fringe capacitance. */
TITORECT(tp, &sov.so_clip);
GEOCLIP(&sov.so_clip, esws->area);
/* Calculate the length of the clipped area */
if (bp->b_segment.r_xtop == bp->b_segment.r_xbot)
length = sov.so_clip.r_ytop - sov.so_clip.r_ybot;
else
length = sov.so_clip.r_xtop - sov.so_clip.r_xbot;
/* ta is the tile type of the edge generating the fringe cap. */
ta = TiGetType(bp->b_inside);
@ -1125,9 +1135,12 @@ extSideOverlapHalo(tp, esws)
/* The fringe portion extracted from the substrate will be */
/* different than the portion added to the coupling layer. */
mult = ExtCurStyle->exts_overlapMult[ta][0];
sfar = 0.6366 * atan(mult * dfar);
snear = 0.6366 * atan(mult * dnear);
if (ExtCurStyle->exts_overlapMult[ta][0] != mult)
{
mult = ExtCurStyle->exts_overlapMult[ta][0];
sfar = 0.6366 * atan(mult * dfar);
snear = 0.6366 * atan(mult * dnear);
}
sfrac = sfar - snear;
/* Apply each rule, incorporating shielding into the edge length. */
@ -1390,6 +1403,11 @@ extSideOverlap(tp, esws)
subcap = (ExtCurStyle->exts_perimCap[ta][outtype] *
MIN(areaAccountedFor, length));
rbp->nreg_cap -= subcap;
/* XXX WIP XXX */
TxPrintf("(4) Subtracting cap value %g in clip area %d %d %d %d\n",
subcap,
ov.o_clip.r_xbot, ov.o_clip.r_ybot,
ov.o_clip.r_xtop, ov.o_clip.r_ytop);
/* Ignore residual error at ~zero zeptoFarads. Probably */
/* there should be better handling of round-off here. */
if ((rbp->nreg_cap > -0.001) && (rbp->nreg_cap < 0.001))
@ -1490,6 +1508,8 @@ extWalkTop(area, mask, func, bp, esws)
/* Clip coupling area and call fringe coupling calculation function */
aloc = *area;
aloc.r_ytop = BOTTOM(tp);
aloc.r_xbot = bloc.b_segment.r_xbot;
aloc.r_xtop = bloc.b_segment.r_xtop;
if (extFindOverlap(bp->b_outside, &aloc, esws) != 0) return 1;
extRemoveSubcap(&bloc, &aloc, esws);
@ -1600,6 +1620,8 @@ extWalkBottom(area, mask, func, bp, esws)
/* Clip coupling area and call fringe coupling calculation function */
aloc = *area;
aloc.r_ybot = TOP(tp);
aloc.r_xbot = bloc.b_segment.r_xbot;
aloc.r_xtop = bloc.b_segment.r_xtop;
if (extFindOverlap(bp->b_outside, &aloc, esws) != 0) return 1;
extRemoveSubcap(&bloc, &aloc, esws);
@ -1710,6 +1732,8 @@ extWalkRight(area, mask, func, bp, esws)
/* Clip coupling area and call fringe coupling calculation function */
aloc = *area;
aloc.r_xtop = LEFT(tp);
aloc.r_ybot = bloc.b_segment.r_ybot;
aloc.r_ytop = bloc.b_segment.r_ytop;
if (extFindOverlap(bp->b_outside, &aloc, esws) != 0) return 1;
extRemoveSubcap(&bloc, &aloc, esws);
@ -1820,6 +1844,8 @@ extWalkLeft(area, mask, func, bp, esws)
/* Clip coupling area and call fringe coupling calculation function */
aloc = *area;
aloc.r_xbot = RIGHT(tp);
aloc.r_ybot = bloc.b_segment.r_ybot;
aloc.r_ytop = bloc.b_segment.r_ytop;
if (extFindOverlap(bp->b_outside, &aloc, esws) != 0) return 1;
extRemoveSubcap(&bloc, &aloc, esws);
@ -1830,7 +1856,7 @@ extWalkLeft(area, mask, func, bp, esws)
aloc.r_ytop = bloc.b_segment.r_ybot;
bloc.b_segment.r_ybot = bp->b_segment.r_ybot;
bloc.b_segment.r_ytop = aloc.r_ytop;
if (extWalkRight(&aloc, mask, func, &bloc, esws) != 0)
if (extWalkLeft(&aloc, mask, func, &bloc, esws) != 0)
return 1;
}
@ -1841,7 +1867,7 @@ extWalkLeft(area, mask, func, bp, esws)
aloc.r_ybot = bloc.b_segment.r_ytop;
bloc.b_segment.r_ytop = bp->b_segment.r_ytop;
bloc.b_segment.r_ybot = aloc.r_ybot;
if (extWalkRight(&aloc, mask, func, &bloc, esws) != 0)
if (extWalkLeft(&aloc, mask, func, &bloc, esws) != 0)
return 1;
}