Additional tweaks to the handling of the three new options for
determining what does and doesn't get into the R-C extraction output. Added option "debug" and moved all excess diagnostic information to be gated by this flag. Corrected an issue in the standard extraction in which the substrate is always output with zero lumped resistance, preventing it from being checked by "extresist" for inclusion or exclusion in the .res.ext output. Reinstated the computation of minimum resistance transistor but excluded other devices. Added more sane handling of exceptional conditions like loops. The result is a more consistent check of nets in the design. However, I still need to recheck the "rg_maxres" calculation because it appears to be too low.
This commit is contained in:
parent
c22031724a
commit
03610f6d40
|
|
@ -61,7 +61,9 @@ information.
|
|||
<DT> <B>lumped</B> [<B>on</B>|<B>off</B>]
|
||||
<DD> Turn on/off writing of updated lumped resistances.
|
||||
<DT> <B>silent</B> [<B>on</B>|<B>off</B>]
|
||||
<DD> Turn off/on printing of net statistics.
|
||||
<DD> Turn off/on printing of nets being processed.
|
||||
<DT> <B>debug</B> [<B>on</B>|<B>off</B>]
|
||||
<DD> Turn off/on additional diagnostic information.
|
||||
<DT> <B>skip</B> <I>mask</I>
|
||||
<DD> Don't extract types indicated in the comma-separated list <I>mask</I>
|
||||
<DT> <B>ignore</B> [<I>netname</I>|<B>none</B>]
|
||||
|
|
|
|||
|
|
@ -731,7 +731,8 @@ extOutputNodes(nodeList, outFile)
|
|||
/* Check if this node is the substrate */
|
||||
if (reg == glob_subsnode)
|
||||
{
|
||||
fprintf(outFile, "substrate \"%s\" 0 0", text);
|
||||
intR = (reg->nreg_resist + rround) / ExtCurStyle->exts_resistScale;
|
||||
fprintf(outFile, "substrate \"%s\" %d 0", text, intR);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -387,10 +387,13 @@ ResReadDrivePoint(CellDef *def,
|
|||
node->drivepoints = newdriver;
|
||||
node->status |= FORCE | DRIVELOC;
|
||||
|
||||
/* XXX Diagnostic XXX */
|
||||
TxPrintf("Added driver at %d %d %d %d\n",
|
||||
if (ResOptionsFlags & ResOpt_Debug)
|
||||
{
|
||||
/* Diagnostic */
|
||||
TxPrintf("Added driver at %d %d %d %d\n",
|
||||
newdriver->rc_rect.r_xbot, newdriver->rc_rect.r_ybot,
|
||||
newdriver->rc_rect.r_xtop, newdriver->rc_rect.r_ytop);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -607,10 +610,13 @@ ResReadConnectPoint(CellDef *def,
|
|||
node->sinkpoints = newsink;
|
||||
node->status |= FORCE | DRIVELOC;
|
||||
|
||||
/* XXX Diagnostic XXX */
|
||||
TxPrintf("Added sink at %d %d %d %d\n", newsink->rc_rect.r_xbot,
|
||||
if (ResOptionsFlags & ResOpt_Debug)
|
||||
{
|
||||
/* Diagnostic */
|
||||
TxPrintf("Added sink at %d %d %d %d\n", newsink->rc_rect.r_xbot,
|
||||
newsink->rc_rect.r_ybot, newsink->rc_rect.r_xtop,
|
||||
newsink->rc_rect.r_ytop);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -662,10 +668,13 @@ ResReadPort(int argc,
|
|||
node->drivepoints = newdriver;
|
||||
node->status |= FORCE | DRIVELOC | PORTNODE;
|
||||
|
||||
/* XXX Diagnostic XXX */
|
||||
TxPrintf("Added port at %d %d %d %d\n",
|
||||
if (ResOptionsFlags & ResOpt_Debug)
|
||||
{
|
||||
/* Diagnostic */
|
||||
TxPrintf("Added port at %d %d %d %d\n",
|
||||
newdriver->rc_rect.r_xbot, newdriver->rc_rect.r_ybot,
|
||||
newdriver->rc_rect.r_xtop, newdriver->rc_rect.r_ytop);
|
||||
}
|
||||
|
||||
if (node->type == -1)
|
||||
{
|
||||
|
|
@ -728,7 +737,7 @@ ResReadDevice(int argc,
|
|||
char *argv[])
|
||||
{
|
||||
RDev *device;
|
||||
int rvalue, i, j, k;
|
||||
int rvalue, i, j, k, w, l;
|
||||
ExtDevice *devptr;
|
||||
TileType ttype;
|
||||
HashEntry *entry;
|
||||
|
|
@ -792,6 +801,8 @@ ResReadDevice(int argc,
|
|||
entry = HashFind(&ResNodeTable, argv[i]);
|
||||
device->gate = (ResExtNode *)HashGetValue(entry);
|
||||
device->rs_gattr = StrDup((char **)NULL, argv[i + 2]);
|
||||
l = atoi(argv[i + 1]);
|
||||
w = 0;
|
||||
ResNodeAddDevice(device->gate, device, GATE);
|
||||
i += 3;
|
||||
|
||||
|
|
@ -800,6 +811,7 @@ ResReadDevice(int argc,
|
|||
entry = HashFind(&ResNodeTable, argv[i]);
|
||||
device->source = (ResExtNode *)HashGetValue(entry);
|
||||
device->rs_sattr = StrDup((char **)NULL, argv[i + 2]);
|
||||
w = atoi(argv[i + 1]);
|
||||
ResNodeAddDevice(device->source, device, SOURCE);
|
||||
i += 3;
|
||||
}
|
||||
|
|
@ -809,6 +821,7 @@ ResReadDevice(int argc,
|
|||
entry = HashFind(&ResNodeTable, argv[i]);
|
||||
device->drain = (ResExtNode *)HashGetValue(entry);
|
||||
device->rs_dattr = StrDup((char **)NULL, argv[i + 2]);
|
||||
w = MAX(w, atoi(argv[i + 1]));
|
||||
ResNodeAddDevice(device->drain, device, DRAIN);
|
||||
i += 3;
|
||||
}
|
||||
|
|
@ -819,6 +832,7 @@ ResReadDevice(int argc,
|
|||
}
|
||||
|
||||
device->rs_ttype = extGetDevType(devptr->exts_deviceName);
|
||||
device->rs_wl = (l == 0) ? 0.0 : (float)w / (float)l;
|
||||
|
||||
ResRDevList = device;
|
||||
device->layout = NULL;
|
||||
|
|
@ -842,7 +856,7 @@ ResReadFET(int argc,
|
|||
char *argv[])
|
||||
{
|
||||
RDev *device;
|
||||
int rvalue, i, j, k;
|
||||
int rvalue, i, j, k, w, l;
|
||||
ExtDevice *devptr;
|
||||
TileType ttype;
|
||||
HashEntry *entry;
|
||||
|
|
@ -892,6 +906,11 @@ ResReadFET(int argc,
|
|||
device->rs_sattr = StrDup((char **)NULL, argv[FET_SOURCE_ATTR]);
|
||||
device->rs_dattr = StrDup((char **)NULL, argv[FET_DRAIN_ATTR]);
|
||||
|
||||
l = atoi(argv[FET_GATE_ATTR - 1]);
|
||||
w = atoi(argv[FET_SOURCE_ATTR - 1]);
|
||||
w = MAX(w, atoi(argv[FET_DRAIN_ATTR - 1]));
|
||||
device->rs_wl = (l == 0) ? 0.0 : (float)w / (float)l;
|
||||
|
||||
ResRDevList = device;
|
||||
device->layout = NULL;
|
||||
return 0;
|
||||
|
|
|
|||
250
resis/ResRex.c
250
resis/ResRex.c
|
|
@ -44,15 +44,15 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#define P_TO_Z 1e9
|
||||
|
||||
/* Table of nodes to ignore (manually specified) */
|
||||
|
||||
HashTable ResIgnoreTable; /* Hash table of nodes to ignore */
|
||||
|
||||
/* Table of nodes to include (manually specified) */
|
||||
|
||||
HashTable ResIncludeTable; /* Hash table of nodes to include */
|
||||
|
||||
/* Table of cells that have been processed */
|
||||
/* Table of nodes to force extraction of (manually specified) */
|
||||
HashTable ResForceTable; /* Hash table of nodes to include */
|
||||
|
||||
/* Table of cells that have been processed */
|
||||
HashTable ResProcessedTable;
|
||||
|
||||
/* ResExtNode is a node read in from a .ext file */
|
||||
|
|
@ -226,6 +226,7 @@ ResInit()
|
|||
resisdata->frequency = 10e6; /* 10 MHz default */
|
||||
|
||||
HashInit(&ResIgnoreTable, INITFLATSIZE, HT_STRINGKEYS);
|
||||
HashInit(&ResForceTable, INITFLATSIZE, HT_STRINGKEYS);
|
||||
HashInit(&ResIncludeTable, INITFLATSIZE, HT_STRINGKEYS);
|
||||
init = 0;
|
||||
}
|
||||
|
|
@ -295,7 +296,9 @@ CmdExtResis(win, cmd)
|
|||
"extout [on/off] turn on/off writing of .res.ext file",
|
||||
"lumped [on/off] turn on/off writing of updated lumped resistances",
|
||||
"silent [on/off] turn on/off printing of net statistics",
|
||||
"debug [on/off] turn on/off printing of detailed information",
|
||||
"skip mask don't extract these types",
|
||||
"force names force these nets to be extracted",
|
||||
"ignore names don't extract these nets",
|
||||
"include names extract only these nets",
|
||||
"box type extract the signal under the box on layer type",
|
||||
|
|
@ -311,10 +314,10 @@ CmdExtResis(win, cmd)
|
|||
typedef enum {
|
||||
RES_BAD=-2, RES_AMBIG, RES_ALL,
|
||||
RES_THRESH, RES_MINRES, RES_MINDELAY, RES_TOL,
|
||||
RES_SIMP, RES_EXTOUT, RES_LUMPED, RES_SILENT,
|
||||
RES_SKIP, RES_IGNORE, RES_INCLUDE, RES_BOX, RES_CELL,
|
||||
RES_BLACKBOX, RES_FASTHENRY, RES_GEOMETRY, RES_STATS,
|
||||
RES_HELP, RES_RUN
|
||||
RES_SIMP, RES_EXTOUT, RES_LUMPED, RES_SILENT, RES_DEBUG,
|
||||
RES_SKIP, RES_FORCE, RES_IGNORE, RES_INCLUDE, RES_BOX,
|
||||
RES_CELL, RES_BLACKBOX, RES_FASTHENRY, RES_GEOMETRY,
|
||||
RES_STATS, RES_HELP, RES_RUN
|
||||
} ResOptions;
|
||||
|
||||
resisdata = ResInit();
|
||||
|
|
@ -549,6 +552,23 @@ typedef enum {
|
|||
}
|
||||
return;
|
||||
|
||||
case RES_DEBUG:
|
||||
if (cmd->tx_argc == 2)
|
||||
{
|
||||
value = (ResOptionsFlags & ResOpt_Debug) ?
|
||||
TRUE : FALSE;
|
||||
TxPrintf("%s\n", onOff[value]);
|
||||
}
|
||||
else
|
||||
{
|
||||
value = Lookup(cmd->tx_argv[2], onOff);
|
||||
if (value)
|
||||
ResOptionsFlags |= ResOpt_Debug;
|
||||
else
|
||||
ResOptionsFlags &= ~ResOpt_Debug;
|
||||
}
|
||||
return;
|
||||
|
||||
case RES_SKIP:
|
||||
if (cmd->tx_argc > 2)
|
||||
{
|
||||
|
|
@ -568,6 +588,31 @@ typedef enum {
|
|||
}
|
||||
return;
|
||||
|
||||
case RES_FORCE:
|
||||
if (cmd->tx_argc > 2)
|
||||
{
|
||||
if (!strcasecmp(cmd->tx_argv[2], "none"))
|
||||
{
|
||||
/* Kill and reinitialize the table of forced nets */
|
||||
HashKill(&ResForceTable);
|
||||
HashInit(&ResForceTable, INITFLATSIZE, HT_STRINGKEYS);
|
||||
}
|
||||
else
|
||||
HashFind(&ResForceTable, cmd->tx_argv[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
HashSearch hs;
|
||||
HashEntry *entry;
|
||||
|
||||
/* List all net names that are being ignored */
|
||||
HashStartSearch(&hs);
|
||||
while((entry = HashNext(&ResForceTable, &hs)) != NULL)
|
||||
TxPrintf("%s ", (char *)entry->h_key.h_name);
|
||||
TxPrintf("\n");
|
||||
}
|
||||
return;
|
||||
|
||||
case RES_IGNORE:
|
||||
if (cmd->tx_argc > 2)
|
||||
{
|
||||
|
|
@ -1028,7 +1073,9 @@ ResProcessNode(
|
|||
{
|
||||
HashEntry *he;
|
||||
devPtr *ptr;
|
||||
int totWL, maxWL = 0;
|
||||
int nidx = 1, eidx = 1; /* node & segment counters for geom. */
|
||||
bool processThis;
|
||||
|
||||
/* Ignore or include specified nodes */
|
||||
|
||||
|
|
@ -1063,32 +1110,71 @@ ResProcessNode(
|
|||
|
||||
resisdata->rg_ttype = node->type;
|
||||
|
||||
/* Pick the first device connected to node. */
|
||||
/* Find the device with largest drive on the net; this will be
|
||||
* assumed to be the primary net driver. Make sure that devices
|
||||
* in parallel have been combined to determine which device is the
|
||||
* largest. If there are no drivers on the net, then choose a
|
||||
* source or sink point as the driver. The driver will be used as
|
||||
* the starting point to determine the longest driver-to-terminal
|
||||
* resistance or delay.
|
||||
*/
|
||||
|
||||
for (ptr = node->devices; ptr != NULL; ptr = ptr->nextDev)
|
||||
{
|
||||
RDev *t1;
|
||||
RDev *t1, *t2;
|
||||
|
||||
/* Ignore devices unless they are FETs or BJTs */
|
||||
switch (ptr->thisDev->rs_devptr->exts_deviceClass)
|
||||
{
|
||||
case DEV_FET:
|
||||
case DEV_MOSFET:
|
||||
case DEV_ASYMMETRIC:
|
||||
case DEV_MSUBCKT:
|
||||
case DEV_BJT:
|
||||
break;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Devices have been sorted with those being gate terminals
|
||||
* at the end, so once the first gate terminal is reached,
|
||||
* there are no more drivers to be found.
|
||||
*/
|
||||
if (ptr->terminal == GATE)
|
||||
break;
|
||||
else
|
||||
{
|
||||
/* Sorting has put all parallel devices together, so
|
||||
* combine their total W/L
|
||||
*/
|
||||
totWL = ptr->thisDev->rs_wl;
|
||||
t1 = ptr->thisDev;
|
||||
resisdata->rg_devloc = &t1->location;
|
||||
resisdata->rg_ttype = t1->rs_ttype;
|
||||
break;
|
||||
for (; ptr->nextDev != NULL; ptr = ptr->nextDev)
|
||||
{
|
||||
t1 = ptr->thisDev;
|
||||
t2 = ptr->nextDev->thisDev;
|
||||
if (t1->gate != t2->gate) break;
|
||||
if ((t1->source != t2->source || t1->drain != t2->drain) &&
|
||||
(t1->source != t2->drain || t2->drain != t2->source))
|
||||
break;
|
||||
|
||||
/* Sum the W/L value of devices in parallel */
|
||||
totWL += t2->rs_wl;
|
||||
}
|
||||
if (totWL > maxWL)
|
||||
{
|
||||
maxWL = totWL;
|
||||
resisdata->rg_devloc = &t1->location;
|
||||
resisdata->rg_ttype = t1->rs_ttype;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Special handling for FORCE and DRIVELOC labels: */
|
||||
/* Special handling for DRIVELOC labels: */
|
||||
|
||||
if (node->status & (FORCE|DRIVELOC))
|
||||
if (node->status & DRIVELOC)
|
||||
{
|
||||
/* NOTE: This needs to be fixed, as it is assuming that
|
||||
* a node has exactly one drivepoint; this is (probably)
|
||||
* valid for top level cells, but not in general.
|
||||
*/
|
||||
if ((node->status & (DRIVELOC | PORTNODE)) && (node->drivepoints != NULL))
|
||||
if ((node->status & DRIVELOC) && (node->drivepoints != NULL))
|
||||
{
|
||||
resisdata->rg_devloc = &node->drivepoints->rc_rect.r_ll;
|
||||
resisdata->rg_ttype = node->drivepoints->rc_type;
|
||||
|
|
@ -1097,15 +1183,40 @@ ResProcessNode(
|
|||
|
||||
/* If there is no drivepoint but there is a sinkpoint, use that.
|
||||
* The "drivers" and "sinks" are arbitrary, anyway, and any of
|
||||
* them can be considered a node start point.
|
||||
* them can be considered a node driver.
|
||||
*/
|
||||
else if ((node->status & (DRIVELOC | PORTNODE)) && (node->sinkpoints != NULL))
|
||||
else if ((node->status & DRIVELOC) && (node->sinkpoints != NULL))
|
||||
{
|
||||
resisdata->rg_devloc = &node->sinkpoints->rc_rect.r_ll;
|
||||
resisdata->rg_ttype = node->sinkpoints->rc_type;
|
||||
resisdata->rg_status |= DRIVEONLY;
|
||||
}
|
||||
}
|
||||
|
||||
/* If no driving device was found and node was not marked with a
|
||||
* DRIVELOC label, then use the first drivepoint as the driver.
|
||||
* If there are no drivepoints, then use a sinkpoint. Using sinkpoints
|
||||
* (design is hierarchical) is problematic because there is no information
|
||||
* on whether the sinkpoint leads to a driver in the child cell, which
|
||||
* needs to be addressed to correctly handle hierarchical R-C extraction.
|
||||
*/
|
||||
|
||||
if (resisdata->rg_devloc == NULL)
|
||||
{
|
||||
if (node->drivepoints != NULL)
|
||||
{
|
||||
resisdata->rg_devloc = &node->drivepoints->rc_rect.r_ll;
|
||||
resisdata->rg_ttype = node->drivepoints->rc_type;
|
||||
resisdata->rg_status |= DRIVEONLY;
|
||||
}
|
||||
else if (node->sinkpoints != NULL)
|
||||
{
|
||||
resisdata->rg_devloc = &node->sinkpoints->rc_rect.r_ll;
|
||||
resisdata->rg_ttype = node->sinkpoints->rc_type;
|
||||
resisdata->rg_status |= DRIVEONLY;
|
||||
}
|
||||
}
|
||||
|
||||
if ((resisdata->rg_devloc == NULL) && (node->status & FORCE))
|
||||
{
|
||||
TxError("Node %s has force label but no drive point or "
|
||||
|
|
@ -1124,19 +1235,38 @@ ResProcessNode(
|
|||
* by absolute resistance ("extresist threshold") or by effective signal
|
||||
* propagation delay ("extresist mindelay"). If either one is set to zero,
|
||||
* it will be ignored, although they can also be used in combination.
|
||||
*
|
||||
* Note that the substrate net has a capacitance to substrate of zero by
|
||||
* definition, and should be the only net with a zero capacitance.
|
||||
* Therefore, for any node with zero capacitance, use only the lumped
|
||||
* resistance to determine whether or not to process the node.
|
||||
*/
|
||||
|
||||
if ((ResOpt_ExtractAll & ResOptionsFlags) ||
|
||||
((node->resistance > resisdata->rthresh) &&
|
||||
(node->resistance * node->capacitance > resisdata->mindelay)))
|
||||
processThis = FALSE;
|
||||
if (ResOpt_ExtractAll & ResOptionsFlags)
|
||||
processThis = TRUE;
|
||||
else if ((node->capacitance > 0) && (node->resistance > resisdata->rthresh) &&
|
||||
(node->resistance * node->capacitance > resisdata->mindelay))
|
||||
processThis = TRUE;
|
||||
else if ((node->capacitance == 0) && (node->resistance > resisdata->rthresh))
|
||||
processThis = TRUE;
|
||||
else if (HashLookOnly(&ResForceTable, node->name) != NULL)
|
||||
processThis = TRUE;
|
||||
|
||||
if (processThis)
|
||||
{
|
||||
ResFixPoint fp;
|
||||
|
||||
/* Diagnostic */
|
||||
TxPrintf("Extracting %s (Rnode = %.2fohm ; Rthresh = %.2fohm)\n",
|
||||
node->name,
|
||||
if (!(ResOptionsFlags & ResOpt_RunSilent))
|
||||
{
|
||||
TxPrintf("Extracting %s", node->name);
|
||||
if (ResOptionsFlags & ResOpt_Debug)
|
||||
TxPrintf(" (Rnode = %.2fohm ; Rthresh = %.2fohm)",
|
||||
node->resistance * MILLIOHMSTOOHMS,
|
||||
resisdata->rthresh * MILLIOHMSTOOHMS);
|
||||
TxPrintf("\n");
|
||||
}
|
||||
|
||||
(*num_extracted)++;
|
||||
if (ResExtractNet(node, resisdata, outfile) != 0)
|
||||
|
|
@ -1904,21 +2034,69 @@ ResWriteExtFile(celldef, node, resisdata, nidx, eidx)
|
|||
* the original estimate. If the new estimate falls below the
|
||||
* threshold, then return without outputting the node's network.
|
||||
*/
|
||||
if (resisdata->rg_Tdi < resisdata->mindelay) return 0;
|
||||
|
||||
if (!(ResOptionsFlags & ResOpt_RunSilent))
|
||||
if (resisdata->rg_Tdi == 0)
|
||||
{
|
||||
float ftdi, fdmin;
|
||||
/* The substrate net has zero capacitance by definition and
|
||||
* so it also has zero delay by definition. In that case,
|
||||
* check if the updated lumped resistance exceeds the
|
||||
* threshold or not.
|
||||
*/
|
||||
if (resisdata->rg_maxres < resisdata->rthresh)
|
||||
if (HashLookOnly(&ResForceTable, node->name) == NULL)
|
||||
{
|
||||
if (ResOptionsFlags & ResOpt_Debug)
|
||||
TxPrintf("Not adding %s (maxres = %.2fohm)\n", node->name,
|
||||
resisdata->rg_maxres / 1000.0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else if ((resisdata->rg_Tdi != -1) && (resisdata->rg_Tdi < resisdata->mindelay))
|
||||
{
|
||||
if (HashLookOnly(&ResForceTable, node->name) == NULL)
|
||||
{
|
||||
if (ResOptionsFlags & ResOpt_Debug)
|
||||
{
|
||||
/* Diagnostic */
|
||||
float ftdi, fdmin;
|
||||
|
||||
ftdi = resisdata->rg_Tdi * Z_TO_P;
|
||||
fdmin = resisdata->mindelay * Z_TO_P;
|
||||
ftdi = resisdata->rg_Tdi * Z_TO_P;
|
||||
fdmin = resisdata->mindelay * Z_TO_P;
|
||||
|
||||
if ((ftdi < 0.01) || ((fdmin < 0.01) && (resisdata->mindelay > 0)))
|
||||
TxPrintf("Adding %s; (Tnew = %.2ffs ; Tmin = %.2ffs)\n",
|
||||
node->name, ftdi * 1000, fdmin * 1000);
|
||||
if ((ftdi < 0.01) || ((fdmin < 0.01) && (resisdata->mindelay > 0)))
|
||||
TxPrintf("Not adding %s; (Tnew = %.2ffs ; Tmin = %.2ffs)\n",
|
||||
node->name, ftdi * 1000, fdmin * 1000);
|
||||
else
|
||||
TxPrintf("Not adding %s; (Tnew = %.2fps ; Tmin = %.2fps)\n",
|
||||
node->name, ftdi, fdmin);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (ResOptionsFlags & ResOpt_Debug)
|
||||
{
|
||||
if (resisdata->mindelay == 0)
|
||||
{
|
||||
TxPrintf("Adding %s (maxres = %.2fohm)\n", node->name,
|
||||
resisdata->rg_maxres / 1000.0);
|
||||
}
|
||||
else
|
||||
TxPrintf("Adding %s; (Tnew = %.2fps ; Tmin = %.2fps)\n",
|
||||
{
|
||||
float ftdi, fdmin;
|
||||
fdmin = resisdata->mindelay * Z_TO_P;
|
||||
|
||||
if (resisdata->rg_Tdi == -1)
|
||||
ftdi = resisdata->rg_maxres * resisdata->rg_nodecap * Z_TO_P;
|
||||
else
|
||||
ftdi = resisdata->rg_Tdi * Z_TO_P;
|
||||
|
||||
if ((ftdi < 0.01) || ((fdmin < 0.01) && (resisdata->mindelay > 0)))
|
||||
TxPrintf("Adding %s; (Tnew = %.2ffs ; Tmin = %.2ffs)\n",
|
||||
node->name, ftdi * 1000, fdmin * 1000);
|
||||
else
|
||||
TxPrintf("Adding %s; (Tnew = %.2fps ; Tmin = %.2fps)\n",
|
||||
node->name, ftdi, fdmin);
|
||||
}
|
||||
}
|
||||
|
||||
for (ptr = node->devices; ptr != NULL; ptr = ptr->nextDev)
|
||||
|
|
|
|||
|
|
@ -311,20 +311,19 @@ typedef struct rcdelaystuff
|
|||
typedef struct rdev
|
||||
{
|
||||
struct rdev *nextDev; /* Next device in linked list */
|
||||
struct rdev *realDev; /* Single Lumped Device for */
|
||||
/* devices connected in parallel */
|
||||
resDevice *layout; /* pointer to resDevice that */
|
||||
/* corresponds to RDev */
|
||||
int status;
|
||||
struct resextnode *gate; /* Terminals of transistor. */
|
||||
struct resextnode *source;
|
||||
struct resextnode *drain;
|
||||
struct resextnode *subs; /* Used with subcircuit type only */
|
||||
Point location; /* Location of lower left point of */
|
||||
/* device. */
|
||||
TileType rs_ttype; /* tile type for device */
|
||||
ExtDevice *rs_devptr; /* device extraction record */
|
||||
char *rs_gattr; /* Gate attributes, if any */
|
||||
struct resextnode *subs; /* Used with subcircuit type only */
|
||||
Point location; /* Location of lower left point */
|
||||
/* of the device. */
|
||||
TileType rs_ttype; /* tile type for device */
|
||||
float rs_wl; /* device W/L, if relevant */
|
||||
ExtDevice *rs_devptr; /* device extraction record */
|
||||
char *rs_gattr; /* Gate attributes, if any */
|
||||
char *rs_sattr;
|
||||
char *rs_dattr;
|
||||
} RDev;
|
||||
|
|
@ -495,11 +494,12 @@ typedef struct capval
|
|||
#define ResOpt_DoExtFile 0x0004
|
||||
#define ResOpt_DoLumpFile 0x0008
|
||||
#define ResOpt_RunSilent 0x0010
|
||||
#define ResOpt_Stats 0x0020
|
||||
#define ResOpt_Signal 0x0040
|
||||
#define ResOpt_Debug 0x0020
|
||||
#define ResOpt_Stats 0x0040
|
||||
#define ResOpt_Signal 0x0080
|
||||
#define ResOpt_Geometry 0x0100
|
||||
#define ResOpt_FastHenry 0x0200
|
||||
#define ResOpt_Blackbox 0x0300
|
||||
#define ResOpt_Blackbox 0x0400
|
||||
#define ResOpt_DoSubstrate 0x0800
|
||||
#define ResOpt_Box 0x1000
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue