From b371af9235219ef40865ed1987c8a693d1d57276 Mon Sep 17 00:00:00 2001 From: "R. Timothy Edwards" Date: Wed, 22 Oct 2025 10:43:00 -0400 Subject: [PATCH] Corrected an error that was assumed to have been fixed three years ago (and may have been, but only under limited circumstances). Do to several errors, using "-noflatten" on the command line and using "flatten prohibit" in a script would not prevent cells from being flattened; the "-noflatten" list needed to be used to call "flatten prohibit", and "flatten prohibit" needed to be fixed to flag the specified cell instead of the top level cell where it exists. --- VERSION | 2 +- base/flatten.c | 67 +++++++++++++++++++++++++++++++++++---------- tcltk/netgen.tcl.in | 12 ++++++++ tcltk/tclnetgen.c | 20 ++++++++------ 4 files changed, 78 insertions(+), 23 deletions(-) diff --git a/VERSION b/VERSION index cf5e6f2..bfd53ed 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.5.303 +1.5.304 diff --git a/base/flatten.c b/base/flatten.c index 90017dd..8828eea 100644 --- a/base/flatten.c +++ b/base/flatten.c @@ -1756,6 +1756,11 @@ PrematchLists(char *name1, int file1, char *name2, int file2) flattenInstancesOf(name1, file1, ecomp->cell1->name); modified1++; } + else if (ecomp->cell1 && (ecomp->num1 > 0)) { + Fprintf(stdout, "Flattening instances of %s in cell %s (%d)" + " would make a better match but is prohibited.\n", + ecomp->cell1->name, name1, file1); + } if (ecomp->cell2 && (ecomp->num2 > 0) && (!(ecomp->cell2->flags & CELL_PLACEHOLDER))) { Fprintf(stdout, "Flattening instances of %s in cell %s (%d)" @@ -1764,6 +1769,11 @@ PrematchLists(char *name1, int file1, char *name2, int file2) flattenInstancesOf(name2, file2, ecomp->cell2->name); modified2++; } + else if (ecomp->cell2 && (ecomp->num2 > 0)) { + Fprintf(stdout, "Flattening instances of %s in cell %s (%d)" + " would make a better match but is prohibited.\n", + ecomp->cell2->name, name2, file2); + } } /* Reset or apply the count adjustments */ @@ -1854,6 +1864,11 @@ PrematchLists(char *name1, int file1, char *name2, int file2) flattenInstancesOf(name2, file2, ecomp->cell2->name); modified2++; } + else if (ecomp->cell2) { + Fprintf(stdout, "Flattening instances of %s in cell %s (%d)" + " would make a better match but is prohibited.\n", + ecomp->cell2->name, name2, file2); + } } } @@ -1920,6 +1935,11 @@ PrematchLists(char *name1, int file1, char *name2, int file2) flattenInstancesOf(name1, file1, ecomp->cell1->name); modified1++; } + else if (ecomp->cell1) { + Fprintf(stdout, "Flattening instances of %s in cell %s (%d)" + " would make a better match but is prohibited.\n", + ecomp->cell1->name, name1, file1); + } } } @@ -2271,13 +2291,23 @@ PrematchLists(char *name1, int file1, char *name2, int file2) ecompX0->cell1->file, &compdict); if (dstr) *dstr = '['; if ((ncomp == ecomp0X) && (ecomp0X->num2 <= ecompX0->num1)) { - Fprintf(stdout, "Flattening instances of %s in cell %s" - "(%d) makes a better match\n", - ecompX0->cell1->name, name1, file1); - flattenInstancesOf(name1, file1, ecompX0->cell1->name); - ecompX0->num1 = 0; - ecomp0X->num1 += ecompX0->num1; - modified1++; + if (!(ecompX0->cell1->flags & CELL_PLACEHOLDER)) { + Fprintf(stdout, "Flattening instances of %s in cell" + " %s (%d) makes a better match\n", + ecompX0->cell1->name, name1, file1); + flattenInstancesOf(name1, file1, + ecompX0->cell1->name); + ecompX0->num1 = 0; + ecomp0X->num1 += ecompX0->num1; + modified1++; + } + else + { + Fprintf(stdout, "Flattening instances of %s in " + "cell %s (%d) would make a better " + "match but is prohibited.\n", + ecompX0->cell1->name, name1, file1); + } break; } } @@ -2297,13 +2327,22 @@ PrematchLists(char *name1, int file1, char *name2, int file2) ecomp0X->cell2->file, &compdict); if (dstr) *dstr = '['; if ((ncomp == ecompX0) && (ecompX0->num1 <= ecomp0X->num2)) { - Fprintf(stdout, "Flattening instances of %s in cell %s" - " (%d) makes a better match\n", - ecomp0X->cell2->name, name2, file2); - flattenInstancesOf(name2, file2, ecomp0X->cell2->name); - ecomp0X->num2 = 0; - ecompX0->num2 += ecomp0X->num2; - modified2++; + if (!(ecomp0X->cell2->flags & CELL_PLACEHOLDER)) { + Fprintf(stdout, "Flattening instances of %s in cell" + " %s (%d) makes a better match\n", + ecomp0X->cell2->name, name2, file2); + flattenInstancesOf(name2, file2, + ecomp0X->cell2->name); + ecomp0X->num2 = 0; + ecompX0->num2 += ecomp0X->num2; + modified2++; + } + else { + Fprintf(stdout, "Flattening instances of %s in " + "cell %s (%d) would make a better " + "match but is prohibited.\n", + ecompX0->cell2->name, name2, file2); + } break; } } diff --git a/tcltk/netgen.tcl.in b/tcltk/netgen.tcl.in index c413f44..a55f942 100644 --- a/tcltk/netgen.tcl.in +++ b/tcltk/netgen.tcl.in @@ -477,6 +477,18 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} { set cell2 [lindex $clist2 $cidx] } + # The "noflat" list is non-file-specific, so run on each file. + foreach cell $noflat { + set cidx [lsearch -regexp $clist1 ^$cell$] + if {$cidx >= 0} { + netgen::flatten prohibit "$fnum1 $cell" + } + set cidx [lsearch -regexp $clist2 ^$cell$] + if {$cidx >= 0} { + netgen::flatten prohibit "$fnum2 $cell" + } + } + netgen::compare assign "$fnum1 $cell1" "$fnum2 $cell2" if {$setupfile == ""} { diff --git a/tcltk/tclnetgen.c b/tcltk/tclnetgen.c index 04274f6..bb0832f 100644 --- a/tcltk/tclnetgen.c +++ b/tcltk/tclnetgen.c @@ -1021,7 +1021,7 @@ _netgen_flatten(ClientData clientData, { char *repstr, *file; int result, llen, filenum; - struct nlist *tp, *tp2; + struct nlist *tp, *tp2, *tptop; if ((objc < 2) || (objc > 4)) { Tcl_WrongNumArgs(interp, 1, objv, "?class? valid_cellname"); @@ -1035,7 +1035,7 @@ _netgen_flatten(ClientData clientData, if (objc >= 3) { char *argv = Tcl_GetString(objv[1]); if (!strcmp(argv, "class")) { - tp = GetTopCell(filenum); + tptop = GetTopCell(filenum); if (objc == 4) { int numflat; @@ -1046,7 +1046,7 @@ _netgen_flatten(ClientData clientData, } else { Printf("Flattening instances of %s in cell %s within file %s\n", - repstr, tp2->name, tp->name); + repstr, tp2->name, tptop->name); numflat = flattenInstancesOf(tp2->name, filenum, repstr); if (numflat == 0) { Tcl_SetResult(interp, "No instances found to flatten.", NULL); @@ -1055,15 +1055,19 @@ _netgen_flatten(ClientData clientData, } } else { - Printf("Flattening instances of %s in file %s\n", repstr, tp->name); + Printf("Flattening instances of %s in file %s\n", repstr, tptop->name); FlattenInstancesOf(repstr, filenum); } } else if (!strcmp(argv, "prohibit") || !strcmp(argv, "deny")) { - tp = GetTopCell(filenum); - Printf("Will not flatten instances of %s in file %s\n", repstr, tp->name); - /* Mark cell as placeholder so it will not be flattened */ - tp->flags |= CELL_PLACEHOLDER; + tptop = GetTopCell(filenum); + if (tp == NULL) + Printf("Error: Cell %s does not exist.\n", repstr); + else { + Printf("Will not flatten instances of %s in file %s\n", repstr, tptop->name); + /* Mark cell as placeholder so it will not be flattened */ + tp->flags |= CELL_PLACEHOLDER; + } } else { Tcl_WrongNumArgs(interp, 1, objv, "class valid_cellname");