Added code to calculate area and perimeter of layers that are not
on the same plane as a device identifier layer. This (finally!) allows proper calculation of area and perimeter of diodes and bipolars, for example.
This commit is contained in:
parent
6caab5da37
commit
5300f322de
|
|
@ -1768,6 +1768,49 @@ extOutputDevParams(reg, devptr, outFile, length, width, areavec)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Structures used by extTermAPFunc() for storing area and perimeter data */
|
||||||
|
|
||||||
|
typedef struct _nodelist {
|
||||||
|
struct _nodelist *nl_next;
|
||||||
|
NodeRegion *nl_node;
|
||||||
|
} ExtNodeList;
|
||||||
|
|
||||||
|
typedef struct _extareaperimdata {
|
||||||
|
int eapd_area;
|
||||||
|
int eapd_perim;
|
||||||
|
TileTypeBitMask eapd_mask;
|
||||||
|
TileTypeBitMask *eapd_gatemask;
|
||||||
|
NodeRegion *eapd_gatenode;
|
||||||
|
ExtNodeList *eapd_shared;
|
||||||
|
} ExtAreaPerimData;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* extTransFindTermArea --
|
||||||
|
*
|
||||||
|
* Callback function to find the area and perimeter of a terminal area in
|
||||||
|
* a plane other than the plane of the device identifier type. This routine
|
||||||
|
* searches around the first tile of the terminal for all connected terminal
|
||||||
|
* types and calculates area and perimeter.
|
||||||
|
*
|
||||||
|
* Return value:
|
||||||
|
* Always return 1 to stop the search, because we need only one tile
|
||||||
|
* under the identifier tile to start the search.
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
extTransFindTermArea(tile, eapd)
|
||||||
|
Tile *tile;
|
||||||
|
ExtAreaPerimData *eapd;
|
||||||
|
{
|
||||||
|
int extTermAPFunc(); /* Forward declaration */
|
||||||
|
|
||||||
|
DBSrConnectOnePlane(tile, DBConnectTbl, extTermAPFunc, (ClientData)eapd);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
@ -1929,10 +1972,14 @@ extOutputDevices(def, transList, outFile)
|
||||||
else if (!TTMaskIntersect(tmask, &DBPlaneTypes[reg->treg_pnum])
|
else if (!TTMaskIntersect(tmask, &DBPlaneTypes[reg->treg_pnum])
|
||||||
|| (TTMaskHasType(tmask, TT_SPACE)))
|
|| (TTMaskHasType(tmask, TT_SPACE)))
|
||||||
{
|
{
|
||||||
|
ExtAreaPerimData eapd;
|
||||||
|
TileType tt = TT_SPACE;
|
||||||
|
Rect r;
|
||||||
|
|
||||||
node = NULL;
|
node = NULL;
|
||||||
|
|
||||||
/* First try to find a region under the device */
|
/* First try to find a region under the device */
|
||||||
extTransFindSubs(reg->treg_tile, t, tmask, def, &node, NULL);
|
extTransFindSubs(reg->treg_tile, t, tmask, def, &node, &tt);
|
||||||
|
|
||||||
if ((node == NULL) && (TTMaskHasType(tmask, TT_SPACE))) {
|
if ((node == NULL) && (TTMaskHasType(tmask, TT_SPACE))) {
|
||||||
/* Device node is the global substrate. */
|
/* Device node is the global substrate. */
|
||||||
|
|
@ -1946,6 +1993,38 @@ extOutputDevices(def, transList, outFile)
|
||||||
}
|
}
|
||||||
extTransRec.tr_devmatch |= (MATCH_TERM << termcount);
|
extTransRec.tr_devmatch |= (MATCH_TERM << termcount);
|
||||||
extTransRec.tr_termnode[termcount] = node;
|
extTransRec.tr_termnode[termcount] = node;
|
||||||
|
|
||||||
|
/* Terminals on other planes will not have area and perimeter
|
||||||
|
* computed, so do that here.
|
||||||
|
*/
|
||||||
|
TiToRect(reg->treg_tile, &r);
|
||||||
|
eapd.eapd_area = 0;
|
||||||
|
eapd.eapd_perim = 0;
|
||||||
|
eapd.eapd_shared = NULL;
|
||||||
|
/* NOTE: Currently there is no way to determine if a
|
||||||
|
* terminal on another plane belongs to multiple devices,
|
||||||
|
* so device sharing is not checked. Could be done by
|
||||||
|
* checking the terminal area for the gate mask (on its
|
||||||
|
* own plane) in extTermAPFunc().
|
||||||
|
*/
|
||||||
|
eapd.eapd_gatemask = &DBZeroTypeBits;
|
||||||
|
TTMaskCom2(&eapd.eapd_mask, tmask);
|
||||||
|
if (tt == TT_SPACE)
|
||||||
|
{
|
||||||
|
/* Terminal may be the substrate, in which case */
|
||||||
|
/* the device should not be recording area or */
|
||||||
|
/* perimeter, so leave them as zero. */
|
||||||
|
extTransRec.tr_termarea[termcount] = 0;
|
||||||
|
extTransRec.tr_termperim[termcount] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBSrPaintArea((Tile *)NULL, def->cd_planes[DBPlane(tt)],
|
||||||
|
&r, &tmask, extTransFindTermArea, (ClientData)&eapd);
|
||||||
|
extTransRec.tr_termarea[termcount] = eapd.eapd_area;
|
||||||
|
extTransRec.tr_termperim[termcount] = eapd.eapd_perim;
|
||||||
|
}
|
||||||
|
extTransRec.tr_termshared[termcount] = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Determine if there is another matching device record */
|
/* Determine if there is another matching device record */
|
||||||
|
|
@ -2749,7 +2828,7 @@ extTransTileFunc(tile, pNum, arg)
|
||||||
{
|
{
|
||||||
TileTypeBitMask mask, cmask, *smask;
|
TileTypeBitMask mask, cmask, *smask;
|
||||||
TileType loctype, idlayer, sublayer;
|
TileType loctype, idlayer, sublayer;
|
||||||
int perim, result;
|
int perim, result, i;
|
||||||
bool allow_globsubsnode;
|
bool allow_globsubsnode;
|
||||||
ExtDevice *devptr, *deventry, *devtest;
|
ExtDevice *devptr, *deventry, *devtest;
|
||||||
NodeRegion *region;
|
NodeRegion *region;
|
||||||
|
|
@ -2758,12 +2837,12 @@ extTransTileFunc(tile, pNum, arg)
|
||||||
Label *lab;
|
Label *lab;
|
||||||
Rect r;
|
Rect r;
|
||||||
|
|
||||||
|
TITORECT(tile, &r);
|
||||||
for (ll = extTransRec.tr_gatenode->nreg_labels; ll; ll = ll->ll_next)
|
for (ll = extTransRec.tr_gatenode->nreg_labels; ll; ll = ll->ll_next)
|
||||||
{
|
{
|
||||||
/* Skip if already marked */
|
/* Skip if already marked */
|
||||||
if (ll->ll_attr != LL_NOATTR) continue;
|
if (ll->ll_attr != LL_NOATTR) continue;
|
||||||
lab = ll->ll_label;
|
lab = ll->ll_label;
|
||||||
TITORECT(tile, &r);
|
|
||||||
if (GEO_TOUCH(&r, &lab->lab_rect) &&
|
if (GEO_TOUCH(&r, &lab->lab_rect) &&
|
||||||
extLabType(lab->lab_text, LABTYPE_GATEATTR))
|
extLabType(lab->lab_text, LABTYPE_GATEATTR))
|
||||||
{
|
{
|
||||||
|
|
@ -2944,26 +3023,9 @@ extTransTileFunc(tile, pNum, arg)
|
||||||
extTransRec.tr_devmatch |= MATCH_ID;
|
extTransRec.tr_devmatch |= MATCH_ID;
|
||||||
}
|
}
|
||||||
extTransRec.tr_devrec = devptr;
|
extTransRec.tr_devrec = devptr;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Structures used by extTermAPFunc() for storing area and perimeter data */
|
|
||||||
|
|
||||||
typedef struct _nodelist {
|
|
||||||
struct _nodelist *nl_next;
|
|
||||||
NodeRegion *nl_node;
|
|
||||||
} ExtNodeList;
|
|
||||||
|
|
||||||
typedef struct _extareaperimdata {
|
|
||||||
int eapd_area;
|
|
||||||
int eapd_perim;
|
|
||||||
TileTypeBitMask eapd_mask;
|
|
||||||
TileTypeBitMask *eapd_gatemask;
|
|
||||||
NodeRegion *eapd_gatenode;
|
|
||||||
ExtNodeList *eapd_shared;
|
|
||||||
} ExtAreaPerimData;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue