From 79a3934d4072562f256227d2a74cfc7414ed9f6d Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 29 Oct 2018 17:29:15 -0400 Subject: [PATCH] Corrected an error that was previously assumed to be fixed in 8.2.74. Top-level port names are now flagged independently of any subcircuit port, so they are easier to identify when determining naming precedence for the net. This makes the code cleaner and removes the problems arising from non-top-level ports and global names overriding the subcircuit port names. --- dbwind/DBWhlights.c | 12 +++++++++--- extflat/EFbuild.c | 28 ++++++++++++++++------------ extflat/EFread.c | 2 +- extflat/extflat.h | 8 ++++++-- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/dbwind/DBWhlights.c b/dbwind/DBWhlights.c index 2110889a..40971408 100644 --- a/dbwind/DBWhlights.c +++ b/dbwind/DBWhlights.c @@ -190,16 +190,22 @@ DBWHLRedraw(rootDef, area, erase) dbwhlDef = rootDef; /* Must pass to search function. */ dbwhlErase = erase; - /* If we're passed a NULL area, expand it by one unit so that - * we're certain to have non-zero area. Otherwise the various - * search procedures have big troubles. + /* If we're passed a NULL area, expand it by one unit in both + * directions so that we're certain to have non-zero area. + * Otherwise the various search procedures have big troubles. */ ourArea = *area; if (ourArea.r_xbot >= ourArea.r_xtop) + { ourArea.r_xtop = ourArea.r_xbot + 1; + ourArea.r_xbot--; + } if (ourArea.r_ybot >= ourArea.r_ytop) + { ourArea.r_ytop = ourArea.r_ybot + 1; + ourArea.r_ybot--; + } (void) WindSearch(DBWclientID, (ClientData) NULL, &ourArea, dbwhlRedrawFunc, (ClientData) &ourArea); } diff --git a/extflat/EFbuild.c b/extflat/EFbuild.c index 1e9e5459..5a5d3384 100644 --- a/extflat/EFbuild.c +++ b/extflat/EFbuild.c @@ -879,12 +879,13 @@ efBuildDevice(def, class, type, r, argc, argv) */ void -efBuildPortNode(def, name, idx, x, y, layername) +efBuildPortNode(def, name, idx, x, y, layername, toplevel) Def *def; /* Def to which this connection is to be added */ char *name; /* One of the names for this node */ int idx; /* Port number (order) */ int x; int y; /* Location of a point inside this node */ char *layername; /* Name of tile type */ + bool toplevel; /* 1 if the cell def is the top level cell */ { HashEntry *he; EFNodeName *nn; @@ -902,6 +903,8 @@ efBuildPortNode(def, name, idx, x, y, layername) if (nn != (EFNodeName *) NULL) { nn->efnn_node->efnode_flags |= EF_PORT; + if (toplevel) + nn->efnn_node->efnode_flags |= EF_TOP_PORT; nn->efnn_port = idx; } } @@ -1442,7 +1445,7 @@ efNodeAddName(node, he, hn) { EFNodeName *newnn; EFNodeName *oldnn; - bool topport; + bool topport; // New node to add is a top-level port newnn = (EFNodeName *) mallocMagic((unsigned)(sizeof (EFNodeName))); newnn->efnn_node = node; @@ -1450,13 +1453,15 @@ efNodeAddName(node, he, hn) newnn->efnn_port = -1; HashSetValue(he, (char *) newnn); - topport = ((node->efnode_flags & EF_PORT) && - (node->efnode_name->efnn_hier->hn_parent == NULL)) ? - TRUE : FALSE; + /* If the node is a port of the top level cell, denoted by flag */ + /* EF_TOP_PORT, then the name given to the port always stays at the */ + /* head of the list. */ + + topport = (node->efnode_flags & EF_TOP_PORT) ? TRUE : FALSE; /* Link in the new name */ oldnn = node->efnode_name; - if (oldnn == NULL || EFHNBest(newnn->efnn_hier, oldnn->efnn_hier) || topport) + if (oldnn == NULL || (EFHNBest(newnn->efnn_hier, oldnn->efnn_hier) && !topport)) { /* New head of list */ newnn->efnn_next = oldnn; @@ -1532,7 +1537,7 @@ efNodeMerge(node1, node2) /* Make all EFNodeNames point to node1 */ if (node2->efnode_name) { - bool topport; + bool topport1, topport2; for (nn = node2->efnode_name; nn; nn = nn->efnn_next) { @@ -1540,13 +1545,12 @@ efNodeMerge(node1, node2) nn->efnn_node = node1; } - topport = ((node2->efnode_flags & EF_PORT) && - (node2->efnode_name->efnn_hier->hn_parent == NULL)) ? - TRUE : FALSE; + topport1 = (node1->efnode_flags & EF_TOP_PORT) ? TRUE : FALSE; + topport2 = (node2->efnode_flags & EF_TOP_PORT) ? TRUE : FALSE; /* Concatenate list of EFNodeNames, taking into account precedence */ - if (topport || EFHNBest(node2->efnode_name->efnn_hier, - node1->efnode_name->efnn_hier)) + if (!topport1 && (topport2 || EFHNBest(node2->efnode_name->efnn_hier, + node1->efnode_name->efnn_hier))) { /* * New official name is that of node2. diff --git a/extflat/EFread.c b/extflat/EFread.c index 056ae03b..0b13d268 100644 --- a/extflat/EFread.c +++ b/extflat/EFread.c @@ -428,7 +428,7 @@ readfile: def->def_flags |= DEF_SUBCIRCUIT; } efBuildPortNode(def, argv[1], atoi(argv[2]), atoi(argv[3]), - atoi(argv[4]), argv[7]); + atoi(argv[4]), argv[7], toplevel); break; /* diff --git a/extflat/extflat.h b/extflat/extflat.h index 996b8c5f..8d8f1dba 100644 --- a/extflat/extflat.h +++ b/extflat/extflat.h @@ -182,18 +182,22 @@ typedef struct efnhdr * multiple ports per node (for example, a thru route). */ #define EF_PORT 0x08 + /* + * Flag ports of a top-level cell in addition to setting EF_PORT + */ +#define EF_TOP_PORT 0x10 /* * This is used when a node is a substrate node with a local * node name, making it an implicitly-defined port. It differs * from EF_DEVTERM in that EF_DEVTERM includes global substrate * nodes, which are not declared ports. */ -#define EF_SUBS_PORT 0x10 +#define EF_SUBS_PORT 0x20 /* * EF_SUBS_NODE is defined for substrate nodes defined in the * .ext file. */ -#define EF_SUBS_NODE 0x20 +#define EF_SUBS_NODE 0x40 extern int efNumResistClasses; /* Number of resistance classes in efResists */