diff --git a/extflat/EFantenna.c b/extflat/EFantenna.c index 470edfe8..661fde43 100644 --- a/extflat/EFantenna.c +++ b/extflat/EFantenna.c @@ -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); diff --git a/extract/ExtTech.c b/extract/ExtTech.c index 96e3d4c7..506f0d92 100644 --- a/extract/ExtTech.c +++ b/extract/ExtTech.c @@ -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: diff --git a/extract/extractInt.h b/extract/extractInt.h index 7e9c7a2e..72e2424f 100644 --- a/extract/extractInt.h +++ b/extract/extractInt.h @@ -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 --------------------------- */