More corrections to extresist, which now appears to work if used
with ext2spice without the hierarchy option. More work needed to produce correct hierarchical output and to support extraction devices other than the old "fet" record.
This commit is contained in:
parent
0e966af926
commit
a4ea827d1e
|
|
@ -1771,7 +1771,8 @@ esHierVisit(hc, cdata)
|
||||||
|
|
||||||
if (def != topdef)
|
if (def != topdef)
|
||||||
{
|
{
|
||||||
if ((def->def_devs == NULL) && (HashGetNumEntries(&def->def_uses) == 0))
|
if ((HashGetNumEntries(&def->def_devs) == 0) &&
|
||||||
|
(HashGetNumEntries(&def->def_uses) == 0))
|
||||||
{
|
{
|
||||||
if (locDoSubckt == AUTO)
|
if (locDoSubckt == AUTO)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -591,23 +591,28 @@ efBuildDevice(def, class, type, r, argc, argv)
|
||||||
Rect *r; /* Coordinates of 1x1 rectangle entirely inside device */
|
Rect *r; /* Coordinates of 1x1 rectangle entirely inside device */
|
||||||
int argc; /* Size of argv */
|
int argc; /* Size of argv */
|
||||||
char *argv[]; /* Tokens for the rest of the dev line.
|
char *argv[]; /* Tokens for the rest of the dev line.
|
||||||
* The first depend on the type of device. The rest
|
* Starts with the last two position values, used to
|
||||||
* are taken in groups of 3, one for each terminal.
|
* hash the device record. The next arguments depend
|
||||||
* Each group of 3 consists of the node name to which
|
* on the type of device. The rest are taken in groups
|
||||||
* the terminal connects, the length of the terminal,
|
* of 3, one for each terminal. Each group of 3 consists
|
||||||
* and an attribute list (or the token 0).
|
* of the node name to which the terminal connects, the
|
||||||
|
* length of the terminal, and an attribute list (or the
|
||||||
|
* token 0).
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
int n, nterminals, pn;
|
int n, nterminals, pn;
|
||||||
|
HashEntry *he;
|
||||||
DevTerm *term;
|
DevTerm *term;
|
||||||
Dev *newdev, devtmp;
|
Dev *newdev, devtmp;
|
||||||
DevParam *newparm, *devp, *sparm;
|
DevParam *newparm, *devp, *sparm;
|
||||||
char ptype, *pptr, **av;
|
char ptype, *pptr, **av;
|
||||||
|
char devhash[24];
|
||||||
int argstart = 1; /* start of terminal list in argv[] */
|
int argstart = 1; /* start of terminal list in argv[] */
|
||||||
bool hasModel = strcmp(type, "None") ? TRUE : FALSE;
|
bool hasModel = strcmp(type, "None") ? TRUE : FALSE;
|
||||||
|
|
||||||
int area, perim; /* Total area, perimeter of primary type (i.e., channel) */
|
int area, perim; /* Total area, perimeter of primary type (i.e., channel) */
|
||||||
|
|
||||||
|
newdev = (Dev *)NULL;
|
||||||
devtmp.dev_subsnode = NULL;
|
devtmp.dev_subsnode = NULL;
|
||||||
devtmp.dev_cap = 0.0;
|
devtmp.dev_cap = 0.0;
|
||||||
devtmp.dev_res = 0.0;
|
devtmp.dev_res = 0.0;
|
||||||
|
|
@ -713,7 +718,6 @@ efBuildDevice(def, class, type, r, argc, argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for optional substrate node */
|
/* Check for optional substrate node */
|
||||||
|
|
||||||
switch (class)
|
switch (class)
|
||||||
{
|
{
|
||||||
case DEV_RES:
|
case DEV_RES:
|
||||||
|
|
@ -743,93 +747,149 @@ efBuildDevice(def, class, type, r, argc, argv)
|
||||||
|
|
||||||
nterminals = (argc - argstart) / 3;
|
nterminals = (argc - argstart) / 3;
|
||||||
|
|
||||||
newdev = (Dev *) mallocMagic((unsigned) DevSize(nterminals));
|
/* Determine if this device has been seen before */
|
||||||
|
|
||||||
|
sprintf(devhash, "%dx%d", r->r_xbot, r->r_ybot);
|
||||||
|
he = HashFind(&def->def_devs, devhash);
|
||||||
|
newdev = (Dev *)HashGetValue(he);
|
||||||
|
if (newdev)
|
||||||
|
{
|
||||||
|
/* Duplicate device. Duplicates will only appear in res.ext files
|
||||||
|
* where a device has nodes changed. Merge all properties of the
|
||||||
|
* original device with nodes from the new device. Keep the
|
||||||
|
* original device and discard the new one.
|
||||||
|
*
|
||||||
|
* Check that the device is actually the same device type and number
|
||||||
|
* of terminals. If not, throw an error and abandon the new device.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ((newdev->dev_class != class) ||
|
||||||
|
(strcmp(EFDevTypes[newdev->dev_type], type)))
|
||||||
|
{
|
||||||
|
TxError("Device %s %s at (%d, %d) overlaps incompatible device %s %s!\n",
|
||||||
|
extDevTable[class], type, r->r_xbot, r->r_ybot,
|
||||||
|
extDevTable[newdev->dev_class], EFDevTypes[newdev->dev_type]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (newdev->dev_nterm != nterminals)
|
||||||
|
{
|
||||||
|
TxError("Device %s %s at (%d, %d) overlaps device with incompatible"
|
||||||
|
" number of terminals (%d vs. %d)!\n",
|
||||||
|
extDevTable[class], type, r->r_xbot, r->r_ybot, nterminals,
|
||||||
|
newdev->dev_nterm);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newdev = (Dev *) mallocMagic((unsigned) DevSize(nterminals));
|
||||||
|
|
||||||
|
/* Add this dev to the hash table for def */
|
||||||
|
HashSetValue(he, (ClientData)newdev);
|
||||||
|
|
||||||
|
newdev->dev_cap = devtmp.dev_cap;
|
||||||
|
newdev->dev_res = devtmp.dev_res;
|
||||||
|
newdev->dev_area = devtmp.dev_area;
|
||||||
|
newdev->dev_perim = devtmp.dev_perim;
|
||||||
|
newdev->dev_length = devtmp.dev_length;
|
||||||
|
newdev->dev_width = devtmp.dev_width;
|
||||||
|
newdev->dev_params = devtmp.dev_params;
|
||||||
|
|
||||||
|
newdev->dev_nterm = nterminals;
|
||||||
|
newdev->dev_rect = *r;
|
||||||
|
newdev->dev_type = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, type);
|
||||||
|
newdev->dev_class = class;
|
||||||
|
|
||||||
|
switch (class)
|
||||||
|
{
|
||||||
|
case DEV_FET: /* old-style "fet" record */
|
||||||
|
newdev->dev_area = atoi(argv[0]);
|
||||||
|
newdev->dev_perim = atoi(argv[1]);
|
||||||
|
break;
|
||||||
|
case DEV_MOSFET: /* new-style "device mosfet" record */
|
||||||
|
case DEV_ASYMMETRIC:
|
||||||
|
case DEV_BJT:
|
||||||
|
newdev->dev_length = atoi(argv[0]);
|
||||||
|
newdev->dev_width = atoi(argv[1]);
|
||||||
|
break;
|
||||||
|
case DEV_RES:
|
||||||
|
if (hasModel && StrIsInt(argv[0]) && StrIsInt(argv[1]))
|
||||||
|
{
|
||||||
|
newdev->dev_length = atoi(argv[0]);
|
||||||
|
newdev->dev_width = atoi(argv[1]);
|
||||||
|
}
|
||||||
|
else if (StrIsNumeric(argv[0]))
|
||||||
|
{
|
||||||
|
newdev->dev_res = (float)atof(argv[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (hasModel)
|
||||||
|
{
|
||||||
|
efReadError("Error: expected L and W, got %s %s\n", argv[0],
|
||||||
|
argv[1]);
|
||||||
|
newdev->dev_length = 0;
|
||||||
|
newdev->dev_width = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
efReadError("Error: expected resistance value, got %s\n",
|
||||||
|
argv[0]);
|
||||||
|
newdev->dev_res = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DEV_CAP:
|
||||||
|
case DEV_CAPREV:
|
||||||
|
if (hasModel && StrIsInt(argv[0]) && StrIsInt(argv[1]))
|
||||||
|
{
|
||||||
|
newdev->dev_length = atoi(argv[0]);
|
||||||
|
newdev->dev_width = atoi(argv[1]);
|
||||||
|
}
|
||||||
|
else if (StrIsNumeric(argv[0]))
|
||||||
|
{
|
||||||
|
newdev->dev_cap = (float)atof(argv[0]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (hasModel)
|
||||||
|
{
|
||||||
|
efReadError("Error: expected L and W, got %s %s\n", argv[0],
|
||||||
|
argv[1]);
|
||||||
|
newdev->dev_length = 0;
|
||||||
|
newdev->dev_width = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
efReadError("Error: expected capacitance value, got %s\n",
|
||||||
|
argv[0]);
|
||||||
|
newdev->dev_cap = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
newdev->dev_subsnode = devtmp.dev_subsnode;
|
newdev->dev_subsnode = devtmp.dev_subsnode;
|
||||||
newdev->dev_cap = devtmp.dev_cap;
|
|
||||||
newdev->dev_res = devtmp.dev_res;
|
|
||||||
newdev->dev_area = devtmp.dev_area;
|
|
||||||
newdev->dev_perim = devtmp.dev_perim;
|
|
||||||
newdev->dev_length = devtmp.dev_length;
|
|
||||||
newdev->dev_width = devtmp.dev_width;
|
|
||||||
newdev->dev_params = devtmp.dev_params;
|
|
||||||
|
|
||||||
newdev->dev_nterm = nterminals;
|
|
||||||
newdev->dev_rect = *r;
|
|
||||||
newdev->dev_type = efBuildAddStr(EFDevTypes, &EFDevNumTypes, MAXDEVTYPES, type);
|
|
||||||
newdev->dev_class = class;
|
|
||||||
|
|
||||||
switch (class)
|
switch (class)
|
||||||
{
|
{
|
||||||
case DEV_FET: /* old-style "fet" record */
|
case DEV_FET: /* old-style "fet" record */
|
||||||
newdev->dev_area = atoi(argv[0]);
|
|
||||||
newdev->dev_perim = atoi(argv[1]);
|
|
||||||
newdev->dev_subsnode = efBuildDevNode(def, argv[2], TRUE);
|
newdev->dev_subsnode = efBuildDevNode(def, argv[2], TRUE);
|
||||||
break;
|
break;
|
||||||
case DEV_MOSFET: /* new-style "device mosfet" record */
|
case DEV_MOSFET: /* new-style "device mosfet" record */
|
||||||
case DEV_ASYMMETRIC:
|
case DEV_ASYMMETRIC:
|
||||||
case DEV_BJT:
|
case DEV_BJT:
|
||||||
newdev->dev_length = atoi(argv[0]);
|
|
||||||
newdev->dev_width = atoi(argv[1]);
|
|
||||||
|
|
||||||
/* "None" in the place of the substrate name means substrate is ignored */
|
/* "None" in the place of the substrate name means substrate is ignored */
|
||||||
if ((argstart == 3) && (strncmp(argv[2], "None", 4) != 0))
|
if ((argstart == 3) && (strncmp(argv[2], "None", 4) != 0))
|
||||||
newdev->dev_subsnode = efBuildDevNode(def, argv[2], TRUE);
|
newdev->dev_subsnode = efBuildDevNode(def, argv[2], TRUE);
|
||||||
break;
|
break;
|
||||||
case DEV_RES:
|
case DEV_RES:
|
||||||
if (hasModel && StrIsInt(argv[0]) && StrIsInt(argv[1]))
|
|
||||||
{
|
|
||||||
newdev->dev_length = atoi(argv[0]);
|
|
||||||
newdev->dev_width = atoi(argv[1]);
|
|
||||||
}
|
|
||||||
else if (StrIsNumeric(argv[0]))
|
|
||||||
{
|
|
||||||
newdev->dev_res = (float)atof(argv[0]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (hasModel)
|
|
||||||
{
|
|
||||||
efReadError("Error: expected L and W, got %s %s\n", argv[0],
|
|
||||||
argv[1]);
|
|
||||||
newdev->dev_length = 0;
|
|
||||||
newdev->dev_width = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
efReadError("Error: expected resistance value, got %s\n", argv[0]);
|
|
||||||
newdev->dev_res = 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((argstart == 3) && (strncmp(argv[2], "None", 4) != 0))
|
if ((argstart == 3) && (strncmp(argv[2], "None", 4) != 0))
|
||||||
newdev->dev_subsnode = efBuildDevNode(def, argv[2], TRUE);
|
newdev->dev_subsnode = efBuildDevNode(def, argv[2], TRUE);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case DEV_CAP:
|
case DEV_CAP:
|
||||||
case DEV_CAPREV:
|
case DEV_CAPREV:
|
||||||
if (hasModel && StrIsInt(argv[0]) && StrIsInt(argv[1]))
|
|
||||||
{
|
|
||||||
newdev->dev_length = atoi(argv[0]);
|
|
||||||
newdev->dev_width = atoi(argv[1]);
|
|
||||||
}
|
|
||||||
else if (StrIsNumeric(argv[0]))
|
|
||||||
{
|
|
||||||
newdev->dev_cap = (float)atof(argv[0]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (hasModel)
|
|
||||||
{
|
|
||||||
efReadError("Error: expected L and W, got %s %s\n", argv[0],
|
|
||||||
argv[1]);
|
|
||||||
newdev->dev_length = 0;
|
|
||||||
newdev->dev_width = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
efReadError("Error: expected capacitance value, got %s\n", argv[0]);
|
|
||||||
newdev->dev_cap = 0.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((argstart == 3) && (strncmp(argv[2], "None", 4) != 0))
|
if ((argstart == 3) && (strncmp(argv[2], "None", 4) != 0))
|
||||||
newdev->dev_subsnode = efBuildDevNode(def, argv[2], TRUE);
|
newdev->dev_subsnode = efBuildDevNode(def, argv[2], TRUE);
|
||||||
|
|
||||||
|
|
@ -859,10 +919,6 @@ efBuildDevice(def, class, type, r, argc, argv)
|
||||||
#undef TERM_PERIM
|
#undef TERM_PERIM
|
||||||
#undef TERM_ATTRS
|
#undef TERM_ATTRS
|
||||||
|
|
||||||
/* Add this dev to the list for def */
|
|
||||||
newdev->dev_next = def->def_devs;
|
|
||||||
def->def_devs = newdev;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1696,6 +1752,36 @@ efFreeUseTable(table)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*
|
||||||
|
* efFreeDevTable --
|
||||||
|
*
|
||||||
|
* Free the device records allocated for each entry in the device hash table,
|
||||||
|
* the memory allocated by the device, leaving the hash entry null.
|
||||||
|
*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
efFreeDevTable(table)
|
||||||
|
HashTable *table;
|
||||||
|
{
|
||||||
|
Dev *dev;
|
||||||
|
HashSearch hs;
|
||||||
|
HashEntry *he;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
HashStartSearch(&hs);
|
||||||
|
while (he = HashNext(table, &hs))
|
||||||
|
{
|
||||||
|
dev = (Dev *)HashGetValue(he);
|
||||||
|
for (n = 0; n < (int)dev->dev_nterm; n++)
|
||||||
|
if (dev->dev_terms[n].dterm_attrs)
|
||||||
|
freeMagic((char *) dev->dev_terms[n].dterm_attrs);
|
||||||
|
freeMagic((char *) dev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -103,7 +103,6 @@ EFDone()
|
||||||
Kill *kill;
|
Kill *kill;
|
||||||
Def *def;
|
Def *def;
|
||||||
Use *use;
|
Use *use;
|
||||||
Dev *dev;
|
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
HashStartSearch(&hs);
|
HashStartSearch(&hs);
|
||||||
|
|
@ -114,22 +113,18 @@ EFDone()
|
||||||
efFreeNodeTable(&def->def_nodes);
|
efFreeNodeTable(&def->def_nodes);
|
||||||
efFreeNodeList(&def->def_firstn);
|
efFreeNodeList(&def->def_firstn);
|
||||||
efFreeUseTable(&def->def_uses);
|
efFreeUseTable(&def->def_uses);
|
||||||
|
efFreeDevTable(&def->def_devs);
|
||||||
HashKill(&def->def_nodes);
|
HashKill(&def->def_nodes);
|
||||||
HashKill(&def->def_dists);
|
HashKill(&def->def_dists);
|
||||||
HashKill(&def->def_uses);
|
HashKill(&def->def_uses);
|
||||||
|
HashKill(&def->def_devs);
|
||||||
for (conn = def->def_conns; conn; conn = conn->conn_next)
|
for (conn = def->def_conns; conn; conn = conn->conn_next)
|
||||||
efFreeConn(conn);
|
efFreeConn(conn);
|
||||||
for (conn = def->def_caps; conn; conn = conn->conn_next)
|
for (conn = def->def_caps; conn; conn = conn->conn_next)
|
||||||
efFreeConn(conn);
|
efFreeConn(conn);
|
||||||
for (conn = def->def_resistors; conn; conn = conn->conn_next)
|
for (conn = def->def_resistors; conn; conn = conn->conn_next)
|
||||||
efFreeConn(conn);
|
efFreeConn(conn);
|
||||||
for (dev = def->def_devs; dev; dev = dev->dev_next)
|
|
||||||
{
|
|
||||||
for (n = 0; n < (int)dev->dev_nterm; n++)
|
|
||||||
if (dev->dev_terms[n].dterm_attrs)
|
|
||||||
freeMagic((char *) dev->dev_terms[n].dterm_attrs);
|
|
||||||
freeMagic((char *) dev);
|
|
||||||
}
|
|
||||||
for (kill = def->def_kills; kill; kill = kill->kill_next)
|
for (kill = def->def_kills; kill; kill = kill->kill_next)
|
||||||
{
|
{
|
||||||
freeMagic(kill->kill_name);
|
freeMagic(kill->kill_name);
|
||||||
|
|
@ -151,13 +146,6 @@ EFDone()
|
||||||
EFTech = (char *)NULL;
|
EFTech = (char *)NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Free up all HierNames that were stored in efFreeHashTable */
|
|
||||||
/*
|
|
||||||
HashStartSearch(&hs);
|
|
||||||
while (he = HashNext(&efFreeHashTable, &hs))
|
|
||||||
freeMagic(he->h_key.h_ptr);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Free up the parameter name tables for each device */
|
/* Free up the parameter name tables for each device */
|
||||||
|
|
||||||
HashStartSearch(&hs);
|
HashStartSearch(&hs);
|
||||||
|
|
@ -244,7 +232,6 @@ efDefNew(name)
|
||||||
newdef->def_conns = (Connection *) NULL;
|
newdef->def_conns = (Connection *) NULL;
|
||||||
newdef->def_caps = (Connection *) NULL;
|
newdef->def_caps = (Connection *) NULL;
|
||||||
newdef->def_resistors = (Connection *) NULL;
|
newdef->def_resistors = (Connection *) NULL;
|
||||||
newdef->def_devs = (Dev *) NULL;
|
|
||||||
newdef->def_kills = (Kill *) NULL;
|
newdef->def_kills = (Kill *) NULL;
|
||||||
|
|
||||||
/* Initialize circular list of nodes */
|
/* Initialize circular list of nodes */
|
||||||
|
|
@ -257,6 +244,9 @@ efDefNew(name)
|
||||||
/* Initialize hash table of node names */
|
/* Initialize hash table of node names */
|
||||||
HashInit(&newdef->def_nodes, INITNODESIZE, HT_STRINGKEYS);
|
HashInit(&newdef->def_nodes, INITNODESIZE, HT_STRINGKEYS);
|
||||||
|
|
||||||
|
/* Initialize hash table of devices */
|
||||||
|
HashInit(&newdef->def_devs, INITNODESIZE, HT_STRINGKEYS);
|
||||||
|
|
||||||
/* Initialize hash table of distances */
|
/* Initialize hash table of distances */
|
||||||
HashInitClient(&newdef->def_dists, INITNODESIZE, HT_CLIENTKEYS,
|
HashInitClient(&newdef->def_dists, INITNODESIZE, HT_CLIENTKEYS,
|
||||||
efHNDistCompare, efHNDistCopy, efHNDistHash, efHNDistKill);
|
efHNDistCompare, efHNDistCopy, efHNDistHash, efHNDistKill);
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,7 @@ EFFlatBuildOneLevel(def, flags)
|
||||||
if (usecount > 0)
|
if (usecount > 0)
|
||||||
efHierSrUses(&efFlatContext, efFlatNodesDeviceless, (ClientData)&usecount);
|
efHierSrUses(&efFlatContext, efFlatNodesDeviceless, (ClientData)&usecount);
|
||||||
|
|
||||||
if ((usecount == 0) && (efFlatRootUse.use_def->def_devs == NULL))
|
if ((usecount == 0) && (HashGetNumEntries(&efFlatRootUse.use_def->def_devs) == 0))
|
||||||
efFlatRootUse.use_def->def_flags |= DEF_NODEVICES;
|
efFlatRootUse.use_def->def_flags |= DEF_NODEVICES;
|
||||||
|
|
||||||
/* Record all local nodes */
|
/* Record all local nodes */
|
||||||
|
|
@ -372,7 +372,7 @@ efFlatNodesDeviceless(hc, cdata)
|
||||||
if (newcount > 0)
|
if (newcount > 0)
|
||||||
efHierSrUses(hc, efFlatNodesDeviceless, (ClientData)&newcount);
|
efHierSrUses(hc, efFlatNodesDeviceless, (ClientData)&newcount);
|
||||||
|
|
||||||
if ((hc->hc_use->use_def->def_devs == NULL) && (newcount == 0))
|
if ((HashGetNumEntries(&hc->hc_use->use_def->def_devs) == 0) && (newcount == 0))
|
||||||
{
|
{
|
||||||
/* Add all our own nodes to the table */
|
/* Add all our own nodes to the table */
|
||||||
efAddNodes(hc, TRUE);
|
efAddNodes(hc, TRUE);
|
||||||
|
|
|
||||||
|
|
@ -471,6 +471,8 @@ efHierVisitDevs(hc, ca)
|
||||||
{
|
{
|
||||||
Def *def = hc->hc_use->use_def;
|
Def *def = hc->hc_use->use_def;
|
||||||
Dev *dev;
|
Dev *dev;
|
||||||
|
HashSearch hs;
|
||||||
|
HashEntry *he;
|
||||||
float scale;
|
float scale;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -482,8 +484,10 @@ efHierVisitDevs(hc, ca)
|
||||||
scale = (efScaleChanged && def->def_scale != 1.0) ? def->def_scale : 1.0;
|
scale = (efScaleChanged && def->def_scale != 1.0) ? def->def_scale : 1.0;
|
||||||
|
|
||||||
/* Visit all devices */
|
/* Visit all devices */
|
||||||
for (dev = def->def_devs; dev; dev = dev->dev_next)
|
HashStartSearch(&hs);
|
||||||
|
while (he = HashNext(&def->def_devs, &hs))
|
||||||
{
|
{
|
||||||
|
dev = (Dev *)HashGetValue(he);
|
||||||
if (efHierDevKilled(hc, dev, hc->hc_hierName))
|
if (efHierDevKilled(hc, dev, hc->hc_hierName))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,7 @@ typedef struct def
|
||||||
HashTable def_nodes; /* Map names into EFNodeNames */
|
HashTable def_nodes; /* Map names into EFNodeNames */
|
||||||
HashTable def_dists; /* Map pairs of names into Distances */
|
HashTable def_dists; /* Map pairs of names into Distances */
|
||||||
HashTable def_uses; /* Hash children of this def by name */
|
HashTable def_uses; /* Hash children of this def by name */
|
||||||
|
HashTable def_devs; /* Devices (hash by position) */
|
||||||
EFNode def_firstn; /* Head of circular list of nodes */
|
EFNode def_firstn; /* Head of circular list of nodes */
|
||||||
|
|
||||||
/* The following are all NULL-terminated lists */
|
/* The following are all NULL-terminated lists */
|
||||||
|
|
@ -163,7 +164,6 @@ typedef struct def
|
||||||
Connection *def_conns; /* Hierarchical connections/adjustments */
|
Connection *def_conns; /* Hierarchical connections/adjustments */
|
||||||
Connection *def_caps; /* Two-terminal capacitors */
|
Connection *def_caps; /* Two-terminal capacitors */
|
||||||
Connection *def_resistors; /* Two-terminal resistors */
|
Connection *def_resistors; /* Two-terminal resistors */
|
||||||
Dev *def_devs; /* Devices */
|
|
||||||
Kill *def_kills; /* Used to modify hierarchical structure
|
Kill *def_kills; /* Used to modify hierarchical structure
|
||||||
* using information present only in the
|
* using information present only in the
|
||||||
* parent, e.g, to kill an old node and
|
* parent, e.g, to kill an old node and
|
||||||
|
|
|
||||||
|
|
@ -356,8 +356,7 @@ readfile:
|
||||||
r.r_xtop = atoi(argv[5]);
|
r.r_xtop = atoi(argv[5]);
|
||||||
r.r_ytop = atoi(argv[6]);
|
r.r_ytop = atoi(argv[6]);
|
||||||
|
|
||||||
if (efBuildDevice(def, (char)n, argv[2], &r, argc - 7,
|
if (efBuildDevice(def, (char)n, argv[2], &r, argc - 7, &argv[7]) != 0)
|
||||||
&argv[7]) != 0)
|
|
||||||
{
|
{
|
||||||
efReadError("Incomplete terminal description for device\n");
|
efReadError("Incomplete terminal description for device\n");
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -300,6 +300,8 @@ efVisitDevs(hc, ca)
|
||||||
Dev *dev;
|
Dev *dev;
|
||||||
float scale;
|
float scale;
|
||||||
Transform t;
|
Transform t;
|
||||||
|
HashSearch hs;
|
||||||
|
HashEntry *he;
|
||||||
|
|
||||||
if (def->def_flags & DEF_SUBCIRCUIT) return 0;
|
if (def->def_flags & DEF_SUBCIRCUIT) return 0;
|
||||||
|
|
||||||
|
|
@ -311,15 +313,17 @@ efVisitDevs(hc, ca)
|
||||||
t = hc->hc_trans;
|
t = hc->hc_trans;
|
||||||
|
|
||||||
/* Visit our own devices */
|
/* Visit our own devices */
|
||||||
for (dev = def->def_devs; dev; dev = dev->dev_next)
|
|
||||||
|
HashStartSearch(&hs);
|
||||||
|
while (he = HashNext(&def->def_devs, &hs))
|
||||||
{
|
{
|
||||||
|
dev = (Dev *)HashGetValue(he);
|
||||||
if (efDevKilled(dev, hc->hc_hierName))
|
if (efDevKilled(dev, hc->hc_hierName))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((*ca->ca_proc)(dev, hc->hc_hierName, scale, &t, ca->ca_cdata))
|
if ((*ca->ca_proc)(dev, hc->hc_hierName, scale, &t, ca->ca_cdata))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
||||||
ResSimNode *ResInitializeNode();
|
ResSimNode *ResInitializeNode();
|
||||||
|
|
||||||
ResSimNode *ResOriginalNodes; /*Linked List of Nodes */
|
ResSimNode *ResOriginalNodes; /*Linked List of Nodes */
|
||||||
static float lambda=1.0; /* Scale factor */
|
static float resscale=1.0; /* Scale factor */
|
||||||
char RDEV_NOATTR[1]={'0'};
|
char RDEV_NOATTR[1]={'0'};
|
||||||
ResFixPoint *ResFixList;
|
ResFixPoint *ResFixList;
|
||||||
|
|
||||||
|
|
@ -146,12 +146,8 @@ ResReadSim(simfile,fetproc,capproc,resproc,attrproc,mergeproc)
|
||||||
case '|':
|
case '|':
|
||||||
if (strcmp(line[NODEUNITS],"units:") == 0)
|
if (strcmp(line[NODEUNITS],"units:") == 0)
|
||||||
{
|
{
|
||||||
lambda = (float)atof(line[NODELAMBDA]);
|
resscale = (float)atof(line[NODELAMBDA]);
|
||||||
if (lambda == 0.0) lambda = 1.0;
|
if (resscale == 0.0) resscale = 1.0;
|
||||||
/* NOTE: units is derived from EFScale */
|
|
||||||
/* which needs a factor of 100 conversion */
|
|
||||||
/* to database units. */
|
|
||||||
lambda *= 100.0;
|
|
||||||
}
|
}
|
||||||
result=0;
|
result=0;
|
||||||
break;
|
break;
|
||||||
|
|
@ -231,6 +227,14 @@ ResReadNode(nodefile)
|
||||||
HashEntry *entry;
|
HashEntry *entry;
|
||||||
ResSimNode *node;
|
ResSimNode *node;
|
||||||
char *cp;
|
char *cp;
|
||||||
|
float lambda;
|
||||||
|
|
||||||
|
/* NOTE: Units from the .sim file or the .nodes file are in centimicrons
|
||||||
|
* when multiplied by resscale (units from the .sim file 1st line).
|
||||||
|
* multiply resscale by the extract scale (exts_unitsPerLambda) used to
|
||||||
|
* generate .ext dimensions originally, to get back to database units.
|
||||||
|
*/
|
||||||
|
lambda = resscale * (float)ExtCurStyle->exts_unitsPerLambda;
|
||||||
|
|
||||||
fp = PaOpen(nodefile,"r",".nodes",".", (char *) NULL, (char **) NULL);
|
fp = PaOpen(nodefile,"r",".nodes",".", (char *) NULL, (char **) NULL);
|
||||||
if (fp == NULL)
|
if (fp == NULL)
|
||||||
|
|
@ -243,17 +247,13 @@ ResReadNode(nodefile)
|
||||||
entry = HashFind(&ResNodeTable,line[NODENODENAME]);
|
entry = HashFind(&ResNodeTable,line[NODENODENAME]);
|
||||||
node = ResInitializeNode(entry);
|
node = ResInitializeNode(entry);
|
||||||
|
|
||||||
/* NOTE: Fixed 10/15/2019. No scalefactor is passed to EFNodeVisit()
|
node->location.p_x = (int)((float)atof(line[NODENODEX]) / lambda);
|
||||||
* so there is no scaling by lambda. Values are in centimicrons always,
|
node->location.p_y = (int)((float)atof(line[NODENODEY]) / lambda);
|
||||||
* and factor of 100 is required to get database units.
|
|
||||||
*/
|
|
||||||
node->location.p_x = (int)((float)atof(line[NODENODEX]) / 100.0);
|
|
||||||
node->location.p_y = (int)((float)atof(line[NODENODEY]) / 100.0);
|
|
||||||
#ifdef ARIEL
|
#ifdef ARIEL
|
||||||
node->rs_bbox.r_xbot = (int)((float)atof(line[NODE_BBOX_LL_X]) / 100.0);
|
node->rs_bbox.r_xbot = (int)((float)atof(line[NODE_BBOX_LL_X]) / lambda);
|
||||||
node->rs_bbox.r_ybot = (int)((float)atof(line[NODE_BBOX_LL_Y]) / 100.0);
|
node->rs_bbox.r_ybot = (int)((float)atof(line[NODE_BBOX_LL_Y]) / lambda);
|
||||||
node->rs_bbox.r_xtop = (int)((float)atof(line[NODE_BBOX_UR_X]) / 100.0);
|
node->rs_bbox.r_xtop = (int)((float)atof(line[NODE_BBOX_UR_X]) / lambda);
|
||||||
node->rs_bbox.r_ytop = (int)((float)atof(line[NODE_BBOX_UR_Y]) / 100.0);
|
node->rs_bbox.r_ytop = (int)((float)atof(line[NODE_BBOX_UR_Y]) / lambda);
|
||||||
#endif
|
#endif
|
||||||
if (cp = strchr(line[NODETYPE], ';')) *cp = '\0';
|
if (cp = strchr(line[NODETYPE], ';')) *cp = '\0';
|
||||||
node->type = DBTechNameType(line[NODETYPE]);
|
node->type = DBTechNameType(line[NODETYPE]);
|
||||||
|
|
@ -340,6 +340,7 @@ ResSimDevice(line,rpersquare,ttype)
|
||||||
int rvalue,i,j,k;
|
int rvalue,i,j,k;
|
||||||
char *newattr,tmpattr[MAXTOKEN];
|
char *newattr,tmpattr[MAXTOKEN];
|
||||||
static int nowarning = TRUE;
|
static int nowarning = TRUE;
|
||||||
|
float lambda;
|
||||||
|
|
||||||
device = (RDev *) mallocMagic((unsigned) (sizeof(RDev)));
|
device = (RDev *) mallocMagic((unsigned) (sizeof(RDev)));
|
||||||
if ((line[RDEV_WIDTH][0] == '\0') || (line[RDEV_LENGTH][0] == '\0'))
|
if ((line[RDEV_WIDTH][0] == '\0') || (line[RDEV_LENGTH][0] == '\0'))
|
||||||
|
|
@ -360,8 +361,11 @@ ResSimDevice(line,rpersquare,ttype)
|
||||||
device->tnumber = ++Maxtnumber;
|
device->tnumber = ++Maxtnumber;
|
||||||
device->status = FALSE;
|
device->status = FALSE;
|
||||||
device->nextDev = ResRDevList;
|
device->nextDev = ResRDevList;
|
||||||
device->location.p_x = atoi(line[RDEV_DEVX]);
|
|
||||||
device->location.p_y = atoi(line[RDEV_DEVY]);
|
lambda = resscale * (float)ExtCurStyle->exts_unitsPerLambda;
|
||||||
|
device->location.p_x = (int)((float)atof(line[RDEV_DEVX]) / lambda);
|
||||||
|
device->location.p_y = (int)((float)atof(line[RDEV_DEVY]) / lambda);
|
||||||
|
|
||||||
device->rs_gattr=RDEV_NOATTR;
|
device->rs_gattr=RDEV_NOATTR;
|
||||||
device->rs_sattr=RDEV_NOATTR;
|
device->rs_sattr=RDEV_NOATTR;
|
||||||
device->rs_dattr=RDEV_NOATTR;
|
device->rs_dattr=RDEV_NOATTR;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue