diff --git a/ext2spice/ext2spice.c b/ext2spice/ext2spice.c index 6947027a..43ebabbe 100644 --- a/ext2spice/ext2spice.c +++ b/ext2spice/ext2spice.c @@ -140,9 +140,16 @@ esFormatSubs(outf, suf) if ((EFTrimFlags & EF_TRIMGLOB ) && suf[l] == '!' || (EFTrimFlags & EF_TRIMLOCAL) && suf[l] == '#') suf[l] = '\0' ; - if (EFTrimFlags & EF_CONVERTCOMMAS) + if (EFTrimFlags & EF_CONVERTCOMMA) while ((specchar = strchr(suf, ',')) != NULL) - *specchar = ';'; + *specchar = '|'; + if (EFTrimFlags & EF_CONVERTBRACKETS) + { + while ((specchar = strchr(suf, '[')) != NULL) + *specchar = '_'; + while ((specchar = strchr(suf, ']')) != NULL) + *specchar = '_'; + } if (EFTrimFlags & EF_CONVERTEQUAL) while ((specchar = strchr(suf, '=')) != NULL) *specchar = ':'; @@ -607,7 +614,7 @@ CmdExtToSpice(w, cmd) case EXTTOSPC_DEFAULT: LocCapThreshold = 2; LocResistThreshold = INFINITE_THRESHOLD; - EFTrimFlags = EF_CONVERTCOMMAS | EF_CONVERTEQUAL; + EFTrimFlags = EF_CONVERTCOMMA | EF_CONVERTEQUAL; EFScale = 0.0; if (EFArgTech) { @@ -821,7 +828,7 @@ runexttospice: // This forces options TRIMGLOB and CONVERTEQUAL, not sure that's such a // good idea. . . - EFTrimFlags |= EF_TRIMGLOB | EF_CONVERTEQUAL; + EFTrimFlags |= EF_TRIMGLOB | EF_CONVERTEQUAL | EF_CONVERTCOMMA; if (IS_FINITE_F(EFCapThreshold)) flatFlags |= EF_FLATCAPS; if (esFormat == HSPICE) EFTrimFlags |= EF_TRIMLOCAL; @@ -1248,7 +1255,7 @@ spcmainArgs(pargc, pargv) usage: TxError("Usage: ext2spice [-B] [-o spicefile] [-M|-m] [-y cap_digits] " "[-J flat|hier]\n" - "[-f spice2|spice3|hspice] [-M] [-m] " + "[-f spice2|spice3|hspice|ngspice] [-M] [-m] " #ifdef MAGIC_WRAPPER "[file]\n" #else @@ -1379,7 +1386,7 @@ subcktVisit(use, hierName, is_top) else { int savflags = EFTrimFlags; - EFTrimFlags = 0; // Do no substitutions on subcircuit names + EFTrimFlags = EF_CONVERTCOMMA; // Only substitute commas on subcircuit names /* Use full hierarchical decomposition for name */ /* (not just use->use_id. hierName already has use->use_id at end) */ @@ -2714,7 +2721,9 @@ FILE *outf; if ((nodeClient *)nn->efnn_node->efnode_client == (ClientData)NULL) initNodeClientHier(nn->efnn_node); - ((nodeClient *)nn->efnn_node->efnode_client)->m_w.visitMask |= DEV_CONNECT_MASK; + if (!esDistrJunct) + ((nodeClient *)nn->efnn_node->efnode_client)->m_w.visitMask |= + DEV_CONNECT_MASK; return nn->efnn_node; } } @@ -2919,8 +2928,11 @@ spcdevOutNode(prefix, suffix, name, outf) nn = (EFNodeName *) HashGetValue(he); nname = nodeSpiceName(nn->efnn_node->efnode_name->efnn_hier); fprintf(outf, " %s", nname); + /* Mark node as visited */ - ((nodeClient *)nn->efnn_node->efnode_client)->m_w.visitMask |= DEV_CONNECT_MASK; + if (!esDistrJunct) + ((nodeClient *)nn->efnn_node->efnode_client)->m_w.visitMask |= DEV_CONNECT_MASK; + return (1 + strlen(nname)); } @@ -3215,7 +3227,7 @@ EFHNSprintf(str, hierName) char *str; HierName *hierName; { - bool trimGlob, trimLocal, convertComma, convertEqual; + bool trimGlob, trimLocal, convertComma, convertEqual, convertBrackets; char *s, *cp, c; char *efHNSprintfPrefix(HierName *, char *); @@ -3226,8 +3238,9 @@ EFHNSprintf(str, hierName) cp = hierName->hn_name; trimGlob = (EFTrimFlags & EF_TRIMGLOB); trimLocal = (EFTrimFlags & EF_TRIMLOCAL); - convertComma = (EFTrimFlags & EF_CONVERTCOMMAS); + convertComma = (EFTrimFlags & EF_CONVERTCOMMA); convertEqual = (EFTrimFlags & EF_CONVERTEQUAL); + convertBrackets = (EFTrimFlags & EF_CONVERTBRACKETS); while (c = *cp++) { switch (c) @@ -3235,7 +3248,9 @@ EFHNSprintf(str, hierName) case '!': if (!trimGlob) *str++ = c; break; case '.': *str++ = (esFormat == HSPICE)?'@':'.'; break; case '=': if (convertEqual) *str++ = ':'; break; - case ',': if (convertComma) *str++ = ';'; break; + case ',': if (convertComma) *str++ = '|'; break; + case '[': *str++ = (convertBrackets) ? '_' : '['; break; + case ']': *str++ = (convertBrackets) ? '_' : ']'; break; case '#': if (trimLocal) break; // else fall through default: *str++ = c; break; } @@ -3252,6 +3267,8 @@ char *efHNSprintfPrefix(hierName, str) { char *cp, c; bool convertEqual = (EFTrimFlags & EF_CONVERTEQUAL) ? TRUE : FALSE; + bool convertComma = (EFTrimFlags & EF_CONVERTCOMMA) ? TRUE : FALSE; + bool convertBrackets = (EFTrimFlags & EF_CONVERTBRACKETS) ? TRUE : FALSE; if (hierName->hn_parent) str = efHNSprintfPrefix(hierName->hn_parent, str); @@ -3260,6 +3277,13 @@ char *efHNSprintfPrefix(hierName, str) while (1) { if (convertEqual && (*cp == '=')) *str = ':'; + else if (convertBrackets && ((*cp == '[') || (*cp == ']'))) + *str = '_'; + else if (*cp == ',') + { + if (convertComma) *str = '|'; + else str--; + } else *str = *cp; if (!(*str)) break; diff --git a/extflat/EFargs.c b/extflat/EFargs.c index 40b57278..dd812dac 100644 --- a/extflat/EFargs.c +++ b/extflat/EFargs.c @@ -209,8 +209,10 @@ EFArgs(argc, argv, err_result, argsProc, cdata) goto usage; if (strchr(cp, '!')) EFTrimFlags |= EF_TRIMGLOB; if (strchr(cp, '#')) EFTrimFlags |= EF_TRIMLOCAL; - if (strchr(cp, ',')) EFTrimFlags |= EF_CONVERTCOMMAS; + if (strchr(cp, ',')) EFTrimFlags |= EF_CONVERTCOMMA; if (strchr(cp, '=')) EFTrimFlags |= EF_CONVERTEQUAL; + if (strchr(cp, '[')) EFTrimFlags |= EF_CONVERTBRACKETS; + if (strchr(cp, ']')) EFTrimFlags |= EF_CONVERTBRACKETS; break; case 'C': EFCapThreshold = (EFCapValue)INFINITE_THRESHOLD_F; diff --git a/extflat/EFvisit.c b/extflat/EFvisit.c index aadb98ff..8d802edd 100644 --- a/extflat/EFvisit.c +++ b/extflat/EFvisit.c @@ -859,7 +859,7 @@ EFHNOut(hierName, outf) HierName *hierName; FILE *outf; { - bool trimGlob, trimLocal, trimComma; + bool trimGlob, trimLocal, convComma, convBrackets; char *cp, c; if (hierName->hn_parent) efHNOutPrefix(hierName->hn_parent, outf); @@ -868,13 +868,19 @@ EFHNOut(hierName, outf) cp = hierName->hn_name; trimGlob = (EFTrimFlags & EF_TRIMGLOB); trimLocal = (EFTrimFlags & EF_TRIMLOCAL); - trimComma = (EFTrimFlags & EF_CONVERTCOMMAS); + convComma = (EFTrimFlags & EF_CONVERTCOMMA); + convBrackets = (EFTrimFlags & EF_CONVERTBRACKETS); while (c = *cp++) { if (*cp) { - if (trimComma && (c == ',')) - putc(';', outf); + if (c == ',') + { + if (convComma) + putc('|', outf); + } + else if (convBrackets && ((c == '[') || (c == ']'))) + putc('_', outf); else putc(c, outf); } diff --git a/extflat/extflat.h b/extflat/extflat.h index 8d8f1dba..f249e37c 100644 --- a/extflat/extflat.h +++ b/extflat/extflat.h @@ -40,8 +40,9 @@ typedef unsigned char U_char; /* Flags to control output of node names. Stored in EFTrimFlags */ #define EF_TRIMGLOB 0x01 /* Delete trailing '!' from names */ #define EF_TRIMLOCAL 0x02 /* Delete trailing '#' from names */ -#define EF_CONVERTCOMMAS 0x04 /* Change ',' to ';' in names */ -#define EF_CONVERTEQUAL 0x08 /* Change '=' to ':' in names */ +#define EF_CONVERTCOMMA 0x04 /* Change ',' to '|' in names, else remove */ +#define EF_CONVERTEQUAL 0x08 /* Change '=' to ':' in names, else remove */ +#define EF_CONVERTBRACKETS 0x10 /* Change '[' and ']' to '_' in names */ /* * capacitance type now set to float diff --git a/extract/ExtBasic.c b/extract/ExtBasic.c index 38d76441..e0503d20 100644 --- a/extract/ExtBasic.c +++ b/extract/ExtBasic.c @@ -2337,7 +2337,7 @@ extDevFindMatch(deventry, t) TileType t; { ExtDevice *devptr; - int i, j, matchflags; + int i, j, k, matchflags; bool match; matchflags = extTransRec.tr_devmatch; @@ -2362,10 +2362,11 @@ extDevFindMatch(deventry, t) &deventry->exts_deviceSubstrateTypes)) continue; j = MATCH_TERM; + i = 0; match = True; - for (i = 0; i < MAXSD; i++) + for (k = 0; k < devptr->exts_deviceSDCount; k++) { - if (extTransRec.tr_termnode[i] == NULL) break; + if (extTransRec.tr_termnode[k] == NULL) break; if (matchflags & j) /* Must have the same terminal type */ { if (TTMaskIsZero(&devptr->exts_deviceSDTypes[i])) @@ -2380,7 +2381,13 @@ extDevFindMatch(deventry, t) break; } } - j >>= 1; + j <<= 1; + + /* NOTE: There are fewer exts_deviceSDTypes records than */ + /* terminals if all S/D terminals are the same type. In */ + /* that case k increments and j bit shifts but i remains */ + /* the same. */ + if (!TTMaskIsZero(&devptr->exts_deviceSDTypes[i + 1])) i++; } if (match) break; } @@ -2522,9 +2529,19 @@ extTransTileFunc(tile, pNum, arg) } else if (region == (NodeRegion *)NULL) { - TxError("Device %s does not have a compatible substrate node!\n", - DBTypeLongNameTbl[loctype]); - devptr = NULL; + /* If ExtCurStyle->exts_globSubstrateTypes contains no types */ + /* then this is an older style techfile without a "substrate" */ + /* definition in the extract section. In that case, it is */ + /* expected that the substrate name in the device line will be */ + /* used. */ + + if (!TTMaskIsZero(&ExtCurStyle->exts_globSubstrateTypes) || + (devptr->exts_deviceSubstrateName == NULL)) + { + TxError("Device %s does not have a compatible substrate node!\n", + DBTypeLongNameTbl[loctype]); + devptr = NULL; + } } } extTransRec.tr_devrec = devptr; @@ -2737,8 +2754,27 @@ extTransPerimFunc(bp) ll->ll_attr = thisterm; } } - SDterm = TRUE; + + /* Check if number of terminals exceeds the number allowed in */ + /* this device record. If so, check if there is another device */ + /* record with a different number of terminals. */ + extTransRec.tr_devmatch |= (MATCH_TERM << thisterm); + if (thisterm >= devptr->exts_deviceSDCount) + { + devptr = extDevFindMatch(devptr, tinside); + + /* Should this be an error instead of a warning? */ + /* Traditionally more terminals than defined was allowed */ + /* but not necessarily handled correctly by ext2spice. */ + + if (devptr == deventry) + TxError("Warning: Device has more terminals than defined " + "for type!\n"); + else + extTransRec.tr_devrec = devptr; + } + SDterm = TRUE; break; } } diff --git a/extract/ExtTech.c b/extract/ExtTech.c index 314bed99..d2b3ebbf 100644 --- a/extract/ExtTech.c +++ b/extract/ExtTech.c @@ -298,12 +298,12 @@ ExtGetDevInfo(idx, devnameptr, sd_rclassptr, sub_rclassptr, subnameptr) TileType t; TileTypeBitMask *rmask, *tmask; int n, i = 0, j; - bool repeat; + bool repeat, found; ExtDevice *devptr; char *locdname; char **uniquenamelist = (char **)mallocMagic(DBNumTypes * sizeof(char *)); - + found = FALSE; for (t = TT_TECHDEPBASE; t < DBNumTypes; t++) { for (devptr = ExtCurStyle->exts_device[t]; devptr; devptr = devptr->exts_next) @@ -320,12 +320,17 @@ ExtGetDevInfo(idx, devnameptr, sd_rclassptr, sub_rclassptr, subnameptr) } if (repeat == FALSE) { - if (i == idx) break; + if (i == idx) + { + found = TRUE; + break; + } uniquenamelist[i] = locdname; i++; } } } + if (found == TRUE) break; } if (t == DBNumTypes) return FALSE; if (devptr == NULL) return FALSE; diff --git a/resis/Depend b/resis/Depend index b73eacf7..f22d303f 100644 --- a/resis/Depend +++ b/resis/Depend @@ -15,7 +15,7 @@ ResMakeRes.o: ResMakeRes.c ../utils/magic.h ../utils/geometry.h \ ../database/database.h ../utils/malloc.h ../textio/textio.h \ ../extract/extract.h ../extract/extractInt.h ../extract/extDebugInt.h \ ../windows/windows.h ../dbwind/dbwind.h ../utils/tech.h \ - ../textio/txcommands.h ../resis/resis.h + ../textio/txcommands.h ../resis/resis.h ../cif/CIFint.h ResSimple.o: ResSimple.c ../utils/magic.h ../utils/geometry.h \ ../utils/geofast.h ../tiles/tile.h ../utils/hash.h ../utils/heap.h \ ../database/database.h ../utils/malloc.h ../textio/textio.h \ diff --git a/resis/ResConDCS.c b/resis/ResConDCS.c index 69adc06a..da5cb7fe 100644 --- a/resis/ResConDCS.c +++ b/resis/ResConDCS.c @@ -450,8 +450,8 @@ DBTreeCopyConnectDCS(scx, mask, xMask, connect, area, destUse) for (tran = TT_TECHDEPBASE; tran < TT_MAXTYPES; tran++) { devptr = ExtCurStyle->exts_device[tran]; - tran_name = devptr->exts_deviceName; - if ((tran_name != NULL) && (strcmp(tran_name, "None"))) + if ((devptr != NULL) && ((tran_name = devptr->exts_deviceName) != NULL) + && (strcmp(tran_name, "None"))) { TTMaskSetMask(&DiffTypeBitMask, &(devptr->exts_deviceSDTypes[0])); diff --git a/resis/ResMain.c b/resis/ResMain.c index 33657767..767c599e 100644 --- a/resis/ResMain.c +++ b/resis/ResMain.c @@ -72,8 +72,8 @@ ResInitializeConn() for (tran = TT_TECHDEPBASE; tran < TT_MAXTYPES; tran++) { devptr = ExtCurStyle->exts_device[tran]; - tran_name = devptr->exts_deviceName; - if ((tran_name != NULL) && (strcmp(tran_name, "None"))) + if ((devptr != NULL) && ((tran_name = devptr->exts_deviceName) != NULL) + && (strcmp(tran_name, "None"))) { for (diff = TT_TECHDEPBASE; diff < TT_MAXTYPES; diff++) { diff --git a/resis/ResMakeRes.c b/resis/ResMakeRes.c index 1ff30a22..5d874d1d 100644 --- a/resis/ResMakeRes.c +++ b/resis/ResMakeRes.c @@ -24,6 +24,7 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ #include "utils/tech.h" #include "textio/txcommands.h" #include "resis/resis.h" +#include "cif/CIFint.h" /* Forward declarations */ bool ResCalcNearTransistor(); @@ -783,13 +784,14 @@ ResDoContacts(contact, nodes, resList) resNode *resptr; cElement *ccell; int tilenum, squaresx, squaresy, viawidth; - int minside, spacing, border; + int minside, spacing, border, cscale; float squaresf; resResistor *resistor; resElement *element; static int too_small = 1; minside = CIFGetContactSize(contact->cp_type, &viawidth, &spacing, &border); + cscale = CIFCurStyle->cs_scaleFactor; if ((ExtCurStyle->exts_viaResist[contact->cp_type] == 0) || (viawidth == 0)) { @@ -818,7 +820,8 @@ ResDoContacts(contact, nodes, resList) } else { - if ((contact->cp_width < minside) || (contact->cp_height < minside)) + if (((contact->cp_width * cscale) < minside) || + ((contact->cp_height * cscale) < minside)) { if (too_small) { @@ -832,13 +835,13 @@ ResDoContacts(contact, nodes, resList) else { viawidth += spacing; - squaresf = (float)(contact->cp_width - minside) / (float)viawidth; + squaresf = (float)((contact->cp_width * cscale) - minside) / (float)viawidth; squaresf *= ExtCurStyle->exts_unitsPerLambda; squaresf /= (float)viawidth; squaresx = (int)squaresf; squaresx++; - squaresf = (float)(contact->cp_height - minside) / (float)viawidth; + squaresf = (float)((contact->cp_height * cscale) - minside) / (float)viawidth; squaresf *= ExtCurStyle->exts_unitsPerLambda; squaresf /= (float)viawidth; squaresy = (int)squaresf; diff --git a/resis/ResReadSim.c b/resis/ResReadSim.c index 6cb38633..cc47fb4b 100644 --- a/resis/ResReadSim.c +++ b/resis/ResReadSim.c @@ -146,8 +146,12 @@ ResReadSim(simfile,fetproc,capproc,resproc,attrproc,mergeproc) case '|': if (strcmp(line[NODEUNITS],"units:") == 0) { - lambda = (float)atof(line[NODELAMBDA]); - if (lambda == 0.0) lambda = 1.0; + lambda = (float)atof(line[NODELAMBDA]); + if (lambda == 0.0) lambda = 1.0; + /* NOTE: units is derived from EFScale */ + /* which needs a factor of 100 conversion */ + /* to database units. */ + lambda *= 100.0; } result=0; break;