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:
Tim Edwards 2020-05-21 16:26:24 -04:00
parent 6635817383
commit 6adb5dbacf
3 changed files with 156 additions and 2 deletions

View File

@ -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
/*

View File

@ -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();

View File

@ -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.