Expanded the antenna rule violation setup and calculations to

include (1) specification of sidewall or surface to use for
each type individually, rather than a single method for all
types, and (2) specification of a linear model R = Ax + B for
the ratio limit when diodes are attached to the wire, where x
is the diode surface area (unitless, as this is a ratio).
This commit is contained in:
Tim Edwards 2019-11-27 10:38:47 -05:00
parent a374230d88
commit cfaccd973f
3 changed files with 101 additions and 34 deletions

View File

@ -347,7 +347,7 @@ antennacheckVisit(dev, hierName, scale, trans, editUse)
TileType t, conType;
int pos, pNum, pNum2, pmax, p, i, j, gatearea, diffarea, total;
double anttotal;
float saveRatio;
float saveRatio, ratioTotal;
int *antennaarea;
Rect r, gaterect;
EFNode *gnode;
@ -566,13 +566,15 @@ antennacheckVisit(dev, hierName, scale, trans, editUse)
anttotal = 0.0;
saveRatio = 0.0;
for (i = 0; i < DBNumTypes; i++)
if (ExtCurStyle->exts_antennaRatio[i].ratioDiff != INFINITY)
if (ExtCurStyle->exts_antennaRatio[i].ratioDiffB != INFINITY)
{
if (ExtCurStyle->exts_antennaRatio[i].ratioDiff > 0)
anttotal += (double)antennaarea[i] /
(double)ExtCurStyle->exts_antennaRatio[i].ratioDiff;
if (ExtCurStyle->exts_antennaRatio[i].ratioDiff > saveRatio)
saveRatio = ExtCurStyle->exts_antennaRatio[i].ratioDiff;
ratioTotal = ExtCurStyle->exts_antennaRatio[i].ratioDiffB +
diffarea * ExtCurStyle->exts_antennaRatio[i].ratioDiffA;
if (ratioTotal > 0)
anttotal += (double)antennaarea[i] / (double)ratioTotal;
if (ratioTotal > saveRatio)
saveRatio = ratioTotal;
}
if (anttotal > (double)gatearea)
@ -702,7 +704,7 @@ antennaAccumFunc(tile, aaptr)
TiToRect(tile, rect);
if (ExtCurStyle->exts_antennaModel & ANTENNAMODEL_SIDEWALL)
if (ExtCurStyle->exts_antennaRatio[type].areaType & ANTENNAMODEL_SIDEWALL)
{
/* Accumulate perimeter of tile where tile abuts space */
@ -799,7 +801,7 @@ antennaAccumFunc(tile, aaptr)
typeareas[type] += (int)((float)perimeter * thick);
}
}
else
else if (ExtCurStyle->exts_antennaRatio[type].areaType & ANTENNAMODEL_SURFACE)
{
/* Simple tile area calculation */
area = (rect->r_xtop - rect->r_xbot) * (rect->r_ytop - rect->r_ybot);

View File

@ -122,11 +122,11 @@ static keydesc keyTable[] = {
"height", HEIGHT, 4, 4,
"type height-above-subtrate thickness",
"antenna", ANTENNA, 4, 4,
"type antenna-ratio",
"antenna", ANTENNA, 4, 6,
"type [calc-type] [antenna-ratio-proportional] antenna-ratio-const",
"model", MODEL, 3, 3,
"partial-cumulative area-sidewall",
"model", MODEL, 2, 3,
"partial-cumulative [area-sidewall]",
"tiedown", TIEDOWN, 2, 2,
"types",
@ -704,8 +704,10 @@ extTechStyleInit(style)
for (r = 0; r < DBNumTypes; r++)
{
style->exts_antennaRatio[r].areaType = (char)0;
style->exts_antennaRatio[r].ratioGate = 0.0;
style->exts_antennaRatio[r].ratioDiff = 0.0;
style->exts_antennaRatio[r].ratioDiffA = 0.0;
style->exts_antennaRatio[r].ratioDiffB = 0.0;
style->exts_resistByResistClass[r] = 0;
TTMaskZero(&style->exts_typesByResistClass[r]);
style->exts_typesResistChanged[r] = DBAllButSpaceAndDRCBits;
@ -2351,38 +2353,96 @@ ExtTechLine(sectionName, argc, argv)
break;
case ANTENNA: {
float antennaratio;
char areaType;
bool hasModel = FALSE;
int argidx = 2;
if (!StrIsNumeric(argv[2]))
{
TechError("Gate layer antenna ratio %s must be numeric\n", argv[2]);
break;
if (!strcmp(argv[2], "surface") || !strcmp(argv[2], "area"))
{
areaType = ANTENNAMODEL_SURFACE;
hasModel = TRUE;
}
else if (!strcmp(argv[2], "sidewall") || !strcmp(argv[2], "perimeter"))
{
areaType = ANTENNAMODEL_SIDEWALL;
hasModel = TRUE;
}
else
{
TechError("Error in layer antenna calculation type \"%s\"; "
" must be \"surface\" or \"sidewall\"\n", argv[2]);
break;
}
}
antennaratio = (float)strtod(argv[2], NULL);
if (hasModel == FALSE)
{
if (ExtCurStyle->exts_antennaModel & ANTENNAMODEL_SURFACE)
areaType = ANTENNAMODEL_SURFACE;
else if (ExtCurStyle->exts_antennaModel & ANTENNAMODEL_SIDEWALL)
areaType = ANTENNAMODEL_SIDEWALL;
else
TechError("No antenna calculation type given for layer(s) %s "
" and no default calculation type found.\n", argv[1]);
}
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
if (TTMaskHasType(&types1, t))
{
ExtCurStyle->exts_antennaRatio[t].ratioGate = antennaratio;
}
ExtCurStyle->exts_antennaRatio[t].areaType = areaType;
if (!StrIsNumeric(argv[3]))
if (hasModel == TRUE) argidx = 3;
if (!StrIsNumeric(argv[argidx]))
{
if (!strcasecmp(argv[3], "none"))
TechError("Gate layer antenna ratio %s must be numeric\n", argv[argidx]);
break;
}
antennaratio = (float)strtod(argv[argidx], NULL);
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
if (TTMaskHasType(&types1, t))
ExtCurStyle->exts_antennaRatio[t].ratioGate = antennaratio;
argidx++;
if (!StrIsNumeric(argv[argidx]))
{
if (!strcasecmp(argv[argidx], "none"))
antennaratio = INFINITY;
else
{
TechError("Diff layer antenna ratio %s must be numeric\n", argv[3]);
TechError("Diff layer antenna ratio %s must be numeric\n",
argv[argidx]);
break;
}
}
else
antennaratio = (float)strtod(argv[3], NULL);
antennaratio = (float)strtod(argv[argidx], NULL);
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
if (TTMaskHasType(&types1, t))
ExtCurStyle->exts_antennaRatio[t].ratioDiffB = antennaratio;
argidx++;
if (argidx < argc)
{
if (!StrIsNumeric(argv[argidx]))
{
ExtCurStyle->exts_antennaRatio[t].ratioDiff = antennaratio;
TechError("Diff layer antenna ratio %s must be numeric\n",
argv[argidx]);
break;
}
antennaratio = (float)strtod(argv[argidx], NULL);
}
else
antennaratio = 0;
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
if (TTMaskHasType(&types1, t))
ExtCurStyle->exts_antennaRatio[t].ratioDiffA = antennaratio;
break;
}
case MODEL:
if (!strcmp(argv[1], "partial"))
ExtCurStyle->exts_antennaModel |= ANTENNAMODEL_PARTIAL;
@ -2392,13 +2452,16 @@ ExtTechLine(sectionName, argc, argv)
TxError("Unknown antenna model \"%s\": Use \"partial\" or "
"\"cumulative\"");
if (!strcmp(argv[2], "area"))
ExtCurStyle->exts_antennaModel |= ANTENNAMODEL_AREA;
else if (!strcmp(argv[2], "sidewall"))
ExtCurStyle->exts_antennaModel |= ANTENNAMODEL_SIDEWALL;
else
TxError("Unknown antenna model \"%s\": Use \"area\" or "
"\"sidewall\"");
if (argc > 2)
{
if (!strcmp(argv[2], "surface") || !strcmp(argv[2], "area"))
ExtCurStyle->exts_antennaModel |= ANTENNAMODEL_SURFACE;
else if (!strcmp(argv[2], "sidewall") || !strcmp(argv[2], "perimeter"))
ExtCurStyle->exts_antennaModel |= ANTENNAMODEL_SIDEWALL;
else
TxError("Unknown antenna model \"%s\": Use \"surface\" or "
"\"sidewall\"");
}
break;
case TIEDOWN:

View File

@ -49,14 +49,16 @@ typedef int ResValue; /* Warning: in some places resistances are stored
*/
typedef struct {
char areaType; /* ANTENNAMODEL_SURFACE or ANTENNAMODEL_SIDEWALL */
float ratioGate;
float ratioDiff;
float ratioDiffA; /* Proportional */
float ratioDiffB; /* Constant */
} RatioValues;
/* Antenna models */
#define ANTENNAMODEL_PARTIAL 0x01
#define ANTENNAMODEL_CUMULATIVE 0x02
#define ANTENNAMODEL_AREA 0x04
#define ANTENNAMODEL_SURFACE 0x04
#define ANTENNAMODEL_SIDEWALL 0x08
/* ------------------------ Parameter lists --------------------------- */