Merge branch 'master' into magic-8.2

This commit is contained in:
Tim Edwards 2019-08-20 03:00:04 -04:00
commit 5c614c3d64
13 changed files with 856 additions and 491 deletions

File diff suppressed because it is too large Load Diff

View File

@ -299,36 +299,41 @@ ExtGetDevInfo(idx, devnameptr, sd_rclassptr, sub_rclassptr, subnameptr)
TileTypeBitMask *rmask, *tmask;
int n, i = 0, j;
bool repeat;
ExtDevice *devptr;
char *locdname;
char **uniquenamelist = (char **)mallocMagic(DBNumTypes * sizeof(char *));
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
{
locdname = ExtCurStyle->exts_transName[t];
if (locdname != NULL)
for (devptr = ExtCurStyle->exts_device[t]; devptr; devptr = devptr->exts_next)
{
repeat = FALSE;
for (j = 0; j < i; j++)
if (!strcmp(uniquenamelist[j], locdname))
{
repeat = TRUE;
break;
}
if (repeat == FALSE)
locdname = devptr->exts_deviceName;
if (locdname != NULL)
{
if (i == idx) break;
uniquenamelist[i] = locdname;
i++;
repeat = FALSE;
for (j = 0; j < i; j++)
if (!strcmp(uniquenamelist[j], locdname))
{
repeat = TRUE;
break;
}
if (repeat == FALSE)
{
if (i == idx) break;
uniquenamelist[i] = locdname;
i++;
}
}
}
}
if (t == DBNumTypes) return FALSE;
if (devptr == NULL) return FALSE;
*devnameptr = locdname;
*subnameptr = ExtCurStyle->exts_transSubstrateName[t];
*subnameptr = devptr->exts_deviceSubstrateName;
tmask = &ExtCurStyle->exts_transSDTypes[t][0];
tmask = &devptr->exts_deviceSDTypes[0];
*sd_rclassptr = (short)(-1); /* NO_RESCLASS */
for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++)
@ -341,7 +346,7 @@ ExtGetDevInfo(idx, devnameptr, sd_rclassptr, sub_rclassptr, subnameptr)
}
}
tmask = &ExtCurStyle->exts_transSubstrateTypes[t];
tmask = &devptr->exts_deviceSubstrateTypes;
*sub_rclassptr = (short)(-1); /* NO_RESCLASS */
for (n = 0; n < ExtCurStyle->exts_numResistClasses; n++)
@ -538,23 +543,10 @@ extTechStyleAlloc()
TileType r;
style = (ExtStyle *) mallocMagic(sizeof (ExtStyle));
/* Make sure that the memory for character strings is NULL, */
/* because we want the Init section to free memory if it */
/* has been previously allocated. */
for (r = 0; r < NT; r++)
{
style->exts_transSubstrateName[r] = (char *) NULL;
style->exts_transName[r] = (char *) NULL;
style->exts_transSDTypes[r] = (TileTypeBitMask *) NULL;
style->exts_deviceParams[r] = (ParamList *) NULL;
style->exts_deviceClass[r] = (char) 0;
style->exts_transResist[r].ht_table = (HashEntry **) NULL;
}
return style;
}
/*
* ----------------------------------------------------------------------------
*
@ -575,7 +567,7 @@ extTechStyleInit(style)
style->exts_status = TECH_NOT_LOADED;
style->exts_sidePlanes = style->exts_overlapPlanes = 0;
TTMaskZero(&style->exts_transMask);
TTMaskZero(&style->exts_deviceMask);
style->exts_activeTypes = DBAllButSpaceAndDRCBits;
for (r = 0; r < NP; r++)
@ -589,7 +581,7 @@ extTechStyleInit(style)
{
TTMaskZero(&style->exts_nodeConn[r]);
TTMaskZero(&style->exts_resistConn[r]);
TTMaskZero(&style->exts_transConn[r]);
TTMaskZero(&style->exts_deviceConn[r]);
style->exts_allConn[r] = DBAllTypeBits;
style->exts_sheetResist[r] = 0;
@ -620,43 +612,41 @@ extTechStyleInit(style)
#ifdef ARIEL
TTMaskZero(&style->exts_subsTransistorTypes[r]);
#endif
if (style->exts_transSDTypes[r] != NULL)
freeMagic(style->exts_transSDTypes[r]);
style->exts_transSDTypes[r] = NULL;
style->exts_transSDCount[r] = 0;
style->exts_transGateCap[r] = (CapValue) 0;
style->exts_transSDCap[r] = (CapValue) 0;
if (style->exts_transSubstrateName[r] != (char *) NULL)
if (style->exts_device[r] != NULL)
{
freeMagic(style->exts_transSubstrateName[r]);
style->exts_transSubstrateName[r] = (char *) NULL;
}
if (style->exts_transName[r] != (char *) NULL)
{
freeMagic(style->exts_transName[r]);
style->exts_transName[r] = (char *) NULL;
}
while (style->exts_deviceParams[r] != (ParamList *) NULL)
{
/* Parameter lists are shared. Only free the last one! */
ExtDevice *devptr;
for (devptr = style->exts_device[r]; devptr; devptr = devptr->exts_next)
{
if (style->exts_deviceParams[r]->pl_count > 1)
{
style->exts_deviceParams[r]->pl_count--;
style->exts_deviceParams[r] = (ParamList *)NULL;
}
else
{
freeMagic(style->exts_deviceParams[r]->pl_name);
freeMagic(style->exts_deviceParams[r]);
style->exts_deviceParams[r] = style->exts_deviceParams[r]->pl_next;
if (devptr->exts_deviceSDTypes != NULL)
freeMagic(devptr->exts_deviceSDTypes);
if (devptr->exts_deviceSubstrateName != (char *) NULL)
freeMagic(devptr->exts_deviceSubstrateName);
if (devptr->exts_deviceName != (char *) NULL)
freeMagic(devptr->exts_deviceName);
while (devptr->exts_deviceParams != (ParamList *) NULL)
{
/* Parameter lists are shared. Only free the last one! */
if (devptr->exts_deviceParams->pl_count > 1)
{
devptr->exts_deviceParams->pl_count--;
devptr->exts_deviceParams = (ParamList *)NULL;
}
else
{
freeMagic(devptr->exts_deviceParams->pl_name);
freeMagic(devptr->exts_deviceParams);
devptr->exts_deviceParams = devptr->exts_deviceParams->pl_next;
}
}
if (devptr->exts_deviceResist.ht_table != (HashEntry **) NULL)
HashKill(&devptr->exts_deviceResist);
freeMagic(devptr);
}
style->exts_device[r] = (ExtDevice *)NULL;
}
style->exts_deviceClass[r] = (char)0;
if (style->exts_transResist[r].ht_table != (HashEntry **) NULL)
HashKill(&style->exts_transResist[r]);
HashInit(&style->exts_transResist[r], 8, HT_STRINGKEYS);
style->exts_linearResist[r] = 0;
}
style->exts_sideCoupleHalo = 0;
@ -798,14 +788,6 @@ ExtTechInit()
if (ExtCurStyle != NULL)
{
extTechStyleInit(ExtCurStyle);
/* Everything has been freed except the hash tables, which */
/* were just reinitialized by extTechStyleInit(). */
for (r = 0; r < NT; r++)
{
if (ExtCurStyle->exts_transResist[r].ht_table != (HashEntry **) NULL)
HashKill(&ExtCurStyle->exts_transResist[r]);
}
ExtCurStyle = NULL;
}
@ -1569,7 +1551,7 @@ ExtTechLine(sectionName, argc, argv)
PlaneMask pshield, pov;
CapValue capVal, gscap, gccap;
TileTypeBitMask types1, types2, termtypes[MAXSD];
TileTypeBitMask near, far, ov, shield, subsTypes;
TileTypeBitMask near, far, ov, shield, subsTypes, idTypes;
char *subsName, *transName, *cp, *endptr, *paramName;
TileType s, t, r, o;
keydesc *kp, *dv;
@ -1578,6 +1560,7 @@ ExtTechLine(sectionName, argc, argv)
EdgeCap *cnew;
ExtKeep *es, *newStyle;
ParamList *subcktParams, *newParam;
ExtDevice *devptr;
int refcnt;
double dhalo;
bool bad;
@ -1888,24 +1871,32 @@ ExtTechLine(sectionName, argc, argv)
gccap = (argc > 7) ? aToCap(argv[7]) : (CapValue) 0;
}
TTMaskSetMask(&ExtCurStyle->exts_transMask, &types1);
TTMaskSetMask(&ExtCurStyle->exts_deviceMask, &types1);
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
if (TTMaskHasType(&types1, t))
{
TTMaskSetMask(ExtCurStyle->exts_transConn+t,&types1);
ExtCurStyle->exts_transSDTypes[t] = (TileTypeBitMask *)
devptr = (ExtDevice *)mallocMagic(sizeof(ExtDevice));
devptr->exts_deviceSDTypes = (TileTypeBitMask *)
mallocMagic(2 * sizeof(TileTypeBitMask));
ExtCurStyle->exts_transSDTypes[t][0] = termtypes[0];
ExtCurStyle->exts_transSDTypes[t][1] = DBZeroTypeBits;
ExtCurStyle->exts_transSDCount[t] = nterm;
ExtCurStyle->exts_transSDCap[t] = gscap;
ExtCurStyle->exts_transGateCap[t] = gccap;
ExtCurStyle->exts_deviceClass[t] = DEV_FET;
ExtCurStyle->exts_transName[t] =
StrDup((char **) NULL, transName);
ExtCurStyle->exts_transSubstrateName[t] =
devptr->exts_deviceSDTypes[0] = termtypes[0];
devptr->exts_deviceSDTypes[1] = DBZeroTypeBits;
devptr->exts_deviceSDCount = nterm;
devptr->exts_deviceSDCap = gscap;
devptr->exts_deviceGateCap = gccap;
devptr->exts_deviceClass = DEV_FET;
devptr->exts_deviceName = StrDup((char **) NULL, transName);
devptr->exts_deviceSubstrateName =
StrDup((char **) NULL, subsName);
ExtCurStyle->exts_transSubstrateTypes[t] = subsTypes;
devptr->exts_deviceSubstrateTypes = subsTypes;
devptr->exts_deviceIdentifierTypes = DBZeroTypeBits;
devptr->exts_deviceParams = (ParamList *) NULL;
devptr->exts_deviceResist.ht_table = (HashEntry **) NULL;
HashInit(&devptr->exts_deviceResist, 8, HT_STRINGKEYS);
TTMaskSetMask(ExtCurStyle->exts_deviceConn + t, &types1);
devptr->exts_next = ExtCurStyle->exts_device[t];
ExtCurStyle->exts_device[t] = devptr;
#ifdef ARIEL
{
int z;
@ -1941,7 +1932,7 @@ ExtTechLine(sectionName, argc, argv)
/* Parse second argument for device type */
n = LookupStruct(argv[1], (LookupTable *) devTable, sizeof devTable[0]);
n = LookupStruct(argv[1], (LookupTable *)devTable, sizeof devTable[0]);
if (n < 0)
{
TechError("Illegal device. Legal devices are:\n\t");
@ -1999,6 +1990,18 @@ ExtTechLine(sectionName, argc, argv)
argc--;
}
/* If the last entry before any parameters starts with '+', */
/* then use it to set the identity marker. Otherwise, the */
/* identity marker is NULL. */
idTypes = DBZeroTypeBits;
if (*argv[argc - 1] == '+')
{
if ((DBTechNameMask(argv[argc - 1] + 1, &idTypes)) == 0)
idTypes = DBZeroTypeBits;
argc--;
}
/* Check the number of arguments after splitting out */
/* parameter entries. There is no limit on arguments in */
/* DEV_SUBCKT and DEV_MSUBCKT. */
@ -2194,31 +2197,45 @@ ExtTechLine(sectionName, argc, argv)
break;
}
TTMaskSetMask(&ExtCurStyle->exts_transMask, &types1);
TTMaskSetMask(&ExtCurStyle->exts_deviceMask, &types1);
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
{
if (TTMaskHasType(&types1, t))
{
TTMaskSetMask(ExtCurStyle->exts_transConn + t, &types1);
devptr = (ExtDevice *)mallocMagic(sizeof(ExtDevice));
for (i = 0; !TTMaskIsZero(&termtypes[i]); i++);
ExtCurStyle->exts_transSDTypes[t] = (TileTypeBitMask *)
devptr->exts_deviceSDTypes = (TileTypeBitMask *)
mallocMagic((i + 1) * sizeof(TileTypeBitMask));
for (i = 0; !TTMaskIsZero(&termtypes[i]); i++)
ExtCurStyle->exts_transSDTypes[t][i] = termtypes[i];
ExtCurStyle->exts_transSDTypes[t][i] = DBZeroTypeBits;
devptr->exts_deviceSDTypes[i] = termtypes[i];
devptr->exts_deviceSDTypes[i] = DBZeroTypeBits;
ExtCurStyle->exts_transSDCount[t] = nterm;
ExtCurStyle->exts_transSDCap[t] = gscap;
ExtCurStyle->exts_transGateCap[t] = gccap;
ExtCurStyle->exts_deviceClass[t] = class;
ExtCurStyle->exts_transName[t] =
StrDup((char **) NULL, transName);
devptr->exts_deviceSDCount = nterm;
devptr->exts_deviceSDCap = gscap;
devptr->exts_deviceGateCap = gccap;
devptr->exts_deviceClass = class;
devptr->exts_deviceName = StrDup((char **) NULL, transName);
if (subsName != NULL)
ExtCurStyle->exts_transSubstrateName[t] =
devptr->exts_deviceSubstrateName =
StrDup((char **) NULL, subsName);
ExtCurStyle->exts_transSubstrateTypes[t] = subsTypes;
devptr->exts_deviceSubstrateTypes = subsTypes;
devptr->exts_deviceIdentifierTypes = idTypes;
devptr->exts_deviceParams = (ParamList *) NULL;
if (subcktParams != NULL)
{
devptr->exts_deviceParams = subcktParams;
subcktParams->pl_count++;
}
devptr->exts_deviceResist.ht_table = (HashEntry **) NULL;
HashInit(&devptr->exts_deviceResist, 8, HT_STRINGKEYS);
devptr->exts_next = ExtCurStyle->exts_device[t];
ExtCurStyle->exts_device[t] = devptr;
TTMaskSetMask(ExtCurStyle->exts_deviceConn + t, &types1);
#ifdef ARIEL
{
int z;
@ -2231,11 +2248,6 @@ ExtTechLine(sectionName, argc, argv)
}
}
#endif
if (subcktParams != NULL)
{
ExtCurStyle->exts_deviceParams[t] = subcktParams;
subcktParams->pl_count++;
}
}
}
break;
@ -2249,13 +2261,19 @@ ExtTechLine(sectionName, argc, argv)
val = atoi(argv[3]);
isLinear = (strcmp(argv[2], "linear") == 0);
for (t = TT_TECHDEPBASE; t < DBNumTypes; t++)
{
ExtDevice *devptr;
if (TTMaskHasType(&types1, t))
{
he = HashFind(&ExtCurStyle->exts_transResist[t], argv[2]);
HashSetValue(he, (spointertype)val);
if (isLinear)
ExtCurStyle->exts_linearResist[t] = val;
for (devptr = ExtCurStyle->exts_device[t]; devptr; devptr = devptr->exts_next)
{
he = HashFind(&devptr->exts_deviceResist, argv[2]);
HashSetValue(he, (spointertype)val);
if (isLinear)
devptr->exts_linearResist = val;
}
}
}
break;
case HEIGHT: {
float height, thick;
@ -2619,7 +2637,7 @@ diffplane:
*
* Postprocess the technology specific information for extraction.
* Builds the connectivity tables exts_nodeConn[], exts_resistConn[],
* and exts_transConn[].
* and exts_deviceConn[].
*
* Results:
* None.
@ -2664,9 +2682,9 @@ extTechFinalStyle(style)
for (r = TT_TECHDEPBASE; r < DBNumTypes; r++)
{
maskBits = style->exts_nodeConn[r] = DBConnectTbl[r];
if (!TTMaskHasType(&style->exts_transMask, r))
if (!TTMaskHasType(&style->exts_deviceMask, r))
{
TTMaskZero(&style->exts_transConn[r]);
TTMaskZero(&style->exts_deviceConn[r]);
}
for (s = TT_TECHDEPBASE; s < DBNumTypes; s++)
{
@ -2870,10 +2888,15 @@ zinit:
for (r = 0; r < DBNumTypes; r++)
{
style->exts_areaCap[r] *= sqfac;
style->exts_transSDCap[r] *= sqfac;
style->exts_transGateCap[r] *= sqfac;
ExtDevice *devptr;
for (devptr = style->exts_device[r]; devptr; devptr = devptr->exts_next)
{
devptr->exts_deviceSDCap *= sqfac;
devptr->exts_deviceGateCap *= sqfac;
}
style->exts_areaCap[r] *= sqfac;
for (s = 0; s < DBNumTypes; s++)
{
EdgeCap *ec;
@ -2953,13 +2976,18 @@ ExtTechScale(scalen, scaled)
for (i = 0; i < DBNumTypes; i++)
{
ExtDevice *devptr;
style->exts_areaCap[i] *= sqn;
style->exts_areaCap[i] /= sqd;
style->exts_transSDCap[i] *= sqn;
style->exts_transSDCap[i] /= sqd;
style->exts_transGateCap[i] *= sqn;
style->exts_transGateCap[i] /= sqd;
for (devptr = style->exts_device[i]; devptr; devptr = devptr->exts_next)
{
devptr->exts_deviceSDCap *= sqn;
devptr->exts_deviceSDCap /= sqd;
devptr->exts_deviceGateCap *= sqn;
devptr->exts_deviceGateCap /= sqd;
}
style->exts_height[i] *= scaled;
style->exts_height[i] /= scalen;

View File

@ -361,7 +361,7 @@ extShowTech(name)
}
}
extShowTrans("Transistor", &ExtCurStyle->exts_transMask, out);
extShowTrans("Transistor", &ExtCurStyle->exts_deviceMask, out);
fprintf(out, "\nNode resistance and capacitance:\n");
fprintf(out, "type R-ohm/sq AreaC-ff/l**2\n");
@ -472,7 +472,7 @@ extShowTech(name)
extShowConnect("\nNode connectivity", ExtCurStyle->exts_nodeConn, out);
extShowConnect("\nResistive region connectivity", ExtCurStyle->exts_resistConn, out);
extShowConnect("\nTransistor connectivity", ExtCurStyle->exts_transConn, out);
extShowConnect("\nTransistor connectivity", ExtCurStyle->exts_deviceConn, out);
if (out != stdout)
(void) fclose(out);
@ -493,12 +493,17 @@ extShowTrans(name, mask, out)
for (t = 0; t < DBNumTypes; t++)
if (TTMaskHasType(mask, t))
{
fprintf(out, " %-8.8s %d terminals: ",
DBTypeShortName(t), ExtCurStyle->exts_transSDCount[t]);
extShowMask(&ExtCurStyle->exts_transSDTypes[t][0], out);
fprintf(out, "\n\tcap (gate-sd/gate-ch) = %lf/%lf\n",
ExtCurStyle->exts_transSDCap[t],
ExtCurStyle->exts_transGateCap[t]);
ExtDevice *devptr;
for (devptr = ExtCurStyle->exts_device[t]; devptr; devptr = devptr->exts_next)
{
fprintf(out, " %-8.8s %d terminals: ",
DBTypeShortName(t), devptr->exts_deviceSDCount);
extShowMask(&devptr->exts_deviceSDTypes[0], out);
fprintf(out, "\n\tcap (gate-sd/gate-ch) = %lf/%lf\n",
devptr->exts_deviceSDCap,
devptr->exts_deviceGateCap);
}
}
}

View File

@ -348,7 +348,7 @@ extTimesCellFunc(cs)
/* Count the number of transistors */
transList = (TransRegion *) ExtFindRegions(def, &TiPlaneRect,
&ExtCurStyle->exts_transMask, ExtCurStyle->exts_transConn,
&ExtCurStyle->exts_deviceMask, ExtCurStyle->exts_deviceConn,
extUnInit, extTransFirst, extTransEach);
ExtResetTiles(def, extUnInit);
for (tl = transList; tl; tl = tl->treg_next)

View File

@ -483,6 +483,82 @@ typedef struct extkeep
char *exts_name;
} ExtKeep;
/*
* Structure used to define transistors and other extracted devices
* One of these records is kept per tile type. However, the record
* can link to additional records through the "exts_next" record,
* so that multiple extraction devices can be defined for the same
* tile type, provided that each definition has a unique combination
* of exts_deviceSDTypes and exts_deviceSubstrateTypes.
*/
typedef struct extDevice
{
/* Name of each transistor type as output in .ext file */
char *exts_deviceName;
/* List of parameter names for each subcircuit type */
ParamList *exts_deviceParams;
/* Device class for each layer type */
char exts_deviceClass;
/*
* Per-square resistances for each possible transistor type,
* in the various regions that such a type might operate.
* The only operating region currently used is "linear",
* which the resistance extractor uses in its thresholding
* operation. NOTE: resistances in this table are in OHMS
* per square, not MILLIOHMS!
*/
HashTable exts_deviceResist;
ResValue exts_linearResist;
/*
* Mask of the types of tiles that connect to the channel terminals
* of a transistor type. The intent is that these will be the
* diffusion terminals of a transistor, ie, its source and drain.
* UPDATED May, 2008: Record is a list of type masks, allowing
* multiple terminal types in the case of, e.g., high-voltage
* or other asymmetric devices. The last entry in the list should
* be equal to DBSpaceBits.
*/
TileTypeBitMask *exts_deviceSDTypes;
/*
* Maximum number of terminals (source/drains) per transistor type.
* This table exists to allow the possibility of transistors with
* more than two diffusion terminals at some point in the future.
*/
int exts_deviceSDCount;
/* Currently unused: gate-source capacitance per unit perimeter */
CapValue exts_deviceSDCap;
/* Currently unused: gate-channel capacitance per unit area */
CapValue exts_deviceGateCap;
/*
* Each type of transistor has a substrate node. By default,
* it is the one given by exts_deviceSubstrateName[t]. However,
* if the mask exts_deviceSubstrateTypes is non-zero, and if
* the transistor overlaps material of one of the types in the
* mask, then the transistor substrate node is the node of the
* material it overlaps.
*/
char *exts_deviceSubstrateName;
TileTypeBitMask exts_deviceSubstrateTypes;
/*
* Each device type can have any number of extract models based
* on identifier layers (such as thickox, esd, etc.)
*/
TileTypeBitMask exts_deviceIdentifierTypes;
struct extDevice *exts_next;
} ExtDevice;
/*
* Parameters for the process being extracted.
* We try to use use integers here, rather than floats, to be nice to
@ -524,11 +600,11 @@ typedef struct extstyle
TileTypeBitMask exts_resistConn[NT];
/*
* Connectivity for determining transistors.
* Each transistor type should connect only to itself.
* Connectivity for determining devices.
* Each devices type should connect only to itself.
* Nothing else should connect to anything else.
*/
TileTypeBitMask exts_transConn[NT];
TileTypeBitMask exts_deviceConn[NT];
/*
* Set of types to be considered for extraction. Types not in
@ -779,65 +855,14 @@ typedef struct extstyle
*/
TileTypeBitMask exts_sideEdges[NT];
/* Transistors */
/* Devices */
/* Name of each transistor type as output in .ext file */
char *exts_transName[NT];
/* Contains one for each type of device, zero for all other tile types */
TileTypeBitMask exts_deviceMask;
/* List of parameter names for each subcircuit type */
ParamList *exts_deviceParams[NT];
/* All information about a device goes in this record (see above) */
ExtDevice *exts_device[NT];
/* Device class for each layer type */
char exts_deviceClass[NT];
/* Contains one for each type of fet, zero for all other types */
TileTypeBitMask exts_transMask;
/*
* Per-square resistances for each possible transistor type,
* in the various regions that such a type might operate.
* The only operating region currently used is "linear",
* which the resistance extractor uses in its thresholding
* operation. NOTE: resistances in this table are in OHMS
* per square, not MILLIOHMS!
*/
HashTable exts_transResist[NT];
ResValue exts_linearResist[NT];
/*
* Mask of the types of tiles that connect to the channel terminals
* of a transistor type. The intent is that these will be the
* diffusion terminals of a transistor, ie, its source and drain.
* UPDATED May, 2008: Record is a list of type masks, allowing
* multiple terminal types in the case of, e.g., high-voltage
* or other asymmetric devices. The last entry in the list should
* be equal to DBSpaceBits.
*/
TileTypeBitMask *exts_transSDTypes[NT];
/*
* Maximum number of terminals (source/drains) per transistor type.
* This table exists to allow the possibility of transistors with
* more than two diffusion terminals at some point in the future.
*/
int exts_transSDCount[NT];
/* Currently unused: gate-source capacitance per unit perimeter */
CapValue exts_transSDCap[NT];
/* Currently unused: gate-channel capacitance per unit area */
CapValue exts_transGateCap[NT];
/*
* Each type of transistor has a substrate node. By default,
* it is the one given by exts_transSubstrateName[t]. However,
* if the mask exts_transSubstrateTypes[t] is non-zero, and if
* the transistor overlaps material of one of the types in the
* mask, then the transistor substrate node is the node of the
* material it overlaps. If exts_transSub
*/
char *exts_transSubstrateName[NT];
TileTypeBitMask exts_transSubstrateTypes[NT];
#ifdef ARIEL
TileTypeBitMask exts_subsTransistorTypes[NT];
#endif /* ARIEL */

View File

@ -139,6 +139,7 @@ ResEachTile(tile, startpoint)
bool merged;
tElement *tcell;
tileJunk *tstructs= (tileJunk *)(tile->ti_client);
ExtDevice *devptr;
ResTileCount++;
@ -165,7 +166,7 @@ ResEachTile(tile, startpoint)
resNodeIsPort(resptr, x, y, tile);
}
if TTMaskHasType(&(ExtCurStyle->exts_transMask), t1)
if TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t1)
{
/*
* The transistor is put in the center of the tile. This is fine
@ -250,8 +251,9 @@ ResEachTile(tile, startpoint)
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp=RT(tp))
{
t2 = TiGetRightType(tp);
if(TTMaskHasType(&(ExtCurStyle->exts_transMask), t2) &&
TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[t2][0]), t1))
devptr = ExtCurStyle->exts_device[t2];
if(TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1))
/* found transistor */
{
xj = LEFT(tile);
@ -272,8 +274,9 @@ ResEachTile(tile, startpoint)
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp=LB(tp))
{
t2 = TiGetLeftType(tp);
if(TTMaskHasType(&(ExtCurStyle->exts_transMask), t2) &&
TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[t2][0]), t1))
devptr = ExtCurStyle->exts_device[t2];
if(TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1))
/* found transistor */
{
xj = RIGHT(tile);
@ -294,8 +297,9 @@ ResEachTile(tile, startpoint)
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp=BL(tp))
{
t2 = TiGetBottomType(tp);
if(TTMaskHasType(&(ExtCurStyle->exts_transMask),t2) &&
TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[t2][0]),t1))
devptr = ExtCurStyle->exts_device[t2];
if(TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) &&
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1))
/* found transistor */
{
yj = TOP(tile);
@ -315,8 +319,9 @@ ResEachTile(tile, startpoint)
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp=TR(tp))
{
t2 = TiGetTopType(tp);
if(TTMaskHasType(&(ExtCurStyle->exts_transMask), t2) &&
TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[t2][0]), t1))
devptr = ExtCurStyle->exts_device[t2];
if(TTMaskHasType(&(ExtCurStyle->exts_deviceMask), t2) &&
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), t1))
/* found transistor */
{
yj = BOTTOM(tile);

View File

@ -102,6 +102,7 @@ dbcConnectFuncDCS(tile, cx)
SearchContext scx2;
int pNum;
CellDef *def;
ExtDevice *devptr;
TiToRect(tile, &tileArea);
srArea = &scx->scx_area;
@ -121,8 +122,9 @@ dbcConnectFuncDCS(tile, cx)
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp=RT(tp))
{
t2 = TiGetType(tp);
if (TTMaskHasType(&(ExtCurStyle->exts_transMask),t2) &&
TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[t2][0]),t1))
devptr = ExtCurStyle->exts_device[t2];
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) &&
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1))
{
TiToRect(tp, &tranArea);
thisTran = (ResTranTile *) mallocMagic((unsigned)(sizeof(ResTranTile)));
@ -137,8 +139,9 @@ dbcConnectFuncDCS(tile, cx)
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp=LB(tp))
{
t2 = TiGetType(tp);
if (TTMaskHasType(&(ExtCurStyle->exts_transMask),t2) &&
TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[t2][0]),t1))
devptr = ExtCurStyle->exts_device[t2];
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) &&
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1))
{
TiToRect(tp, &tranArea);
thisTran = (ResTranTile *) mallocMagic((unsigned)(sizeof(ResTranTile)));
@ -153,8 +156,9 @@ dbcConnectFuncDCS(tile, cx)
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp=BL(tp))
{
t2 = TiGetType(tp);
if (TTMaskHasType(&(ExtCurStyle->exts_transMask),t2) &&
TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[t2][0]),t1))
devptr = ExtCurStyle->exts_device[t2];
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) &&
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1))
{
TiToRect(tp, &tranArea);
thisTran = (ResTranTile *) mallocMagic((unsigned)(sizeof(ResTranTile)));
@ -169,8 +173,9 @@ dbcConnectFuncDCS(tile, cx)
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp=TR(tp))
{
t2 = TiGetType(tp);
if (TTMaskHasType(&(ExtCurStyle->exts_transMask),t2) &&
TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[t2][0]),t1))
devptr = ExtCurStyle->exts_device[t2];
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t2) &&
TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t1))
{
TiToRect(tp, &tranArea);
thisTran = (ResTranTile *) mallocMagic((unsigned)(sizeof(ResTranTile)));
@ -182,7 +187,7 @@ dbcConnectFuncDCS(tile, cx)
}
}
}
else if TTMaskHasType(&(ExtCurStyle->exts_transMask),t1)
else if TTMaskHasType(&(ExtCurStyle->exts_deviceMask),t1)
{
TiToRect(tile, &tranArea);
thisTran = (ResTranTile *) mallocMagic((unsigned)(sizeof(ResTranTile)));
@ -425,6 +430,7 @@ DBTreeCopyConnectDCS(scx, mask, xMask, connect, area, destUse)
ResTranTile *CurrentT;
CellDef *def = destUse->cu_def;
TileType newtype;
ExtDevice *devptr;
csa2.csa2_use = destUse;
csa2.csa2_xMask = xMask;
@ -443,13 +449,14 @@ DBTreeCopyConnectDCS(scx, mask, xMask, connect, area, destUse)
TTMaskZero(&ResSubsTypeBitMask);
for (tran = TT_TECHDEPBASE; tran < TT_MAXTYPES; tran++)
{
tran_name = (ExtCurStyle->exts_transName)[tran];
devptr = ExtCurStyle->exts_device[tran];
tran_name = devptr->exts_deviceName;
if ((tran_name != NULL) && (strcmp(tran_name, "None")))
{
TTMaskSetMask(&DiffTypeBitMask,
&(ExtCurStyle->exts_transSDTypes[tran][0]));
&(devptr->exts_deviceSDTypes[0]));
TTMaskSetMask(&ResSubsTypeBitMask,
&(ExtCurStyle->exts_transSubstrateTypes[tran]));
&(devptr->exts_deviceSubstrateTypes));
}
}
first = 0;
@ -520,12 +527,14 @@ resSubSearchFunc(tile,cx)
ResTranTile *thisTran;
Rect tranArea;
TileType t = TiGetType(tile);
ExtDevice *devptr;
/* Right now, we're only going to extract substrate terminals for
devices with only one diffusion terminal, principally bipolar
devices.
*/
if (ExtCurStyle->exts_transSDCount[t] >1) return 0;
devptr = ExtCurStyle->exts_device[t]
if (devptr->exts_deviceSDCount >1) return 0;
TiToRect(tile, &tranArea);
thisTran = (ResTranTile *) mallocMagic((unsigned)(sizeof(ResTranTile)));
GeoTransRect(&cx->tc_scx->scx_trans, &tranArea, &thisTran->area);

View File

@ -53,7 +53,7 @@ extern HashTable ResNodeTable;
* ResInitializeConn--
*
* Sets up mask by Source/Drain type of transistors. This is
* exts_transSDtypes turned inside out.
* exts_deviceSDtypes turned inside out.
*
* Results: none
*
@ -67,18 +67,20 @@ ResInitializeConn()
{
TileType tran, diff;
char *tran_name;
ExtDevice *devptr;
for (tran = TT_TECHDEPBASE; tran < TT_MAXTYPES; tran++)
{
tran_name = (ExtCurStyle->exts_transName)[tran];
devptr = ExtCurStyle->exts_device[tran];
tran_name = devptr->exts_deviceName;
if ((tran_name != NULL) && (strcmp(tran_name, "None")))
{
for (diff = TT_TECHDEPBASE; diff < TT_MAXTYPES; diff++)
{
if TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[tran][0]), diff)
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]), diff)
TTMaskSetType(&ResConnectWithSD[diff],tran);
if TTMaskHasType(&(ExtCurStyle->exts_transSubstrateTypes[tran]),diff)
if TTMaskHasType(&(devptr->exts_deviceSubstrateTypes),diff)
TTMaskSetType(&ResConnectWithSD[diff],tran);
}
}
@ -163,7 +165,7 @@ ResDissolveContacts(contacts)
{
if (TTMaskHasType(&residues, t))
{
if (TTMaskHasType(&ExtCurStyle->exts_transMask, t))
if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, t))
continue;
DBPaint(ResUse->cu_def, &(contacts->cp_rect), t);
}
@ -824,6 +826,7 @@ FindStartTile(goodies, SourcePoint)
Point workingPoint;
Tile *tile, *tp;
int pnum, t1, t2;
ExtDevice *devptr;
workingPoint.p_x = goodies->rg_tranloc->p_x;
workingPoint.p_y = goodies->rg_tranloc->p_y;
@ -868,12 +871,12 @@ FindStartTile(goodies, SourcePoint)
if (IsSplit(tile))
{
if (TTMaskHasType(&ExtCurStyle->exts_transMask, TiGetLeftType(tile)) != 0)
if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetLeftType(tile)) != 0)
{
t1 = TiGetLeftType(tile);
TiSetBody(tile, t1 & ~TT_SIDE);
}
else if (TTMaskHasType(&ExtCurStyle->exts_transMask, TiGetRightType(tile)) != 0)
else if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetRightType(tile)) != 0)
{
t1 = TiGetRightType(tile);
TiSetBody(tile, t1 & TT_SIDE);
@ -885,7 +888,7 @@ FindStartTile(goodies, SourcePoint)
return(NULL);
}
}
else if (TTMaskHasType(&ExtCurStyle->exts_transMask, TiGetType(tile)) == 0)
else if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetType(tile)) == 0)
{
TxError("Couldn't find transistor at %d %d\n",
goodies->rg_tranloc->p_x, goodies->rg_tranloc->p_y);
@ -894,11 +897,12 @@ FindStartTile(goodies, SourcePoint)
else
t1 = TiGetType(tile);
devptr = ExtCurStyle->exts_device[t1];
/* left */
for (tp = BL(tile); BOTTOM(tp) < TOP(tile); tp=RT(tp))
{
t2 = TiGetRightType(tp);
if (TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[t1][0]),t2))
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2))
{
SourcePoint->p_x = LEFT(tile);
SourcePoint->p_y = (MIN(TOP(tile),TOP(tp))+
@ -911,7 +915,7 @@ FindStartTile(goodies, SourcePoint)
for (tp = TR(tile); TOP(tp) > BOTTOM(tile); tp=LB(tp))
{
t2 = TiGetLeftType(tp);
if (TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[t1][0]),t2))
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2))
{
SourcePoint->p_x = RIGHT(tile);
SourcePoint->p_y = (MIN(TOP(tile),TOP(tp))+
@ -924,7 +928,7 @@ FindStartTile(goodies, SourcePoint)
for (tp = RT(tile); RIGHT(tp) > LEFT(tile); tp=BL(tp))
{
t2 = TiGetBottomType(tp);
if (TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[t1][0]),t2))
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2))
{
SourcePoint->p_y = TOP(tile);
SourcePoint->p_x = (MIN(RIGHT(tile),RIGHT(tp))+
@ -937,7 +941,7 @@ FindStartTile(goodies, SourcePoint)
for (tp = LB(tile); LEFT(tp) < RIGHT(tile); tp=TR(tp))
{
t2 = TiGetTopType(tp);
if (TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[t1][0]),t2))
if (TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),t2))
{
SourcePoint->p_y = BOTTOM(tile);
SourcePoint->p_x = (MIN(RIGHT(tile),RIGHT(tp))+
@ -977,7 +981,7 @@ ResGetTransistor(pt)
for (pnum= PL_TECHDEPBASE; pnum < DBNumPlanes; pnum++)
{
if (TTMaskIntersect(&ExtCurStyle->exts_transMask,&DBPlaneTypes[pnum]) == 0)
if (TTMaskIntersect(&ExtCurStyle->exts_deviceMask,&DBPlaneTypes[pnum]) == 0)
{
continue;
}
@ -987,11 +991,11 @@ ResGetTransistor(pt)
if (IsSplit(tile))
{
if (TTMaskHasType(&ExtCurStyle->exts_transMask, TiGetLeftType(tile))
|| TTMaskHasType(&ExtCurStyle->exts_transMask, TiGetRightType(tile)))
if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetLeftType(tile))
|| TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetRightType(tile)))
return(((tileJunk *)tile->ti_client)->transistorList);
}
else if (TTMaskHasType(&ExtCurStyle->exts_transMask, TiGetType(tile)))
else if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, TiGetType(tile)))
{
return(((tileJunk *)tile->ti_client)->transistorList);
}

View File

@ -114,6 +114,7 @@ ResPrintExtTran(outextfile, transistors)
{
TileType t;
char *subsName;
ExtDevice *devptr;
for (; transistors != NULL; transistors = transistors->nextTran)
{
@ -122,7 +123,8 @@ ResPrintExtTran(outextfile, transistors)
if (ResOptionsFlags & ResOpt_DoExtFile)
{
t = transistors->layout->rt_trantype;
subsName = ExtCurStyle->exts_transSubstrateName[t];
devptr = ExtCurStyle->exts_device[t];
subsName = devptr->exts_deviceSubstrateName;
#ifdef MAGIC_WRAPPER
/* Substrate variable name substitution */
@ -139,7 +141,7 @@ ResPrintExtTran(outextfile, transistors)
/* fet type xl yl xh yh area perim sub gate t1 t2 */
fprintf(outextfile,"fet %s %d %d %d %d %d %d "
"%s \"%s\" %d %s \"%s\" %d %s \"%s\" %d %s\n",
ExtCurStyle->exts_transName[t],
devptr->exts_deviceName,
transistors->layout->rt_inside.r_ll.p_x,
transistors->layout->rt_inside.r_ll.p_y,
transistors->layout->rt_inside.r_ll.p_x + 1,

View File

@ -187,8 +187,10 @@ ResReadSim(simfile,fetproc,capproc,resproc,attrproc,mergeproc)
else if (fettype != MINFINITY)
{
float sheetr;
ExtDevice *devptr;
sheetr=(float)ExtCurStyle->exts_linearResist[fettype];
devptr = ExtCurStyle->exts_device[fettype];
sheetr=(float)devptr->exts_linearResist;
result = (*fetproc)(line,sheetr,fettype);
}
if (result != 0)

View File

@ -732,6 +732,7 @@ ResCalculateChildCapacitance(me)
float childcap;
tElement *tptr;
int t;
ExtDevice *devptr;
if (me->rn_client != (ClientData) NULL) /* we have a loop */
@ -752,12 +753,13 @@ ResCalculateChildCapacitance(me)
t = TiGetType(tran->rt_tile);
if (tran->rt_gate == me)
{
devptr = ExtCurStyle->exts_device[t];
myC->rc_Cdownstream +=
tran->rt_length*
tran->rt_width*
ExtCurStyle->exts_transGateCap[t]+
devptr->exts_deviceGateCap+
(tran->rt_width+tran->rt_width)*
ExtCurStyle->exts_transSDCap[t];
devptr->exts_deviceSDCap;
}
}

View File

@ -144,6 +144,7 @@ ResAddPlumbing(tile, arg)
TileType loctype, t1;
Tile *tp1,*tp2,*source;
resTransistor *resFet;
ExtDevice *devptr;
if (resTransStack == NULL)
{
@ -159,8 +160,9 @@ ResAddPlumbing(tile, arg)
else
loctype = TiGetTypeExact(tile);
devptr = ExtCurStyle->exts_device[loctype];
junk2 = resAddField(tile);
if (TTMaskHasType(&(ExtCurStyle->exts_transMask), loctype))
if (TTMaskHasType(&(ExtCurStyle->exts_deviceMask), loctype))
{
resFet = (resTransistor *) mallocMagic((unsigned)(sizeof(resTransistor)));
{
@ -191,7 +193,7 @@ ResAddPlumbing(tile, arg)
/* top */
for (tp2= RT(tile); RIGHT(tp2) > LEFT(tile); tp2 = BL(tp2))
{
if TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[loctype][0]),
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
TiGetBottomType(tp2))
{
junk2->sourceEdge |= TOPEDGE;
@ -206,7 +208,7 @@ ResAddPlumbing(tile, arg)
if (source == NULL)
for (tp2= LB(tile); LEFT(tp2) < RIGHT(tile); tp2 = TR(tp2))
{
if TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[loctype][0]),
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
TiGetTopType(tp2))
{
junk2->sourceEdge |= BOTTOMEDGE;
@ -221,7 +223,7 @@ ResAddPlumbing(tile, arg)
if (source == NULL)
for (tp2= TR(tile); TOP(tp2) > BOTTOM(tile); tp2 = LB(tp2))
{
if TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[loctype][0]),
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
TiGetLeftType(tp2))
{
junk2->sourceEdge |= RIGHTEDGE;
@ -236,7 +238,7 @@ ResAddPlumbing(tile, arg)
if (source == NULL)
for (tp2= BL(tile); BOTTOM(tp2) < TOP(tile); tp2 = RT(tp2))
{
if TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[loctype][0]),
if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
TiGetRightType(tp2))
{
source = tp2;
@ -339,6 +341,7 @@ ResAddPlumbing(tile, arg)
else
t1 = TiGetTypeExact(tp1);
devptr = ExtCurStyle->exts_device[t1];
j0 = (tileJunk *) tp1->ti_client;
/* top */
for (tp2= RT(tp1); RIGHT(tp2) > LEFT(tp1); tp2 = BL(tp2))
@ -352,7 +355,7 @@ ResAddPlumbing(tile, arg)
Junk->tj_status |= RES_TILE_TRAN;
}
else if TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[t1][0]),
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
TiGetBottomType(tp2))
{
Junk = resAddField(tp2);
@ -373,7 +376,7 @@ ResAddPlumbing(tile, arg)
Junk->transistorList = resFet;
Junk->tj_status |= RES_TILE_TRAN;
}
else if TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[t1][0]),
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
TiGetTopType(tp2))
{
Junk = resAddField(tp2);
@ -394,7 +397,7 @@ ResAddPlumbing(tile, arg)
Junk->transistorList = resFet;
Junk->tj_status |= RES_TILE_TRAN;
}
else if TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[t1][0]),
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
TiGetLeftType(tp2))
{
Junk = resAddField(tp2);
@ -415,7 +418,7 @@ ResAddPlumbing(tile, arg)
Junk->transistorList = resFet;
Junk->tj_status |= RES_TILE_TRAN;
}
else if TTMaskHasType(&(ExtCurStyle->exts_transSDTypes[t1][0]),
else if TTMaskHasType(&(devptr->exts_deviceSDTypes[0]),
TiGetRightType(tp2))
{
Junk = resAddField(tp2);
@ -577,7 +580,7 @@ ResPreProcessTransistors(TileList, TransistorList, Def)
{
if (TTMaskHasType(&ttresidues, residue))
{
if (TTMaskHasType(&ExtCurStyle->exts_transMask, residue))
if (TTMaskHasType(&ExtCurStyle->exts_deviceMask, residue))
{
pNum = DBPlane(residue);
break;
@ -594,7 +597,7 @@ ResPreProcessTransistors(TileList, TransistorList, Def)
tt = TiGetType(tile);
tstruct = (tileJunk *) tile->ti_client;
if (!TTMaskHasType(&ExtCurStyle->exts_transMask, tt) ||
if (!TTMaskHasType(&ExtCurStyle->exts_deviceMask, tt) ||
tstruct->transistorList == NULL)
{
TxError("Bad Transistor Location at %d,%d\n",

View File

@ -239,16 +239,18 @@ SimFreeNodeRegs()
int SimInitConnTables()
{
int i, t, sd, p;
ExtDevice *devptr;
SimTransMask = ExtCurStyle->exts_transMask;
SimTransMask = ExtCurStyle->exts_deviceMask;
TTMaskZero( &SimSDMask );
for( t = TT_TECHDEPBASE; t < DBNumTypes; t++ )
{
for (i = 0; !TTMaskHasType(&ExtCurStyle->exts_transSDTypes[t][i],
devptr = ExtCurStyle->exts_device[t];
for (i = 0; !TTMaskHasType(&devptr->exts_deviceSDTypes[i],
TT_SPACE); i++)
{
TTMaskSetMask( &SimSDMask, &ExtCurStyle->exts_transSDTypes[t][i] );
TTMaskSetMask( &SimSDMask, &devptr->exts_deviceSDTypes[i] );
TTMaskZero( &SimFetMask[t] );
}
}
@ -258,12 +260,13 @@ int SimInitConnTables()
{
if (TTMaskHasType(&SimTransMask, t))
{
devptr = ExtCurStyle->exts_device[t];
for (sd = TT_TECHDEPBASE; sd < DBNumTypes; sd++)
{
for (i = 0; !TTMaskHasType(&ExtCurStyle->exts_transSDTypes[t][i],
for (i = 0; !TTMaskHasType(&devptr->exts_deviceSDTypes[i],
TT_SPACE); i++)
{
if (TTMaskHasType(&ExtCurStyle->exts_transSDTypes[t][i], sd))
if (TTMaskHasType(&devptr->exts_deviceSDTypes[i], sd))
{
TTMaskSetType(&SimFetMask[sd], t);
SimFetPlanes |= PlaneNumToMaskBit(DBPlane(t));
@ -471,14 +474,16 @@ SimTransistorTile(tile, pNum, arg)
{
int i;
TileType t;
ExtDevice *devptr;
extSetNodeNum((LabRegion *)&transistor, pNum, tile);
if (transistor.t_do_terms)
{
t = TiGetType(tile);
for (i = 0; !TTMaskHasType(&ExtCurStyle->exts_transSDTypes[t][i],
devptr = ExtCurStyle->exts_device[t];
for (i = 0; !TTMaskHasType(&devptr->exts_deviceSDTypes[i],
TT_SPACE); i++)
extEnumTilePerim(tile, ExtCurStyle->exts_transSDTypes[t][i],
extEnumTilePerim(tile, devptr->exts_deviceSDTypes[i],
SimTransTerms, (ClientData) &transistor );
}