diff --git a/Makefile b/Makefile index e1d61fbd..12a20220 100644 --- a/Makefile +++ b/Makefile @@ -19,11 +19,11 @@ all: $(ALL_TARGET) standard: @echo --- errors and warnings logged in file make.log - @${MAKE} mains 2>&1 | tee -a make.log | egrep -i "(.c:|Stop.|---)" + @${MAKE} mains tcl: @echo --- errors and warnings logged in file make.log - @${MAKE} tcllibrary 2>&1 | tee -a make.log | egrep -i "(.c:|Stop.|---)" + @${MAKE} tcllibrary force: clean all @@ -36,12 +36,12 @@ config: tcllibrary: database/database.h modules @echo --- making Tcl shared libraries for dir in ${PROGRAMS}; do \ - (cd $$dir && ${MAKE} tcl-main); done + (cd $$dir && ${MAKE} tcl-main) || exit 1; done mains: database/database.h modules libs @echo --- making main programs for dir in ${PROGRAMS}; do \ - (cd $$dir && ${MAKE} main); done + (cd $$dir && ${MAKE} main) || exit 1; done database/database.h: database/database.h.in @echo --- making header file database/database.h @@ -50,25 +50,25 @@ database/database.h: database/database.h.in modules: database/database.h depend @echo --- making modules for dir in ${MODULES} ${PROGRAMS}; do \ - (cd $$dir && ${MAKE} module); done + (cd $$dir && ${MAKE} module) || exit 1; done libs: @echo --- making libraries for dir in ${LIBRARIES}; do \ - (cd $$dir && ${MAKE} lib); done + (cd $$dir && ${MAKE} lib) || exit 1; done depend: database/database.h @echo --- making dependencies ${RM} */Depend for dir in ${MODULES} ${UNUSED_MODULES} ${PROGRAMS}; do \ - (cd $$dir && ${MAKE} depend); done + (cd $$dir && ${MAKE} depend) || exit 1; done install: $(INSTALL_TARGET) install-magic: @echo --- installing executable to $(DESTDIR)${INSTALL_BINDIR} @echo --- installing runtime files to $(DESTDIR)${INSTALL_LIBDIR} - @${MAKE} install-real 2>&1 >> install.log + @${MAKE} install-real install-real: install-dirs for dir in ${INSTALL_CAD_DIRS}; do \ @@ -89,7 +89,7 @@ install-dirs: install-tcl: @echo --- installing executable to $(DESTDIR)${INSTALL_BINDIR} @echo --- installing runtime files to $(DESTDIR)${INSTALL_LIBDIR} - @${MAKE} install-tcl-real 2>&1 >> install.log + @${MAKE} install-tcl-real install-tcl-real: install-tcl-dirs for dir in ${INSTALL_CAD_DIRS} ${PROGRAMS}; do \ diff --git a/VERSION b/VERSION index 7129a9fd..0513e5cf 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.282 +8.3.283 diff --git a/commands/CmdTZ.c b/commands/CmdTZ.c index 12f5442d..1e082742 100644 --- a/commands/CmdTZ.c +++ b/commands/CmdTZ.c @@ -497,6 +497,29 @@ CmdTech(w, cmd) Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(tresult)); #else TxPrintf("Minimum surround is %d\n", tresult); +#endif + } + else if (!strncmp(cmd->tx_argv[2], "direc", 5)) + { + if (cmd->tx_argc >= 5) + { + t2 = DBTechNoisyNameType(cmd->tx_argv[4]); + if (t2 < 0) { + TxError("No such layer %s\n", cmd->tx_argv[4]); + break; + } + } + else + { + TxError("Requires two layer types.\n"); + break; + } + + tresult = DRCGetDirectionalLayerSurround(t1, t2); +#ifdef MAGIC_WRAPPER + Tcl_SetObjResult(magicinterp, Tcl_NewIntObj(tresult)); +#else + TxPrintf("Minimum surround (in one orientation) is %d\n", tresult); #endif } } diff --git a/drc/DRCtech.c b/drc/DRCtech.c index cc669782..d2c73f54 100644 --- a/drc/DRCtech.c +++ b/drc/DRCtech.c @@ -4115,7 +4115,7 @@ DRCGetDefaultLayerSurround(ttype1, ttype2) { int layerSurround = 0; DRCCookie *cptr; - TileTypeBitMask *set; + TileTypeBitMask *set, *cset; for (cptr = DRCCurStyle->DRCRulesTbl[ttype1][TT_SPACE]; cptr != (DRCCookie *) NULL; cptr = cptr->drcc_next) @@ -4137,6 +4137,81 @@ DRCGetDefaultLayerSurround(ttype1, ttype2) } } } + if (layerSurround > 0) return layerSurround; + + for (cptr = DRCCurStyle->DRCRulesTbl[TT_SPACE][ttype1]; cptr != (DRCCookie *) NULL; + cptr = cptr->drcc_next) + { + if ((cptr->drcc_flags & DRC_REVERSE) == 0) /* FORWARD only */ + { + set = &cptr->drcc_mask; + cset = &cptr->drcc_corner; + if (TTMaskHasType(set, TT_SPACE) && !TTMaskHasType(set, ttype1)) + if ((TTMaskHasType(cset, ttype2)) && + (cptr->drcc_flags && DRC_BOTHCORNERS) && + (cptr->drcc_edgeplane == cptr->drcc_plane) && + (cptr->drcc_dist == cptr->drcc_cdist)) + { + layerSurround = cptr->drcc_dist; + /* Diagnostic */ + /* + TxPrintf("DRC: Layer %s has default surround %d over layer %s\n", + DBTypeLongNameTbl[ttype2], layerSurround, + DBTypeLongNameTbl[ttype1]); + */ + } + } + } + return layerSurround; +} + +/* + *----------------------------------------------------------------------------- + * DRCGetDirectionalLayerSurround --- + * + * Determine the minimum required surround amount of layer type 2 + * around layer type 1 for a directional surround rule (rule + * applies for two opposing sides of layer type 1). + * + * Results: + * The minimum spacing between the specified magic layer types, + * in magic internal units + * + * Side effects: + * None. + * + *----------------------------------------------------------------------------- + */ + +int +DRCGetDirectionalLayerSurround(ttype1, ttype2) + TileType ttype1, ttype2; +{ + int layerSurround = 0; + DRCCookie *cptr, *cnext; + TileTypeBitMask *set, *cset; + + for (cptr = DRCCurStyle->DRCRulesTbl[ttype1][TT_SPACE]; cptr != (DRCCookie *) NULL; + cptr = cptr->drcc_next) + { + if (cptr->drcc_flags & DRC_TRIGGER) + { + set = &cptr->drcc_mask; + if (!TTMaskHasType(set, TT_SPACE) && TTMaskHasType(set, ttype2)) + if ((cptr->drcc_plane == cptr->drcc_edgeplane) && + (cptr->drcc_cdist == 0)) + { + layerSurround = cptr->drcc_dist; + /* Diagnostic */ + /* + TxPrintf("DRC: Layer %s has default surround %d over layer %s\n", + DBTypeLongNameTbl[ttype2], layerSurround, + DBTypeLongNameTbl[ttype1]); + */ + } + cnext = cptr->drcc_next; + } + } return layerSurround; } diff --git a/drc/drc.h b/drc/drc.h index 1a8ad1be..86c65da7 100644 --- a/drc/drc.h +++ b/drc/drc.h @@ -249,6 +249,7 @@ extern int DRCGetDefaultLayerWidth(); extern int DRCGetDefaultLayerSpacing(); extern int DRCGetDefaultWideLayerSpacing(); extern int DRCGetDefaultLayerSurround(); +extern int DRCGetDirectionalLayerSurround(); extern int DRCInteractionCheck(); extern int drcArrayFunc(); diff --git a/lef/defWrite.c b/lef/defWrite.c index eccd1ba2..80b8323c 100644 --- a/lef/defWrite.c +++ b/lef/defWrite.c @@ -48,6 +48,7 @@ typedef struct { unsigned char orient; LefMapping *MagicToLefTbl; + HashTable *defViaTable; int outcolumn; /* Current column of output in file */ unsigned char specialmode; /* What nets to write as SPECIALNETS */ } DefData; @@ -61,11 +62,12 @@ typedef struct { } DefObsData; typedef struct { + CellDef *def; float scale; int total; - int plane; TileTypeBitMask *mask; LefMapping *MagicToLefTbl; + HashTable *defViaTable; } CViaData; /*----------------------------------------------------------------------*/ @@ -595,11 +597,12 @@ defWriteCoord(defdata, x, y, orient) */ void -defWriteNets(f, rootDef, oscale, MagicToLefTable, specialmode) +defWriteNets(f, rootDef, oscale, MagicToLefTable, defViaTable, specialmode) FILE *f; /* File to write to */ CellDef *rootDef; /* Cell definition to use */ float oscale; /* Output scale factor */ LefMapping *MagicToLefTable; /* Magic to LEF layer mapping */ + HashTable *defViaTable; /* Hash table of contact positions */ unsigned char specialmode; /* What to write as a SPECIALNET */ { DefData defdata; @@ -611,6 +614,7 @@ defWriteNets(f, rootDef, oscale, MagicToLefTable, specialmode) defdata.MagicToLefTbl = MagicToLefTable; defdata.outcolumn = 0; defdata.specialmode = specialmode; + defdata.defViaTable = defViaTable; EFVisitNodes(defnodeVisit, (ClientData)&defdata); } @@ -769,6 +773,30 @@ defnodeVisit(node, res, cap, defdata) return 0; /* Keep going */ } +/* Callback function for defNetGeometryFunc(). Determines if any tile */ +/* sets the lower bound of the clip line for extending a wire upward */ + +int +defMaxWireFunc(tile, yclip) + Tile *tile; + int *yclip; +{ + if (BOTTOM(tile) < (*yclip)) *yclip = BOTTOM(tile); + return 0; +} + +/* Callback function for defNetGeometryFunc(). Determines if any tile */ +/* sets the upper bound of the clip line for extending a wire downward */ + +int +defMinWireFunc(tile, yclip) + Tile *tile; + int *yclip; +{ + if (TOP(tile) > (*yclip)) *yclip = TOP(tile); + return 0; +} + /* Callback function for DBTreeSrUniqueTiles. When no routed areas */ /* were found, we assume that there was no routing material overlapping */ /* the port. So, we need to find the area of a tile defining the port */ @@ -810,13 +838,15 @@ defNetGeometryFunc(tile, plane, defdata) float oscale = defdata->scale; TileTypeBitMask *rMask, *r2Mask; TileType rtype, r2type, ttype = TiGetType(tile); - Rect r; + Rect r, rorig; unsigned char orient; bool sameroute = FALSE; - int routeWidth, w, h, midlinex2; + int routeWidth, w, h, midlinex2, topClip, botClip; float x1, y1, x2, y2, extlen; - lefLayer *lefType; - char *lefName, viaName[24]; + lefLayer *lefType, *lefl; + char *lefName, viaName[128], posstr[24]; + HashEntry *he; + HashTable *defViaTable = defdata->defViaTable; LefMapping *MagicToLefTable = defdata->MagicToLefTbl; if (ttype == TT_SPACE) return 0; @@ -923,6 +953,7 @@ defNetGeometryFunc(tile, plane, defdata) } } } + rorig = r; /* Layer names are taken from the LEF database. */ @@ -970,6 +1001,43 @@ defNetGeometryFunc(tile, plane, defdata) /* This means a regular net should have been a special net. */ if ((h != routeWidth) && (w != routeWidth)) { + /* Handle slivers. There are two main cases: + * (1) Sliver is part of a via extension, so it can be ignored. + * (2) Sliver is a route split into several tiles due to geometry + * to the left. Expand up and down to include all tiles. + */ + + if (w < routeWidth) return 0; + + if (h < routeWidth) + { + /* Check upward */ + r = rorig; + r.r_ytop = r.r_ybot + routeWidth; + r.r_ybot = rorig.r_ytop; + topClip = r.r_ytop; + DBSrPaintArea(tile, def->cd_planes[plane], + &r, &DBNotConnectTbl[ttype], + defMaxWireFunc, (ClientData)&topClip); + + /* Check downward */ + r = rorig; + r.r_ybot = r.r_ytop - routeWidth; + r.r_ytop = rorig.r_ybot; + botClip = r.r_ybot; + DBSrPaintArea(tile, def->cd_planes[plane], + &r, &DBNotConnectTbl[ttype], + defMinWireFunc, (ClientData)&botClip); + + r = rorig; + if (topClip > r.r_ytop) r.r_ytop = topClip; + if (botClip < r.r_ybot) r.r_ybot = botClip; + + /* If height is still less that a route width, bail */ + h = r.r_ytop - r.r_ybot; + if (h < routeWidth) return 0; + } + /* Diagnostic */ TxPrintf("Net at (%d, %d) has width %d, default width is %d\n", r.r_xbot, r.r_ybot, @@ -981,6 +1049,8 @@ defNetGeometryFunc(tile, plane, defdata) orient = GEO_NORTH; midlinex2 = (r.r_xtop + r.r_xbot); } + else + midlinex2 = (r.r_ytop + r.r_ybot); } /* Find the route orientation and centerline endpoint coordinates */ @@ -1145,10 +1215,23 @@ defNetGeometryFunc(tile, plane, defdata) } /* Via type continues route */ - snprintf(viaName, (size_t)24, "_%.10g_%.10g", + sprintf(posstr, "%s_%d_%d", DBPlaneShortName(DBPlane(ttype)), + rorig.r_xbot, rorig.r_ybot); + he = HashLookOnly(defViaTable, posstr); + if (he != NULL) + { + lefl = (lefLayer *)HashGetValue(he); + defCheckForBreak(strlen(lefl->canonName) + 2, defdata); + fprintf(f, " %s ", lefl->canonName); + } + else + { + TxError("Cannot find via name %s in table!\n", posstr); + snprintf(viaName, (size_t)24, "_%.10g_%.10g", ((float)w * oscale), ((float)h * oscale)); - defCheckForBreak(strlen(lefName) + strlen(viaName) + 2, defdata); - fprintf(f, " %s%s ", lefName, viaName); + defCheckForBreak(strlen(lefName) + strlen(viaName) + 2, defdata); + fprintf(f, " %s%s ", lefName, viaName); + } } else { @@ -1196,10 +1279,24 @@ defNetGeometryFunc(tile, plane, defdata) if (defdata->specialmode != DO_REGULAR) defWriteRouteWidth(defdata, routeWidth); defWriteCoord(defdata, x1, y1, GEO_CENTER); - snprintf(viaName, (size_t)24, "_%.10g_%.10g", - ((float)w * oscale), ((float)h * oscale)); - defCheckForBreak(strlen(lefName) + strlen(viaName) + 2, defdata); - fprintf(f, " %s%s ", lefName, viaName); + + sprintf(posstr, "%s_%d_%d", DBPlaneShortName(DBPlane(ttype)), + rorig.r_xbot, rorig.r_ybot); + he = HashLookOnly(defViaTable, posstr); + if (he != NULL) + { + lefl = (lefLayer *)HashGetValue(he); + defCheckForBreak(strlen(lefl->canonName) + 2, defdata); + fprintf(f, " %s ", lefl->canonName); + } + else + { + TxError("Cannot find via name %s in table!\n", posstr); + snprintf(viaName, (size_t)24, "_%.10g_%.10g", + ((float)w * oscale), ((float)h * oscale)); + defCheckForBreak(strlen(lefName) + strlen(viaName) + 2, defdata); + fprintf(f, " %s%s ", lefName, viaName); + } } else { @@ -1347,9 +1444,10 @@ defNetGeometryFunc(tile, plane, defdata) */ int -defCountVias(rootDef, MagicToLefTable, oscale) +defCountVias(rootDef, MagicToLefTable, defViaTable, oscale) CellDef *rootDef; LefMapping *MagicToLefTable; + HashTable *defViaTable; float oscale; { TileTypeBitMask contactMask, *rmask; @@ -1361,11 +1459,11 @@ defCountVias(rootDef, MagicToLefTable, oscale) cviadata.scale = oscale; cviadata.total = 0; cviadata.MagicToLefTbl = MagicToLefTable; + cviadata.defViaTable = defViaTable; + cviadata.def = rootDef; for (pNum = PL_SELECTBASE; pNum < DBNumPlanes; pNum++) { - cviadata.plane = pNum; - /* Only search for contacts that are on their *home* plane */ TTMaskZero(&contactMask); @@ -1396,6 +1494,14 @@ defCountVias(rootDef, MagicToLefTable, oscale) return cviadata.total; } +/* Simple callback function used by defCountViaFunc */ + +int +defCheckFunc(tile) +{ + return 1; +} + /* Callback function used by defCountVias */ int @@ -1406,12 +1512,17 @@ defCountViaFunc(tile, cviadata) TileType ttype = TiGetType(tile), ctype, rtype; TileTypeBitMask *rmask, *rmask2; Tile *tp; - char *lname, vname[100], *vp; - Rect r, r2; - int w, h, offx, offy; + char *lname, vname[100], *vp, posstr[24]; + Rect r, r2, rorig; + int w, h, offx, offy, sdist, lorient, horient; + int ldist, hdist, sldist, shdist, pNum; + TileType ltype, htype; float oscale = cviadata->scale; lefLayer *lefl; + LinkedRect *newlr; + CellDef *def = cviadata->def; HashEntry *he; + HashTable *defViaTable = cviadata->defViaTable; LefMapping *MagicToLefTable = cviadata->MagicToLefTbl; /* Techfiles are allowed not to declare a LEF entry, in which */ @@ -1521,6 +1632,7 @@ defCountViaFunc(tile, cviadata) /* All values for the via rect are in 1/2 lambda to account */ /* for a centerpoint not on the internal grid. */ + rorig = r; r.r_xbot <<= 1; r.r_xtop <<= 1; r.r_ybot <<= 1; @@ -1537,7 +1649,67 @@ defCountViaFunc(tile, cviadata) r.r_xtop = -offx + w; r.r_ytop = -offy + h; - sprintf(vname, "%s_%.10g_%.10g", lname, + /* If the via type has directional surround rules, then determine */ + /* the orientation of the lower and upper metal layers and add a */ + /* suffix to the via name. */ + + rmask = DBResidueMask(ctype); + ldist = hdist = 0; + ltype = htype = TT_SPACE; + for (rtype = TT_TECHDEPBASE; rtype < DBNumUserLayers; rtype++) + if (TTMaskHasType(rmask, rtype)) + { + sdist = DRCGetDefaultLayerSurround(ctype, rtype); + if (ltype == TT_SPACE) + sldist = sdist; + else + shdist = sdist; + + sdist = DRCGetDirectionalLayerSurround(ctype, rtype); + if (ltype == TT_SPACE) + { + ldist = sdist; + ltype = rtype; + } + else + { + hdist = sdist; + htype = rtype; + break; + } + } + lorient = horient = 0; + if (ldist > 0) + { + r2.r_ybot = rorig.r_ybot - sldist; + r2.r_ytop = rorig.r_ytop + sldist; + r2.r_xbot = rorig.r_xbot - ldist + sldist; + r2.r_xtop = rorig.r_xtop + ldist + sldist; + pNum = DBPlane(ltype); + lorient = DBSrPaintArea((Tile *)NULL, def->cd_planes[pNum], &r2, + &DBNotConnectTbl[ltype], defCheckFunc, + (ClientData)NULL); + } + if (hdist > 0) + { + r2.r_ybot = rorig.r_ybot - shdist; + r2.r_ytop = rorig.r_ytop + shdist; + r2.r_xbot = rorig.r_xbot - hdist + shdist; + r2.r_xtop = rorig.r_xtop + hdist + shdist; + pNum = DBPlane(htype); + horient = DBSrPaintArea((Tile *)NULL, def->cd_planes[pNum], &r2, + &DBNotConnectTbl[htype], defCheckFunc, + (ClientData)NULL); + } + if ((ldist > 0) || (hdist > 0)) + { + sprintf(vname, "%s_%.10g_%.10g_%c%c", lname, + ((float)offx * oscale), ((float)offy * oscale), + (ldist == 0) ? 'x' : (lorient == 0) ? 'h' : 'v', + (hdist == 0) ? 'x' : (horient == 0) ? 'h' : 'v'); + } + else + sprintf(vname, "%s_%.10g_%.10g", lname, ((float)offx * oscale), ((float)offy * oscale)); he = HashFind(&LefInfo, vname); @@ -1555,7 +1727,67 @@ defCountViaFunc(tile, cviadata) lefl->refCnt = 0; /* These entries will be removed after writing */ HashSetValue(he, lefl); lefl->canonName = (char *)he->h_key.h_name; + + if ((sldist > 0) || (ldist > 0)) + { + newlr = (LinkedRect *)mallocMagic(sizeof(LinkedRect)); + newlr->r_next = lefl->info.via.lr; + lefl->info.via.lr = newlr; + newlr->r_type = ltype; + r2.r_xbot = r.r_xbot - 2 * sldist; + r2.r_xtop = r.r_xtop + 2 * sldist; + r2.r_ybot = r.r_ybot - 2 * sldist; + r2.r_ytop = r.r_ytop + 2 * sldist; + if (ldist > 0) + { + if (lorient == 0) + { + r2.r_xbot -= 2 * ldist; + r2.r_xtop += 2 * ldist; + } + else + { + r2.r_ybot -= 2 * ldist; + r2.r_ytop += 2 * ldist; + } + } + newlr->r_r = r2; + } + if ((shdist > 0) || (hdist > 0)) + { + newlr = (LinkedRect *)mallocMagic(sizeof(LinkedRect)); + newlr->r_next = lefl->info.via.lr; + lefl->info.via.lr = newlr; + newlr->r_type = htype; + r2.r_xbot = r.r_xbot - 2 * shdist; + r2.r_xtop = r.r_xtop + 2 * shdist; + r2.r_ybot = r.r_ybot - 2 * shdist; + r2.r_ytop = r.r_ytop + 2 * shdist; + if (hdist > 0) + { + if (horient == 0) + { + r2.r_xbot -= 2 * hdist; + r2.r_xtop += 2 * hdist; + } + else + { + r2.r_ybot -= 2 * hdist; + r2.r_ytop += 2 * hdist; + } + } + newlr->r_r = r2; + } } + /* Record this tile position in the contact hash table */ + sprintf(posstr, "%s_%d_%d", DBPlaneShortName(DBPlane(ctype)), + rorig.r_xbot, rorig.r_ybot); + he = HashFind(defViaTable, posstr); + HashSetValue(he, lefl); + + /* XXX WIP XXX */ + TxPrintf("Via name \"%s\" hashed as \"%s\"\n", lefl->canonName, posstr); + return 0; /* Keep the search going */ } @@ -1647,6 +1879,8 @@ defWriteVias(f, rootDef, oscale, lefMagicToLefLayer) lefLayer *lefl; TileTypeBitMask *rMask; TileType ttype; + Rect *r; + LinkedRect *lr; /* Pick up information from the LefInfo hash table */ /* created by fucntion defCountVias() */ @@ -1677,12 +1911,24 @@ defWriteVias(f, rootDef, oscale, lefMagicToLefLayer) rMask = DBResidueMask(lefl->type); for (ttype = TT_TECHDEPBASE; ttype < DBNumUserLayers; ttype++) if (TTMaskHasType(rMask, ttype)) + { + r = &lefl->info.via.area; + + /* If an lr entry was made, then it includes */ + /* any required surround distance, so use that */ + /* rectangle instead of the via area. */ + + for (lr =lefl->info.via.lr; lr; lr = lr->r_next) + if (lr->r_type == ttype) + r = &lr->r_r; + fprintf(f, "\n + RECT %s ( %.10g %.10g ) ( %.10g %.10g )", lefMagicToLefLayer[ttype].lefName, - (float)(lefl->info.via.area.r_xbot) * oscale / 2, - (float)(lefl->info.via.area.r_ybot) * oscale / 2, - (float)(lefl->info.via.area.r_xtop) * oscale / 2, - (float)(lefl->info.via.area.r_ytop) * oscale / 2); + (float)(r->r_xbot) * oscale / 2, + (float)(r->r_ybot) * oscale / 2, + (float)(r->r_xtop) * oscale / 2, + (float)(r->r_ytop) * oscale / 2); + } /* Handle the contact cuts. */ @@ -2409,6 +2655,7 @@ DefWriteCell(def, outName, allSpecial, units) NetCount nets; int total; float scale; + HashTable defViaTable; LefMapping *lefMagicToLefLayer; int i; @@ -2438,10 +2685,12 @@ DefWriteCell(def, outName, allSpecial, units) defWriteHeader(def, f, scale, units); + HashInit(&defViaTable, 256, HT_STRINGKEYS); + lefMagicToLefLayer = defMakeInverseLayerMap(LAYER_MAP_VIAS); /* Vias---magic contact areas are reported as vias. */ - total = defCountVias(def, lefMagicToLefLayer, scale); + total = defCountVias(def, lefMagicToLefLayer, &defViaTable, scale); fprintf(f, "VIAS %d ;\n", total); if (total > 0) defWriteVias(f, def, scale, lefMagicToLefLayer); @@ -2485,8 +2734,8 @@ DefWriteCell(def, outName, allSpecial, units) if (nets.special > 0) { fprintf(f, "SPECIALNETS %d ;\n", nets.special); - defWriteNets(f, def, scale, lefMagicToLefLayer, (allSpecial) ? - ALL_SPECIAL : DO_SPECIAL); + defWriteNets(f, def, scale, lefMagicToLefLayer, &defViaTable, + (allSpecial) ? ALL_SPECIAL : DO_SPECIAL); fprintf(f, "END SPECIALNETS\n\n"); } @@ -2494,7 +2743,7 @@ DefWriteCell(def, outName, allSpecial, units) if (nets.regular > 0) { fprintf(f, "NETS %d ;\n", nets.regular); - defWriteNets(f, def, scale, lefMagicToLefLayer, DO_REGULAR); + defWriteNets(f, def, scale, lefMagicToLefLayer, &defViaTable, DO_REGULAR); fprintf(f, "END NETS\n\n"); } @@ -2511,6 +2760,7 @@ DefWriteCell(def, outName, allSpecial, units) } freeMagic((char *)lefMagicToLefLayer); + HashKill(&defViaTable); lefRemoveGeneratedVias(); } diff --git a/scripts/configure b/scripts/configure index 549324e3..33d10b9c 100755 --- a/scripts/configure +++ b/scripts/configure @@ -5322,7 +5322,7 @@ fi -if test "x${CSH}" = "x"; then +if test "x${CSH}" = "xno"; then as_fn_error $? "cannot find /bin/csh---cannot compile!" "$LINENO" 5 fi @@ -5367,7 +5367,7 @@ $as_echo "no" >&6; } fi -if test "x${PYTHON3}" == "x"; then +if test "x${PYTHON3}" == "xno"; then usingPython3= diff --git a/scripts/configure.in b/scripts/configure.in index 79b4cd80..65d828e7 100644 --- a/scripts/configure.in +++ b/scripts/configure.in @@ -281,14 +281,14 @@ dnl csh not being in /bin, or only tcsh being available. AC_PATH_PROG(CSH, csh, [no]) -if test "x${CSH}" = "x"; then +if test "x${CSH}" = "xno"; then AC_MSG_ERROR([cannot find /bin/csh---cannot compile!]) fi dnl Python3 is preferred for running the preprocessor script dnl but CPP can be used instead. AC_PATH_PROG([PYTHON3], [python3], [no]) -if test "x${PYTHON3}" == "x"; then +if test "x${PYTHON3}" == "xno"; then dnl check size of pointer for correct behavior on 64-bit systems dnl If the C preprocessor is GCC, we need to force the flag to