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; TileType t, conType;
int pos, pNum, pNum2, pmax, p, i, j, gatearea, diffarea, total; int pos, pNum, pNum2, pmax, p, i, j, gatearea, diffarea, total;
double anttotal; double anttotal;
float saveRatio; float saveRatio, ratioTotal;
int *antennaarea; int *antennaarea;
Rect r, gaterect; Rect r, gaterect;
EFNode *gnode; EFNode *gnode;
@ -566,13 +566,15 @@ antennacheckVisit(dev, hierName, scale, trans, editUse)
anttotal = 0.0; anttotal = 0.0;
saveRatio = 0.0; saveRatio = 0.0;
for (i = 0; i < DBNumTypes; i++) 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) ratioTotal = ExtCurStyle->exts_antennaRatio[i].ratioDiffB +
anttotal += (double)antennaarea[i] / diffarea * ExtCurStyle->exts_antennaRatio[i].ratioDiffA;
(double)ExtCurStyle->exts_antennaRatio[i].ratioDiff;
if (ExtCurStyle->exts_antennaRatio[i].ratioDiff > saveRatio) if (ratioTotal > 0)
saveRatio = ExtCurStyle->exts_antennaRatio[i].ratioDiff; anttotal += (double)antennaarea[i] / (double)ratioTotal;
if (ratioTotal > saveRatio)
saveRatio = ratioTotal;
} }
if (anttotal > (double)gatearea) if (anttotal > (double)gatearea)
@ -702,7 +704,7 @@ antennaAccumFunc(tile, aaptr)
TiToRect(tile, rect); 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 */ /* Accumulate perimeter of tile where tile abuts space */
@ -799,7 +801,7 @@ antennaAccumFunc(tile, aaptr)
typeareas[type] += (int)((float)perimeter * thick); typeareas[type] += (int)((float)perimeter * thick);
} }
} }
else else if (ExtCurStyle->exts_antennaRatio[type].areaType & ANTENNAMODEL_SURFACE)
{ {
/* Simple tile area calculation */ /* Simple tile area calculation */
area = (rect->r_xtop - rect->r_xbot) * (rect->r_ytop - rect->r_ybot); 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, "height", HEIGHT, 4, 4,
"type height-above-subtrate thickness", "type height-above-subtrate thickness",
"antenna", ANTENNA, 4, 4, "antenna", ANTENNA, 4, 6,
"type antenna-ratio", "type [calc-type] [antenna-ratio-proportional] antenna-ratio-const",
"model", MODEL, 3, 3, "model", MODEL, 2, 3,
"partial-cumulative area-sidewall", "partial-cumulative [area-sidewall]",
"tiedown", TIEDOWN, 2, 2, "tiedown", TIEDOWN, 2, 2,
"types", "types",
@ -704,8 +704,10 @@ extTechStyleInit(style)
for (r = 0; r < DBNumTypes; r++) for (r = 0; r < DBNumTypes; r++)
{ {
style->exts_antennaRatio[r].areaType = (char)0;
style->exts_antennaRatio[r].ratioGate = 0.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; style->exts_resistByResistClass[r] = 0;
TTMaskZero(&style->exts_typesByResistClass[r]); TTMaskZero(&style->exts_typesByResistClass[r]);
style->exts_typesResistChanged[r] = DBAllButSpaceAndDRCBits; style->exts_typesResistChanged[r] = DBAllButSpaceAndDRCBits;
@ -2351,38 +2353,96 @@ ExtTechLine(sectionName, argc, argv)
break; break;
case ANTENNA: { case ANTENNA: {
float antennaratio; float antennaratio;
char areaType;
bool hasModel = FALSE;
int argidx = 2;
if (!StrIsNumeric(argv[2])) if (!StrIsNumeric(argv[2]))
{ {
TechError("Gate layer antenna ratio %s must be numeric\n", argv[2]); if (!strcmp(argv[2], "surface") || !strcmp(argv[2], "area"))
break; {
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++) for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
if (TTMaskHasType(&types1, t)) if (TTMaskHasType(&types1, t))
{ ExtCurStyle->exts_antennaRatio[t].areaType = areaType;
ExtCurStyle->exts_antennaRatio[t].ratioGate = antennaratio;
}
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; antennaratio = INFINITY;
else 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; break;
} }
} }
else else
antennaratio = (float)strtod(argv[3], NULL); antennaratio = (float)strtod(argv[argidx], NULL);
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
if (TTMaskHasType(&types1, 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; break;
}
case MODEL: case MODEL:
if (!strcmp(argv[1], "partial")) if (!strcmp(argv[1], "partial"))
ExtCurStyle->exts_antennaModel |= ANTENNAMODEL_PARTIAL; ExtCurStyle->exts_antennaModel |= ANTENNAMODEL_PARTIAL;
@ -2392,13 +2452,16 @@ ExtTechLine(sectionName, argc, argv)
TxError("Unknown antenna model \"%s\": Use \"partial\" or " TxError("Unknown antenna model \"%s\": Use \"partial\" or "
"\"cumulative\""); "\"cumulative\"");
if (!strcmp(argv[2], "area")) if (argc > 2)
ExtCurStyle->exts_antennaModel |= ANTENNAMODEL_AREA; {
else if (!strcmp(argv[2], "sidewall")) if (!strcmp(argv[2], "surface") || !strcmp(argv[2], "area"))
ExtCurStyle->exts_antennaModel |= ANTENNAMODEL_SIDEWALL; ExtCurStyle->exts_antennaModel |= ANTENNAMODEL_SURFACE;
else else if (!strcmp(argv[2], "sidewall") || !strcmp(argv[2], "perimeter"))
TxError("Unknown antenna model \"%s\": Use \"area\" or " ExtCurStyle->exts_antennaModel |= ANTENNAMODEL_SIDEWALL;
"\"sidewall\""); else
TxError("Unknown antenna model \"%s\": Use \"surface\" or "
"\"sidewall\"");
}
break; break;
case TIEDOWN: case TIEDOWN:

View File

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