diff --git a/extract/ExtTech.c b/extract/ExtTech.c index 3878d784..5559f4db 100644 --- a/extract/ExtTech.c +++ b/extract/ExtTech.c @@ -408,6 +408,67 @@ extGetDevType(devname) return -1; } +/* + * ---------------------------------------------------------------------------- + * + * ExtGetGateTypesMask -- + * + * Put a mask of FET gate types in the mask pointer argument. + * Return 0 on success, 1 on failure (no extraction style set) + * + * ---------------------------------------------------------------------------- + */ + +int +ExtGetGateTypesMask(mask) + TileTypeBitMask *mask; +{ + TileType ttype; + + if (ExtCurStyle == NULL) return 1; + + TTMaskZero(mask); + for (ttype = TT_TECHDEPBASE; ttype < DBNumTypes; ttype++) + { + if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, ttype)) + { + ExtDevice *devptr = ExtCurStyle->exts_device[ttype]; + + for (; devptr; devptr = devptr->exts_next) + if ((devptr->exts_deviceClass == DEV_MOSFET) || + (devptr->exts_deviceClass == DEV_FET) || + (devptr->exts_deviceClass == DEV_ASYMMETRIC) || + (devptr->exts_deviceClass == DEV_MSUBCKT)) + TTMaskSetType(mask, ttype); + } + } + return 0; +} + +/* + * ---------------------------------------------------------------------------- + * + * ExtGetDiffTypesMask -- + * + * Put a mask of diffusion types in the mask pointer argument. + * Return 0 on success, 1 on failure (no extraction style set) + * + * ---------------------------------------------------------------------------- + */ + +int +ExtGetDiffTypesMask(mask) + TileTypeBitMask *mask; +{ + TileType ttype; + + if (ExtCurStyle == NULL) return 1; + + TTMaskZero(mask); + TTMaskSetMask(mask, &ExtCurStyle->exts_antennaTieTypes); + + return 0; +} #ifdef THREE_D /* diff --git a/extract/extract.h b/extract/extract.h index 57332f89..3bc6cb5b 100644 --- a/extract/extract.h +++ b/extract/extract.h @@ -77,6 +77,8 @@ extern void ExtSetStyle(); extern void ExtPrintStyle(); extern void ExtCell(); +extern int ExtGetGateTypesMask(); +extern int ExtGetDiffTypesMask(); #ifdef MAGIC_WRAPPER extern bool ExtGetDevInfo(); diff --git a/lef/lefWrite.c b/lef/lefWrite.c index c9abe0d5..055400f9 100644 --- a/lef/lefWrite.c +++ b/lef/lefWrite.c @@ -27,6 +27,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" +#include "extract/extract.h" #include "utils/tech.h" #include "utils/utils.h" #include "utils/malloc.h" @@ -370,6 +371,32 @@ lefGetBound(tile, cdata) return 0; } +/* + * ---------------------------------------------------------------------------- + * + * lefAccumulateArea -- + * + * Function called to accumulate the tile area of tiles + * + * Return 0 to keep the search going. + * ---------------------------------------------------------------------------- + */ + +int +lefAccumulateArea(tile, cdata) + Tile *tile; + ClientData cdata; +{ + int *area = (int *)cdata; + Rect rarea; + + TiToRect(tile, &rarea); + + *area += (rarea.r_xtop - rarea.r_xbot) * (rarea.r_ytop - rarea.r_ybot); + + return 0; +} + /* * ---------------------------------------------------------------------------- * @@ -652,14 +679,14 @@ lefWriteMacro(def, f, scale, hide) float scale; /* Output distance units conversion factor */ bool hide; /* If TRUE, hide all detail except pins */ { - bool propfound; + bool propfound, ispwrrail; char *propvalue, *class = NULL; Label *lab, *tlab, *reflab; Rect boundary, labr; SearchContext scx; CellDef *lefFlatDef; CellUse lefFlatUse, lefSourceUse; - TileTypeBitMask lmask, boundmask, *lrmask; + TileTypeBitMask lmask, boundmask, *lrmask, gatetypemask, difftypemask; TileType ttype; lefClient lc; int idx, pNum, maxport, curport; @@ -746,6 +773,10 @@ lefWriteMacro(def, f, scale, hide) TTMaskSetType(&boundmask, lefl->type); } + /* Gate and diff types are determined from the extraction style */ + ExtGetGateTypesMask(&gatetypemask); + ExtGetDiffTypesMask(&difftypemask); + /* NOTE: This routine corresponds to Envisia LEF/DEF Language */ /* Reference version 5.3 (May 31, 2000) */ @@ -904,6 +935,7 @@ lefWriteMacro(def, f, scale, hide) } fprintf(f, " ;\n"); } + ispwrrail = FALSE; if (lab->lab_flags & PORT_USE_MASK) { fprintf(f, " USE "); @@ -917,9 +949,11 @@ lefWriteMacro(def, f, scale, hide) break; case PORT_USE_POWER: fprintf(f, "POWER"); + ispwrrail = TRUE; break; case PORT_USE_GROUND: fprintf(f, "GROUND"); + ispwrrail = TRUE; break; case PORT_USE_CLOCK: fprintf(f, "CLOCK"); @@ -927,6 +961,27 @@ lefWriteMacro(def, f, scale, hide) } fprintf(f, " ;\n"); } +#ifdef MAGIC_WRAPPER + else + { + char *pwr; + + /* Determine power rails by matching the $VDD and $GND Tcl variables */ + + pwr = (char *)Tcl_GetVar(magicinterp, "VDD", TCL_GLOBAL_ONLY); + if (pwr && (!strcmp(lab->lab_text, pwr))) + { + ispwrrail = TRUE; + fprintf(f, " USE POWER ;\n"); + } + pwr = (char *)Tcl_GetVar(magicinterp, "GND", TCL_GLOBAL_ONLY); + if (pwr && (!strcmp(lab->lab_text, pwr))) + { + ispwrrail = TRUE; + fprintf(f, " USE GROUND ;\n"); + } + } +#endif /* Query pin geometry for SHAPE (to be done?) */ @@ -948,6 +1003,7 @@ lefWriteMacro(def, f, scale, hide) while (lab != NULL) { + int antarea; labr = lab->lab_rect; @@ -999,6 +1055,41 @@ lefWriteMacro(def, f, scale, hide) else SelectNet(&scx, lab->lab_type, 0, NULL, FALSE); + // Search for gate and diff types and accumulate antenna + // areas. For gates, check for all gate types tied to + // devices with MOSFET types (including "msubcircuit", etc.). + // For diffusion, use the types declared in the "tiedown" + // statement in the extract section of the techfile. + + if (ispwrrail == FALSE) + { + antarea = 0; + for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) + { + DBSrPaintArea((Tile *)NULL, SelectDef->cd_planes[pNum], + &TiPlaneRect, &gatetypemask, + lefAccumulateArea, (ClientData) &antarea); + } + if (antarea > 0) + { + fprintf(f, " ANTENNAGATEAREA %.4f ;\n", + lc.oscale * lc.oscale * (float)antarea); + } + + antarea = 0; + for (pNum = PL_TECHDEPBASE; pNum < DBNumPlanes; pNum++) + { + DBSrPaintArea((Tile *)NULL, SelectDef->cd_planes[pNum], + &TiPlaneRect, &difftypemask, + lefAccumulateArea, (ClientData) &antarea); + } + if (antarea > 0) + { + fprintf(f, " ANTENNADIFFAREA %.4f ;\n", + lc.oscale * lc.oscale * (float)antarea); + } + } + // For all geometry in the selection, write LEF records, // and mark the corresponding tiles in lefFlatDef as // visited.