Merge branch 'master' into bplane

Conflicts:
	extract/ExtSubtree.c
	utils/Depend

Updated bplane branch from master branch.
This commit is contained in:
Tim Edwards 2020-03-13 11:39:56 -04:00
commit bb1c9a6c0e
11 changed files with 155 additions and 75 deletions

2
.gitignore vendored
View File

@ -1,5 +1,5 @@
defs.mak
Depend
*/Depend
config.cache
config.log
scripts/config.log

View File

@ -345,6 +345,7 @@ calmaParseStructure(filename)
}
}
cifReadCellDef = calmaFindCell(strname, &was_called);
def->cd_flags &= ~CDDEREFERENCE;
DBCellClearDef(cifReadCellDef);
DBCellSetAvail(cifReadCellDef);
HashSetValue(he, cifReadCellDef);
@ -664,6 +665,10 @@ calmaElementSref(filename)
TxPrintf("Cell definition %s does not exist!\n", sname);
fseek(calmaInputFile, originalFilePos, SEEK_SET);
def = calmaFindCell(sname, NULL);
/* Cell flags set to "dereferenced" in case there is no */
/* definition in the GDS file. If there is a definition */
/* made after the instance, then the flag will be cleared. */
def->cd_flags |= CDDEREFERENCE;
}
}

View File

@ -1455,7 +1455,8 @@ badTransform:
pathOK = TRUE;
}
if ((pathOK == FALSE) && strcmp(subCellDef->cd_file, pathptr))
if ((pathOK == FALSE) && strcmp(subCellDef->cd_file, pathptr)
&& (dereference == FALSE))
{
TxError("Duplicate cell in %s: Instance of cell %s is from "
"path %s but cell was previously read from %s.\n",

View File

@ -507,6 +507,11 @@ typedef struct celluse
*/
#define CU_SELECT_NET 0x02
#define CU_SELECT_CHUNK 0x04
/* CU_SUB_EXTRACTED is a temporary flag indicating that the substrate
* of the use has been extracted and the extraction
* does not need to be repeated for this use.
*/
#define CU_SUB_EXTRACTED 0x08
/* Character prefix used to denote a locked cell use in a .mag file */
#define CULOCKCHAR '*'

View File

@ -184,6 +184,7 @@ efBuildNode(def, isSubsnode, nodeName, nodeCap, x, y, layerName, av, ac)
newnode->efnode_loc.r_xtop = newnode->efnode_loc.r_xbot + 1;
newnode->efnode_loc.r_ytop = newnode->efnode_loc.r_ybot + 1;
newnode->efnode_client = (ClientData) NULL;
newnode->efnode_num = 1;
if (layerName) newnode->efnode_type =
efBuildAddStr(EFLayerNames, &EFLayerNumNames, MAXTYPES, layerName);
else newnode->efnode_type = 0;
@ -464,7 +465,7 @@ efBuildEquiv(def, nodeName1, nodeName2)
{
if (efWarn)
efReadError("Merged nodes %s and %s\n", nodeName1, nodeName2);
efNodeMerge(nn1->efnn_node, nn2->efnn_node);
efNodeMerge(&nn1->efnn_node, &nn2->efnn_node);
}
return;
}
@ -1580,70 +1581,86 @@ efNodeAddName(node, he, hn)
*/
void
efNodeMerge(node1, node2)
EFNode *node1, *node2; /* Hierarchical nodes */
efNodeMerge(node1ptr, node2ptr)
EFNode **node1ptr, **node2ptr; /* Pointers to hierarchical nodes */
{
EFNodeName *nn, *nnlast;
EFAttr *ap;
int n;
EFNode *keeping, *removing;
/* Sanity check: ignore if same node */
if (node1 == node2)
if (*node1ptr == *node2ptr)
return;
/* Keep the node with the greater number of entries, and merge */
/* the node with fewer entries into it. */
if ((*node1ptr)->efnode_num >= (*node2ptr)->efnode_num)
{
keeping = *node1ptr;
removing = *node2ptr;
}
else
{
keeping = *node2ptr;
removing = *node1ptr;
}
if (efWatchNodes)
{
if (HashLookOnly(&efWatchTable, (char *) node1->efnode_name->efnn_hier)
|| (node2->efnode_name
if (HashLookOnly(&efWatchTable, (char *) keeping->efnode_name->efnn_hier)
|| (removing->efnode_name
&& HashLookOnly(&efWatchTable,
(char *) node2->efnode_name->efnn_hier)))
(char *) removing->efnode_name->efnn_hier)))
{
printf("\ncombine: %s\n",
EFHNToStr(node1->efnode_name->efnn_hier));
EFHNToStr(keeping->efnode_name->efnn_hier));
printf(" with %s\n\n",
node2->efnode_name
? EFHNToStr(node2->efnode_name->efnn_hier)
removing->efnode_name
? EFHNToStr(removing->efnode_name->efnn_hier)
: "(unnamed)");
}
}
/* Sum capacitances, perimeters, areas */
node1->efnode_cap += node2->efnode_cap;
keeping->efnode_cap += removing->efnode_cap;
for (n = 0; n < efNumResistClasses; n++)
{
node1->efnode_pa[n].pa_area += node2->efnode_pa[n].pa_area;
node1->efnode_pa[n].pa_perim += node2->efnode_pa[n].pa_perim;
keeping->efnode_pa[n].pa_area += removing->efnode_pa[n].pa_area;
keeping->efnode_pa[n].pa_perim += removing->efnode_pa[n].pa_perim;
}
/* Make all EFNodeNames point to node1 */
if (node2->efnode_name)
/* Make all EFNodeNames point to "keeping" */
if (removing->efnode_name)
{
bool topport1, topport2;
bool topportk, topportr;
for (nn = node2->efnode_name; nn; nn = nn->efnn_next)
for (nn = removing->efnode_name; nn; nn = nn->efnn_next)
{
nnlast = nn;
nn->efnn_node = node1;
nn->efnn_node = keeping;
}
topport1 = (node1->efnode_flags & EF_TOP_PORT) ? TRUE : FALSE;
topport2 = (node2->efnode_flags & EF_TOP_PORT) ? TRUE : FALSE;
topportk = (keeping->efnode_flags & EF_TOP_PORT) ? TRUE : FALSE;
topportr = (removing->efnode_flags & EF_TOP_PORT) ? TRUE : FALSE;
/* Concatenate list of EFNodeNames, taking into account precedence */
if (!topport1 && (topport2 || EFHNBest(node2->efnode_name->efnn_hier,
node1->efnode_name->efnn_hier)))
if ((!keeping->efnode_name) || (!topportk && (topportr
|| EFHNBest(removing->efnode_name->efnn_hier,
keeping->efnode_name->efnn_hier))))
{
/*
* New official name is that of node2.
* New official name is that of "removing".
* The new list of names is:
* node2-names, node1-names
* removing-names, keeping-names
*/
nnlast->efnn_next = node1->efnode_name;
node1->efnode_name = node2->efnode_name;
nnlast->efnn_next = keeping->efnode_name;
keeping->efnode_name = removing->efnode_name;
/*
* Choose the new location only if node2's location is a valid one,
* i.e, node2 wasn't created before it was mentioned. This is mainly
* Choose the new location only if "removing"'s location is a valid one,
* i.e, "removing" wasn't created before it was mentioned. This is mainly
* to deal with new fets, resistors, and capacitors created by resistance
* extraction, which appear with their full hierarchical names in the
* .ext file for the root cell.
@ -1658,18 +1675,10 @@ efNodeMerge(node1, node2)
*
* Tim, 6/14/04
*/
if (node2->efnode_type > 0)
if (removing->efnode_type > 0)
{
node1->efnode_loc = node2->efnode_loc;
node1->efnode_type = node2->efnode_type;
if (node2->efnode_loc.r_ybot < node1->efnode_loc.r_ybot
|| (node2->efnode_loc.r_ybot == node1->efnode_loc.r_ybot
&& node2->efnode_loc.r_xbot < node1->efnode_loc.r_xbot))
{
// node1->efnode_loc = node2->efnode_loc;
// node1->efnode_type = node2->efnode_type;
}
keeping->efnode_loc = removing->efnode_loc;
keeping->efnode_type = removing->efnode_type;
}
}
else
@ -1677,52 +1686,59 @@ efNodeMerge(node1, node2)
/*
* Keep old official name.
* The new list of names is:
* node1-names[0], node2-names, node1-names[1-]
* keeping-names[0], removing-names, keeping-names[1-]
*/
nnlast->efnn_next = node1->efnode_name->efnn_next;
node1->efnode_name->efnn_next = node2->efnode_name;
nnlast->efnn_next = keeping->efnode_name->efnn_next;
keeping->efnode_name->efnn_next = removing->efnode_name;
}
}
/* Merge list counts */
keeping->efnode_num += removing->efnode_num;
/* Merge attribute lists */
if (ap = node2->efnode_attrs)
if (ap = removing->efnode_attrs)
{
while (ap->efa_next)
ap = ap->efa_next;
ap->efa_next = node1->efnode_attrs;
node1->efnode_attrs = ap;
node2->efnode_attrs = (EFAttr *) NULL; /* Sanity */
ap->efa_next = keeping->efnode_attrs;
keeping->efnode_attrs = ap;
removing->efnode_attrs = (EFAttr *) NULL; /* Sanity */
}
/* Unlink node2 from list for def */
node2->efnode_prev->efnhdr_next = node2->efnode_next;
node2->efnode_next->efnhdr_prev = node2->efnode_prev;
/* Unlink "removing" from list for def */
removing->efnode_prev->efnhdr_next = removing->efnode_next;
removing->efnode_next->efnhdr_prev = removing->efnode_prev;
/*
* Only if both nodes were EF_DEVTERM do we keep EF_DEVTERM set
* in the resultant node.
*/
if ((node2->efnode_flags & EF_DEVTERM) == 0)
node1->efnode_flags &= ~EF_DEVTERM;
if ((removing->efnode_flags & EF_DEVTERM) == 0)
keeping->efnode_flags &= ~EF_DEVTERM;
/*
* If node2 has the EF_PORT flag set, then copy the port
* If "removing" has the EF_PORT flag set, then copy the port
* record in the flags to node1.
*/
if (node2->efnode_flags & EF_PORT)
node1->efnode_flags |= EF_PORT;
if (node2->efnode_flags & EF_TOP_PORT)
node1->efnode_flags |= EF_TOP_PORT;
if (removing->efnode_flags & EF_PORT)
keeping->efnode_flags |= EF_PORT;
if (removing->efnode_flags & EF_TOP_PORT)
keeping->efnode_flags |= EF_TOP_PORT;
/*
* If node2 has the EF_SUBS_NODE flag set, then copy the port
* record in the flags to node1.
* If "removing" has the EF_SUBS_NODE flag set, then copy the port
* record in the flags to "keeping".
*/
if (node2->efnode_flags & EF_SUBS_NODE)
node1->efnode_flags |= EF_SUBS_NODE;
if (removing->efnode_flags & EF_SUBS_NODE)
keeping->efnode_flags |= EF_SUBS_NODE;
/* Get rid of node2 */
freeMagic((char *) node2);
/* Get rid of "removing" */
freeMagic((char *) removing);
/* Make sure that the active node is always node1 */
*node1ptr = keeping;
*node2ptr = (EFNode *)NULL; /* Sanity check */
}

View File

@ -62,6 +62,11 @@ int efAddNodes(HierContext *, bool);
int efAddConns(HierContext *, bool);
int efAddOneConn(HierContext *, char *, char *, Connection *, bool);
/* Flags passed to efFlatNode() */
#define FLATNODE_STDCELL 0x01
#define FLATNODE_DOWARN 0x02
/*
* ----------------------------------------------------------------------------
@ -127,7 +132,10 @@ EFFlatBuild(name, flags)
if (flags & EF_NOFLATSUBCKT)
efFlatNodesStdCell(&efFlatContext);
else
efFlatNodes(&efFlatContext, FALSE, TRUE);
{
int flags = FLATNODE_DOWARN; /* No FLATNODE_STDCELL flag */
efFlatNodes(&efFlatContext, (ClientData)flags);
}
efFlatKills(&efFlatContext);
if (!(flags & EF_NONAMEMERGE))
efFlatGlob();
@ -166,6 +174,7 @@ EFFlatBuildOneLevel(def, flags)
Use *use;
int efFlatNodesDeviceless(); /* Forward declaration */
int efFlatCapsDeviceless(); /* Forward declaration */
int flatnodeflags;
efFlatRootDef = def;
@ -195,7 +204,8 @@ EFFlatBuildOneLevel(def, flags)
efFlatRootUse.use_def = efFlatRootDef;
/* Record all nodes down the hierarchy from here */
efFlatNodes(&efFlatContext, (ClientData)TRUE, (ClientData)FALSE);
flatnodeflags = FLATNODE_STDCELL; /* No FLATDNODE_DOWARN flag */
efFlatNodes(&efFlatContext, (ClientData)flatnodeflags);
/* Expand all subcells that contain connectivity information but */
/* no active devices (including those in subcells). */
@ -292,10 +302,16 @@ EFFlatDone()
*/
int
efFlatNodes(hc, stdcell, doWarn)
efFlatNodes(hc, clientData)
HierContext *hc;
ClientData clientData;
{
(void) efHierSrUses(hc, efFlatNodes);
int flags = (int)clientData;
bool stdcell = (flags & FLATNODE_STDCELL) ? TRUE : FALSE;
bool doWarn = (flags & FLATNODE_DOWARN) ? TRUE : FALSE;
(void) efHierSrUses(hc, efFlatNodes, clientData);
/* Add all our own nodes to the table */
efAddNodes(hc, stdcell);
@ -466,6 +482,7 @@ efAddNodes(hc, stdcell)
newnode->efnode_client = (ClientData) NULL;
newnode->efnode_flags = node->efnode_flags;
newnode->efnode_type = node->efnode_type;
newnode->efnode_num = 1;
if (!stdcell)
bcopy((char *) node->efnode_pa, (char *) newnode->efnode_pa,
efNumResistClasses * sizeof (EFPerimArea));
@ -514,7 +531,7 @@ efAddNodes(hc, stdcell)
if (hierName != nn->efnn_hier)
EFHNFree(hierName, hc->hc_hierName, HN_CONCAT);
if (oldname->efnn_node != newnode)
efNodeMerge(oldname->efnn_node, newnode);
efNodeMerge(&oldname->efnn_node, &newnode);
newnode = oldname->efnn_node;
continue;
}
@ -638,7 +655,7 @@ efAddOneConn(hc, name1, name2, conn, doWarn)
return 0;
newnode = ((EFNodeName *) HashGetValue(he2))->efnn_node;
if (node != newnode)
efNodeMerge(node, newnode);
efNodeMerge(&node, &newnode);
}
return 0;
@ -744,7 +761,7 @@ efFlatGlob()
{
efFlatGlobError(nameGlob, nameFlat);
}
efNodeMerge(nodeFlat, nodeGlob);
efNodeMerge(&nodeFlat, &nodeGlob);
nameGlob->efnn_node = nodeFlat;
}
}

View File

@ -212,6 +212,7 @@ typedef struct efnode
EFCapValue efnode_cap; /* Total capacitance to ground for this node */
int efnode_type; /* Index into type table for node */
int efnode_num; /* Number of items in efnode_hdr list */
Rect efnode_loc; /* Location of a 1x1 rect contained in this
* node. This information is provided in the
* .ext file so it will be easy to map between

View File

@ -91,6 +91,10 @@ extHierSubstrate(ha, use, x, y)
/* define a substrate plane or substrate connections. */
if (glob_subsnode == NULL) return;
/* If the substrate has already been extracted for this use */
/* then there is no need to do it again. */
if (use->cu_flags & CU_SUB_EXTRACTED) return;
def = (CellDef *)ha->ha_parentUse->cu_def;
/* Register the name of the parent's substrate */
@ -107,7 +111,6 @@ extHierSubstrate(ha, use, x, y)
/* Make sure substrate labels are represented */
ExtLabelRegions(use->cu_def, ExtCurStyle->exts_nodeConn, &nodeList,
&TiPlaneRect);
ExtResetTiles(use->cu_def, extUnInit);
name2 = extNodeName(temp_subsnode);

View File

@ -94,6 +94,26 @@ void extSubtreeAdjustInit();
void extSubtreeOutputCoupling();
void extSubtreeHardSearch();
/*
* ----------------------------------------------------------------------------
*
* extClearUseFlags --
*
* Callback function to clear the CU_SUB_EXTRACTED flag from each child
* use of a CellDef.
*
* ----------------------------------------------------------------------------
*/
int
extClearUseFlags(use, clientData)
CellUse *use;
ClientData clientData;
{
use->cu_flags &= ~CU_SUB_EXTRACTED;
return 0;
}
/*
* ----------------------------------------------------------------------------
@ -146,6 +166,7 @@ extSubtree(parentUse, reg, f)
bool result;
int cuts, totcuts;
float pdone, plast;
SearchContext scx;
if ((ExtOptions & (EXT_DOCOUPLING|EXT_DOADJUST))
!= (EXT_DOCOUPLING|EXT_DOADJUST))
@ -232,8 +253,8 @@ extSubtree(parentUse, reg, f)
{
/* Make sure substrate connections have been handled */
/* even if there were no other interactions found. */
SearchContext scx;
ha.ha_clipArea = r;
scx.scx_trans = GeoIdentityTransform;
scx.scx_area = r;
scx.scx_use = ha.ha_parentUse;
@ -292,6 +313,9 @@ done:
/* Output connections and node adjustments */
extOutputConns(&ha.ha_connHash, f);
HashKill(&ha.ha_connHash);
/* Clear the CU_SUB_EXTRACTED flag from all children instances */
DBCellEnum(def, extClearUseFlags, (ClientData)NULL);
}
#ifdef exactinteractions
@ -800,6 +824,8 @@ extSubtreeFunc(scx, ha)
for (y = use->cu_ylo; y <= use->cu_yhi; y++)
extHierSubstrate(ha, use, x, y);
}
/* Mark substrate as having been extracted for this use. */
use->cu_flags |= CU_SUB_EXTRACTED;
/* Free the cumulative node list we extracted above */
if (ha->ha_cumFlat.et_nodes)

View File

@ -3,10 +3,15 @@ child.o: child.c ../utils/utils.h ../utils/magic.h ../utils/malloc.h
dqueue.o: dqueue.c ../utils/magic.h ../utils/dqueue.h ../utils/malloc.h
finddisp.o: finddisp.c ../utils/magic.h ../utils/utils.h
flock.o: flock.c ../utils/magic.h ../utils/hash.h ../utils/geometry.h \
<<<<<<< HEAD
../tiles/tile.h ../database/database.h ../bplane/bplane.h \
../bplane/bpOpaque.h ../utils/ihash.h ../bplane/bpEnum.h \
../utils/utils.h ../utils/geofast.h ../bplane/bplaneInt.h \
../windows/windows.h ../utils/malloc.h
=======
../tiles/tile.h ../database/database.h ../windows/windows.h \
../utils/malloc.h
>>>>>>> master
flsbuf.o: flsbuf.c
fraction.o: fraction.c ../utils/magic.h ../utils/geometry.h
geometry.o: geometry.c ../utils/magic.h ../utils/geometry.h \

View File

@ -220,14 +220,15 @@ hash(table, key)
char *key;
{
unsigned *up;
int i, j;
unsigned long i;
int j;
i = 0;
switch (table->ht_ptrKeys)
{
/* Add up the characters as though this were a number */
case HT_STRINGKEYS:
while (*key != 0) i = (i*10) + (*key++ - '0');
while (*key != 0) i = (*key++) + (i << 6) + (i << 16) - i;
break;
/* Map the key into another 32-bit value if necessary */