From 04dd4a64d509b937cc18b35c6cf31956046db77b Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Wed, 7 Oct 2020 21:32:07 -0400 Subject: [PATCH] Corrected problems with the port count routine not being specified with the file number, so that it can get confused between libraries. Also made a fix to coerce one cell class to be forced to be the same in both circuits under some circumstances. --- VERSION | 2 +- base/objlist.c | 8 ++++++-- base/objlist.h | 2 +- base/place.c | 2 +- base/query.c | 4 ++-- tcltk/tclnetgen.c | 45 ++++++++++++++++++++++++++++++++++++++++----- 6 files changed, 51 insertions(+), 12 deletions(-) diff --git a/VERSION b/VERSION index df85035..05c3baa 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.5.155 +1.5.156 diff --git a/base/objlist.c b/base/objlist.c index aa189b1..c0b5448 100644 --- a/base/objlist.c +++ b/base/objlist.c @@ -1112,13 +1112,17 @@ void FreeObjectAndHash(struct objlist *ob, struct nlist *ptr) /*************** GENERAL UTILITIES ****************************/ -int NumberOfPorts(char *cellname) +int NumberOfPorts(char *cellname, int file) { struct nlist *tp; struct objlist *ob; int ports; - tp = LookupCell(cellname); + if (file == -1) + tp = LookupCell(cellname); + else + tp = LookupCellFile(cellname, file); + if (tp == NULL) return(0); ports = 0; for (ob = tp->cell; ob != NULL; ob = ob->next) diff --git a/base/objlist.h b/base/objlist.h index 5ed4b41..1ab920e 100644 --- a/base/objlist.h +++ b/base/objlist.h @@ -242,7 +242,7 @@ extern void FreeObjectAndHash(struct objlist *ob, struct nlist *ptr); extern void FreePorts(char *cellname); extern struct IgnoreList *ClassIgnore; -extern int NumberOfPorts(char *cellname); +extern int NumberOfPorts(char *cellname, int file); extern struct objlist *InstanceNumber(struct nlist *tp, int inst); extern struct objlist *List(char *list_template); diff --git a/base/place.c b/base/place.c index b2f860f..f2568bc 100644 --- a/base/place.c +++ b/base/place.c @@ -929,7 +929,7 @@ void ToggleDebug(void) void DescribeCell(char *name, int detail) { Printf("Cell: %s contains %d instances, %d nodes and %d ports\n", name, - NumberOfInstances(name), RenumberNodes(name), NumberOfPorts(name)); + NumberOfInstances(name), RenumberNodes(name), NumberOfPorts(name, -1)); PrintEmbeddingTree(stdout,name,detail); } diff --git a/base/query.c b/base/query.c index 7da724f..60ba9be 100644 --- a/base/query.c +++ b/base/query.c @@ -907,7 +907,7 @@ void PrintLeavesInCell(char *cellname, int filenum) np->dumped = 1; if (np->class != CLASS_SUBCKT) { - Printf("%s; %d ports; Primitive.\n", cellname, NumberOfPorts(cellname)); + Printf("%s; %d ports; Primitive.\n", cellname, NumberOfPorts(cellname, filenum)); return; } @@ -920,7 +920,7 @@ void PrintLeavesInCell(char *cellname, int filenum) am_a_leaf = 0; } - if (am_a_leaf) Printf("%s; %d ports\n", cellname, NumberOfPorts(cellname)); + if (am_a_leaf) Printf("%s; %d ports\n", cellname, NumberOfPorts(cellname, filenum)); return; } diff --git a/tcltk/tclnetgen.c b/tcltk/tclnetgen.c index 22dc13f..89e9f7d 100644 --- a/tcltk/tclnetgen.c +++ b/tcltk/tclnetgen.c @@ -1532,23 +1532,24 @@ int _netgen_model(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { - struct nlist *tp; + struct nlist *tp, *tp2; char *model, *retclass; unsigned char class; int fnum = -1; - int result, index, nports; + int result, index, nports, nports2; char *modelclasses[] = { "undefined", "nmos", "pmos", "pnp", "npn", "resistor", "capacitor", "diode", "inductor", "module", "blackbox", "xline", - "moscap", "mosfet", "bjt", "subcircuit", NULL + "moscap", "mosfet", "bjt", "subcircuit", "copy", + NULL }; enum OptionIdx { UNDEF_IDX, NMOS_IDX, PMOS_IDX, PNP_IDX, NPN_IDX, RES_IDX, CAP_IDX, DIODE_IDX, INDUCT_IDX, MODULE_IDX, BLACKBOX_IDX, XLINE_IDX, MOSCAP_IDX, - MOSFET_IDX, BJT_IDX, SUBCKT_IDX + MOSFET_IDX, BJT_IDX, SUBCKT_IDX, COPY_IDX }; if (objc != 3 && objc != 2) { @@ -1580,7 +1581,7 @@ _netgen_model(ClientData clientData, if (objc == 3) { model = Tcl_GetString(objv[2]); - nports = NumberOfPorts(model); + nports = NumberOfPorts(model, fnum); if (Tcl_GetIndexFromObj(interp, objv[2], (CONST84 char **)modelclasses, "class", 0, &index) != TCL_OK) { @@ -1644,6 +1645,40 @@ _netgen_model(ClientData clientData, break; case SUBCKT_IDX: class = CLASS_SUBCKT; + break; + case COPY_IDX: + /* "copy" is not a class, but indicates that the cell, */ + /* if undefined or a module, should have its class */ + /* taken from the other circuit, if that circuit has a */ + /* cell of the same name. */ + if (Circuit1 == NULL || Circuit2 == NULL) { + Tcl_SetResult(interp, "Circuits have not been queued for comparison.", + NULL); + return TCL_ERROR; + } + if (tp == Circuit1) { + tp2 = LookupCellFile(tp->name, Circuit2->file); + nports2 = NumberOfPorts(tp2->name, Circuit2->file); + } + else if (tp == Circuit2) { + tp2 = LookupCellFile(tp->name, Circuit1->file); + nports2 = NumberOfPorts(tp2->name, Circuit1->file); + } + else { + Tcl_SetResult(interp, "The referenced netlist is not being compared.", + NULL); + return TCL_ERROR; + } + /* Should a non-matching number of ports be considered a fatal error? */ + // if (nports2 != nports) { + // Tcl_SetResult(interp, "The number of ports for this cell does not " + // "match between netlists.", NULL); + // return TCL_ERROR; + // } + + class = tp2->class; + /* To do (maybe): Rename tp ports to match tp2? */ + break; } tp->class = class;