Implemented a command option "ext2spice short voltage|resistor|none" that
implements a method for handling ports in a subcircuit that have different port names and indexes but are shorted together. "none" is the default and backwards-compatible behavior that merges ports together, which will often cause one of the ports to be optimized out of the netlist. "resistor" will separate the port names with a 0-ohm ideal resistor. "voltage" will separate the port names with a 0-volt voltage source. This should work well for simulation and potentially for LVS, although its impact on LVS has not been fully investigated.
This commit is contained in:
parent
355399d3ef
commit
6136d3ff0f
|
|
@ -446,7 +446,7 @@ CmdExtToSim(w, cmd)
|
|||
case EXTTOSIM_DEFAULT:
|
||||
LocCapThreshold = 2;
|
||||
LocResistThreshold = 10;
|
||||
EFTrimFlags = 0;
|
||||
EFOutputFlags = 0;
|
||||
EFScale = 0.0;
|
||||
if (EFArgTech)
|
||||
{
|
||||
|
|
@ -1307,8 +1307,8 @@ FILE *outf;
|
|||
suf = EFHNToStr(suffix);
|
||||
if (fetInfo[type].defSubs && strcasecmp(suf,fetInfo[type].defSubs) == 0) {
|
||||
l = strlen(suf) - 1;
|
||||
if ( ( EFTrimFlags & EF_TRIMGLOB ) && suf[l] =='!' ||
|
||||
( EFTrimFlags & EF_TRIMLOCAL ) && suf[l] == '#' )
|
||||
if ( ( EFOutputFlags & EF_TRIMGLOB ) && suf[l] =='!' ||
|
||||
( EFOutputFlags & EF_TRIMLOCAL ) && suf[l] == '#' )
|
||||
suf[l] = '\0' ;
|
||||
if ( esFormat == SU )
|
||||
fprintf(outf, "S_");
|
||||
|
|
|
|||
|
|
@ -555,7 +555,8 @@ spcdevHierVisit(hc, dev, scale)
|
|||
case DEV_RES:
|
||||
case DEV_CAP:
|
||||
case DEV_CAPREV:
|
||||
if (dev->dev_type == esNoModelType)
|
||||
if ((dev->dev_type == esNoModelType) ||
|
||||
!strcmp(EFDevTypes[dev->dev_type], "None"))
|
||||
has_model = FALSE;
|
||||
break;
|
||||
}
|
||||
|
|
@ -601,6 +602,9 @@ spcdevHierVisit(hc, dev, scale)
|
|||
case DEV_RES:
|
||||
devchar = 'R';
|
||||
break;
|
||||
case DEV_VOLT:
|
||||
devchar = 'V';
|
||||
break;
|
||||
case DEV_CAP:
|
||||
case DEV_CAPREV:
|
||||
devchar = 'C';
|
||||
|
|
@ -638,6 +642,9 @@ spcdevHierVisit(hc, dev, scale)
|
|||
case DEV_CAPREV:
|
||||
fprintf(esSpiceF, "%d", esCapNum++);
|
||||
break;
|
||||
case DEV_VOLT:
|
||||
fprintf(esSpiceF, "%d", esVoltNum++);
|
||||
break;
|
||||
case DEV_SUBCKT:
|
||||
case DEV_RSUBCKT:
|
||||
case DEV_CSUBCKT:
|
||||
|
|
@ -792,6 +799,21 @@ spcdevHierVisit(hc, dev, scale)
|
|||
}
|
||||
break;
|
||||
|
||||
case DEV_VOLT:
|
||||
/* Voltage source is "Vnnn term1 term2 0.0". It is used only to
|
||||
* separate port names that have been shorted.
|
||||
*/
|
||||
if (dev->dev_nterm > 1)
|
||||
spcdevOutNode(hc->hc_hierName,
|
||||
source->dterm_node->efnode_name->efnn_hier,
|
||||
"plus", esSpiceF);
|
||||
if (dev->dev_nterm > 2)
|
||||
spcdevOutNode(hc->hc_hierName,
|
||||
drain->dterm_node->efnode_name->efnn_hier,
|
||||
"minus", esSpiceF);
|
||||
fprintf(esSpiceF, " 0.0");
|
||||
break;
|
||||
|
||||
case DEV_DIODE:
|
||||
case DEV_PDIODE:
|
||||
if (source == NULL) break;
|
||||
|
|
@ -1083,7 +1105,8 @@ spcdevHierMergeVisit(hc, dev, scale)
|
|||
break;
|
||||
case DEV_RSUBCKT:
|
||||
case DEV_RES:
|
||||
if (fp->dev->dev_type == esNoModelType)
|
||||
if ((fp->dev->dev_type == esNoModelType) ||
|
||||
!strcmp(EFDevTypes[fp->dev->dev_type], "None"))
|
||||
m = esFMult[cfp->esFMIndex] + (fp->dev->dev_res
|
||||
/ cfp->dev->dev_res);
|
||||
else
|
||||
|
|
@ -1092,7 +1115,8 @@ spcdevHierMergeVisit(hc, dev, scale)
|
|||
case DEV_CSUBCKT:
|
||||
case DEV_CAP:
|
||||
case DEV_CAPREV:
|
||||
if (fp->dev->dev_type == esNoModelType)
|
||||
if ((fp->dev->dev_type == esNoModelType) ||
|
||||
!strcmp(EFDevTypes[fp->dev->dev_type], "None"))
|
||||
m = esFMult[cfp->esFMIndex] + (fp->dev->dev_cap
|
||||
/ cfp->dev->dev_cap);
|
||||
else
|
||||
|
|
@ -1481,7 +1505,8 @@ mergeThem:
|
|||
break;
|
||||
case DEV_RSUBCKT:
|
||||
case DEV_RES:
|
||||
if (fp->dev->dev_type == esNoModelType)
|
||||
if ((fp->dev->dev_type == esNoModelType) ||
|
||||
!strcmp(EFDevTypes[fp->dev->dev_type], "None"))
|
||||
m = esFMult[cfp->esFMIndex] + (fp->dev->dev_res
|
||||
/ cfp->dev->dev_res);
|
||||
else
|
||||
|
|
@ -1490,7 +1515,8 @@ mergeThem:
|
|||
case DEV_CSUBCKT:
|
||||
case DEV_CAP:
|
||||
case DEV_CAPREV:
|
||||
if (fp->dev->dev_type == esNoModelType)
|
||||
if ((fp->dev->dev_type == esNoModelType) ||
|
||||
!strcmp(EFDevTypes[fp->dev->dev_type], "None"))
|
||||
m = esFMult[cfp->esFMIndex] + (fp->dev->dev_cap
|
||||
/ cfp->dev->dev_cap);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ float esScale = -1.0 ; /* negative if hspice the EFScale/100 otherwise */
|
|||
|
||||
unsigned short esFormat = SPICE3 ;
|
||||
|
||||
int esCapNum, esDevNum, esResNum, esDiodeNum;
|
||||
int esCapNum, esDevNum, esResNum, esDiodeNum, esVoltNum;
|
||||
int esNodeNum; /* just in case we're extracting spice2 */
|
||||
int esSbckNum; /* used in hspice node name shortening */
|
||||
int esNoModelType; /* index for device type "None" (model-less device) */
|
||||
|
|
@ -137,20 +137,20 @@ esFormatSubs(outf, suf)
|
|||
if (outf)
|
||||
{
|
||||
l = strlen(suf) - 1;
|
||||
if ((EFTrimFlags & EF_TRIMGLOB ) && suf[l] == '!' ||
|
||||
(EFTrimFlags & EF_TRIMLOCAL) && suf[l] == '#')
|
||||
if ((EFOutputFlags & EF_TRIMGLOB ) && suf[l] == '!' ||
|
||||
(EFOutputFlags & EF_TRIMLOCAL) && suf[l] == '#')
|
||||
suf[l] = '\0' ;
|
||||
if (EFTrimFlags & EF_CONVERTCOMMA)
|
||||
if (EFOutputFlags & EF_CONVERTCOMMA)
|
||||
while ((specchar = strchr(suf, ',')) != NULL)
|
||||
*specchar = '|';
|
||||
if (EFTrimFlags & EF_CONVERTBRACKETS)
|
||||
if (EFOutputFlags & EF_CONVERTBRACKETS)
|
||||
{
|
||||
while ((specchar = strchr(suf, '[')) != NULL)
|
||||
*specchar = '_';
|
||||
while ((specchar = strchr(suf, ']')) != NULL)
|
||||
*specchar = '_';
|
||||
}
|
||||
if (EFTrimFlags & EF_CONVERTEQUAL)
|
||||
if (EFOutputFlags & EF_CONVERTEQUAL)
|
||||
while ((specchar = strchr(suf, '=')) != NULL)
|
||||
*specchar = ':';
|
||||
fprintf(outf, "%s", suf);
|
||||
|
|
@ -213,13 +213,14 @@ Exttospice_Init(interp)
|
|||
#define EXTTOSPC_EXTRESIST 6
|
||||
#define EXTTOSPC_RESISTORTEE 7
|
||||
#define EXTTOSPC_SCALE 8
|
||||
#define EXTTOSPC_SUBCIRCUITS 9
|
||||
#define EXTTOSPC_HIERARCHY 10
|
||||
#define EXTTOSPC_BLACKBOX 11
|
||||
#define EXTTOSPC_RENUMBER 12
|
||||
#define EXTTOSPC_MERGENAMES 13
|
||||
#define EXTTOSPC_LVS 14
|
||||
#define EXTTOSPC_HELP 15
|
||||
#define EXTTOSPC_SHORT 9
|
||||
#define EXTTOSPC_SUBCIRCUITS 10
|
||||
#define EXTTOSPC_HIERARCHY 11
|
||||
#define EXTTOSPC_BLACKBOX 12
|
||||
#define EXTTOSPC_RENUMBER 13
|
||||
#define EXTTOSPC_MERGENAMES 14
|
||||
#define EXTTOSPC_LVS 15
|
||||
#define EXTTOSPC_HELP 16
|
||||
|
||||
void
|
||||
CmdExtToSpice(w, cmd)
|
||||
|
|
@ -264,6 +265,8 @@ CmdExtToSpice(w, cmd)
|
|||
"extresist [on|off] incorporate information from extresist",
|
||||
"resistor tee [on|off] model resistor capacitance as a T-network",
|
||||
"scale [on|off] use .option card for scaling",
|
||||
"short [voltage|resistor|none]\n"
|
||||
" set method for handling shorted ports",
|
||||
"subcircuits [top|descend] [on|off|auto]\n"
|
||||
" standard cells become subcircuit calls",
|
||||
"hierarchy [on|off] output hierarchical spice for LVS",
|
||||
|
|
@ -283,6 +286,12 @@ CmdExtToSpice(w, cmd)
|
|||
NULL
|
||||
};
|
||||
|
||||
static char *cmdShortTypes[] = {
|
||||
"none merge shorted ports",
|
||||
"resistor separate shorted ports with 0 ohm resistor",
|
||||
"voltage separate shorted ports with 0 volt source",
|
||||
NULL
|
||||
};
|
||||
static char *cmdExtToSpcFormat[] = {
|
||||
"spice2",
|
||||
"spice3",
|
||||
|
|
@ -314,6 +323,13 @@ CmdExtToSpice(w, cmd)
|
|||
NULL
|
||||
};
|
||||
|
||||
static char *shorttypes[] = {
|
||||
"none",
|
||||
"resistor",
|
||||
"voltage",
|
||||
NULL
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
IDX_YES, IDX_TRUE, IDX_ON, IDX_NO, IDX_FALSE, IDX_OFF,
|
||||
IDX_AUTO, IDX_TOP, IDX_DESCEND
|
||||
|
|
@ -428,6 +444,36 @@ CmdExtToSpice(w, cmd)
|
|||
esMergeNames = FALSE;
|
||||
break;
|
||||
|
||||
case EXTTOSPC_SHORT:
|
||||
if (cmd->tx_argc == 2)
|
||||
{
|
||||
if ((EFOutputFlags & EF_SHORT_MASK) == EF_SHORT_NONE)
|
||||
Tcl_SetResult(magicinterp, "none", NULL);
|
||||
else if ((EFOutputFlags & EF_SHORT_MASK) == EF_SHORT_R)
|
||||
Tcl_SetResult(magicinterp, "resistor", NULL);
|
||||
else if ((EFOutputFlags & EF_SHORT_MASK) == EF_SHORT_V)
|
||||
Tcl_SetResult(magicinterp, "voltage source", NULL);
|
||||
return;
|
||||
}
|
||||
idx = Lookup(cmd->tx_argv[2], cmdShortTypes);
|
||||
if (idx < 0) goto usage;
|
||||
else switch (idx)
|
||||
{
|
||||
case 0:
|
||||
EFOutputFlags &= ~EF_SHORT_MASK;
|
||||
EFOutputFlags |= EF_SHORT_NONE;
|
||||
break;
|
||||
case 1:
|
||||
EFOutputFlags &= ~EF_SHORT_MASK;
|
||||
EFOutputFlags |= EF_SHORT_R;
|
||||
break;
|
||||
case 2:
|
||||
EFOutputFlags &= ~EF_SHORT_MASK;
|
||||
EFOutputFlags |= EF_SHORT_V;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case EXTTOSPC_LVS:
|
||||
/* Apply default command settings for LVS */
|
||||
/* hierarchy = on */
|
||||
|
|
@ -615,7 +661,7 @@ CmdExtToSpice(w, cmd)
|
|||
case EXTTOSPC_DEFAULT:
|
||||
LocCapThreshold = 2;
|
||||
LocResistThreshold = INFINITE_THRESHOLD;
|
||||
EFTrimFlags = EF_CONVERTCOMMA | EF_CONVERTEQUAL;
|
||||
EFOutputFlags = EF_CONVERTCOMMA | EF_CONVERTEQUAL;
|
||||
EFScale = 0.0;
|
||||
if (EFArgTech)
|
||||
{
|
||||
|
|
@ -647,6 +693,7 @@ runexttospice:
|
|||
|
||||
/* Reset the device indices */
|
||||
esCapNum = 0;
|
||||
esVoltNum = 0;
|
||||
esDevNum = 1000;
|
||||
esResNum = 0;
|
||||
esDiodeNum = 0;
|
||||
|
|
@ -832,10 +879,10 @@ runexttospice:
|
|||
|
||||
// This forces options TRIMGLOB and CONVERTEQUAL, not sure that's such a
|
||||
// good idea. . .
|
||||
EFTrimFlags |= EF_TRIMGLOB | EF_CONVERTEQUAL | EF_CONVERTCOMMA;
|
||||
EFOutputFlags |= EF_TRIMGLOB | EF_CONVERTEQUAL | EF_CONVERTCOMMA;
|
||||
if (IS_FINITE_F(EFCapThreshold)) flatFlags |= EF_FLATCAPS;
|
||||
if (esFormat == HSPICE)
|
||||
EFTrimFlags |= EF_TRIMLOCAL;
|
||||
EFOutputFlags |= EF_TRIMLOCAL;
|
||||
|
||||
/* Write globals under a ".global" card */
|
||||
|
||||
|
|
@ -1054,10 +1101,10 @@ main(argc, argv)
|
|||
|
||||
/* Convert the hierarchical description to a flat one */
|
||||
flatFlags = EF_FLATNODES;
|
||||
EFTrimFlags |= EF_TRIMGLOB ;
|
||||
EFOutputFlags |= EF_TRIMGLOB ;
|
||||
if (IS_FINITE_F(EFCapThreshold)) flatFlags |= EF_FLATCAPS;
|
||||
if (esFormat == HSPICE) {
|
||||
EFTrimFlags |= EF_TRIMLOCAL ;
|
||||
EFOutputFlags |= EF_TRIMLOCAL ;
|
||||
HashInit(&subcktNameTable, 32, HT_STRINGKEYS);
|
||||
#ifndef UNSORTED_SUBCKT
|
||||
DQInit(&subcktNameQueue, 64);
|
||||
|
|
@ -1392,14 +1439,14 @@ subcktVisit(use, hierName, is_top)
|
|||
}
|
||||
else
|
||||
{
|
||||
int savflags = EFTrimFlags;
|
||||
EFTrimFlags = EF_CONVERTCOMMA; // Only substitute commas on subcircuit names
|
||||
int savflags = EFOutputFlags;
|
||||
EFOutputFlags = EF_CONVERTCOMMA; // Only substitute commas on subcircuit names
|
||||
|
||||
/* Use full hierarchical decomposition for name */
|
||||
/* (not just use->use_id. hierName already has use->use_id at end) */
|
||||
EFHNSprintf(stmp, hierName);
|
||||
fprintf(esSpiceF, "X%s", stmp);
|
||||
EFTrimFlags = savflags;
|
||||
EFOutputFlags = savflags;
|
||||
tchars = 1 + strlen(stmp);
|
||||
}
|
||||
|
||||
|
|
@ -2393,7 +2440,8 @@ spcdevVisit(dev, hc, scale, trans)
|
|||
case DEV_CAPREV:
|
||||
if (dev->dev_nterm < 1)
|
||||
return 0;
|
||||
if (dev->dev_type == esNoModelType)
|
||||
if ((dev->dev_type == esNoModelType) ||
|
||||
!strcmp(EFDevTypes[dev->dev_type], "None"))
|
||||
has_model = FALSE;
|
||||
break;
|
||||
}
|
||||
|
|
@ -2439,6 +2487,9 @@ spcdevVisit(dev, hc, scale, trans)
|
|||
case DEV_RES:
|
||||
devchar = 'R';
|
||||
break;
|
||||
case DEV_VOLT:
|
||||
devchar = 'V';
|
||||
break;
|
||||
case DEV_CAP:
|
||||
case DEV_CAPREV:
|
||||
devchar = 'C';
|
||||
|
|
@ -2480,6 +2531,9 @@ spcdevVisit(dev, hc, scale, trans)
|
|||
case DEV_CAPREV:
|
||||
fprintf(esSpiceF, "%d", esCapNum++);
|
||||
break;
|
||||
case DEV_VOLT:
|
||||
fprintf(esSpiceF, "%d", esVoltNum++);
|
||||
break;
|
||||
case DEV_SUBCKT:
|
||||
case DEV_RSUBCKT:
|
||||
case DEV_CSUBCKT:
|
||||
|
|
@ -2631,6 +2685,19 @@ spcdevVisit(dev, hc, scale, trans)
|
|||
}
|
||||
break;
|
||||
|
||||
case DEV_VOLT:
|
||||
/* The voltage source is "Vnnn term1 term2 0.0" and is used
|
||||
* only to separate shorted port names.
|
||||
*/
|
||||
if (dev->dev_nterm > 1)
|
||||
spcdevOutNode(hierName, source->dterm_node->efnode_name->efnn_hier,
|
||||
name, esSpiceF);
|
||||
if (dev->dev_nterm > 1)
|
||||
spcdevOutNode(hierName, drain->dterm_node->efnode_name->efnn_hier,
|
||||
name, esSpiceF);
|
||||
fprintf(esSpiceF, " 0.0");
|
||||
break;
|
||||
|
||||
case DEV_DIODE:
|
||||
case DEV_PDIODE:
|
||||
|
||||
|
|
@ -3408,7 +3475,7 @@ retName:
|
|||
* EFHNSprintf --
|
||||
*
|
||||
* Create a hierarchical node name.
|
||||
* The flags in EFTrimFlags control whether global (!) or local (#)
|
||||
* The flags in EFOutputFlags control whether global (!) or local (#)
|
||||
* suffixes are to be trimmed. Also substitutes \. with \@ if the
|
||||
* format is hspice.
|
||||
*
|
||||
|
|
@ -3432,14 +3499,14 @@ EFHNSprintf(str, hierName)
|
|||
|
||||
s = str;
|
||||
if (hierName->hn_parent) str = efHNSprintfPrefix(hierName->hn_parent, str);
|
||||
if (EFTrimFlags)
|
||||
if (EFOutputFlags)
|
||||
{
|
||||
cp = hierName->hn_name;
|
||||
trimGlob = (EFTrimFlags & EF_TRIMGLOB);
|
||||
trimLocal = (EFTrimFlags & EF_TRIMLOCAL);
|
||||
convertComma = (EFTrimFlags & EF_CONVERTCOMMA);
|
||||
convertEqual = (EFTrimFlags & EF_CONVERTEQUAL);
|
||||
convertBrackets = (EFTrimFlags & EF_CONVERTBRACKETS);
|
||||
trimGlob = (EFOutputFlags & EF_TRIMGLOB);
|
||||
trimLocal = (EFOutputFlags & EF_TRIMLOCAL);
|
||||
convertComma = (EFOutputFlags & EF_CONVERTCOMMA);
|
||||
convertEqual = (EFOutputFlags & EF_CONVERTEQUAL);
|
||||
convertBrackets = (EFOutputFlags & EF_CONVERTBRACKETS);
|
||||
while (c = *cp++)
|
||||
{
|
||||
switch (c)
|
||||
|
|
@ -3465,9 +3532,9 @@ char *efHNSprintfPrefix(hierName, str)
|
|||
char *str;
|
||||
{
|
||||
char *cp, c;
|
||||
bool convertEqual = (EFTrimFlags & EF_CONVERTEQUAL) ? TRUE : FALSE;
|
||||
bool convertComma = (EFTrimFlags & EF_CONVERTCOMMA) ? TRUE : FALSE;
|
||||
bool convertBrackets = (EFTrimFlags & EF_CONVERTBRACKETS) ? TRUE : FALSE;
|
||||
bool convertEqual = (EFOutputFlags & EF_CONVERTEQUAL) ? TRUE : FALSE;
|
||||
bool convertComma = (EFOutputFlags & EF_CONVERTCOMMA) ? TRUE : FALSE;
|
||||
bool convertBrackets = (EFOutputFlags & EF_CONVERTBRACKETS) ? TRUE : FALSE;
|
||||
|
||||
if (hierName->hn_parent)
|
||||
str = efHNSprintfPrefix(hierName->hn_parent, str);
|
||||
|
|
@ -3750,6 +3817,9 @@ parallelDevs(f1, f2)
|
|||
case DEV_RSUBCKT:
|
||||
case DEV_CSUBCKT:
|
||||
break;
|
||||
|
||||
case DEV_VOLT:
|
||||
break;
|
||||
}
|
||||
return NOT_PARALLEL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ extern float esScale; /* negative if hspice the EFScale/100 otherwise */
|
|||
extern unsigned short esFormat;
|
||||
extern TileTypeBitMask initMask;
|
||||
|
||||
extern int esCapNum, esDevNum, esResNum, esDiodeNum;
|
||||
extern int esCapNum, esDevNum, esResNum, esDiodeNum, esVoltNum;
|
||||
extern int esNodeNum; /* just in case we're extracting spice2 */
|
||||
extern int esSbckNum; /* used in hspice node name shortening */
|
||||
extern int esNoModelType; /* index for device type "None" (model-less device) */
|
||||
|
|
@ -144,8 +144,6 @@ typedef struct {
|
|||
TTMaskZero (&((nodeClientHier *) (node)->efnode_client)->m_w.visitMask); \
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* attributes controlling the Area/Perimeter extraction of dev terminals */
|
||||
#define ATTR_FLATAP "*[Ee][Xx][Tt]:[Aa][Pp][Ff]*"
|
||||
#define ATTR_HIERAP "*[Ee][Xx][Tt]:[Aa][Pp][Hh]*"
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
/* Command-line flags */
|
||||
EFCapValue EFCapThreshold = 2; /* -c/-C: (fF) smallest interesting C */
|
||||
int EFResistThreshold = 10; /* -r/-R: (Ohms) smallest interesting R */
|
||||
int EFTrimFlags = 0; /* -t: output of nodename trailing #!'s */
|
||||
int EFOutputFlags = 0; /* -t: output of nodename trailing #!'s */
|
||||
char *EFSearchPath = NULL; /* -p: Search path for .ext files */
|
||||
char *EFArgTech = NULL; /* -T: Tech specified on command line */
|
||||
|
||||
|
|
@ -216,12 +216,12 @@ EFArgs(argc, argv, err_result, argsProc, cdata)
|
|||
case 't':
|
||||
if ((cp = ArgStr(&argc, &argv, "trim characters")) == NULL)
|
||||
goto usage;
|
||||
if (strchr(cp, '!')) EFTrimFlags |= EF_TRIMGLOB;
|
||||
if (strchr(cp, '#')) EFTrimFlags |= EF_TRIMLOCAL;
|
||||
if (strchr(cp, ',')) EFTrimFlags |= EF_CONVERTCOMMA;
|
||||
if (strchr(cp, '=')) EFTrimFlags |= EF_CONVERTEQUAL;
|
||||
if (strchr(cp, '[')) EFTrimFlags |= EF_CONVERTBRACKETS;
|
||||
if (strchr(cp, ']')) EFTrimFlags |= EF_CONVERTBRACKETS;
|
||||
if (strchr(cp, '!')) EFOutputFlags |= EF_TRIMGLOB;
|
||||
if (strchr(cp, '#')) EFOutputFlags |= EF_TRIMLOCAL;
|
||||
if (strchr(cp, ',')) EFOutputFlags |= EF_CONVERTCOMMA;
|
||||
if (strchr(cp, '=')) EFOutputFlags |= EF_CONVERTEQUAL;
|
||||
if (strchr(cp, '[')) EFOutputFlags |= EF_CONVERTBRACKETS;
|
||||
if (strchr(cp, ']')) EFOutputFlags |= EF_CONVERTBRACKETS;
|
||||
break;
|
||||
case 'C':
|
||||
EFCapThreshold = (EFCapValue)INFINITE_THRESHOLD_F;
|
||||
|
|
|
|||
|
|
@ -479,6 +479,35 @@ efBuildEquiv(def, nodeName1, nodeName2)
|
|||
else if (nn2->efnn_node == (EFNode *)NULL)
|
||||
return; /* Repeated "equiv" statement */
|
||||
|
||||
/* If both names exist and are for different ports, then keep */
|
||||
/* them separate and add a zero ohm resistor or a zero volt */
|
||||
/* source between them, based on the method set by "ext2spice */
|
||||
/* shorts". */
|
||||
|
||||
if (nn1 && nn2 && (nn1->efnn_port >= 0) && (nn2->efnn_port >= 0) &&
|
||||
(nn1->efnn_port != nn2->efnn_port))
|
||||
{
|
||||
if ((EFOutputFlags & EF_SHORT_MASK) != EF_SHORT_NONE)
|
||||
{
|
||||
int i;
|
||||
int sdev;
|
||||
char *argv[7], zeroarg[] = "0";
|
||||
|
||||
if ((EFOutputFlags & EF_SHORT_MASK) == EF_SHORT_R)
|
||||
sdev = DEV_RES;
|
||||
else
|
||||
sdev = DEV_VOLT;
|
||||
|
||||
for (i = 0; i < 10; i++) argv[i] = zeroarg;
|
||||
argv[4] = StrDup((char **)NULL, nodeName1);
|
||||
argv[7] = StrDup((char **)NULL, nodeName2);
|
||||
efBuildDevice(def, sdev, "None", &GeoNullRect, 10, argv);
|
||||
freeMagic(argv[4]);
|
||||
freeMagic(argv[7]);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* If both names exist and are for different nodes, merge them */
|
||||
if (nn1)
|
||||
{
|
||||
|
|
@ -813,9 +842,24 @@ efBuildDevice(def, class, type, r, argc, argv)
|
|||
*/
|
||||
|
||||
ttype = extGetDevType(type);
|
||||
if (ttype < 0)
|
||||
{
|
||||
/* For zero-ohm resistors used to separate ports on the same */
|
||||
/* net, generate a unique devhash. */
|
||||
ttype = DBNumTypes;
|
||||
while (1)
|
||||
{
|
||||
sprintf(devhash, "%dx%d_%d", r->r_xbot, r->r_ybot, ttype);
|
||||
he = HashLookOnly(&def->def_devs, devhash);
|
||||
if (he == NULL) break;
|
||||
ttype++;
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(devhash, "%dx%d_%d", r->r_xbot, r->r_ybot, ttype);
|
||||
he = HashFind(&def->def_devs, devhash);
|
||||
newdev = (Dev *)HashGetValue(he);
|
||||
|
||||
if (newdev)
|
||||
{
|
||||
/* Duplicate device. Duplicates will only appear in res.ext files
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/
|
|||
#ifndef MAGIC_WRAPPER
|
||||
/* This must match the definition for extDevTable in extract/ExtBasic.c */
|
||||
char *extDevTable[] = {"fet", "mosfet", "asymmetric", "bjt", "devres",
|
||||
"devcap", "devcaprev", "diode", "pdiode", "ndiode",
|
||||
"subckt", "rsubckt", "msubckt", "csubckt", NULL};
|
||||
"devcap", "devcaprev", "vsource", "diode", "pdiode",
|
||||
"ndiode", "subckt", "rsubckt", "msubckt", "csubckt", NULL};
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -847,7 +847,7 @@ EFLookDist(hn1, hn2, pMinDist, pMaxDist)
|
|||
* EFHNOut --
|
||||
*
|
||||
* Output a hierarchical node name.
|
||||
* The flags in EFTrimFlags control whether global (!) or local (#)
|
||||
* The flags in EFOutputFlags control whether global (!) or local (#)
|
||||
* suffixes are to be trimmed.
|
||||
*
|
||||
* Results:
|
||||
|
|
@ -868,13 +868,13 @@ EFHNOut(hierName, outf)
|
|||
char *cp, c;
|
||||
|
||||
if (hierName->hn_parent) efHNOutPrefix(hierName->hn_parent, outf);
|
||||
if (EFTrimFlags)
|
||||
if (EFOutputFlags)
|
||||
{
|
||||
cp = hierName->hn_name;
|
||||
trimGlob = (EFTrimFlags & EF_TRIMGLOB);
|
||||
trimLocal = (EFTrimFlags & EF_TRIMLOCAL);
|
||||
convComma = (EFTrimFlags & EF_CONVERTCOMMA);
|
||||
convBrackets = (EFTrimFlags & EF_CONVERTBRACKETS);
|
||||
trimGlob = (EFOutputFlags & EF_TRIMGLOB);
|
||||
trimLocal = (EFOutputFlags & EF_TRIMLOCAL);
|
||||
convComma = (EFOutputFlags & EF_CONVERTCOMMA);
|
||||
convBrackets = (EFOutputFlags & EF_CONVERTBRACKETS);
|
||||
while (c = *cp++)
|
||||
{
|
||||
if (*cp)
|
||||
|
|
|
|||
|
|
@ -37,13 +37,18 @@ typedef unsigned char U_char;
|
|||
#define EF_NONAMEMERGE 0x20 /* Don't merge unconnected nets */
|
||||
/* with the same name. */
|
||||
|
||||
/* Flags to control output of node names. Stored in EFTrimFlags */
|
||||
/* Flags to control output of node names. Stored in EFOutputFlags */
|
||||
#define EF_TRIMGLOB 0x01 /* Delete trailing '!' from names */
|
||||
#define EF_TRIMLOCAL 0x02 /* Delete trailing '#' from names */
|
||||
#define EF_CONVERTCOMMA 0x04 /* Change ',' to '|' in names, else remove */
|
||||
#define EF_CONVERTEQUAL 0x08 /* Change '=' to ':' in names, else remove */
|
||||
#define EF_CONVERTBRACKETS 0x10 /* Change '[' and ']' to '_' in names */
|
||||
|
||||
#define EF_SHORT_MASK 0x30 /* Mask for handling port shorts */
|
||||
#define EF_SHORT_NONE 0x00 /* Shorted ports are merged */
|
||||
#define EF_SHORT_R 0x10 /* Shorted ports separated with 0 ohm resistor */
|
||||
#define EF_SHORT_V 0x20 /* Shorted ports separated with 0 volt source */
|
||||
|
||||
/*
|
||||
* capacitance type now set to float
|
||||
*/
|
||||
|
|
@ -327,7 +332,7 @@ extern char *EFLayerNames[];
|
|||
extern int EFLayerNumNames;
|
||||
|
||||
/* Output control flags */
|
||||
extern int EFTrimFlags;
|
||||
extern int EFOutputFlags;
|
||||
|
||||
/* -------------------------- Exported procedures --------------------- */
|
||||
|
||||
|
|
|
|||
|
|
@ -55,8 +55,8 @@ static char sccsid[] = "@(#)ExtBasic.c 4.13 MAGIC (Berkeley) 12/5/85";
|
|||
|
||||
#ifdef MAGIC_WRAPPER
|
||||
char *extDevTable[] = {"fet", "mosfet", "asymmetric", "bjt", "devres",
|
||||
"devcap", "devcaprev", "diode", "pdiode", "ndiode", "subckt",
|
||||
"rsubckt", "msubckt", "csubckt", NULL};
|
||||
"devcap", "devcaprev", "vsource", "diode", "pdiode", "ndiode",
|
||||
"subckt", "rsubckt", "msubckt", "csubckt", NULL};
|
||||
#endif
|
||||
|
||||
/* --------------------- Data local to this file ---------------------- */
|
||||
|
|
|
|||
|
|
@ -46,13 +46,14 @@ extern int ExtDoWarn; /* Bitmask of above */
|
|||
#define DEV_RES 4 /* Resistor */
|
||||
#define DEV_CAP 5 /* Capacitor */
|
||||
#define DEV_CAPREV 6 /* Capacitor, terminals reversed */
|
||||
#define DEV_DIODE 7 /* Diode */
|
||||
#define DEV_PDIODE 8 /* pDiode, same as Diode */
|
||||
#define DEV_NDIODE 9 /* nDiode, terminals reversed */
|
||||
#define DEV_SUBCKT 10 /* general-purpose subcircuit */
|
||||
#define DEV_RSUBCKT 11 /* Resistor-like subcircuit. */
|
||||
#define DEV_MSUBCKT 12 /* MOSFET-like subcircuit. */
|
||||
#define DEV_CSUBCKT 13 /* Capacitor-like subcircuit. */
|
||||
#define DEV_VOLT 7 /* Voltage source (used for shorts) */
|
||||
#define DEV_DIODE 8 /* Diode */
|
||||
#define DEV_PDIODE 9 /* pDiode, same as Diode */
|
||||
#define DEV_NDIODE 10 /* nDiode, terminals reversed */
|
||||
#define DEV_SUBCKT 11 /* general-purpose subcircuit */
|
||||
#define DEV_RSUBCKT 12 /* Resistor-like subcircuit. */
|
||||
#define DEV_MSUBCKT 13 /* MOSFET-like subcircuit. */
|
||||
#define DEV_CSUBCKT 14 /* Capacitor-like subcircuit. */
|
||||
|
||||
/* Device names for .ext file output (new in version 7.2) */
|
||||
/* (defined in extract/ExtBasic.c *and* extflat/EFread.c) */
|
||||
|
|
@ -60,14 +61,15 @@ extern int ExtDoWarn; /* Bitmask of above */
|
|||
extern char *extDevTable[];
|
||||
|
||||
/* Extractor options */
|
||||
#define EXT_DOADJUST 0x01 /* Extract hierarchical adjustments */
|
||||
#define EXT_DOCAPACITANCE 0x02 /* Extract capacitance */
|
||||
#define EXT_DOCOUPLING 0x04 /* Extract coupling capacitance */
|
||||
#define EXT_DORESISTANCE 0x08 /* Extract resistance */
|
||||
#define EXT_DOLENGTH 0x10 /* Extract pathlengths */
|
||||
#define EXT_DOALL 0x1f /* ALL OF THE ABOVE */
|
||||
#define EXT_DOLOCAL 0x20 /* Write to local directory only */
|
||||
#define EXT_DOLABELCHECK 0x40 /* Check for connections by label */
|
||||
|
||||
#define EXT_DOADJUST 0x001 /* Extract hierarchical adjustments */
|
||||
#define EXT_DOCAPACITANCE 0x002 /* Extract capacitance */
|
||||
#define EXT_DOCOUPLING 0x004 /* Extract coupling capacitance */
|
||||
#define EXT_DORESISTANCE 0x008 /* Extract resistance */
|
||||
#define EXT_DOLENGTH 0x010 /* Extract pathlengths */
|
||||
#define EXT_DOALL 0x01f /* ALL OF THE ABOVE */
|
||||
#define EXT_DOLOCAL 0x020 /* Write to local directory only */
|
||||
#define EXT_DOLABELCHECK 0x040 /* Check for connections by label */
|
||||
|
||||
extern int ExtOptions; /* Bitmask of above */
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue