Merge branch 'master' into magic-8.2

This commit is contained in:
Tim Edwards 2019-10-19 03:00:05 -04:00
commit 56c1829610
9 changed files with 244 additions and 31 deletions

View File

@ -1596,7 +1596,7 @@ esMakePorts(hc, cdata)
// Find the cell for the instance
portdef = NULL;
he = HashFind(&updef->def_uses, portname);
he = HashLookOnly(&updef->def_uses, portname);
if (he != NULL)
{
use = (Use *)HashGetValue(he);
@ -1686,7 +1686,7 @@ esMakePorts(hc, cdata)
// Find the cell for the instance
portdef = NULL;
he = HashFind(&updef->def_uses, portname);
he = HashLookOnly(&updef->def_uses, portname);
if (he != NULL)
{
use = (Use *)HashGetValue(he);

View File

@ -32,4 +32,5 @@ EFantenna.o: EFantenna.c ../tcltk/tclmagic.h ../utils/magic.h \
../utils/geometry.h ../utils/hash.h ../utils/utils.h ../tiles/tile.h \
../database/database.h ../windows/windows.h ../textio/textio.h \
../dbwind/dbwind.h ../textio/txcommands.h ../extflat/extflat.h \
../extract/extract.h ../utils/malloc.h
../extract/extract.h ../extract/extractInt.h ../extract/extDebugInt.h \
../utils/malloc.h

View File

@ -29,7 +29,8 @@
#include "textio/txcommands.h"
#endif
#include "extflat/extflat.h"
#include "extract/extract.h" /* for extDevTable */
#include "extract/extract.h"
#include "extract/extractInt.h"
#include "utils/malloc.h"
/* Forward declarations */
@ -103,6 +104,8 @@ CmdAntennaCheck(w, cmd)
char *subname;
int idx;
CellUse *editUse;
static char *cmdAntennaCheckOption[] = {
"[run] [options] run antennacheck on current cell\n"
" use \"run -help\" to get standard options",
@ -134,6 +137,13 @@ usage:
runantennacheck:
if (ExtCurStyle->exts_planeOrderStatus == noPlaneOrder)
{
TxError("No planeorder specified for this process: "
"Cannot run antenna checks!\n");
return;
}
EFInit();
EFCapThreshold = INFINITY;
EFResistThreshold = INFINITY;
@ -162,6 +172,7 @@ runantennacheck:
}
inName = ((CellUse *) w->w_surfaceID)->cu_def->cd_name;
}
editUse = (CellUse *)w->w_surfaceID;
/*
* Initializations specific to this program.
@ -178,7 +189,7 @@ runantennacheck:
flatFlags = EF_FLATNODES;
EFFlatBuild(inName, flatFlags);
EFVisitDevs(antennacheckVisit, (ClientData)NULL);
EFVisitDevs(antennacheckVisit, (ClientData)editUse);
EFFlatDone();
EFDone();
@ -234,9 +245,30 @@ usage:
TxError("Usage: antennacheck\n");
return 1;
}
/*
* ----------------------------------------------------------------------------
*
* AntennaGetNode --
*
* function to find a node given its hierarchical prefix and suffix
*
* Results:
* a pointer to the node struct or NULL
*
* ----------------------------------------------------------------------------
*/
EFNode *
AntennaGetNode(prefix, suffix)
HierName *prefix;
HierName *suffix;
{
HashEntry *he;
he = EFHNConcatLook(prefix, suffix, "output");
return(((EFNodeName *) HashGetValue(he))->efnn_node);
}
/*
* ----------------------------------------------------------------------------
*
@ -256,15 +288,30 @@ usage:
*/
int
antennacheckVisit(dev, hierName, scale, trans)
antennacheckVisit(dev, hierName, scale, trans, editUse)
Dev *dev; /* Device being output */
HierName *hierName; /* Hierarchical path down to this device */
float scale; /* Scale transform for output */
Transform *trans; /* Coordinate transform */
CellUse *editUse; /* ClientData is edit cell use */
{
DevTerm *gate, *source, *drain;
int l, w;
DevTerm *gate;
int pos, pNum, pNum2, pmax, p, i, j, gatearea, diffarea, total;
double difftotal;
int *antennaarea;
Rect r;
EFNode *gnode;
SearchContext scx;
TileTypeBitMask gatemask;
extern CellDef *extPathDef; /* see extract/ExtLength.c */
extern CellUse *extPathUse; /* see extract/ExtLength.c */
extern int areaAccumFunc(), antennaAccumFunc();
antennaarea = (int *)mallocMagic(DBNumTypes * sizeof(int));
for (i = 0; i < DBNumTypes; i++) antennaarea[i] = 0;
switch(dev->dev_class)
{
@ -274,24 +321,176 @@ antennacheckVisit(dev, hierName, scale, trans)
/* Procedure:
*
* 1. If device is marked visited, return.
* 2. Mark device visited
* 3. Mark all connected devices visited
* 4. For each plane from metal1 up (determined by planeorder):
* a. Run SimTreeCopyConnect()
* 1. If device gate node is marked visited, return.
* 2. Mark device gate node visited
* 3. For each plane from metal1 up (determined by planeorder):
* a. Run DBTreeCopyConnect()
* b. Accumulate gate area of connected devices
* c. Accumulate metal area of connected devices
* d. Check against antenna ratio
* e. Generate feedback if in violation of antenna rule
* c. Accumulate diffusion area of connected devices
* d. Accumulate metal area of connected devices
* e. Check against antenna ratio(s)
* f. Generate feedback if in violation of antenna rule
*
* NOTE: SimTreeCopyConnect() is used cumulatively, so that
* NOTE: DBTreeCopyConnect() is used cumulatively, so that
* additional searching only needs to be done for the additional
* layer being searched. This is the reason for using
* SimTreeCopyConnect() instead of DBTreeCopyConnect().
* layer being searched.
*/
/* To be completed */
gate = &dev->dev_terms[0];
gnode = AntennaGetNode(hierName, gate->dterm_node->efnode_name->efnn_hier);
if (beenVisited((nodeClient *)gnode->efnode_client, 0))
return 0;
else
markVisited((nodeClient *)gnode->efnode_client, 0);
/* Find the plane of the gate type */
pNum = DBPlane(dev->dev_type);
pos = ExtCurStyle->exts_planeOrder[pNum];
pmax = ++pos;
/* Find the highest plane in the technology */
for (p = PL_TECHDEPBASE; p < DBNumPlanes; p++)
if (ExtCurStyle->exts_planeOrder[p] > pmax)
pmax = ExtCurStyle->exts_planeOrder[p];
/* Use the cellDef reserved for extraction */
DBCellClearDef(extPathDef);
scx.scx_use = editUse;
scx.scx_trans = GeoIdentityTransform;
/* gatemask is a mask of all gate types for MOSFET devices */
TTMaskZero(&gatemask);
for (i = 0; i < DBNumTypes; i++)
{
ExtDevice *ed;
char devclass;
if (ExtCurStyle->exts_device[i] != NULL)
{
for (ed = ExtCurStyle->exts_device[i]; ed; ed = ed->exts_next)
{
devclass = ed->exts_deviceClass;
switch (devclass)
{
case DEV_MOSFET:
case DEV_FET:
case DEV_ASYMMETRIC:
case DEV_MSUBCKT:
TTMaskSetType(&gatemask, i);
break;
}
}
}
}
for (; pos <= pmax; pos++)
{
/* Modify DBConnectTbl to limit connectivity to the plane */
/* of the antenna check and below */
/* To be completed */
DBTreeCopyConnect(&scx, &DBConnectTbl[dev->dev_type], 0,
DBConnectTbl, &TiPlaneRect, extPathUse);
/* Search plane of gate type and accumulate all (new) gate area */
DBSrPaintArea((Tile *)NULL, extPathUse->cu_def->cd_planes[pNum],
&TiPlaneRect, &gatemask, areaAccumFunc, (ClientData)&gatearea);
/* Search planes of tie type and accumulate all (new) tiedown areas */
for (p = 0; p < DBNumPlanes; p++)
DBSrPaintArea((Tile *)NULL, extPathUse->cu_def->cd_planes[p],
&TiPlaneRect, &ExtCurStyle->exts_antennaTieTypes,
areaAccumFunc, (ClientData)&diffarea);
/* Search metal planes and accumulate all (new) antenna areas */
for (p = 0; p < DBNumPlanes; p++)
{
if (ExtCurStyle->exts_planeOrder[p] == pos)
{
pNum2 = p;
}
if (ExtCurStyle->exts_planeOrder[p] <= pos)
DBSrPaintArea((Tile *)NULL, extPathUse->cu_def->cd_planes[p],
&TiPlaneRect, &DBAllButSpaceAndDRCBits,
antennaAccumFunc, (ClientData)&antennaarea);
}
/* To be elaborated. . . this encodes only one of several */
/* methods of calculating antenna violations. */
if (diffarea == 0)
{
difftotal = 0.0;
for (i = 0; i < DBNumTypes; i++)
difftotal += antennaarea[i] / ExtCurStyle->exts_antennaRatio[i];
if (difftotal > gatearea)
TxError("Antenna violation detected at plane %s "
"(violation to be elaborated)",
DBPlaneLongNameTbl[pNum2]);
}
}
}
return 0;
}
/*
* ----------------------------------------------------------------------------
*
* areaAccumFunc --
*
* Accumulate the total tile area searched
*
* ----------------------------------------------------------------------------
*/
int
areaAccumFunc(tile, totalarea)
Tile *tile;
int *totalarea;
{
Rect rect;
int area;
TiToRect(tile, &rect);
area += (rect.r_xtop - rect.r_xbot) * (rect.r_ytop - rect.r_ybot);
*totalarea += area;
return 0;
}
/*
* ----------------------------------------------------------------------------
*
* antennaAccumFunc --
*
* Accumulate the total tile area searched, keeping an individual
* count for each tile type.
*
* ----------------------------------------------------------------------------
*/
int
antennaAccumFunc(tile, typeareas)
Tile *tile;
int **typeareas;
{
Rect rect;
int area;
int type;
type = TiGetType(tile);
TiToRect(tile, &rect);
area += (rect.r_xtop - rect.r_xbot) * (rect.r_ytop - rect.r_ybot);
*typeareas[type] += area;
return 0;
}

View File

@ -172,7 +172,7 @@ efBuildNode(def, isSubsnode, nodeName, nodeCap, x, y, layerName, av, ac)
HashSetValue(he, (char *) newname);
/* New node itself */
size = sizeof (EFNode) + (efNumResistClasses - 1) * sizeof (PerimArea);
size = sizeof (EFNode) + (efNumResistClasses - 1) * sizeof (EFPerimArea);
newnode = (EFNode *) mallocMagic((unsigned)(size));
newnode->efnode_flags = (isSubsnode == TRUE) ? EF_SUBS_NODE : 0;
newnode->efnode_cap = nodeCap;
@ -1182,7 +1182,7 @@ efBuildConnect(def, nodeName1, nodeName2, deltaC, av, ac)
int n;
Connection *conn;
unsigned size = sizeof (Connection)
+ (efNumResistClasses - 1) * sizeof (PerimArea);
+ (efNumResistClasses - 1) * sizeof (EFPerimArea);
conn = (Connection *) mallocMagic((unsigned)(size));

View File

@ -430,7 +430,7 @@ efAddNodes(hc, stdcell)
bool is_subcircuit = (def->def_flags & DEF_SUBCIRCUIT) ? TRUE : FALSE;
scale = def->def_scale;
size = sizeof (EFNode) + (efNumResistClasses-1) * sizeof (PerimArea);
size = sizeof (EFNode) + (efNumResistClasses-1) * sizeof (EFPerimArea);
for (node = (EFNode *) def->def_firstn.efnode_next;
node != &def->def_firstn;
@ -467,10 +467,10 @@ efAddNodes(hc, stdcell)
newnode->efnode_type = node->efnode_type;
if (!stdcell)
bcopy((char *) node->efnode_pa, (char *) newnode->efnode_pa,
efNumResistClasses * sizeof (PerimArea));
efNumResistClasses * sizeof (EFPerimArea));
else
bzero((char *) newnode->efnode_pa,
efNumResistClasses * sizeof (PerimArea));
efNumResistClasses * sizeof (EFPerimArea));
GeoTransRect(&hc->hc_trans, &node->efnode_loc, &newnode->efnode_loc);
/* Scale the result by "scale" --- hopefully we end up with an integer */

View File

@ -133,7 +133,7 @@ typedef struct conn
} conn_value;
struct conn *conn_next; /* Next connection in list */
PerimArea conn_pa[1]; /* Dummy; each connection actually has
EFPerimArea conn_pa[1]; /* Dummy; each connection actually has
* efNumResistClasses array elements
* allocated to it.
*/

View File

@ -142,7 +142,7 @@ typedef struct
{
int pa_area;
int pa_perim;
} PerimArea;
} EFPerimArea;
typedef struct efnhdr
{
@ -219,7 +219,7 @@ typedef struct efnode
*/
EFAttr *efnode_attrs; /* Node attribute list */
ClientData efnode_client; /* For hire */
PerimArea efnode_pa[1]; /* Dummy; each node actually has
EFPerimArea efnode_pa[1]; /* Dummy; each node actually has
* efNumResistClasses array elements
* allocated to it.
*/

View File

@ -71,7 +71,7 @@ typedef enum
AREAC, CONTACT, CSCALE,
DEFAULTAREACAP, DEFAULTOVERLAP, DEFAULTPERIMETER, DEFAULTSIDEOVERLAP,
DEFAULTSIDEWALL,
DEVICE, FET, FETRESIST, HEIGHT, ANTENNA, LAMBDA, OVERC,
DEVICE, FET, FETRESIST, HEIGHT, ANTENNA, TIEDOWN, LAMBDA, OVERC,
PERIMC, PLANEORDER, NOPLANEORDER, RESIST, RSCALE, SIDEHALO, SIDEOVERLAP,
SIDEWALL, STEP, STYLE, SUBSTRATE, UNITS, VARIANT
} Key;
@ -125,6 +125,9 @@ static keydesc keyTable[] = {
"antenna", ANTENNA, 3, 3,
"type antenna-ratio",
"tiedown", TIEDOWN, 2, 2,
"types",
"lambda", LAMBDA, 2, 2,
"units-per-lambda",
@ -665,14 +668,17 @@ extTechStyleInit(style)
style->exts_numResistClasses = 0;
style->exts_planeOrderStatus = needPlaneOrder ;
TTMaskZero(&style->exts_antennaTieTypes);
for (r = 0; r < DBNumTypes; r++)
{
style->exts_antennaRatio[r] = 0;
style->exts_resistByResistClass[r] = 0;
TTMaskZero(&style->exts_typesByResistClass[r]);
style->exts_typesResistChanged[r] = DBAllButSpaceAndDRCBits;
TTMaskSetType(&style->exts_typesResistChanged[r], TT_SPACE);
style->exts_typeToResistClass[r] = -1;
}
doConvert = FALSE;
@ -1789,6 +1795,7 @@ ExtTechLine(sectionName, argc, argv)
case FETRESIST:
case HEIGHT:
case ANTENNA:
case TIEDOWN:
case OVERC:
case PERIMC:
case RESIST:
@ -2325,6 +2332,9 @@ ExtTechLine(sectionName, argc, argv)
}
}
break;
case TIEDOWN:
TTMaskSetMask(&ExtCurStyle->exts_antennaTieTypes, &types1);
break;
case UNITS:
if (!strcmp(argv[1], "microns"))
doConvert = TRUE;

View File

@ -659,6 +659,9 @@ typedef struct extstyle
/* Antenna area ratio for each layer */
float exts_antennaRatio[NT];
/* Mask of types that tie down antennas */
TileTypeBitMask exts_antennaTieTypes;
/*
* Capacitance to substrate for each tile type, in units of
* attofarads per square lambda.