Enhanced the "lef write" routine: (1) Calculates gate and diff
areas and writes ANTENNAGATEAREA and ANTENNADIFFAREA values. (2) Determines "USE POWER" or "USE GROUND" from label names matching Tcl variables $VDD and $GND, if the USE has not been registered as a cell property (knowning the use allows magic to avoid writing an ANTENNADIFFAREA for power rails, although doing so should not be an issue).
This commit is contained in:
parent
6635817383
commit
6adb5dbacf
|
|
@ -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
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in New Issue