Revised the method for multiple extraction models per device type
to be more robust and not depend on the ordering of the devices in the techfile. The extraction method now keeps a mask of which properties of the device (source/drain types, substrate type, identifier type) have been found, and will look only for device records that match what is known about the device. Added a device identifier record which is the last record before parameters if the record begins with "+". This allows marker layers to be placed over a device such that it will extract with a different type. This helps reduce the complexity of the techfile and allows certain specialized devices like RF or ESD to be identified without a separate layer type for the device.
This commit is contained in:
parent
f429e4eca4
commit
8c75f81cc4
File diff suppressed because it is too large
Load Diff
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue