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.
This commit is contained in:
R. Timothy Edwards 2025-10-22 10:43:00 -04:00
parent b5432d139b
commit b371af9235
4 changed files with 78 additions and 23 deletions

View File

@ -1 +1 @@
1.5.303 1.5.304

View File

@ -1756,6 +1756,11 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
flattenInstancesOf(name1, file1, ecomp->cell1->name); flattenInstancesOf(name1, file1, ecomp->cell1->name);
modified1++; 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) && if (ecomp->cell2 && (ecomp->num2 > 0) &&
(!(ecomp->cell2->flags & CELL_PLACEHOLDER))) { (!(ecomp->cell2->flags & CELL_PLACEHOLDER))) {
Fprintf(stdout, "Flattening instances of %s in cell %s (%d)" 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); flattenInstancesOf(name2, file2, ecomp->cell2->name);
modified2++; 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 */ /* 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); flattenInstancesOf(name2, file2, ecomp->cell2->name);
modified2++; 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); flattenInstancesOf(name1, file1, ecomp->cell1->name);
modified1++; 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); ecompX0->cell1->file, &compdict);
if (dstr) *dstr = '['; if (dstr) *dstr = '[';
if ((ncomp == ecomp0X) && (ecomp0X->num2 <= ecompX0->num1)) { if ((ncomp == ecomp0X) && (ecomp0X->num2 <= ecompX0->num1)) {
Fprintf(stdout, "Flattening instances of %s in cell %s" if (!(ecompX0->cell1->flags & CELL_PLACEHOLDER)) {
"(%d) makes a better match\n", Fprintf(stdout, "Flattening instances of %s in cell"
" %s (%d) makes a better match\n",
ecompX0->cell1->name, name1, file1); ecompX0->cell1->name, name1, file1);
flattenInstancesOf(name1, file1, ecompX0->cell1->name); flattenInstancesOf(name1, file1,
ecompX0->cell1->name);
ecompX0->num1 = 0; ecompX0->num1 = 0;
ecomp0X->num1 += ecompX0->num1; ecomp0X->num1 += ecompX0->num1;
modified1++; 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; break;
} }
} }
@ -2297,13 +2327,22 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
ecomp0X->cell2->file, &compdict); ecomp0X->cell2->file, &compdict);
if (dstr) *dstr = '['; if (dstr) *dstr = '[';
if ((ncomp == ecompX0) && (ecompX0->num1 <= ecomp0X->num2)) { if ((ncomp == ecompX0) && (ecompX0->num1 <= ecomp0X->num2)) {
Fprintf(stdout, "Flattening instances of %s in cell %s" if (!(ecomp0X->cell2->flags & CELL_PLACEHOLDER)) {
" (%d) makes a better match\n", Fprintf(stdout, "Flattening instances of %s in cell"
" %s (%d) makes a better match\n",
ecomp0X->cell2->name, name2, file2); ecomp0X->cell2->name, name2, file2);
flattenInstancesOf(name2, file2, ecomp0X->cell2->name); flattenInstancesOf(name2, file2,
ecomp0X->cell2->name);
ecomp0X->num2 = 0; ecomp0X->num2 = 0;
ecompX0->num2 += ecomp0X->num2; ecompX0->num2 += ecomp0X->num2;
modified2++; 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; break;
} }
} }

View File

@ -477,6 +477,18 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
set cell2 [lindex $clist2 $cidx] 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" netgen::compare assign "$fnum1 $cell1" "$fnum2 $cell2"
if {$setupfile == ""} { if {$setupfile == ""} {

View File

@ -1021,7 +1021,7 @@ _netgen_flatten(ClientData clientData,
{ {
char *repstr, *file; char *repstr, *file;
int result, llen, filenum; int result, llen, filenum;
struct nlist *tp, *tp2; struct nlist *tp, *tp2, *tptop;
if ((objc < 2) || (objc > 4)) { if ((objc < 2) || (objc > 4)) {
Tcl_WrongNumArgs(interp, 1, objv, "?class? valid_cellname"); Tcl_WrongNumArgs(interp, 1, objv, "?class? valid_cellname");
@ -1035,7 +1035,7 @@ _netgen_flatten(ClientData clientData,
if (objc >= 3) { if (objc >= 3) {
char *argv = Tcl_GetString(objv[1]); char *argv = Tcl_GetString(objv[1]);
if (!strcmp(argv, "class")) { if (!strcmp(argv, "class")) {
tp = GetTopCell(filenum); tptop = GetTopCell(filenum);
if (objc == 4) { if (objc == 4) {
int numflat; int numflat;
@ -1046,7 +1046,7 @@ _netgen_flatten(ClientData clientData,
} }
else { else {
Printf("Flattening instances of %s in cell %s within file %s\n", 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); numflat = flattenInstancesOf(tp2->name, filenum, repstr);
if (numflat == 0) { if (numflat == 0) {
Tcl_SetResult(interp, "No instances found to flatten.", NULL); Tcl_SetResult(interp, "No instances found to flatten.", NULL);
@ -1055,16 +1055,20 @@ _netgen_flatten(ClientData clientData,
} }
} }
else { 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); FlattenInstancesOf(repstr, filenum);
} }
} }
else if (!strcmp(argv, "prohibit") || !strcmp(argv, "deny")) { else if (!strcmp(argv, "prohibit") || !strcmp(argv, "deny")) {
tp = GetTopCell(filenum); tptop = GetTopCell(filenum);
Printf("Will not flatten instances of %s in file %s\n", repstr, tp->name); 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 */ /* Mark cell as placeholder so it will not be flattened */
tp->flags |= CELL_PLACEHOLDER; tp->flags |= CELL_PLACEHOLDER;
} }
}
else { else {
Tcl_WrongNumArgs(interp, 1, objv, "class valid_cellname"); Tcl_WrongNumArgs(interp, 1, objv, "class valid_cellname");
return TCL_ERROR; return TCL_ERROR;