From 4557dd16394f8c339d968775fb22793aed574a64 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Fri, 22 Sep 2023 15:51:38 -0400 Subject: [PATCH] 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"). --- lef/defWrite.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 7 deletions(-) diff --git a/lef/defWrite.c b/lef/defWrite.c index 44ace580..901fab79 100644 --- a/lef/defWrite.c +++ b/lef/defWrite.c @@ -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);