Corrected an error that had been introduced when creating the
parameter types "l1", "l2", etc., for terminal lengths. There was a string comparison against an unterminated character array which was causing intermittant errors. This problem was masking the incorrect handling of "l1", "l2", etc., parameters. The parameter types had been introduced to cover a specific type of drain-unsalicided FET in GF180MCU, which is used as an ESD device in the foundry I/O cells, so the impact had been relatively limited, although typically showed up as unexpected property errors on the ESD devices when running LVS on a chip top level. Both discovered errors have been fixed.
This commit is contained in:
parent
949ec7672c
commit
662e21a2d1
|
|
@ -242,9 +242,20 @@ spcHierWriteParams(
|
|||
|
||||
/* Write all requested parameters to the subcircuit call. */
|
||||
|
||||
bool checkme = FALSE;
|
||||
|
||||
if ((!strcmp(EFDevTypes[dev->dev_type], "pfet_06v0_dss")) ||
|
||||
(!strcmp(EFDevTypes[dev->dev_type], "nfet_06v0_dss")))
|
||||
{
|
||||
checkme = TRUE;
|
||||
TxPrintf("Diagnostic: Parameter list for %s\n", EFDevTypes[dev->dev_type]);
|
||||
}
|
||||
|
||||
plist = efGetDeviceParams(EFDevTypes[dev->dev_type]);
|
||||
while (plist != NULL)
|
||||
{
|
||||
if (checkme) TxPrintf("Plist entry %s %s\n", plist->parm_name, plist->parm_type);
|
||||
|
||||
switch (plist->parm_type[0])
|
||||
{
|
||||
case 'a':
|
||||
|
|
@ -345,6 +356,7 @@ spcHierWriteParams(
|
|||
// Check for device length vs. terminal length
|
||||
if (plist->parm_type[1] == '\0' || plist->parm_type[1] == '0')
|
||||
{
|
||||
if (checkme) TxPrintf("Handling entry l or l0\n");
|
||||
fprintf(esSpiceF, " %s=", plist->parm_name);
|
||||
if (esScale < 0)
|
||||
fprintf(esSpiceF, "%g", l * scale);
|
||||
|
|
@ -359,8 +371,10 @@ spcHierWriteParams(
|
|||
{
|
||||
/* l1, l2, etc. used to indicate the length of the terminal */
|
||||
/* Find value in dev_params */
|
||||
if (checkme) TxPrintf("Handling entry l1 or l2\n");
|
||||
for (dparam = dev->dev_params; dparam; dparam = dparam->parm_next)
|
||||
{
|
||||
if (checkme) TxPrintf("Checking dev_params entry %s\n", dparam->parm_name);
|
||||
if ((strlen(dparam->parm_name) > 2) &&
|
||||
(dparam->parm_name[0] == 'l') &&
|
||||
(dparam->parm_name[1] == plist->parm_type[1]) &&
|
||||
|
|
@ -369,6 +383,8 @@ spcHierWriteParams(
|
|||
int dval;
|
||||
if (sscanf(&dparam->parm_name[3], "%d", &dval) == 1)
|
||||
{
|
||||
if (checkme) TxPrintf("Handling dev_params entry %s (to be "
|
||||
"culled at end)\n", dparam->parm_name);
|
||||
fprintf(esSpiceF, " %s=", plist->parm_name);
|
||||
if (esScale < 0)
|
||||
fprintf(esSpiceF, "%g", dval * scale);
|
||||
|
|
@ -378,6 +394,7 @@ spcHierWriteParams(
|
|||
else
|
||||
esSIvalue(esSpiceF, (dval + plist->parm_offset)
|
||||
* scale * esScale * 1.0E-6);
|
||||
/* Why is this here? */
|
||||
dparam->parm_name[0] = '\0';
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -926,20 +926,22 @@ efBuildDevice(
|
|||
/* Parse initial arguments for parameters */
|
||||
while ((pptr = strchr(argv[argstart], '=')) != NULL)
|
||||
{
|
||||
// Check if this parameter is in the table.
|
||||
// If so, handle appropriately. Otherwise, the
|
||||
// parameter gets saved verbatim locally. The
|
||||
// "parameters" line comes before any "device" line
|
||||
// in the .ext file, so the table should be complete.
|
||||
/* If the parameter is in the parameter list "devp", then save
|
||||
* the value as appropriate. If not, then the entire phrase
|
||||
* will be output verbatim, so just save the whole string.
|
||||
*
|
||||
* The "parameters" line comes before any "device" line in the
|
||||
* .ext file, so the "devp" list should be complete.
|
||||
*/
|
||||
|
||||
*pptr = '\0';
|
||||
for (sparm = devp; sparm; sparm = sparm->parm_next)
|
||||
if (!strcasecmp(sparm->parm_type, argv[argstart]))
|
||||
if (!strncasecmp(sparm->parm_type, argv[argstart], 2))
|
||||
break;
|
||||
*pptr = '=';
|
||||
if (sparm == NULL)
|
||||
{
|
||||
/* Copy the parameter into dev_params */
|
||||
/* Copy the whole string into dev_params */
|
||||
/* (parm_type and parm_scale records are not used) */
|
||||
newparm = (DevParam *)mallocMagic(sizeof(DevParam));
|
||||
newparm->parm_name = StrDup((char **)NULL, argv[argstart]);
|
||||
|
|
@ -954,30 +956,59 @@ efBuildDevice(
|
|||
{
|
||||
case 'a':
|
||||
if ((pptr - argv[argstart]) == 2)
|
||||
devtmp.dev_area = atoi(pptr);
|
||||
devtmp.dev_area = (int)(0.5 + (float)atoi(pptr)
|
||||
* locScale * locScale);
|
||||
else
|
||||
{
|
||||
/* Check for a0, a1, a2, ... If a0, handle like "a".
|
||||
* Otherwise, don't handle it here.
|
||||
*/
|
||||
pn = *(argv[argstart] + 1) - '0';
|
||||
if (pn == 0)
|
||||
devtmp.dev_area = (int)(0.5 + (float)atoi(pptr)
|
||||
* locScale * locScale);
|
||||
/* Otherwise, punt */
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
if ((pptr - argv[argstart]) == 2)
|
||||
devtmp.dev_perim = atoi(pptr);
|
||||
devtmp.dev_perim = (int)(0.5 + (float)atoi(pptr) * locScale);
|
||||
else
|
||||
{
|
||||
/* Check for p0, p1, p2, ... If p0, handle like "p".
|
||||
* Otherwise, don't handle it here.
|
||||
*/
|
||||
pn = *(argv[argstart] + 1) - '0';
|
||||
if (pn == 0)
|
||||
devtmp.dev_perim = (int)(0.5 + (float)atoi(pptr) * locScale);
|
||||
/* Otherwise, use verbatim */
|
||||
}
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
devtmp.dev_length = (int)(0.5 + (float)atoi(pptr) * locScale);
|
||||
if ((pptr - argv[argstart]) == 2)
|
||||
devtmp.dev_length = (int)(0.5 + (float)atoi(pptr) * locScale);
|
||||
else
|
||||
{
|
||||
/* Check for l0, l1, l2, ... If l0, handle like "l".
|
||||
* Otherwise, save it verbatim like an unknown parameter,
|
||||
* because its value will not be calculated from terminal
|
||||
* values like "a1, a2, ..." or "p1, p2, ...".
|
||||
*/
|
||||
|
||||
pn = *(argv[argstart] + 1) - '0';
|
||||
if (pn == 0)
|
||||
devtmp.dev_length = (int)(0.5 + (float)atoi(pptr) * locScale);
|
||||
else
|
||||
{
|
||||
/* Copy the whole string into dev_params */
|
||||
newparm = (DevParam *)mallocMagic(sizeof(DevParam));
|
||||
newparm->parm_name = StrDup((char **)NULL, argv[argstart]);
|
||||
newparm->parm_next = devtmp.dev_params;
|
||||
devtmp.dev_params = newparm;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
devtmp.dev_width = (int)(0.5 + (float)atoi(pptr) * locScale);
|
||||
break;
|
||||
|
|
|
|||
Loading…
Reference in New Issue