From 1efa054ac1302a2b8b03a41e90420fc055d5796e Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 12 Jun 2023 17:16:49 -0400 Subject: [PATCH] Corrected an issue with shorted ports. When shorted ports are connected only to ports and not to any devices, then they do not show up in NodeClasses() and so pass through most of the checks in MatchPins(). A separate correspondence check is needed to make sure that the same shorted ports appear in both netlists. --- VERSION | 2 +- base/netcmp.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++++- base/verilog.c | 3 +-- 3 files changed, 64 insertions(+), 4 deletions(-) diff --git a/VERSION b/VERSION index 7acc89c..4b0dfc2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.5.253 +1.5.254 diff --git a/base/netcmp.c b/base/netcmp.c index dbfcaf0..f4e62f1 100644 --- a/base/netcmp.c +++ b/base/netcmp.c @@ -7428,6 +7428,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist) int result = 1, haspins = 0, notempty = 0; int hasproxy1 = 0, hasproxy2 = 0; int needclean1 = 0, needclean2 = 0; + int *correspond; char *ostr; #ifdef TCL_NETGEN Tcl_Obj *mlist, *plist1, *plist2; @@ -7681,6 +7682,8 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist) /* legal SPICE. */ ob1 = tc1->cell; + + correspond = (int *)CALLOC((tc1->nodename_cache_maxnodenum + 1), sizeof(int)); for (i = 0; i < numorig; i++) { bangptr1 = strrchr(ob1->name, '!'); @@ -7723,7 +7726,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist) (tc2->flags & CELL_PLACEHOLDER)) || (NodeClasses == NULL))) { - ob2->model.port = i; /* save order */ + ob2->model.port = i; /* save order */ *(cover + i) = (char)1; if (Debug == 0) { @@ -7752,6 +7755,63 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist) if (bangptr2) *bangptr2 = '!'; break; } + else if ((ob1->node != -1) && (ob2->node != -1)) { + /* Check for the case of ports on both sides being shorted + * together. That means that the nodes on both sides connect + * only to ports, that they connec to the same number of ports, + * and that each port pair has a matching name. + */ + int onlyports = 1; + struct objlist *oba, *obb; + for (oba = tc1->cell; oba != NULL; oba = oba->next) { + if ((oba->node == ob1->node) && (oba->type != PORT)) { + onlyports = 0; + break; + } + } + if (onlyports) { + for (obb = tc2->cell; obb != NULL; obb = obb->next) { + if ((obb->node == ob2->node) && (obb->type != PORT)) { + onlyports = 0; + break; + } + } + } + if (onlyports) { + if ((correspond[ob1->node] == 0) || (correspond[ob1->node] == ob2->node)) { + + correspond[ob1->node] = ob2->node; /* remember corresponding node */ + ob2->model.port = i; /* save order */ + *(cover + i) = (char)1; + + if (Debug == 0) { + for (m = 0; m < left_col_end; m++) *(ostr + m) = ' '; + for (m = left_col_end + 1; m < right_col_end; m++) *(ostr + m) = ' '; + snprintf(ostr, left_col_end, "%s", ob1->name); + snprintf(ostr + left_col_end + 1, left_col_end, "%s", ob2->name); + for (m = 0; m < right_col_end + 1; m++) + if (*(ostr + m) == '\0') *(ostr + m) = ' '; + Fprintf(stdout, ostr); + } + else { + Fprintf(stdout, "Circuit %s port %d \"%s\"" + " = cell %s port %d \"%s\"\n", + tc1->name, i, ob1->name, + tc2->name, j, ob2->name); + } +#ifdef TCL_NETGEN + if (dolist) { + Tcl_ListObjAppendElement(netgeninterp, plist1, + Tcl_NewStringObj(ob1->name, -1)); + Tcl_ListObjAppendElement(netgeninterp, plist2, + Tcl_NewStringObj(ob2->name, -1)); + } +#endif + } + if (bangptr2) *bangptr2 = '!'; + break; + } + } } if (bangptr2) *bangptr2 = '!'; j++; @@ -7760,6 +7820,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist) ob1 = ob1->next; if (bangptr1) *bangptr1 = '!'; } + FREE(correspond); /* Find the end of the pin list in tc1, for adding proxy pins */ diff --git a/base/verilog.c b/base/verilog.c index f4f0a1e..9ba310c 100644 --- a/base/verilog.c +++ b/base/verilog.c @@ -1017,13 +1017,12 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr, char devtype, in_module, in_param; char *eqptr, *matchptr; struct keyvalue *kvlist = NULL; - char inst[MAX_STR_LEN], model[MAX_STR_LEN], instname[MAX_STR_LEN], portname[MAX_STR_LEN], pkey[MAX_STR_LEN]; + char inst[MAX_STR_LEN], model[MAX_STR_LEN], portname[MAX_STR_LEN], pkey[MAX_STR_LEN]; struct nlist *tp; struct objlist *parent, *sobj, *nobj, *lobj, *pobj, *cref; inst[MAX_STR_LEN-1] = '\0'; model[MAX_STR_LEN-1] = '\0'; - instname[MAX_STR_LEN-1] = '\0'; in_module = (char)0; in_param = (char)0;