From 662e21a2d1169341158fd3274f62f870313f77e9 Mon Sep 17 00:00:00 2001 From: "R. Timothy Edwards" Date: Mon, 29 Dec 2025 10:52:08 -0500 Subject: [PATCH] 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. --- VERSION | 2 +- ext2spice/ext2hier.c | 17 ++++++++++++++ extflat/EFbuild.c | 55 ++++++++++++++++++++++++++++++++++---------- 3 files changed, 61 insertions(+), 13 deletions(-) diff --git a/VERSION b/VERSION index 6e102d15..f1b4510c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.585 +8.3.586 diff --git a/ext2spice/ext2hier.c b/ext2spice/ext2hier.c index 5c08a6f5..07d387ed 100644 --- a/ext2spice/ext2hier.c +++ b/ext2spice/ext2hier.c @@ -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; } diff --git a/extflat/EFbuild.c b/extflat/EFbuild.c index 8da6b054..dd21fd8d 100644 --- a/extflat/EFbuild.c +++ b/extflat/EFbuild.c @@ -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;