From 79e193e0c94cd33fceecd755fcb41e9aae85ee63 Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 12 Sep 2022 11:26:21 -0400 Subject: [PATCH] Modified behavior for the "-noflatten" option on LVS: Added a command option "flatten prohibit" (or "flatten deny") to prevent a subcell from being flattened at any time during the compare process. Previously, the "-noflatten" option for the "lvs" script had been used to prevent flattening during initial pre-match, but if the circuit passed the prematch phase and subcells were mismatched, they would be flattened regardless of whether or not they were listed by the "-noflatten" option. This also codifies a way to prevent subcells from being flattened in the setup file rather than in the "lvs" command line. Also: Found and fixed a bug that prevents the use of "-noflatten=" with a cell name or list of cell names instead of a filename. --- VERSION | 2 +- base/flatten.c | 24 +++++++++++++++++------- tcltk/netgen.tcl.in | 4 +++- tcltk/tclnetgen.c | 6 ++++++ 4 files changed, 27 insertions(+), 9 deletions(-) diff --git a/VERSION b/VERSION index ec27d32..12f037c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.5.227 +1.5.228 diff --git a/base/flatten.c b/base/flatten.c index 262570f..7c3b6a4 100644 --- a/base/flatten.c +++ b/base/flatten.c @@ -69,6 +69,10 @@ void flattenCell(char *name, int file) Printf("No cell %s found.\n", name); return; } + + /* Placeholder cells must not be flattened */ + if (ThisCell->flags & CELL_PLACEHOLDER) return; + FreeNodeNames(ThisCell); ParentParams = ThisCell->cell; @@ -288,6 +292,9 @@ int flattenInstancesOf(char *name, int fnum, char *instance) return 0; } } + /* Placeholder cells must not be flattened */ + if (ThisCell->flags & CELL_PLACEHOLDER) return 0; + FreeNodeNames(ThisCell); ParentParams = ThisCell->cell; @@ -1620,19 +1627,22 @@ PrematchLists(char *name1, int file1, char *name2, int file2) } } if (match) { - if (ecomp->cell1 && (ecomp->num1 > 0)) { + if (ecomp->cell1 && (ecomp->num1 > 0) && + (!(ecomp->cell1->flags & CELL_PLACEHOLDER))) { Fprintf(stdout, "Flattening instances of %s in cell %s (%d)" " makes a better match\n", ecomp->cell1->name, name1, file1); flattenInstancesOf(name1, file1, ecomp->cell1->name); + modified++; } - if (ecomp->cell2 && (ecomp->num2 > 0)) { + if (ecomp->cell2 && (ecomp->num2 > 0) && + (!(ecomp->cell2->flags & CELL_PLACEHOLDER))) { Fprintf(stdout, "Flattening instances of %s in cell %s (%d)" " makes a better match\n", ecomp->cell2->name, name2, file2); flattenInstancesOf(name2, file2, ecomp->cell2->name); + modified++; } - modified++; } /* Reset or apply the count adjustments */ @@ -1716,13 +1726,13 @@ PrematchLists(char *name1, int file1, char *name2, int file2) if ((ecomp->num1 == 0) || (ecomp->cell1->class != CLASS_MODULE)) { - if (ecomp->cell2) { + if (ecomp->cell2 && !(ecomp->cell2->flags & CELL_PLACEHOLDER)) { Fprintf(stdout, "Flattening instances of %s in cell %s (%d)" " makes a better match\n", ecomp->cell2->name, name2, file2); flattenInstancesOf(name2, file2, ecomp->cell2->name); + modified++; } - modified++; } } @@ -1782,13 +1792,13 @@ PrematchLists(char *name1, int file1, char *name2, int file2) if ((ecomp->num2 == 0) || (ecomp->cell2->class != CLASS_MODULE)) { - if (ecomp->cell1) { + if (ecomp->cell1 && !(ecomp->cell1->flags & CELL_PLACEHOLDER)) { Fprintf(stdout, "Flattening instances of %s in cell %s (%d)" " makes a better match\n", ecomp->cell1->name, name1, file1); flattenInstancesOf(name1, file1, ecomp->cell1->name); + modified++; } - modified++; } } diff --git a/tcltk/netgen.tcl.in b/tcltk/netgen.tcl.in index f63364f..f9c1ae8 100644 --- a/tcltk/netgen.tcl.in +++ b/tcltk/netgen.tcl.in @@ -393,7 +393,7 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} { # If argument is a filename then read the list of cells from it; # otherwise, argument is the list of files itself in quotes or # braces. - if {![catch {file exists $value}]} { + if {[file exists $value]} { if {![catch {open $value r} fnf]} { while {[gets $fnf line] >= 0} { if {[lindex $line 0] != "#"} { @@ -569,6 +569,8 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} { netgen::log put " Continuing with black-boxed subcircuits $endval\n" lappend matcherr [lindex $endval 0]"($fnum1)" lappend matcherr [lindex $endval 1]"($fnum2)" + netgen::flatten prohibit "[lindex $endval 0] $fnum1" + netgen::flatten prohibit "[lindex $endval 1] $fnum2" # Match pins netgen::log echo off if {$dolist == 1} { diff --git a/tcltk/tclnetgen.c b/tcltk/tclnetgen.c index f6c573c..7a597ed 100644 --- a/tcltk/tclnetgen.c +++ b/tcltk/tclnetgen.c @@ -1056,6 +1056,12 @@ _netgen_flatten(ClientData clientData, 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; + } else { Tcl_WrongNumArgs(interp, 1, objv, "class valid_cellname"); return TCL_ERROR;