Compare commits

..
21 Commits
Author SHA1 Message Date
Tim Edwards 4098b7d5fd Completed an unimplemented method that sets missing properties to
the default before comparing instances against each other for
serial/parallel combination.  In particular, this avoids a
failure to serially combine a device with M = 1 vs. a device with
no M declared.
2017-10-12 15:26:29 -04:00
Tim Edwards f860244700 Provide additional output for mismatched serial/parallel networks.
Netgen was incorrectly treating mismatched networks as a missing
set of parameters on whichever device had more property records,
resulting in misleading output.
2017-10-12 14:17:24 -04:00
Tim Edwards 66015511cb Corrected mismatch count, which was prematurely declaring a
mismatch on "M=" even though some conditions pass.
2017-10-12 12:30:33 -04:00
Tim Edwards b3277ca53e Modified reading of SPICE files so that parameters in quotes get
treated monolithically instead of being broken up into separate
tokens according to space characters, which screws up the parameter
parsing.
2017-10-12 12:11:30 -04:00
Tim Edwards 00c2e74524 Merge branch 'master' into work 2017-10-12 10:52:58 -04:00
Tim Edwards bdb8917327 Update at Thu Oct 12 10:52:56 EDT 2017 by tim 2017-10-12 10:52:56 -04:00
Tim Edwards 95bce5dbd6 Corrected another error in the serial combination in which the
attempt to resolve values by combining over serial chains was
attempting to access a property "S" in the component's master
record, which generally won't exist unless it has been explicitly
set in the netlist (which is unlikely since "S" is not a standard
SPICE/CDL parameter like "M").
2017-10-12 10:51:13 -04:00
Tim Edwards e15620257c Merge branch 'master' into work 2017-10-10 22:25:50 -04:00
Tim Edwards 7a947ee9be Update at Tue Oct 10 22:25:49 EDT 2017 by tim 2017-10-10 22:25:49 -04:00
Tim Edwards b5f188de42 Corrected two errors in the serial combine function, one which
misses a device if it has been already moved due to earlier
merging in the serial combine routine, and runs off the end of
the list;  the other if the pin check routine falls on the last
device in the list, leading to an incorrect check for a record
where there is only a NULL.
2017-10-10 22:24:09 -04:00
Tim Edwards ccbb286cf3 Merge branch 'master' into work 2017-08-24 09:51:46 -04:00
Tim Edwards 4809c02f79 Update at Thu Aug 24 09:51:44 EDT 2017 by tim 2017-08-24 09:51:44 -04:00
Tim Edwards af3982766e Prevented a crash condition in the error case in which ports are
unordered at the time of reaching reorderpins().  Pins will be
ordered arbitrarily (in the order of appearance in the linked
list), but netgen will not crash.
2017-08-24 09:50:40 -04:00
Tim Edwards 25c1f13e16 Update at Thu Aug 10 22:41:12 EDT 2017 by tim 2017-08-10 22:41:12 -04:00
Tim Edwards f0eec657a3 Update at Wed Aug 9 09:04:43 EDT 2017 by tim 2017-08-09 09:04:43 -04:00
Tim Edwards 9d476bc25a Merge branch 'master' into work 2017-06-22 08:13:02 -04:00
Tim Edwards 5ed3fcb3f1 Update at Thu Jun 22 08:12:59 EDT 2017 by tim 2017-06-22 08:13:00 -04:00
Tim Edwards ab9659af17 Corrected coding error in tilde expansion of .include filenames. 2017-06-22 08:12:41 -04:00
Tim Edwards 41939adb84 Merge branch 'master' into work 2017-06-20 22:55:26 -04:00
Tim Edwards 39573981be Update at Tue Jun 20 22:55:24 EDT 2017 by tim 2017-06-20 22:55:24 -04:00
Tim Edwards b9e26f6fce Implemented better black-box handling. Netlist with "stub" entries
for subcircuits (.subckt ... .ends pair with cellname and pin names
and pin order, but no contents) are automatically treated as black-
box circuits if found and if the "-blackbox" option is passed to the
"lvs" (scripted) command.  The "equate pins" command can be used
outside of a comparison to force two circuits (black-box or
otherwise) to be matched by pin name (if not a black-box circuit,
then this is a provisional name match, as a circuit comparison will
order based on connectivity first, not pin names).  So two sets of
black-box circuit libraries can be used as long as their pin names
match.  One hack added to ignore the "!" at the end of global names
when comparing pin names for matching.  Otherwise, pin names must
compare by case-insensitive string match.
2017-06-20 22:50:31 -04:00
8 changed files with 279 additions and 47 deletions
+1 -1
View File
@@ -1 +1 @@
1.5.81
1.5.88
+4
View File
@@ -1230,6 +1230,10 @@ int CleanupPins(char *name, int filenum)
return 0;
}
// If cell is type MODULE, this is a black-box circuit and
// pins are expected to be disconnected (so don't remove them).
if (ThisCell->class == CLASS_MODULE) return 0;
// Avoid a loop through all cells unless we have to do it.
for (ob = ThisCell->cell; ob != NULL; ob = ob->next) {
+167 -25
View File
@@ -3780,12 +3780,14 @@ void serial_sort(struct objlist *ob1, struct nlist *tp1, int idx1, int run)
if (vl->key == NULL) continue;
if (!strcmp(vl->key, "S"))
sval = vl->value.ival;
kl = (struct property *)HashLookup(vl->key, &(tp1->propdict));
if (kl->merge == MERGE_SER_CRIT)
if (vl->type == PROP_INTEGER)
cval = (double)vl->value.ival;
else
cval = vl->value.dval;
else {
kl = (struct property *)HashLookup(vl->key, &(tp1->propdict));
if (kl && (kl->merge == MERGE_SER_CRIT))
if (vl->type == PROP_INTEGER)
cval = (double)vl->value.ival;
else
cval = vl->value.dval;
}
}
proplist[i].value = (double)sval * cval;
proplist[i].idx = i;
@@ -4224,9 +4226,9 @@ int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int serial)
struct property *kl, *m_rec, **plist;
struct valuelist ***vlist, *vl, *vl2, *newvlist;
proplinkptr plink, ptop;
int pcount, p, i, j, pmatch, ival, crit, ctype;
int pcount, p, i, j, k, pmatch, ival, crit, ctype;
double dval;
static struct valuelist nullvl;
static struct valuelist nullvl, dfltvl;
char multiple[2];
int changed = 0;
@@ -4336,9 +4338,37 @@ int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int serial)
pmatch++;
continue;
}
// TO-DO: If either value is missing, it takes kl->pdefault
// If either value is missing, it takes kl->pdefault
// and must apply promotions if necessary.
else if (vl == NULL || vl2 == NULL) continue;
else if (vl == NULL || vl2 == NULL) {
if (vl == NULL) {
if (kl->type != vlist[p][j]->type)
PromoteProperty(kl, vl2);
}
else {
if (kl->type != vlist[p][i]->type)
PromoteProperty(kl, vl);
}
vl = &dfltvl;
dfltvl.type = kl->type;
switch (kl->type) {
case PROP_STRING:
dfltvl.value.string = kl->pdefault.string;
break;
case PROP_INTEGER:
dfltvl.value.ival = kl->pdefault.ival;
break;
case PROP_DOUBLE:
case PROP_VALUE:
dfltvl.value.ival = kl->pdefault.ival;
break;
case PROP_EXPRESSION:
dfltvl.value.stack = kl->pdefault.stack;
break;
}
}
// Critical properties can be multiplied up by M (S) and do not
// need to match. May want a more nuanced comparison, though.
@@ -4953,6 +4983,52 @@ PropertyCheckMismatch(struct objlist *tp1, struct nlist *tc1,
}
/*--------------------------------------------------------------*/
/* Dump a description of a device's serial/parallel network */
/*--------------------------------------------------------------*/
void DumpNetwork(struct objlist *ob, int cidx)
{
struct valuelist *vl;
struct objlist *tp;
int i;
for (tp = ob; tp && (tp->type != PROPERTY); tp = tp->next)
if ((tp > ob) && (tp->type == FIRSTPIN))
return;
if (tp == NULL) return;
Fprintf(stdout, "Circuit %d instance %s network:\n", cidx, ob->instance.name);
for (; tp && (tp->type == PROPERTY); tp = tp->next) {
for (i = 0;; i++) {
vl = &(tp->instance.props[i]);
if (vl->type == PROP_ENDLIST) break;
if (!strcmp(vl->key, "_tag")) {
Fprintf(stdout, "%s\n", vl->value.string);
continue;
}
Fprintf(stdout, " %s = ", vl->key);
switch(vl->type) {
case PROP_STRING:
Fprintf(stdout, "%s\n", vl->value.string);
break;
case PROP_INTEGER:
Fprintf(stdout, "%d\n", vl->value.ival);
break;
case PROP_DOUBLE:
case PROP_VALUE:
Fprintf(stdout, "%g\n", vl->value.dval);
break;
case PROP_EXPRESSION:
Fprintf(stdout, "(expression)\n");
break;
}
}
}
}
/*--------------------------------------------------------------*/
/* Compare the properties of two objects. The passed values */
/* ob1 and ob2 are pointers to the first entry (firstpin) of */
@@ -4981,7 +5057,7 @@ PropertyMatch(struct objlist *ob1, struct objlist *ob2, int do_print,
struct property *kl1, *kl2;
struct valuelist *vl1, *vl2;
int t1type, t2type;
int i, mismatches = 0;
int i, mismatches = 0, checked_one;
int rval = 1;
char *inst1, *inst2;
#ifdef TCL_NETGEN
@@ -5073,8 +5149,18 @@ PropertyMatch(struct objlist *ob1, struct objlist *ob2, int do_print,
inst2 = ob2->instance.name;
if (*inst2 == '/') inst2++;
checked_one = FALSE;
while(1) {
if (t1type != PROPERTY) {
if ((t1type != PROPERTY) && (checked_one == TRUE)) {
// t2 has more property records than t1, and they did not get
// merged equally by PropertySortAndCombine().
Fprintf(stdout, "Circuit 1 parallel/serial network does not match"
" Circuit 2\n");
DumpNetwork(ob1, 1);
DumpNetwork(ob2, 2);
mismatches++;
}
else if (t1type != PROPERTY) {
// t1 has no properties. See if t2's properties are required
// to be checked. If so, flag t2 instance as unmatched
@@ -5084,13 +5170,24 @@ PropertyMatch(struct objlist *ob1, struct objlist *ob2, int do_print,
if (vl2 == NULL) continue;
if (vl2->key == NULL) continue;
kl2 = (struct property *)HashLookup(vl2->key, &(tc2->propdict));
if (kl2 != NULL) break; // Property is required
if (kl2 != NULL) {
// Allowed for one instance to be missing "M" or "S".
if (strcasecmp(vl2->key, "M") && strcasecmp(vl2->key, "S"))
break; // Property is required
}
}
if (vl2->type != PROP_ENDLIST) {
mismatches++;
if (do_print) Fprintf(stdout, "Circuit 2 %s instance %s has no"
" property match in circuit 1.\n",
Circuit2->name, inst2);
if (do_print) {
if (vl2 && vl2->key)
Fprintf(stdout, "Circuit 2 %s instance %s property"
" \"%s\" has no match in circuit 1.\n",
Circuit2->name, inst2, vl2->key);
else
Fprintf(stdout, "Circuit 2 %s instance %s has no"
" property match in circuit 1.\n",
Circuit2->name, inst2);
}
#ifdef TCL_NETGEN
if (do_list) {
mpair = PropertyList(NULL, vl2);
@@ -5105,23 +5202,43 @@ PropertyMatch(struct objlist *ob1, struct objlist *ob2, int do_print,
else
rval = 0;
}
else if ((t2type != PROPERTY) && (checked_one == TRUE)) {
// t1 has more property records than t2, and they did not get
// merged equally by PropertySortAndCombine().
Fprintf(stdout, "Circuit 2 parallel/serial network does not match"
" Circuit 1\n");
DumpNetwork(ob1, 1);
DumpNetwork(ob2, 2);
mismatches++;
}
else if (t2type != PROPERTY) {
// t2 has no properties. See if t1's properties are required
// to be checked. If so, flag t1 instance as unmatched
mismatches++;
for (i = 0;; i++) {
vl1 = &(tp1->instance.props[i]);
if (vl1->type == PROP_ENDLIST) break;
if (vl1 == NULL) continue;
if (vl1->key == NULL) continue;
kl1 = (struct property *)HashLookup(vl1->key, &(tc1->propdict));
if (kl1 != NULL) break; // Property is required
if (kl1 != NULL) {
// Allowed for one instance to be missing "M" or "S".
if (strcasecmp(vl1->key, "M") && strcasecmp(vl1->key, "S"))
break; // Property is required
}
}
if (vl1->type != PROP_ENDLIST) {
if (do_print) Fprintf(stdout, "Circuit 1 %s instance %s has no"
" property match in Circuit 2.\n",
Circuit1->name, inst1);
mismatches++;
if (do_print) {
if (vl1 && vl1->key)
Fprintf(stdout, "Circuit 1 %s instance %s property"
" \"%s\" has no match in circuit 2.\n",
Circuit1->name, inst1, vl1->key);
else
Fprintf(stdout, "Circuit 1 %s instance %s has no"
" property match in circuit 2.\n",
Circuit1->name, inst1);
}
#ifdef TCL_NETGEN
if (do_list) {
mpair = PropertyList(vl1, NULL);
@@ -5171,6 +5288,7 @@ PropertyMatch(struct objlist *ob1, struct objlist *ob2, int do_print,
t1type = (tp1) ? tp1->type : 0;
t2type = (tp2) ? tp2->type : 0;
if ((t1type != PROPERTY) && (t2type != PROPERTY)) break;
checked_one = TRUE;
}
*retval = (rval < 0) ? rval : mismatches;
@@ -6057,7 +6175,7 @@ int reorderpins(struct hashlist *p, int file)
struct nlist *ptr;
struct nlist *tc2 = Circuit2;
struct objlist *ob, *ob2, *firstpin;
int i, numports, *nodes;
int i, numports, *nodes, unordered;
char **names;
ptr = (struct nlist *)(p->ptr);
@@ -6071,14 +6189,23 @@ int reorderpins(struct hashlist *p, int file)
/* instances of both cells. */
numports = 0;
unordered = 0;
ob2 = tc2->cell;
while (ob2 && ob2->type == PORT) {
if (ob2->model.port < 0) {
ob2->model.port = numports;
unordered = 1;
}
numports++;
ob2 = ob2->next;
}
nodes = (int *)CALLOC(numports, sizeof(int));
names = (char **)CALLOC(numports, sizeof(char *));
if (unordered)
Fprintf(stderr, "Ports of %s are unordered. "
"Ordering will be arbitrary.", tc2->name);
for (ob = ptr->cell; ob != NULL; ) {
if (ob->type == FIRSTPIN) {
if ((*matchfunc)(ob->model.class, tc2->name)) {
@@ -6274,6 +6401,7 @@ struct nlist *addproxies(struct hashlist *p, void *clientdata)
int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
{
char *cover, *ctemp;
char *bangptr1, *bangptr2;
struct objlist *ob1, *ob2, *obn, *obp, *ob1s, *ob2s, *obt;
struct NodeClass *NC;
struct Node *N1, *N2;
@@ -6486,13 +6614,25 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
/* Do any unmatched pins have the same name? */
/* (This should not happen if unconnected pins are eliminated) */
/* (Semi-hack: Allow "!" global flag) */
ob1 = tc1->cell;
bangptr1 = strrchr(ob1->name, '!');
if (bangptr1 && (*(bangptr1 + 1) == '\0'))
*bangptr1 = '\0';
else bangptr1 = NULL;
for (i = 0; i < numorig; i++) {
if (*(cover + i) == (char)0) {
j = 0;
for (ob2 = tc2->cell; ob2 != NULL; ob2 = ob2->next) {
if (!IsPort(ob2)) break;
bangptr2 = strrchr(ob2->name, '!');
if (bangptr2 && (*(bangptr2 + 1) == '\0'))
*bangptr2 = '\0';
else bangptr2 = NULL;
if ((*matchfunc)(ob1->name, ob2->name)) {
ob2->model.port = i; /* save order */
*(cover + i) = (char)1;
@@ -6521,11 +6661,13 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
}
#endif
}
if (bangptr2) *bangptr2 = '!';
j++;
}
}
ob1 = ob1->next;
}
if (bangptr1) *bangptr1 = '!';
/* Find the end of the pin list in tc1, for adding proxy pins */
@@ -6709,7 +6851,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
/* Clean up "UNKNOWN" records from Circuit1 */
for (obn = tc1->cell; ; obn = obn->next) {
for (obn = tc1->cell; obn; obn = obn->next) {
if (obn->type == UNKNOWN) obn->type = PORT;
else if (obn->type != PORT) break;
}
@@ -6728,13 +6870,13 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
/* Clean up "UNKNOWN" records from Circuit2 */
for (obn = tc2->cell; ; obn = obn->next) {
for (obn = tc2->cell; obn; obn = obn->next) {
if (obn->type == UNKNOWN) obn->type = PORT;
else if (obn->type != PORT) break;
}
/* Check for ports that did not get ordered */
for (obn = tc2->cell; obn->type == PORT; obn = obn->next) {
for (obn = tc2->cell; obn && (obn->type == PORT); obn = obn->next) {
if (obn->model.port == -1) {
if (obn->node == -1) {
// This only happens when pins have become separated from any net.
+62
View File
@@ -193,6 +193,67 @@ static struct filestack *OpenFiles = NULL;
#define TOKEN_DELIMITER " \t\n\r"
/*----------------------------------------------------------------------*/
/* TrimQuoted() --- */
/* Remove spaces from inside single- or double-quoted strings. */
/*----------------------------------------------------------------------*/
void TrimQuoted(char *line)
{
char *qstart, *qend, *lptr;
int slen;
int changed;
/* Single-quoted entries */
changed = TRUE;
lptr = line;
while (changed)
{
changed = FALSE;
qstart = strchr(lptr, '\'');
if (qstart)
{
qend = strchr(qstart + 1, '\'');
if (qend && (qend > qstart)) {
slen = strlen(lptr);
for (lptr = qstart + 1; lptr < qend; lptr++) {
if (*lptr == ' ') {
memmove(lptr, lptr + 1, slen);
qend--;
changed = TRUE;
}
}
lptr++;
}
}
}
/* Double-quoted entries */
changed = TRUE;
lptr = line;
while (changed)
{
changed = FALSE;
qstart = strchr(lptr, '\"');
if (qstart)
{
qend = strchr(qstart + 1, '\"');
if (qend && (qend > qstart)) {
slen = strlen(lptr);
for (lptr = qstart + 1; lptr < qend; lptr++) {
if (*lptr == ' ') {
memmove(lptr, lptr + 1, slen);
qend--;
changed = TRUE;
}
}
lptr++;
}
}
}
}
/*----------------------------------------------------------------------*/
/* GetNextLineNoNewline() */
/* */
@@ -233,6 +294,7 @@ int GetNextLineNoNewline()
}
linenum++;
strcpy(linetok, line);
TrimQuoted(linetok);
nexttok = strtok(linetok, TOKEN_DELIMITER);
return 0;
+10 -2
View File
@@ -3309,7 +3309,9 @@ int check_pin_nodes(struct objlist *ob1, struct objlist *ob2)
pob = pob->next;
}
if (nob->type > FIRSTPIN || pob->type > FIRSTPIN) return FALSE;
if (nob && pob && (nob->type > FIRSTPIN || pob->type > FIRSTPIN))
return FALSE;
return TRUE;
}
@@ -3486,7 +3488,13 @@ int CombineSerial(char *model, int file)
/* only pointer to it. */
for (obp = instlist[i][0]; obp->next->type > FIRSTPIN ||
obp->next->type == PROPERTY; obp = obp->next);
for (ob2 = obp; ob2->next != instlist[i][1]; ob2 = ob2->next);
for (ob2 = obp; ob2 && ob2->next != instlist[i][1]; ob2 = ob2->next);
/* Device may have been moved by the above code. If so, look for */
/* it from the beginning of the list. */
if (ob2 == NULL)
for (ob2 = tp->cell; ob2->next != instlist[i][1]; ob2 = ob2->next);
for (obs = ob2->next; obs->next && (obs->next->type > FIRSTPIN
|| obs->next->type == PROPERTY); obs = obs->next);
ob2->next = obs->next;
+3 -3
View File
@@ -626,7 +626,7 @@ void ReadSpiceFile(char *fname, int filenum, struct cellstack **CellStackPtr,
}
SpiceTokNoNewline();
}
SetClass((blackbox) ? CLASS_MODULE : CLASS_SUBCKT);
SetClass((blackbox) ? CLASS_MODULE : CLASS_SUBCKT);
if (hasports == 0) {
// If the cell defines no ports, then create a proxy
@@ -777,7 +777,7 @@ skip_ends:
/* For ~/<path>, substitute tilde from $HOME */
userpath = getenv("HOME");
iname = (char *)MALLOC(strlen(userpath) + strlen(iptr));
sprintf(fname, "%s%s", userpath, iptr + 1);
sprintf(iname, "%s%s", userpath, iptr + 1);
}
else if (*iptr == '~') {
/* For ~<user>/<path>, substitute tilde from getpwnam() */
@@ -791,7 +791,7 @@ skip_ends:
if (pathstart) {
*pathstart = '/';
iname = (char *)MALLOC(strlen(userpath) + strlen(pathstart) + 1);
sprintf(fname, "%s%s", userpath, pathstart);
sprintf(iname, "%s%s", userpath, pathstart);
}
else {
/* Almost certainly an error, but make the substitution anyway */
-1
View File
@@ -370,7 +370,6 @@ proc netgen::convert_to_json {filename lvs_final} {
proc netgen::lvs { name1 name2 {setupfile setup.tcl} {logfile comp.out} args} {
set dolist 0
set dojson 0
puts stdout "Diagnostic version"
foreach arg $args {
if {$arg == "-list"} {
puts stdout "Generating list result"
+32 -15
View File
@@ -1676,6 +1676,13 @@ _netgen_model(ClientData clientData,
retclass = modelclasses[SUBCKT_IDX];
break;
case CLASS_MODULE:
if (auto_blackbox)
retclass = modelclasses[BLACKBOX_IDX];
else
retclass = modelclasses[MODULE_IDX];
break;
default: /* (includes case CLASS_UNDEF) */
retclass = modelclasses[UNDEF_IDX];
break;
@@ -2713,10 +2720,10 @@ _netcmp_equate(ClientData clientData,
};
int result, index;
char *name1 = NULL, *name2 = NULL, *optstart;
struct nlist *tp1, *tp2;
struct nlist *tp1, *tp2, *SaveC1, *SaveC2;
struct objlist *ob1, *ob2;
int file1, file2;
int i, l1, l2, ltest, lent, dolist;
int i, l1, l2, ltest, lent, dolist = 0;
Tcl_Obj *tobj1, *tobj2, *tobj3;
if (objc > 1) {
@@ -2884,7 +2891,7 @@ _netcmp_equate(ClientData clientData,
break;
case PINS_IDX:
if (ElementClasses == NULL) {
if ((ElementClasses == NULL) && (auto_blackbox == FALSE)) {
if (CurrentCell == NULL)
Fprintf(stderr, "Equate elements: no current cell.\n");
Fprintf(stderr, "Equate pins: cell %s and/or %s has no elements.\n",
@@ -2892,20 +2899,30 @@ _netcmp_equate(ClientData clientData,
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
return TCL_OK;
}
if (tp1 == Circuit1 && tp2 == Circuit2) {
int result;
if (MatchPins(tp1, tp2, dolist)) {
Fprintf(stdout, "Cell pin lists are equivalent.\n");
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
}
else {
Fprintf(stdout, "Cell pin lists for %s and %s altered to match.\n",
name1, name2);
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
}
else if (ElementClasses == NULL) {
/* This has been called outside of a netlist compare, */
/* probably to force name matching of pins on black-box */
/* devices. But MatchPins only works if tp1 == Circuit1 */
/* and tp2 == Circuit2, so preserve these values and */
/* recover afterward (what a hack). */
SaveC1 = Circuit1;
SaveC2 = Circuit2;
Circuit1 = tp1;
Circuit2 = tp2;
}
if (MatchPins(tp1, tp2, dolist)) {
Fprintf(stdout, "Cell pin lists are equivalent.\n");
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
}
else {
Fprintf(stderr, "Function not defined outside of LVS scope.\n");
Fprintf(stdout, "Cell pin lists for %s and %s altered to match.\n",
name1, name2);
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
}
if (ElementClasses == NULL) {
/* Recover temporarily set global variables (see above) */
Circuit1 = SaveC1;
Circuit2 = SaveC2;
}
break;