diff --git a/VERSION b/VERSION index 8823545..274b8fb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.5.170 +1.5.171 diff --git a/base/netcmp.c b/base/netcmp.c index 962aa18..6f48f86 100644 --- a/base/netcmp.c +++ b/base/netcmp.c @@ -5363,13 +5363,21 @@ PropertyMatch(struct objlist *ob1, int file1, /* WIP---Check for no-connect pins in merged devices on both sides. */ /* Both sides should either have no-connects marked, or neither. */ /* (Permutable pins may need to be handled correctly. . . */ + for (tp1 = ob1, tp2 = ob2; (tp1 != NULL) && tp1->type >= FIRSTPIN && (tp2 != NULL) && tp2->type >= FIRSTPIN; tp1 = tp1->next, tp2 = tp2->next) { struct objlist *node1, *node2; - node1 = Circuit1->nodename_cache[tp1->node]; - node2 = Circuit2->nodename_cache[tp2->node]; + if (file1 == Circuit1->file) + node1 = Circuit1->nodename_cache[tp1->node]; + else + node1 = Circuit2->nodename_cache[tp1->node]; + + if (file2 == Circuit1->file) + node2 = Circuit1->nodename_cache[tp2->node]; + else + node2 = Circuit2->nodename_cache[tp2->node]; if (node1->instance.flags != node2->instance.flags) { diff --git a/tcltk/netgen.tcl.in b/tcltk/netgen.tcl.in index 431bcf1..e3ac928 100644 --- a/tcltk/netgen.tcl.in +++ b/tcltk/netgen.tcl.in @@ -352,7 +352,7 @@ proc netgen::convert_to_json {filename lvs_final} { close $fjson } -#---------------------------------------------------------------- +#----------------------------------------------------------------------- # Define the "lvs" command as a way of calling the netgen options # for standard compare, essentially the same as the old "netcomp" # standalone program. @@ -361,14 +361,20 @@ proc netgen::convert_to_json {filename lvs_final} { # although if the cells have not been read in yet, then the # original syntax of filename or {filename cellname} is required. # -# "args" is passed to verify and may therefore contain only the -# value "-list" or nothing. If "-list", then output is returned -# as a nested list. -#---------------------------------------------------------------- +# "args" may be "-list", "-json", or "-blackbox". +# "-list" returns output as a nested list. +# "-json" creates a .json-format output file in addition to stdout. +# "-blackbox" treats empty cells as black-box entries. +# "-noflatten={list}" is a list of cells not to flatten if mismatched. +# i.e., the cells are expected to match and any mismatch cannot be +# expected to be resolved by flattening the contents of the mismatched +# cells. +#----------------------------------------------------------------------- proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} { set dolist 0 set dojson 0 + set noflat {} foreach arg $args { if {$arg == "-list"} { puts stdout "Generating list result" @@ -382,6 +388,9 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} { } elseif {$arg == "-blackbox"} { puts stdout "Treating empty subcircuits as black-box cells" netgen::model blackbox on + } elseif {[string first "-noflatten=" $arg] == 0} { + set noflat [string trim [string range $arg 11 end] \"\{\}] + puts stdout "Will not flatten these subcells: $noflat" } } @@ -501,6 +510,7 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} { return } set properr {} + set matcherr {} set pinsgood 0 while {$endval != {}} { if {$dolist == 1} { @@ -529,9 +539,30 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} { # Flatten the non-matching subcircuit (but not the top-level cells) if {[netgen::print queue] != {}} { - netgen::log put " Flattening non-matched subcircuits $endval" - netgen::flatten class "[lindex $endval 0] $fnum1" - netgen::flatten class "[lindex $endval 1] $fnum2" + if {([lsearch $noflat [lindex $endval 0]] == -1) && + ([lsearch $noflat [lindex $endval 1]] == -1)} { + netgen::log put " Flattening non-matched subcircuits $endval" + netgen::flatten class "[lindex $endval 0] $fnum1" + netgen::flatten class "[lindex $endval 1] $fnum2" + } else { + netgen::log put " Continuing with black-boxed subcircuits $endval" + lappend matcherr [lindex $endval 0] + # Match pins + netgen::log echo off + if {$dolist == 1} { + set result [equate -list -force pins "$fnum1 [lindex $endval 0]" \ + "$fnum2 [lindex $endval 1]"] + } else { + set result [equate -force pins "$fnum1 [lindex $endval 0]" \ + "$fnum2 [lindex $endval 1]"] + } + if {$result != 0} { + equate classes "$fnum1 [lindex $endval 0]" \ + "$fnum2 [lindex $endval 1]" + } + set pinsgood $result + netgen::log echo on + } } } else { # Match pins @@ -554,9 +585,32 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} { } else { # Flatten the non-matching subcircuit (but not the top-level cells) if {[netgen::print queue] != {}} { - netgen::log put " Flattening non-matched subcircuits $endval" - netgen::flatten class "[lindex $endval 0] $fnum1" - netgen::flatten class "[lindex $endval 1] $fnum2" + if {([lsearch $noflat [lindex $endval 1]] == -1) && + ([lsearch $noflat [lindex $endval 1]] == -1)} { + netgen::log put " Flattening non-matched subcircuits $endval" + netgen::flatten class "[lindex $endval 0] $fnum1" + netgen::flatten class "[lindex $endval 1] $fnum2" + } else { + netgen::log put " Continuing with black-boxed subcircuits $endval" + lappend matcherr [lindex $endval 0] + netgen::log put " Continuing with black-boxed subcircuits $endval" + lappend matcherr [lindex $endval 0] + # Match pins + netgen::log echo off + if {$dolist == 1} { + set result [equate -list -force pins "$fnum1 [lindex $endval 0]" \ + "$fnum2 [lindex $endval 1]"] + } else { + set result [equate -force pins "$fnum1 [lindex $endval 0]" \ + "$fnum2 [lindex $endval 1]"] + } + if {$result != 0} { + equate classes "$fnum1 [lindex $endval 0]" \ + "$fnum2 [lindex $endval 1]" + } + set pinsgood $result + netgen::log echo on + } } } netgen::log echo off @@ -579,6 +633,9 @@ proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} { if {$properr != {}} { netgen::log put "The following cells had property errors: $properr\n" } + if {$matcherr != {}} { + netgen::log put "The following subcells failed to match: $matcherr\n" + } if {$dolog} { netgen::log end } diff --git a/tcltk/tclnetgen.c b/tcltk/tclnetgen.c index e34522f..ccab280 100644 --- a/tcltk/tclnetgen.c +++ b/tcltk/tclnetgen.c @@ -2827,11 +2827,13 @@ _netcmp_equate(ClientData clientData, char *name1 = NULL, *name2 = NULL, *optstart; struct nlist *tp1, *tp2, *SaveC1, *SaveC2; struct objlist *ob1, *ob2; + struct ElementClass *saveEclass = NULL; + struct NodeClass *saveNclass = NULL; int file1, file2; - int i, l1, l2, ltest, lent, dolist = 0; + int i, l1, l2, ltest, lent, dolist = 0, doforce = 0; Tcl_Obj *tobj1, *tobj2, *tobj3; - if (objc > 1) { + while (objc > 1) { optstart = Tcl_GetString(objv[1]); if (*optstart == '-') optstart++; if (!strcmp(optstart, "list")) { @@ -2839,6 +2841,13 @@ _netcmp_equate(ClientData clientData, objv++; objc--; } + else if (!strcmp(optstart, "force")) { + doforce = 1; + objv++; + objc--; + } + else + break; } if ((objc != 2) && (objc != 4) && (objc != 6)) { @@ -2996,6 +3005,12 @@ _netcmp_equate(ClientData clientData, break; case PINS_IDX: + if ((ElementClasses != NULL) && (doforce == TRUE)) { + saveEclass = ElementClasses; + saveNclass = NodeClasses; + ElementClasses = NULL; + NodeClasses = NULL; + } if ((ElementClasses == NULL) && (auto_blackbox == FALSE)) { if (CurrentCell == NULL) { Fprintf(stderr, "Equate elements: no current cell.\n"); @@ -3058,6 +3073,12 @@ _netcmp_equate(ClientData clientData, /* Recover temporarily set global variables (see above) */ Circuit1 = SaveC1; Circuit2 = SaveC2; + + /* Recover ElementClasses if forcing pins on mismatched circuits */ + if (doforce == TRUE) { + ElementClasses = saveEclass; + NodeClasses = saveNclass; + } } break;