diff --git a/VERSION b/VERSION index 0e432872..55e52029 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -8.3.593 +8.3.594 diff --git a/commands/CmdE.c b/commands/CmdE.c index 402ebe09..650a8b5d 100644 --- a/commands/CmdE.c +++ b/commands/CmdE.c @@ -930,6 +930,7 @@ cmdExpandFunc( #define DORESISTANCE 6 #define DOLABELCHECK 7 #define DOALIASES 8 +#define DOUNIQUE 9 #define LENCLEAR 0 #define LENDRIVER 1 @@ -977,6 +978,7 @@ CmdExtract( "resistance estimate resistance", "labelcheck check for connections through sticky labels", "aliases output all net name aliases", + "unique ensure unique node names during extraction", NULL }; static const char * const cmdExtLength[] = @@ -1280,6 +1282,7 @@ CmdExtract( TxPrintf("%s resistance\n", OPTSET(EXT_DORESISTANCE)); TxPrintf("%s label check\n", OPTSET(EXT_DOLABELCHECK)); TxPrintf("%s aliases\n", OPTSET(EXT_DOALIASES)); + TxPrintf("%s unique\n", OPTSET(EXT_DOUNIQUE)); return; #undef OPTSET } @@ -1309,6 +1312,7 @@ CmdExtract( case DORESISTANCE: option = EXT_DORESISTANCE; break; case DOLABELCHECK: option = EXT_DOLABELCHECK; break; case DOALIASES: option = EXT_DOALIASES; break; + case DOUNIQUE: option = EXT_DOUNIQUE; break; case DOLOCAL: /* "extract do local" and "extract no local" are kept for * backwards compatibility, but now effectively implement diff --git a/database/database.h.in b/database/database.h.in index 6801a7cd..a7a089a1 100644 --- a/database/database.h.in +++ b/database/database.h.in @@ -303,9 +303,14 @@ typedef struct label #define PORT_SHAPE_RING 0x1000 /* Port is a ring shape */ #define PORT_SHAPE_THRU 0x1800 /* Port is a feedthrough shape */ -#define PORT_VISITED 0x2000 /* Bit for checking if a port */ +#define LABEL_STICKY 0x2000 /* Label does not change layers */ +#define LABEL_UNIQUE 0x4000 /* Temporary unique label */ + +/* The last two flags are never used at the same time and so can share + * a flag bit. + */ +#define PORT_VISITED 0x8000 /* Bit for checking if a port */ /* has been previously visited. */ -#define LABEL_STICKY 0x4000 /* Label does not change layers */ #define LABEL_GENERATE 0x8000 /* Auto-generated label */ /* diff --git a/doc/html/extract.html b/doc/html/extract.html index 6f9e4896..3dfa4755 100644 --- a/doc/html/extract.html +++ b/doc/html/extract.html @@ -99,6 +99,16 @@ Circuit netlist extractor but will usually just slow down processing by commands like "ext2spice" that use the .ext file contents, so it is disabled by default. +
unique +
(Added in magic version 8.3.594) This setting replaces + the use of the command option "extract unique". Instead + of changing labels in the design, unique labels are + generated for the duration of the extraction, and then + reverted back to the original text. The "extract unique" + command option is maintained for backwards compatibility. + Note the difference: "extract unique" is a command that + runs immediately, and cannot be undone; + "extract do unique" is an option setting for "extract". These options (except for "local") determine how much diff --git a/extflat/EFbuild.c b/extflat/EFbuild.c index 45690838..a9ca61c7 100644 --- a/extflat/EFbuild.c +++ b/extflat/EFbuild.c @@ -907,6 +907,9 @@ efBuildDevice( case DEV_FET: case DEV_MOSFET: case DEV_ASYMMETRIC: + /* Terminals start after L and W values, substrate, and parameters */ + termstart = 3; + break; case DEV_BJT: /* Terminals start after L and W values, plus parameters */ termstart = 2; diff --git a/extract/ExtCell.c b/extract/ExtCell.c index 98bc5898..26fa5cb9 100644 --- a/extract/ExtCell.c +++ b/extract/ExtCell.c @@ -486,6 +486,12 @@ extCellFile(def, f, doLength) UndoDisable(); + /* If "extract do unique" was specified, then make labels in the + * cell unique. + */ + if (ExtOptions & EXT_DOUNIQUE) + extUniqueCell(def, EXT_UNIQ_TEMP); + /* Prep any isolated substrate areas */ saveSub = extPrepSubstrate(def); diff --git a/extract/ExtMain.c b/extract/ExtMain.c index 73db17b6..c502d998 100644 --- a/extract/ExtMain.c +++ b/extract/ExtMain.c @@ -806,12 +806,13 @@ ExtractOneCell(def, outName, doLength) savePlane = ExtCell(def, outName, doLength); - /* Restore all modified substrate planes */ + /* Restore all modified substrate planes and modified labels */ if (savePlane != NULL) ExtRevertSubstrate(def, savePlane); free_magic1_t mm1 = freeMagic1_init(); for (; sl; sl = sl->sl_next) { + if (EXT_DOUNIQUE) ExtRevertUniqueCell(sl->sl_def); ExtRevertSubstrate(sl->sl_def, sl->sl_plane); freeMagic1(&mm1, sl); } @@ -1026,10 +1027,12 @@ extExtractStack(stack, doExtract, rootDef) } } - /* Replace any modified substrate planes */ + /* Replace any modified substrate planes and modified labels */ free_magic1_t mm1 = freeMagic1_init(); for (; sl; sl = sl->sl_next) { + if (EXT_DOUNIQUE) ExtRevertUniqueCell(sl->sl_def); + ExtRevertSubstrate(sl->sl_def, sl->sl_plane); sl->sl_def->cd_flags &= ~CDNOEXTRACT; freeMagic1(&mm1, sl); diff --git a/extract/ExtTech.c b/extract/ExtTech.c index d585f259..973c8179 100644 --- a/extract/ExtTech.c +++ b/extract/ExtTech.c @@ -2747,24 +2747,34 @@ ExtTechLine(sectionName, argc, argv) DBTechNoisyNameMask(argv[4], &termtypes[0]); /* bottom */ TTMaskSetMask(allExtractTypes, &termtypes[0]); termtypes[1] = DBZeroTypeBits; - - if (argc > 5) - gccap = aToCap(argv[argc - 1]); /* area cap */ - if ((argc > 6) && StrIsNumeric(argv[argc - 2])) - { - gscap = aToCap(argv[argc - 2]); /* perimeter cap */ - argc--; - } nterm = 1; - if ((argc > 6) && strcmp(argv[5], "None")) + /* If argv[argc - 1] is a numerical value, then it is + * an area cap value and may be followed by another + * numerical value, the perimeter cap. + */ + + if ((argc > 5) && StrIsNumeric(argv[argc - 1])) { - DBTechNoisyNameMask(argv[5], &subsTypes); /* substrate */ + gccap = aToCap(argv[argc - 1]); /* area cap */ + argc--; + + if ((argc > 5) && StrIsNumeric(argv[argc - 1])) + { + gscap = aToCap(argv[argc - 1]); /* perimeter cap */ + argc--; + } + } + + if ((argc > 5) && strcmp(argv[5], "None")) + { + /* substrate */ + DBTechNoisyNameMask(argv[5], &subsTypes); TTMaskSetMask(allExtractTypes, &subsTypes); } else subsTypes = DBZeroTypeBits; - if (argc > 7) subsName = argv[6]; + if (argc > 6) subsName = argv[6]; break; case DEV_SUBCKT: diff --git a/extract/ExtUnique.c b/extract/ExtUnique.c index c3716a0a..93726a13 100644 --- a/extract/ExtUnique.c +++ b/extract/ExtUnique.c @@ -61,6 +61,11 @@ static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/ * names that don't end in '!'. * If option is EXT_UNIQ_NOPORTS, then generate unique names as for * option 0 only if the label is not a port. + * If option is EXT_UNIQ_TEMP, then generate unique names as for + * EXT_UNIQ_ALL, but also set the LABEL_UNIQUE flag for the + * label. This way, the unique label form can be used by the + * extraction code but labels (and port indexes) can be reverted + * afterward, and no permanent change is made to the circuit. * * Results: * Returns the number of warnings generated. @@ -219,7 +224,7 @@ extMakeUnique(def, ll, lreg, lregList, labelHash, option) * changes a label to make it unique. */ text = ll->ll_label->lab_text; - if (option == EXT_UNIQ_ALL) + if (option == EXT_UNIQ_ALL || option == EXT_UNIQ_TEMP) goto makeUnique; else if ((option == EXT_UNIQ_NOPORTS || option == EXT_UNIQ_NOTOPPORTS) && !(ll->ll_label->lab_flags & PORT_DIR_MASK)) @@ -320,8 +325,11 @@ makeUnique: lab = ll2->ll_label; saveLab = *lab; + /* Flag this label as having been modified */ + if (option == EXT_UNIQ_TEMP) flags |= LABEL_UNIQUE; + DBRemoveLabel(def, lab); - (void) DBPutFontLabel(def, &saveLab.lab_rect, + DBPutFontLabel(def, &saveLab.lab_rect, saveLab.lab_font, saveLab.lab_size, saveLab.lab_rotate, &saveLab.lab_offset, saveLab.lab_just, name2, saveLab.lab_type, flags, (unsigned int)portno); @@ -334,3 +342,64 @@ makeUnique: return 0; } + +/* + * ---------------------------------------------------------------------------- + * + * extRevertUniqueCell -- + * + * For the cell 'def', look for labels marked with LABEL_UNIQUE and + * remove the unique suffix. If the label is a port, then revert + * the port index back to the original port number. + * + * Results: + * None. + * + * Side effects: + * Changes the label records in the cell def. + * + * ---------------------------------------------------------------------------- + */ + +void +ExtRevertUniqueCell(CellDef *def) +{ + Label *lab, *tlab; + char *uptr; + + for (lab = def->cd_labels; lab; lab = lab->lab_next) + { + if (lab->lab_flags & LABEL_UNIQUE) + { + /* There is no need to regenerate the label. We are + * only reducing the string length, so just drop a null + * at the last underscore and leave it at that. + */ + + lab->lab_flags &= ~LABEL_UNIQUE; /* Clear the flag */ + + /* Place a null at the last underscore */ + uptr = strrchr(lab->lab_text, '_'); + if (uptr != NULL) /* should always be true */ + *uptr = '\0'; + + /* If the label is a port, then find the first unmodified + * version of the label and change the port back to its + * port number + */ + if (lab->lab_flags & PORT_DIR_MASK) + { + for (tlab = def->cd_labels; tlab; tlab = tlab->lab_next) + { + if (tlab == lab) continue; + else if (!strcmp(tlab->lab_text, lab->lab_text)) + { + lab->lab_port = tlab->lab_port; + break; + } + } + } + } + } +} + diff --git a/extract/extract.h b/extract/extract.h index fd3d27ea..e0dd2f53 100644 --- a/extract/extract.h +++ b/extract/extract.h @@ -74,6 +74,7 @@ extern const char * const extDevTable[]; #define EXT_DOALL 0x03f /* ALL OF THE ABOVE */ #define EXT_DOLABELCHECK 0x040 /* Check for connections by label */ #define EXT_DOALIASES 0x080 /* Output all node aliases */ +#define EXT_DOUNIQUE 0x100 /* Force unique nodes during extraction */ extern int ExtOptions; /* Bitmask of above */ extern char *ExtLocalPath; /* If non-NULL, location to write .ext files */ @@ -83,6 +84,7 @@ extern char *ExtLocalPath; /* If non-NULL, location to write .ext files */ #define EXT_UNIQ_TAGGED 1 #define EXT_UNIQ_NOPORTS 2 #define EXT_UNIQ_NOTOPPORTS 3 +#define EXT_UNIQ_TEMP 4 /* Used only with "EXT_DOUNIQUE" */ extern bool ExtTechLine(); extern void ExtTechInit(); diff --git a/extract/extractInt.h b/extract/extractInt.h index dc584298..23368c2e 100644 --- a/extract/extractInt.h +++ b/extract/extractInt.h @@ -1126,6 +1126,7 @@ extern int extMakeUnique(); extern void extEnumTerminal(); extern void extEnumTerminal(Tile *tile, TileType dinfo, TileTypeBitMask *connect, void (*func)(), ClientData clientData); +extern void ExtRevertUniqueCell(CellDef *def); /* ------------------ Connectivity table management ------------------- */