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.
This commit is contained in:
Tim Edwards 2018-10-29 17:29:15 -04:00
parent a126a3fe74
commit 79a3934d40
4 changed files with 32 additions and 18 deletions

View File

@ -190,16 +190,22 @@ DBWHLRedraw(rootDef, area, erase)
dbwhlDef = rootDef; /* Must pass to search function. */ dbwhlDef = rootDef; /* Must pass to search function. */
dbwhlErase = erase; dbwhlErase = erase;
/* If we're passed a NULL area, expand it by one unit so that /* If we're passed a NULL area, expand it by one unit in both
* we're certain to have non-zero area. Otherwise the various * directions so that we're certain to have non-zero area.
* search procedures have big troubles. * Otherwise the various search procedures have big troubles.
*/ */
ourArea = *area; ourArea = *area;
if (ourArea.r_xbot >= ourArea.r_xtop) if (ourArea.r_xbot >= ourArea.r_xtop)
{
ourArea.r_xtop = ourArea.r_xbot + 1; ourArea.r_xtop = ourArea.r_xbot + 1;
ourArea.r_xbot--;
}
if (ourArea.r_ybot >= ourArea.r_ytop) if (ourArea.r_ybot >= ourArea.r_ytop)
{
ourArea.r_ytop = ourArea.r_ybot + 1; ourArea.r_ytop = ourArea.r_ybot + 1;
ourArea.r_ybot--;
}
(void) WindSearch(DBWclientID, (ClientData) NULL, &ourArea, (void) WindSearch(DBWclientID, (ClientData) NULL, &ourArea,
dbwhlRedrawFunc, (ClientData) &ourArea); dbwhlRedrawFunc, (ClientData) &ourArea);
} }

View File

@ -879,12 +879,13 @@ efBuildDevice(def, class, type, r, argc, argv)
*/ */
void 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 */ Def *def; /* Def to which this connection is to be added */
char *name; /* One of the names for this node */ char *name; /* One of the names for this node */
int idx; /* Port number (order) */ int idx; /* Port number (order) */
int x; int y; /* Location of a point inside this node */ int x; int y; /* Location of a point inside this node */
char *layername; /* Name of tile type */ char *layername; /* Name of tile type */
bool toplevel; /* 1 if the cell def is the top level cell */
{ {
HashEntry *he; HashEntry *he;
EFNodeName *nn; EFNodeName *nn;
@ -902,6 +903,8 @@ efBuildPortNode(def, name, idx, x, y, layername)
if (nn != (EFNodeName *) NULL) if (nn != (EFNodeName *) NULL)
{ {
nn->efnn_node->efnode_flags |= EF_PORT; nn->efnn_node->efnode_flags |= EF_PORT;
if (toplevel)
nn->efnn_node->efnode_flags |= EF_TOP_PORT;
nn->efnn_port = idx; nn->efnn_port = idx;
} }
} }
@ -1442,7 +1445,7 @@ efNodeAddName(node, he, hn)
{ {
EFNodeName *newnn; EFNodeName *newnn;
EFNodeName *oldnn; EFNodeName *oldnn;
bool topport; bool topport; // New node to add is a top-level port
newnn = (EFNodeName *) mallocMagic((unsigned)(sizeof (EFNodeName))); newnn = (EFNodeName *) mallocMagic((unsigned)(sizeof (EFNodeName)));
newnn->efnn_node = node; newnn->efnn_node = node;
@ -1450,13 +1453,15 @@ efNodeAddName(node, he, hn)
newnn->efnn_port = -1; newnn->efnn_port = -1;
HashSetValue(he, (char *) newnn); HashSetValue(he, (char *) newnn);
topport = ((node->efnode_flags & EF_PORT) && /* If the node is a port of the top level cell, denoted by flag */
(node->efnode_name->efnn_hier->hn_parent == NULL)) ? /* EF_TOP_PORT, then the name given to the port always stays at the */
TRUE : FALSE; /* head of the list. */
topport = (node->efnode_flags & EF_TOP_PORT) ? TRUE : FALSE;
/* Link in the new name */ /* Link in the new name */
oldnn = node->efnode_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 */ /* New head of list */
newnn->efnn_next = oldnn; newnn->efnn_next = oldnn;
@ -1532,7 +1537,7 @@ efNodeMerge(node1, node2)
/* Make all EFNodeNames point to node1 */ /* Make all EFNodeNames point to node1 */
if (node2->efnode_name) if (node2->efnode_name)
{ {
bool topport; bool topport1, topport2;
for (nn = node2->efnode_name; nn; nn = nn->efnn_next) for (nn = node2->efnode_name; nn; nn = nn->efnn_next)
{ {
@ -1540,13 +1545,12 @@ efNodeMerge(node1, node2)
nn->efnn_node = node1; nn->efnn_node = node1;
} }
topport = ((node2->efnode_flags & EF_PORT) && topport1 = (node1->efnode_flags & EF_TOP_PORT) ? TRUE : FALSE;
(node2->efnode_name->efnn_hier->hn_parent == NULL)) ? topport2 = (node2->efnode_flags & EF_TOP_PORT) ? TRUE : FALSE;
TRUE : FALSE;
/* Concatenate list of EFNodeNames, taking into account precedence */ /* Concatenate list of EFNodeNames, taking into account precedence */
if (topport || EFHNBest(node2->efnode_name->efnn_hier, if (!topport1 && (topport2 || EFHNBest(node2->efnode_name->efnn_hier,
node1->efnode_name->efnn_hier)) node1->efnode_name->efnn_hier)))
{ {
/* /*
* New official name is that of node2. * New official name is that of node2.

View File

@ -428,7 +428,7 @@ readfile:
def->def_flags |= DEF_SUBCIRCUIT; def->def_flags |= DEF_SUBCIRCUIT;
} }
efBuildPortNode(def, argv[1], atoi(argv[2]), atoi(argv[3]), efBuildPortNode(def, argv[1], atoi(argv[2]), atoi(argv[3]),
atoi(argv[4]), argv[7]); atoi(argv[4]), argv[7], toplevel);
break; break;
/* /*

View File

@ -182,18 +182,22 @@ typedef struct efnhdr
* multiple ports per node (for example, a thru route). * multiple ports per node (for example, a thru route).
*/ */
#define EF_PORT 0x08 #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 * This is used when a node is a substrate node with a local
* node name, making it an implicitly-defined port. It differs * node name, making it an implicitly-defined port. It differs
* from EF_DEVTERM in that EF_DEVTERM includes global substrate * from EF_DEVTERM in that EF_DEVTERM includes global substrate
* nodes, which are not declared ports. * 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 * EF_SUBS_NODE is defined for substrate nodes defined in the
* .ext file. * .ext file.
*/ */
#define EF_SUBS_NODE 0x20 #define EF_SUBS_NODE 0x40
extern int efNumResistClasses; /* Number of resistance classes in efResists */ extern int efNumResistClasses; /* Number of resistance classes in efResists */