Some further refinements to the last commit, and other additions:
(1) An incorrect use of ExtResetTiles() was found in "extresist"
which impacts performance, especially for small nets.
(2) Corrected units for resistance tolerance in extresist, and
handled output printing in fs when delay values get below ps
size.
(3) Added command option "extract do unique notopports" to be the
extraction option equivalent of the standalone command
"extract unique notopports".
(4) Changed the "extresist" default for "mindelay" to 1ps from 0,
in response to the observation that lumped resistance from
"extract" can be an extreme overestimate, and the extracted
time delay from "extesist" calculations should be used as a
better determination of whether a net should be output as a
resistor network or not.
(5) Added documentation for both "extract do unique notopports"
and the change to the "extresist" default values.
This commit is contained in:
parent
349ffd091f
commit
c22031724a
|
|
@ -1096,7 +1096,7 @@ CmdExtract(
|
|||
"lumped estimate lumped resistance",
|
||||
"labelcheck check for connections through sticky labels",
|
||||
"aliases output all net name aliases",
|
||||
"unique ensure unique node names during extraction",
|
||||
"unique [notopports] ensure unique node names during extraction",
|
||||
"resistance extract resistance (same as \"do extresist\")",
|
||||
NULL
|
||||
};
|
||||
|
|
@ -1403,6 +1403,7 @@ CmdExtract(
|
|||
TxPrintf("%s label check\n", OPTSET(EXT_DOLABELCHECK));
|
||||
TxPrintf("%s aliases\n", OPTSET(EXT_DOALIASES));
|
||||
TxPrintf("%s unique\n", OPTSET(EXT_DOUNIQUE));
|
||||
TxPrintf("%s unique notopports\n", OPTSET(EXT_DOUNIQNOTOPPORTS));
|
||||
TxPrintf("%s resistance (extresist)\n", OPTSET(EXT_DOEXTRESIST));
|
||||
return;
|
||||
#undef OPTSET
|
||||
|
|
@ -1433,9 +1434,19 @@ CmdExtract(
|
|||
case DORESISTANCE: option = EXT_DORESISTANCE; break;
|
||||
case DOLABELCHECK: option = EXT_DOLABELCHECK; break;
|
||||
case DOALIASES: option = EXT_DOALIASES; break;
|
||||
case DOUNIQUE: option = EXT_DOUNIQUE; break;
|
||||
case DOEXTRESIST:
|
||||
case DOEXTRESIST2: option = EXT_DOEXTRESIST; break;
|
||||
case DOUNIQUE:
|
||||
if (argc == 4)
|
||||
{
|
||||
if (!strncmp(argv[3], "notop", 5))
|
||||
option = EXT_DOUNIQNOTOPPORTS | EXT_DOUNIQUE;
|
||||
else
|
||||
TxError("Usage: extract do unique [notopports]\n");
|
||||
}
|
||||
else
|
||||
option = EXT_DOUNIQUE;
|
||||
break;
|
||||
case DOLOCAL:
|
||||
/* "extract do local" and "extract no local" are kept for
|
||||
* backwards compatibility, but now effectively implement
|
||||
|
|
|
|||
|
|
@ -102,16 +102,17 @@ Circuit netlist extractor
|
|||
but will usually just slow down processing by commands
|
||||
like "ext2spice" that use the .ext file contents, so it
|
||||
is disabled by default.
|
||||
<DT> <B>unique</B>
|
||||
<DT> <B>unique</B> [<B>notopports</B>]
|
||||
<DD> (Added in magic version 8.3.594) This setting replaces
|
||||
the use of the command option "extract unique". Instead
|
||||
of changing labels in the design, unique labels are
|
||||
generated for the duration of the extraction, and then
|
||||
reverted back to the original text. The "extract unique"
|
||||
command option is maintained for backwards compatibility.
|
||||
Note the difference: "extract unique" is a command that
|
||||
runs immediately, and cannot be undone;
|
||||
"extract do unique" is an option setting for "extract".
|
||||
the use of the command option "extract unique" (and
|
||||
"extract unique notopports"). Instead of changing labels
|
||||
in the design, unique labels are generated for the duration
|
||||
of the extraction, and then reverted back to the original
|
||||
text. The "extract unique" command option is maintained
|
||||
for backwards compatibility. Note the difference:
|
||||
"extract unique" is a command that runs immediately, and
|
||||
cannot be undone; "extract do unique" is an option setting
|
||||
for "extract".
|
||||
<DT> <B>resistance</B>
|
||||
<DD> (Added in magic version 8.3.597) This setting replaces
|
||||
the use of the standalone command "extresist". The
|
||||
|
|
|
|||
|
|
@ -43,8 +43,7 @@ information.
|
|||
<DD> With no value given, returns the current delay time threshold
|
||||
used to determine if a network will or will not be analyzed for
|
||||
resistance extraction, in picoseconds. The default
|
||||
<B>mindelay</B> value is zero, indicating that delay time is
|
||||
not used for determining extraction. If <I>value</I> is given,
|
||||
<B>mindelay</B> value is 1ps. If <I>value</I> is given,
|
||||
then set the delay threshold to <I>value</I> picoseconds.
|
||||
<DT> <B>minres</B> [<I>value</I>]
|
||||
<DD> With no value given, returns the current absolute resistance
|
||||
|
|
|
|||
|
|
@ -629,6 +629,8 @@ extSetResist(reg)
|
|||
|
||||
for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++)
|
||||
{
|
||||
ResValue resnew, restot;
|
||||
|
||||
reg->nreg_pa[n].pa_area = area = extResistArea[n];
|
||||
reg->nreg_pa[n].pa_perim = perim = extResistPerim[n];
|
||||
if (area > 0 && perim > 0)
|
||||
|
|
@ -639,8 +641,15 @@ extSetResist(reg)
|
|||
if (v < 0) s = 0; else s = sqrt(v);
|
||||
|
||||
fperim = (float) perim;
|
||||
reg->nreg_resist += (fperim + s) / (fperim - s)
|
||||
* ExtCurStyle->exts_resistByResistClass[n];
|
||||
resnew = (fperim + s) / (fperim - s) *
|
||||
ExtCurStyle->exts_resistByResistClass[n];
|
||||
restot = reg->nreg_resist + resnew;
|
||||
|
||||
/* Check for integer overflow. There is no point in trying
|
||||
* to accommodate huge resistance values for an estimate.
|
||||
* The value just saturates at the maximum integer value.
|
||||
*/
|
||||
if (restot > 0) reg->nreg_resist = restot;
|
||||
}
|
||||
|
||||
/* Reset for the next pass */
|
||||
|
|
|
|||
|
|
@ -76,14 +76,10 @@ void extHeader();
|
|||
*/
|
||||
|
||||
Plane *
|
||||
ExtCell(def, outName, doLength)
|
||||
ExtCell(def, outName, isTop)
|
||||
CellDef *def; /* Cell being extracted */
|
||||
char *outName; /* Name of output file; if NULL, derive from def name */
|
||||
bool doLength; /* If TRUE, extract pathlengths from drivers to
|
||||
* receivers (the names are stored in ExtLength.c).
|
||||
* Should only be TRUE for the root cell in a
|
||||
* hierarchy.
|
||||
*/
|
||||
bool isTop; /* If TRUE, cell is the top level cell */
|
||||
{
|
||||
char *filename;
|
||||
FILE *f = NULL;
|
||||
|
|
@ -116,7 +112,7 @@ ExtCell(def, outName, doLength)
|
|||
}
|
||||
|
||||
extNumErrors = extNumWarnings = 0;
|
||||
savePlane = extCellFile(def, f, doLength);
|
||||
savePlane = extCellFile(def, f, isTop);
|
||||
if (f != NULL) fclose(f);
|
||||
|
||||
if (extNumErrors > 0 || extNumWarnings > 0)
|
||||
|
|
@ -476,13 +472,10 @@ ExtRevertSubstrate(def, savePlane)
|
|||
*/
|
||||
|
||||
Plane *
|
||||
extCellFile(def, f, doLength)
|
||||
extCellFile(def, f, isTop)
|
||||
CellDef *def; /* Def to be extracted */
|
||||
FILE *f; /* Output to this file */
|
||||
bool doLength; /* TRUE if we should extract driver-receiver path
|
||||
* length information for this cell (see ExtCell
|
||||
* for more details).
|
||||
*/
|
||||
bool isTop; /* TRUE if the cell is the top level cell */
|
||||
{
|
||||
NodeRegion *reg;
|
||||
Plane *saveSub;
|
||||
|
|
@ -493,8 +486,19 @@ extCellFile(def, f, doLength)
|
|||
/* If "extract do unique" was specified, then make labels in the
|
||||
* cell unique.
|
||||
*/
|
||||
|
||||
if (ExtOptions & EXT_DOUNIQUE)
|
||||
extUniqueCell(def, EXT_UNIQ_TEMP);
|
||||
{
|
||||
if (ExtOptions & EXT_DOUNIQNOTOPPORTS)
|
||||
{
|
||||
if (isTop)
|
||||
extUniqueCell(def, EXT_UNIQ_TEMP_NOPORTS);
|
||||
else
|
||||
extUniqueCell(def, EXT_UNIQ_TEMP);
|
||||
}
|
||||
else
|
||||
extUniqueCell(def, EXT_UNIQ_TEMP);
|
||||
}
|
||||
|
||||
/* Prep any isolated substrate areas */
|
||||
if (ExtOptions & EXT_DOEXTRESIST)
|
||||
|
|
@ -524,7 +528,7 @@ extCellFile(def, f, doLength)
|
|||
ExtResetTiles(def, CLIENTDEFAULT);
|
||||
|
||||
/* Final pass: extract length information if desired */
|
||||
if (!SigInterruptPending && doLength && (ExtOptions & EXT_DOLENGTH))
|
||||
if (!SigInterruptPending && isTop && (ExtOptions & EXT_DOLENGTH))
|
||||
extLength(extParentUse, f);
|
||||
|
||||
UndoEnable();
|
||||
|
|
|
|||
|
|
@ -473,6 +473,19 @@ ExtUnique(rootUse, option)
|
|||
/* Fix up bounding boxes if they've changed */
|
||||
DBFixMismatch();
|
||||
|
||||
/* Because the "extract unique" does the same thing as "extract do unique"
|
||||
* but the options may be different, disable "extract do unique" when
|
||||
* "extract unique" is run, on the assumption that no user would
|
||||
* intentionally use both methods. If "do unique" was set and got
|
||||
* disabled, then flag a warning.
|
||||
*/
|
||||
if (ExtOptions & EXT_DOUNIQUE)
|
||||
{
|
||||
ExtOptions &= ~EXT_DOUNIQUE;
|
||||
TxPrintf("Warning: Extract option \"do unique\" disabled because "
|
||||
"\"extract unique\" was run.\n");
|
||||
}
|
||||
|
||||
/* Mark all defs as being unvisited */
|
||||
(void) DBCellSrDefs(0, extDefInitFunc, (ClientData) 0);
|
||||
|
||||
|
|
|
|||
|
|
@ -66,6 +66,8 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
* label. This way, the unique label form can be used by the
|
||||
* extraction code but labels (and port indexes) can be reverted
|
||||
* afterward, and no permanent change is made to the circuit.
|
||||
* Option EXT_UNIQ_TEMP_NOPORTS is a combination of EXT_UNIQ_TEMP and
|
||||
* EXT_UNIQ_NOPORTS.
|
||||
*
|
||||
* Results:
|
||||
* Returns the number of warnings generated.
|
||||
|
|
@ -226,8 +228,9 @@ extMakeUnique(def, ll, lreg, lregList, labelHash, option)
|
|||
text = ll->ll_label->lab_text;
|
||||
if (option == EXT_UNIQ_ALL || option == EXT_UNIQ_TEMP)
|
||||
goto makeUnique;
|
||||
else if ((option == EXT_UNIQ_NOPORTS || option == EXT_UNIQ_NOTOPPORTS)
|
||||
&& !(ll->ll_label->lab_flags & PORT_DIR_MASK))
|
||||
else if ((option == EXT_UNIQ_NOPORTS || option == EXT_UNIQ_NOTOPPORTS ||
|
||||
option == EXT_UNIQ_TEMP_NOPORTS) &&
|
||||
!(ll->ll_label->lab_flags & PORT_DIR_MASK))
|
||||
goto makeUnique;
|
||||
|
||||
cpend = strchr(text, '\0');
|
||||
|
|
@ -326,7 +329,8 @@ makeUnique:
|
|||
saveLab = *lab;
|
||||
|
||||
/* Flag this label as having been modified */
|
||||
if (option == EXT_UNIQ_TEMP) flags |= LABEL_UNIQUE;
|
||||
if ((option == EXT_UNIQ_TEMP) || (option == EXT_UNIQ_TEMP_NOPORTS))
|
||||
flags |= LABEL_UNIQUE;
|
||||
|
||||
DBRemoveLabel(def, lab);
|
||||
DBPutFontLabel(def, &saveLab.lab_rect,
|
||||
|
|
|
|||
|
|
@ -76,6 +76,7 @@ extern const char * const extDevTable[];
|
|||
#define EXT_DOLABELCHECK 0x040 /* Check for connections by label */
|
||||
#define EXT_DOALIASES 0x080 /* Output all node aliases */
|
||||
#define EXT_DOEXTRESIST 0x200 /* Do full R-C extraction */
|
||||
#define EXT_DOUNIQNOTOPPORTS 0x400 /* Ignore top cell ports w/EXT_DOUNIQUE */
|
||||
|
||||
extern int ExtOptions; /* Bitmask of above */
|
||||
extern char *ExtLocalPath; /* If non-NULL, location to write .ext files */
|
||||
|
|
@ -86,6 +87,7 @@ extern char *ExtLocalPath; /* If non-NULL, location to write .ext files */
|
|||
#define EXT_UNIQ_NOPORTS 2
|
||||
#define EXT_UNIQ_NOTOPPORTS 3
|
||||
#define EXT_UNIQ_TEMP 4 /* Used only with "EXT_DOUNIQUE" */
|
||||
#define EXT_UNIQ_TEMP_NOPORTS 5 /* Used only with "EXT_DOUNIQUE" */
|
||||
|
||||
extern bool ExtTechLine();
|
||||
extern void ExtTechInit();
|
||||
|
|
|
|||
|
|
@ -1382,8 +1382,6 @@ ResExtractNet(node, resisdata, cellname)
|
|||
}
|
||||
DBReComputeBbox(ResUse->cu_def);
|
||||
|
||||
ExtResetTiles(scx.scx_use->cu_def, CLIENTDEFAULT);
|
||||
|
||||
/* To avoid issues with overlapping stacked contact types and */
|
||||
/* double-counting contacts on multiple planes, erase the top */
|
||||
/* contact layers of all contacts. ExtFindRegions() will still */
|
||||
|
|
|
|||
|
|
@ -519,6 +519,7 @@ ResReadNode(int argc, char *argv[])
|
|||
{
|
||||
HashEntry *entry;
|
||||
ResExtNode *node;
|
||||
int noderesist;
|
||||
|
||||
entry = HashFind(&ResNodeTable, argv[NODES_NODENAME]);
|
||||
node = ResExtInitNode(entry);
|
||||
|
|
@ -526,7 +527,10 @@ ResReadNode(int argc, char *argv[])
|
|||
node->location.p_x = atoi(argv[NODES_NODEX]);
|
||||
node->location.p_y = atoi(argv[NODES_NODEY]);
|
||||
node->type = DBTechNameType(argv[NODES_NODETYPE]);
|
||||
node->resistance = atoi(argv[NODES_NODERES]);
|
||||
noderesist = atoi(argv[NODES_NODERES]);
|
||||
if (noderesist < 0) noderesist = INFINITY;
|
||||
/* Make sure node resistance is in units of milliohms */
|
||||
node->resistance = (float)noderesist * (float)ExtCurStyle->exts_resistScale;
|
||||
|
||||
if (node->type == -1)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -218,11 +218,11 @@ ResInit()
|
|||
/* Defaults:
|
||||
* (1) rthresh: Only extract networks with a lumped resistance > 10 ohms
|
||||
* (2) minres: Prune resistors < 1 ohm when possible
|
||||
* (3) mindelay: Do not gate extraction based on calculated delay.
|
||||
* (3) mindelay: Only extract networks with a calculated delay > 1 ps
|
||||
*/
|
||||
resisdata->rthresh = 10000.0;
|
||||
resisdata->minres = 1000.0;
|
||||
resisdata->mindelay = 0.0;
|
||||
resisdata->mindelay = 1.0e9; /* 1ps = 1.0e9zs
|
||||
resisdata->frequency = 10e6; /* 10 MHz default */
|
||||
|
||||
HashInit(&ResIgnoreTable, INITFLATSIZE, HT_STRINGKEYS);
|
||||
|
|
@ -407,7 +407,8 @@ typedef enum {
|
|||
Tcl_SetObjResult(magicinterp,
|
||||
Tcl_NewDoubleObj((double)resisdata->rthresh));
|
||||
#else
|
||||
TxPrintf("Minimum resistor threshold is %g.\n", resisdata->rthresh);
|
||||
TxPrintf("Minimum resistor threshold is %g mohms.\n",
|
||||
resisdata->rthresh);
|
||||
#endif
|
||||
}
|
||||
return;
|
||||
|
|
@ -1907,9 +1908,17 @@ ResWriteExtFile(celldef, node, resisdata, nidx, eidx)
|
|||
|
||||
if (!(ResOptionsFlags & ResOpt_RunSilent))
|
||||
{
|
||||
TxPrintf("Adding %s; (Tnew = %.2fps ; Tmin = %.2fps)\n",
|
||||
node->name, resisdata->rg_Tdi * Z_TO_P,
|
||||
resisdata->mindelay * Z_TO_P);
|
||||
float ftdi, fdmin;
|
||||
|
||||
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);
|
||||
else
|
||||
TxPrintf("Adding %s; (Tnew = %.2fps ; Tmin = %.2fps)\n",
|
||||
node->name, ftdi, fdmin);
|
||||
}
|
||||
|
||||
for (ptr = node->devices; ptr != NULL; ptr = ptr->nextDev)
|
||||
|
|
|
|||
Loading…
Reference in New Issue