Modified the "def write" function so that obstruction layers are

output as blockages.  That allows obstruction layers to be placed
in a layout specifically for the purpose of being output as a
blockage.  Otherwise, an obstruction layer is generally considered
non-electrical and will not show up as a node in the extraction
file, so obstruction layers were being missed entirely by "def
write".  Also:  Where "def write" complains about floating labels,
made an exception for labels on non-electrical layers (like
"comment").
This commit is contained in:
Tim Edwards 2023-09-22 15:51:38 -04:00
parent a54a20ee58
commit 4557dd1639
1 changed files with 80 additions and 7 deletions

View File

@ -29,9 +29,10 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
#include "utils/malloc.h"
#include "utils/undo.h"
#include "cif/cif.h"
#include "extract/extractInt.h" /* for ExtCurStyle definition */
#include "extflat/extflat.h"
#include "lef/lefInt.h"
#include "drc/drc.h" /* for querying width,spacing rules */
#include "drc/drc.h" /* for querying width, spacing rules */
/* C99 compat */
#include "utils/signals.h"
@ -800,13 +801,18 @@ defnodeVisit(node, res, cap, defdata)
}
/* Check if anything was found in the location (e.g., .ext file
* could be invalid or outdated).
* could be invalid or outdated). However, if magictype is not
* an electrically active type, then don't issue any warning.
*/
if (GEO_RECTNULL(&rport))
TxError("Nothing found at node %s location (floating label?)!\n", ndn);
{
if (TTMaskHasType(&ExtCurStyle->exts_activeTypes, magictype))
TxError("Nothing of type %s found at node %s location"
" (floating label?)!\n",
DBTypeLongNameTbl[magictype], ndn);
}
else
{
/* Expand the rectangle around the port to overlap any */
/* connecting material. */
rport.r_xbot--;
@ -2430,16 +2436,20 @@ defWriteBlockages(f, rootDef, oscale, MagicToLefTable)
{
DefObsData defobsdata;
lefLayer *lefl;
int i, numblocks, nonempty;
int i, numblocks, nonempty, pNum;
LinkedRect *lr;
HashSearch hs;
HashEntry *he;
TileTypeBitMask ExtraObsLayersMask;
int defSimpleBlockageFunc(); /* Forward declaration */
int defblockageVisit();
defobsdata.def = rootDef;
defobsdata.nlayers = 0;
TTMaskZero(&ExtraObsLayersMask);
/* Blockages are done by layer. Create one blockage per route */
/* layer, and ignore vias. */
@ -2482,7 +2492,16 @@ defWriteBlockages(f, rootDef, oscale, MagicToLefTable)
defobsdata.baseNames[numblocks] = llayer;
TTMaskSetOnlyType(&defobsdata.blockMasks[numblocks], lefl->type);
if (lefl->obsType != -1)
{
TTMaskSetType(&defobsdata.blockMasks[numblocks], lefl->obsType);
/* If the obstruction type is not an active electrical
* type, then add it to the mask of layers to search
* separately from extracted nodes.
*/
if (!TTMaskHasType(&ExtCurStyle->exts_activeTypes,
lefl->obsType))
TTMaskSetType(&ExtraObsLayersMask, lefl->obsType);
}
defobsdata.blockData[numblocks] = NULL;
numblocks++;
}
@ -2492,6 +2511,22 @@ defWriteBlockages(f, rootDef, oscale, MagicToLefTable)
if (numblocks > 0)
EFVisitNodes(defblockageVisit, (ClientData)&defobsdata);
/* If obstruction types are marked as non-electrical layers (which
* normally they are), then they will not be extracted as nodes.
* Do a separate search on obstruction areas and add them to the
* list of blockages. To be considered, the layer must have a
* corresponding LEF route or via layer type, that LEF record must
* define an obstruction type, and that obstruction type must not
* be in the active layer list.
*/
for (pNum = PL_SELECTBASE; pNum < DBNumPlanes; pNum++)
{
DBSrPaintArea((Tile *)NULL, rootDef->cd_planes[pNum], &TiPlaneRect,
&ExtraObsLayersMask, defSimpleBlockageFunc,
(ClientData)&defobsdata);
}
/* Quick check for presence of data to write */
nonempty = 0;
@ -2619,6 +2654,45 @@ defBlockageGeometryFunc(tile, plane, defobsdata)
return 0;
}
/* Callback function for generating a linked list of blockage geometry */
/* pulled from all non-electrical obstruction types. */
int
defSimpleBlockageFunc(tile, defobsdata)
Tile *tile; /* Tile being visited */
DefObsData *defobsdata; /* Data passed to this function */
{
TileType ttype = TiGetTypeExact(tile);
TileType loctype;
Rect r;
LinkedRect *lr;
int i;
if (IsSplit(tile))
loctype = (ttype & TT_SIDE) ? SplitRightType(tile) : SplitLeftType(tile);
else
loctype = ttype;
if (loctype == TT_SPACE) return 0;
for (i = 0; i < defobsdata->nlayers; i++)
if (TTMaskHasType(&(defobsdata->blockMasks[i]), loctype))
break;
if (i < defobsdata->nlayers)
{
TiToRect(tile, &r);
lr = (LinkedRect *)mallocMagic(sizeof(LinkedRect));
lr->r_next = defobsdata->blockData[i];
lr->r_type = loctype;
lr->r_r = r;
defobsdata->blockData[i] = lr;
}
return 0;
}
/*
*------------------------------------------------------------
*
@ -3063,8 +3137,7 @@ DefWriteCell(def, outName, allSpecial, units, analRetentive)
fclose(f2);
/* Blockages */
if (nets.blockages > 0)
defWriteBlockages(f, def, scale, lefMagicToLefLayer);
defWriteBlockages(f, def, scale, lefMagicToLefLayer);
fprintf(f, "END DESIGN\n\n");
fclose(f);