From 7aa846443a4565e66ea3c065fa71eb67f750e6c5 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Tue, 26 Sep 2023 21:26:31 -0400 Subject: [PATCH] Corrected an issue with the implementation of nondefault rules in DEF read and write. The NONDEFAULT LAYER WIREEXT was assumed to refer to the default wire extension at segments, when instead it refers to the wire extension only at vias. The wire extension at segments is presumably defined by the nondefault segment (and wire extension at vias remains unimplemented, which is probably not a big issue because everyone puts the wire extensions into the via definitions anyway). --- VERSION | 2 +- lef/defRead.c | 9 ++++++--- lef/defWrite.c | 42 ++++++++++++++++++++++++++++++------------ 3 files changed, 37 insertions(+), 16 deletions(-) diff --git a/VERSION b/VERSION index 01036633..3c546cf2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.433 +8.3.434 diff --git a/lef/defRead.c b/lef/defRead.c index a806020c..b8a3e9b5 100644 --- a/lef/defRead.c +++ b/lef/defRead.c @@ -209,7 +209,7 @@ DefAddRoutes(rootDef, f, oscale, special, netname, ruleset, defLayerMap, annotat paintWidth = (rule) ? rule->width : (lefl) ? lefl->info.route.width : DEFAULT_WIDTH * DBLambda[1] / DBLambda[0]; - paintExtend = (rule) ? rule->extend : paintWidth; + paintExtend = (rule) ? rule->width : paintWidth; } } else if ((*token == '+') && (special == TRUE)) @@ -377,7 +377,7 @@ DefAddRoutes(rootDef, f, oscale, special, netname, ruleset, defLayerMap, annotat if (rule) { paintWidth = rule->width; - paintExtend = rule->extend; + paintExtend = rule->width; } } else if (!strcmp(token, "DEFAULT")) @@ -874,7 +874,7 @@ DefReadNonDefaultRules(f, rootDef, sname, oscale, total) rule->lefInfo = lefl; rule->width = 0; rule->spacing = 0; - rule->extend = 0; + rule->extend = 0; /* unused */ rule->next = ruleset->rule; ruleset->rule = rule; } @@ -924,7 +924,10 @@ DefReadNonDefaultRules(f, rootDef, sname, oscale, total) else if (lefl == NULL) LefError(DEF_INFO, "No layer for non-default extension.\n"); else + { + LefError(DEF_WARNING, "Non-default extension at via not implemented.\n"); rule->extend = (int)roundf((2 * fvalue) / oscale); + } break; case DEF_NONDEFLAYER_DIAG: if (!inlayer) diff --git a/lef/defWrite.c b/lef/defWrite.c index 901fab79..4b8c742f 100644 --- a/lef/defWrite.c +++ b/lef/defWrite.c @@ -1188,7 +1188,7 @@ defNetGeometryFunc(tile, plane, defdata) ruleset->rule = (lefRule *)mallocMagic(sizeof(lefRule)); ruleset->rule->lefInfo = lefType; ruleset->rule->width = ndv; - /* Policy is never to use a wire extension on non-default rules. */ + /* Non-default rules wire extension-at-via is not used. */ ruleset->rule->extend = 0; /* Spacing is not needed, but set it to the layer default */ ruleset->rule->spacing = DRCGetDefaultLayerSpacing(ttype, ttype); @@ -1226,11 +1226,21 @@ defNetGeometryFunc(tile, plane, defdata) if (routeWidth == 0) routeWidth = h; extlen = 0; - /* NOTE: non-default tapers are not using wire extensions */ - if ((defdata->specialmode == DO_REGULAR) && (defdata->ruleset == NULL)) + /* NOTE: non-default tapers are not using wire */ + /* extension-at-via (need to implement) */ + + if (defdata->specialmode == DO_REGULAR) { - x1 = x1 + (routeWidth / 2 * oscale); - x2 = x2 - (routeWidth / 2 * oscale); + if (defdata->ruleset != NULL) + { + x1 = x1 + (defdata->ruleset->rule->width / 2 * oscale); + x2 = x2 - (defdata->ruleset->rule->width / 2 * oscale); + } + else + { + x1 = x1 + (routeWidth / 2 * oscale); + x2 = x2 - (routeWidth / 2 * oscale); + } } } else /* vertical orientation */ @@ -1243,11 +1253,20 @@ defNetGeometryFunc(tile, plane, defdata) if (routeWidth == 0) routeWidth = w; extlen = 0; - /* NOTE: non-default tapers are not using wire extensions */ - if ((defdata->specialmode == DO_REGULAR) && (defdata->ruleset == NULL)) + /* NOTE: non-default tapers are not using wire */ + /* extension-at-via (need to implement) */ + if (defdata->specialmode == DO_REGULAR) { - y1 = y1 + (routeWidth / 2 * oscale); - y2 = y2 - (routeWidth / 2 * oscale); + if (defdata->ruleset != NULL) + { + y1 = y1 + (defdata->ruleset->rule->width / 2 * oscale); + y2 = y2 - (defdata->ruleset->rule->width / 2 * oscale); + } + else + { + y1 = y1 + (routeWidth / 2 * oscale); + y2 = y2 - (routeWidth / 2 * oscale); + } } } } @@ -3082,10 +3101,9 @@ DefWriteCell(def, outName, allSpecial, units, analRetentive) if (lefl2->type == rule->lefInfo->type) break; if (rule != NULL) continue; - fprintf(f, "\n + LAYER %s WIDTH %.10g WIREEXT %.10g", + fprintf(f, "\n + LAYER %s WIDTH %.10g", lefl2->canonName, - (float)(lefl2->info.route.width) * scale, - (float)(lefl2->info.route.width) * scale / 2.0); + (float)(lefl2->info.route.width) * scale); } }