Corrected the LEF technology setup, where LEF layers (routes and

contacts) take default values from the DRC section.  Since both
are in lambda, but the DRC section uses a two-part integer and
modulus representation, if default values are taken before
scaling, the LEF layers may get rounded values.  This has been
solved by marking values with -1 to indicate that they require
defaults, and then set those defaults (from scaled DRC rules)
after scaling all other tech values.
This commit is contained in:
Tim Edwards 2022-11-20 15:15:04 -05:00
parent 18fc328289
commit 0f05bb1356
4 changed files with 80 additions and 4 deletions

View File

@ -4165,6 +4165,16 @@ DRCGetDefaultLayerWidth(ttype)
for (cptr = DRCCurStyle->DRCRulesTbl[TT_SPACE][ttype]; cptr != (DRCCookie *) NULL;
cptr = cptr->drcc_next)
{
/* Skip triggered and triggering rules */
if (cptr->drcc_flags & DRC_TRIGGER)
{
cptr = cptr->drcc_next;
continue;
}
/* Skip area rule */
if (cptr->drcc_flags & DRC_AREA) continue;
/* FORWARD rules only, and no MAXWIDTH */
if ((cptr->drcc_flags & (DRC_REVERSE | DRC_MAXWIDTH)) == 0)
{
@ -4219,6 +4229,10 @@ DRCGetDefaultLayerSpacing(ttype1, ttype2)
cptr = cptr->drcc_next;
continue;
}
/* Skip area rule */
if (cptr->drcc_flags & DRC_AREA) continue;
if ((cptr->drcc_flags & DRC_REVERSE) == 0) /* FORWARD only */
{
set = &cptr->drcc_mask;

View File

@ -16,6 +16,7 @@
extern void LefTechInit();
extern bool LefTechLine();
extern void LefTechScale();
extern void LefTechSetDefaults();
/* Initialization: */

View File

@ -339,10 +339,10 @@ LefTechLine(sectionName, argc, argv)
break;
case LEFTECH_CONTACT:
newlefl->lefClass = CLASS_VIA;
newlefl->info.via.area.r_xtop = DRCGetDefaultLayerWidth(mtype);
newlefl->info.via.area.r_ytop = newlefl->info.via.area.r_xtop;
newlefl->info.via.area.r_xbot = -newlefl->info.via.area.r_xtop;
newlefl->info.via.area.r_ybot = -newlefl->info.via.area.r_ytop;
newlefl->info.via.area.r_xbot = -1;
newlefl->info.via.area.r_ybot = -1;
newlefl->info.via.area.r_xtop = -1;
newlefl->info.via.area.r_ytop = -1; /* To be filled */
newlefl->info.via.cell = (CellDef *)NULL;
newlefl->info.via.lr = (LinkedRect *)NULL;
newlefl->info.via.obsType = mtype2;
@ -350,13 +350,19 @@ LefTechLine(sectionName, argc, argv)
case LEFTECH_ROUTE:
case LEFTECH_ROUTING:
newlefl->lefClass = CLASS_ROUTE;
/* Set provisional width (to be removed) */
newlefl->info.route.width = DRCGetDefaultLayerWidth(mtype);
if (newlefl->info.route.width == 0)
newlefl->info.route.width = DEFAULT_WIDTH;
else
newlefl->info.route.width = -1; /* To be filled */
/* Set provisional spacing (to be removed) */
newlefl->info.route.spacing =
DRCGetDefaultLayerSpacing(mtype, mtype);
if (newlefl->info.route.spacing == 0)
newlefl->info.route.spacing = DEFAULT_SPACING;
else
newlefl->info.route.spacing = -1; /* To be filled */
newlefl->info.route.pitch = 0;
newlefl->info.route.hdirection = TRUE;
break;
@ -453,3 +459,57 @@ LefTechScale(scalen, scaled)
}
}
}
/*
*-----------------------------------------------------------------------------
* LefTechSetDefaults --
*
* Change parameters of the LEF section after scaling (see above)
* to set default values for each route and contact layer (width and
* spacing have been set to -1). This is because the value is in
* lambda, and calling the DRC defaults before scaling can produce
* a rounded value which is then incorrect when scaled.
*
* ----------------------------------------------------------------------------
*/
void
LefTechSetDefaults()
{
HashSearch hs;
HashEntry *he;
lefLayer *lefl;
if (LefInfo.ht_table != (HashEntry **) NULL)
{
HashStartSearch(&hs);
while (he = HashNext(&LefInfo, &hs))
{
lefl = (lefLayer *)HashGetValue(he);
if (!lefl) continue;
if (lefl->lefClass == CLASS_VIA)
{
if ((lefl->info.via.area.r_xbot == -1) &&
(lefl->info.via.area.r_ybot == -1) &&
(lefl->info.via.area.r_xtop == -1) &&
(lefl->info.via.area.r_ytop == -1))
{
lefl->info.via.area.r_xtop =
DRCGetDefaultLayerWidth(lefl->type);
lefl->info.via.area.r_ytop = lefl->info.via.area.r_xtop;
lefl->info.via.area.r_xbot = -lefl->info.via.area.r_xtop;
lefl->info.via.area.r_ybot = -lefl->info.via.area.r_ytop;
}
}
else if (lefl->lefClass == CLASS_ROUTE)
{
if (lefl->info.route.width = -1)
lefl->info.route.width = DRCGetDefaultLayerWidth(lefl->type);
if (lefl->info.route.spacing = -1)
lefl->info.route.width = DRCGetDefaultLayerSpacing(lefl->type,
lefl->type);
}
}
}
}

View File

@ -772,6 +772,7 @@ skipsection:
WireTechScale(d, n);
#ifdef LEF_MODULE
LefTechScale(d, n);
LefTechSetDefaults();
#endif
#ifdef ROUTE_MODULE
RtrTechScale(d, n);