Compare commits

..
80 Commits
Author SHA1 Message Date
Tim Edwards 1b2cd1497c Merge branch 'master' into netgen-1.5 2020-07-30 03:00:28 -04:00
Tim Edwards 71ad228d8d Modified the symmetry breaking routine that arbitrarily resolves
automorphisms so that it arbitrarily assigns all pairs from
circuit1 and circuit2 at once rather than assigning one pair at
a time and rerunning to convergence.  I'm not sure of the validity
of this, other than that I have never seen a circuit fail to match
after resolving automorphisms, leading me to believe that the way
the symmetry breaking is done is irrelevant.
2020-07-29 21:13:45 -04:00
Tim Edwards 339a0d5d4e Updated version to force the new tarball and github mirror. 2020-07-29 13:59:24 -04:00
Tim Edwards 9cebb76787 Corrected a problem in ResolveAutomorphsByProperty() that causes
long run-times even when there are no properties to check.  Corrected
a problem with SPICE and verilog netlist reading which arbitrarily
replaces file extensions even when a file extension is given,
resulting in reading the wrong file.
2020-07-29 13:57:08 -04:00
Tim Edwards d9d5a46c6e Merge branch 'master' into netgen-1.5 2020-07-25 03:00:09 -04:00
Tim Edwards 251622c8bc Corrected the routines DescendCountQueue and DescendCompareQueue
to include type CLASS_MODULE in the list of types to descend into,
since "module" (black-box) types need to be checked for pin
matching even if they have no contents.  This allows two verilog
netlists to be compared against each other.
2020-07-24 20:50:07 -04:00
Tim Edwards d73b711e3a Merge branch 'master' into netgen-1.5 2020-07-02 03:00:09 -04:00
Tim Edwards 18739235a9 Extended the code from the last commit to cover cases in which the
definition covers multiple lines;  this also is a general handler
of the backslash-newline continuation line.
2020-07-01 16:00:54 -04:00
Tim Edwards 07c493c796 Corrected the verilog parser's behavior with respect to string
definitions:  Now correctly parses everything from the definition
name to the end of line as the definition value.  Also:  The
search for definitions in the body of the text does not reject
non-alphanumerics "_" and "$" in the definition name, without
which definition names containing those characters will go
unrecongized.  Have not yet extended this to multi-line definition
values.
2020-07-01 14:28:00 -04:00
Tim Edwards cca0e4b3f3 Corrected an error in bundle assignment that failed to make a copy
of the root name of the LHS net, and so would use the last root
name copied, which might have belonged to something entirely
different, or nothing at all.
2020-07-01 13:11:37 -04:00
Tim Edwards 1428580109 Merge branch 'master' into netgen-1.5 2020-06-17 03:00:38 -04:00
Tim Edwards fb0e1d10b0 Added back a correction that did not get made in this code base
and so didn't make it into the commit.  Handles implicit pins in
verilog.
2020-06-16 17:16:30 -04:00
Tim Edwards 6f81e1d294 Removed a restriction on the "equate pins" command such that pins
are matched on circuits that have no elements.  This condition
does not necessarily indicate an error, and matching pins has no
adverse affect (while refusing to match them certainly can).
2020-06-16 15:56:59 -04:00
Tim Edwards cec6d89474 Corrected an uninitialized variable error in the verilog reading code
that produces a segfault condition.
2020-06-16 12:52:29 -04:00
Tim Edwards 210dfb25c3 Merge branch 'master' into netgen-1.5 2020-06-04 03:00:24 -04:00
Tim Edwards 9bcca3ac21 Corrected the verilog parsing (yet again!) so that it does not
mistakenly flag bus delimiter characters inside backslash-escaped
names when looking for bus delimiters.
2020-06-03 17:00:42 -04:00
Tim Edwards 27f2ab8b3f Merge branch 'master' into netgen-1.5 2020-03-28 03:00:24 -04:00
Tim Edwards 6ae6a246e9 Some additional changes to better identify behavioral verilog
blocks.
2020-03-27 15:09:56 -04:00
Tim Edwards d985ea340e One more bug fix. . . unitialized variable error. 2020-03-27 12:47:24 -04:00
Tim Edwards 5ea7916ff1 Final (I hope) correction to netgen for handling signal wraparound
for buses applied to instance arrayes.
2020-03-27 12:15:57 -04:00
Tim Edwards cf9dedb2f7 Additional corrections; needed to maintain port width in the
scan structure because it is used in two different places and
would have to run a cost-prohibitive search of the cell's
object list.  Also, was missing recording a bus input/output
signal from an "input" or "output" statement (as opposed to
in-line signals in the I/O list).
2020-03-27 11:31:21 -04:00
Tim Edwards da667c3b17 Corrected handling of wire bundles in the verilog parser. 2020-03-27 08:48:48 -04:00
Tim Edwards 1be00bbd99 Merge branch 'master' into netgen-1.5 2020-03-27 03:00:21 -04:00
Tim Edwards 36aa373fb2 Corrected an error in the verilog read to correctly assign signals
to bus pins over an array of instances.  Takes care of the three
situations where the length of the signal bus equals the number of
instances;  where the length of the signal bus is a multiple of
the number of instances;  and where the number of instances is a
multiple of the length of the signal bus.
2020-03-26 11:53:52 -04:00
Tim Edwards 18f230fc46 Changed the default string size for tmpstr in flattenInstancesOf
from 200 to 1024.  Probably this should be dynamically allocated
and expanded as needed, as it is holding names that are of
increasing length as a hierarchy is descended and the instance
prefixes appended to the name.
2020-03-26 09:04:52 -04:00
Tim Edwards 03b241a5d4 Merge branch 'master' into netgen-1.5 2020-03-11 03:00:17 -04:00
Tim Edwards 0f5a618353 Corrected some problems with property matching in netcmp.c.
However, I have identified an issue that has not yet been resolved,
which is that there can be automorphisms that are potentially
broken by property matching.  Currently, the automorphisms are
arbitrarily resolved, then properties are matched---and may fail
accordingly.
2020-03-10 21:39:41 -04:00
Tim Edwards 43cebd1ef9 Merge branch 'master' into netgen-1.5 2020-03-06 03:00:39 -05:00
Tim Edwards 983c654086 Corrected error in property matching that can cause a segfault. 2020-03-05 15:20:46 -05:00
Tim Edwards 515fccc633 Corrected error in printing the name of a file when it is not found
in an "include" statement in either SPICE or verilog.  Modified pin
matching behavior to force cells in both netlists to be marked as
black-box entries if either one is marked as a black-box entry (this
may not be needed, but shouldn't do any harm, either).
2020-03-05 09:41:22 -05:00
Tim Edwards 0490959b07 Merge branch 'master' into netgen-1.5 2020-03-05 03:00:09 -05:00
Tim Edwards 7d94a7d5f6 Updated VERSION for new tarball. 2020-03-04 21:06:21 -05:00
Tim Edwards 39b3bb4d96 Changed behavior of MatchPins so that disconnected pins that are to
be removed because they do not match pins on the other cell being
compared, are marked with a different number (-2) than the usual
(-1).  CleanupPins then only removes those pins that are marked,
rather than all disconnected pins.
2020-03-04 21:01:43 -05:00
Tim Edwards 44673a04b6 Corrected the verilog parser to handle backslash-escape notation
in instance names, and to ignore bus delimiters inside backslash-
escaped names when determining if a net is a bus or not.
2020-03-04 16:55:53 -05:00
Tim Edwards a34f08b20a Corrected problem in flattening code that would attempt to flatten
a cell that mismatched by having zero instances.  Which fails and
repeats indefinitely.
2020-03-04 15:17:42 -05:00
Tim Edwards 240a276431 Changed behavior of "equate pins" to detect placeholder cells as
a different way of treating "black box" cells.  Even when the
"-blackbox" option is specified, any cell that has no definition
will be treated as a black box.  This allows comparison of a
black-box netlist against a non-black-box netlist, such as a
verilog netlist vs. a SPICE netlist, without forcing the black-box
attribute on the SPICE netlist.  Then, if the SPICE netlist
contains cells without elements such as fill/decap/tap cells,
they can be flattened and removed instead of forcing an error or
requiring the use of "ignore".
2020-03-03 10:50:45 -05:00
Tim Edwards dc841f3293 Merge branch 'master' into netgen-1.5 2020-02-24 17:35:04 -05:00
Tim Edwards f7037fc9e6 Updated VERSION manually; checking regeneration of tarball. 2020-02-24 17:34:38 -05:00
Tim Edwards 23fb9356f4 Corrected Makefile to use -include instead of include on defs.mak
so that "make distclean" works.
2020-02-24 17:31:06 -05:00
Tim Edwards 05bcfede69 Merge branch 'master' into netgen-1.5 2020-02-24 16:39:19 -05:00
Tim Edwards 027b4ae468 Test update of VERSION. 2020-02-24 16:38:56 -05:00
Tim Edwards 72ed78e55a Update for change in ocd git script 2020-02-24 15:04:59 -05:00
Tim Edwards 59bb8a89c0 "ocd_git_pure automatic update to repo" 2020-02-24 15:04:27 -05:00
Tim Edwards 08a442fda2 Removed VERSION from .gitignore, and updated VERSION. 2020-02-24 11:50:38 -05:00
Tim Edwards 9bdaee652e "ocd_git_pure automatic update to repo" 2020-02-18 03:00:14 -05:00
Tim Edwards 9879b58f83 Merge branch 'master' into netgen-1.5 2020-02-18 03:00:13 -05:00
Tim Edwards cc0cc512c0 Modified the Makefile per the patch from Charlene at OpenBSD to
add GR_LIBS to the list of options to CC, as this apparently
prevents problems with older binutils, and should not affect
builds otherwise.
2020-02-17 14:04:40 -05:00
Tim Edwards 9e3b705fcc "ocd_git_pure automatic update to repo" 2020-02-11 03:00:09 -05:00
Tim Edwards d2c9129242 Merge branch 'master' into netgen-1.5 2020-02-11 03:00:09 -05:00
Tim Edwards e9c0596dfe One additional change to allow a single value to the "format" command
to apply to both column widths.
2020-02-10 09:17:45 -05:00
Tim Edwards 9a1e295367 Based on code from John Wood, added command "netgen::format <col1_width>
<col2_width>" to set the output format width, to avoid the fixed column
widths of 41 characters which can truncate long strings in the output
such as deep cell hierarchies.  This command can be placed in the setup
script to widen the output columns to accomodate the result (to-do:
provide an "auto" mode to automatically determine the best width).
2020-02-10 09:11:34 -05:00
Tim Edwards 942f421fa3 "ocd_git_pure automatic update to repo" 2020-01-30 03:01:39 -05:00
Tim Edwards 6bc948d8ba Merge branch 'master' into netgen-1.5 2020-01-30 03:01:38 -05:00
Tim Edwards d7272e4ea1 One correction to a variable not pointing to the correct distributed
install location for --with-distdir.
2020-01-28 13:51:23 -05:00
Tim Edwards 7f4b5817e2 Corrected configure.in to correctly use withval for setting the
with-distdir option.
2020-01-28 13:48:24 -05:00
Tim Edwards b5ab38d5d7 Added a distributed install option "--with-distdir=" which replaces
"prefix" with the specified path during install, so that netgen can
be installed in a separate location to be migrated to the final
install location, without appending the entire install path to
DESTDIR.
2020-01-28 10:49:42 -05:00
Tim Edwards c1ad37f05a "ocd_git_pure automatic update to repo" 2020-01-14 03:00:47 -05:00
Tim Edwards 9edefe7d59 Merge branch 'master' into netgen-1.5 2020-01-14 03:00:47 -05:00
Tim Edwards bf671937b9 Changed the behavior with respect to backslashes in the JSON so that
they are converted to the double-backslash escape that is the proper
JSON syntax for backslashes, instead of being removed, which changes
the name and can be confusing.
2020-01-13 09:03:36 -05:00
Tim Edwards a16086d2e9 Added handling of backslash characters in instance names in the
JSON output.  Previously, only net names were checked for
backslash characters.
2020-01-13 09:00:48 -05:00
Tim Edwards f6b9629521 "ocd_git_pure automatic update to repo" 2019-11-20 03:00:33 -05:00
Tim Edwards 7b2e01f2af Merge branch 'master' into netgen-1.5 2019-11-20 03:00:33 -05:00
Tim Edwards 0e03f0bf97 Corrected an error that allows a variable to be used uninitialized
in parallel_sort, resulting in a (potentially intermittant)
segfault condition.
2019-11-19 11:45:49 -05:00
Tim Edwards 224050f153 "ocd_git_pure automatic update to repo" 2019-10-09 03:00:08 -04:00
Tim Edwards 74e8c3e168 Merge branch 'master' into netgen-1.5 2019-10-09 03:00:08 -04:00
Tim Edwards f12d03fcff Corrected the verilog parser for handling parameters and parameters
with increment/decrement syntax at the end.  Also the parser now
handles additional keywords associated with behavioral verilog
(initial, specify) and flags modules with them as black-box entries.
2019-10-08 12:18:13 -04:00
Tim Edwards 95a29fcd8c "ocd_git_pure automatic update to repo" 2019-09-11 03:00:07 -04:00
Tim Edwards 723a950fd3 Merge branch 'master' into netgen-1.5 2019-09-11 03:00:07 -04:00
Tim Edwards f04c72b984 Corrected missing case (greater-than or equal instead of greater than)
that affects vectors sliced across instance arrays.  Can cause vector
numbers to be out-of-bounds if an instance is arrayed but each
instance is listed separately.
2019-09-10 10:52:15 -04:00
Tim Edwards e3368cb22a "ocd_git_pure automatic update to repo" 2019-09-10 03:00:08 -04:00
Tim Edwards f06e6548bb Merge branch 'master' into netgen-1.5 2019-09-10 03:00:08 -04:00
Tim Edwards d38bd77825 Additional fixes to the verilog parser, including handling the
inline-I/O syntax with "wire" (e.g., "input wire [3:0] test")
and addressed the failure to add buses declared in inline I/O
to the list of known buses.
2019-09-09 13:42:21 -04:00
Tim Edwards ea4083893c A fairly large refactoring of the conditional handling code in the
verilog parser.  The parser should now be able to handle any
conditionals anywhere in the verilog code.  Also a bug was found
in the code that handles "a = b" assignments, and corrected.
2019-09-09 11:26:31 -04:00
Tim Edwards 72ed19ff36 "ocd_git_pure automatic update to repo" 2019-09-09 03:00:10 -04:00
Tim Edwards 39b8e3d14a Merge branch 'master' into netgen-1.5 2019-09-09 03:00:10 -04:00
Tim Edwards 3dc70148d1 Added support in the verilog parser for definitions anywhere in the
code using the backtick expression.  Also expanded the parsing of
"ifdef", "ifndef", and "endif" to include "elsif" and "else".  All
forms of "if" statements should now be handled, since verilog does
not define boolean expressions in ifdef operators like most languages
do.
2019-09-08 19:59:27 -04:00
Tim Edwards b63dfa8638 "ocd_git_pure automatic update to repo" 2019-08-20 03:00:20 -04:00
Tim Edwards f918f33c51 Merge branch 'master' into netgen-1.5 2019-08-20 03:00:20 -04:00
Tim Edwards a8576d26a9 Modified the netgen token parser, which (unwisely) is used both for
SPICE and verilog, in spite of the syntactical differences, to
account for the trick that qflow uses to replace the trailing space
in a verilog backslash-escaped name with a second backslash to get
a SPICE-compatible name that can be easily converted back to its
original verilog name without loss of information.  What this means
is that verilog can read SPICE files containing verilog names (which
is illegal SPICE) and verilog files containing hacked-backslash
names (which is illegal verilog).  This should be mostly harmless
although the wisdom of it is surely questionable.
2019-08-19 17:06:05 -04:00
Tim Edwards 63b2e48ea1 "ocd_git_pure automatic update to repo" 2019-08-13 03:00:08 -04:00
21 changed files with 1225 additions and 1849 deletions
+8 -8
View File
@@ -9,7 +9,7 @@ MODULES = base
MAKEFLAGS =
INSTALL_CAD_DIRS = lib doc
include defs.mak
-include defs.mak
all: $(ALL_TARGET)
@@ -51,8 +51,8 @@ depend:
install: $(INSTALL_TARGET)
install-netgen:
@echo --- installing executable to $(DESTDIR)${BINDIR}
@echo --- installing run-time files to $(DESTDIR)${LIBDIR}
@echo --- installing executable to $(DESTDIR)${INSTALL_BINDIR}
@echo --- installing run-time files to $(DESTDIR)${INSTALL_LIBDIR}
@${MAKE} install-real >> install.log
install-real: install-dirs
@@ -60,15 +60,15 @@ install-real: install-dirs
(cd $$dir && ${MAKE} install); done
install-tcl-dirs:
${NETGENDIR}/scripts/mkdirs $(DESTDIR)${BINDIR} \
$(DESTDIR)${TCLDIR} $(DESTDIR)${PYDIR}
${NETGENDIR}/scripts/mkdirs $(DESTDIR)${INSTALL_BINDIR} \
$(DESTDIR)${INSTALL_TCLDIR} $(DESTDIR)${INSTALL_PYDIR}
install-dirs:
${NETGENDIR}/scripts/mkdirs $(DESTDIR)${BINDIR}
${NETGENDIR}/scripts/mkdirs $(DESTDIR)${INSTALL_BINDIR}
install-tcl: install-dirs
@echo --- installing executable to $(DESTDIR)${BINDIR}
@echo --- installing run-time files to $(DESTDIR)${LIBDIR}
@echo --- installing executable to $(DESTDIR)${INSTALL_BINDIR}
@echo --- installing run-time files to $(DESTDIR)${INSTALL_LIBDIR}
@${MAKE} install-tcl-real 2>&1 >> install.log
install-tcl-real: install-tcl-dirs
+1 -1
View File
@@ -1 +1 @@
1.5.127
1.5.151
+6 -6
View File
@@ -259,7 +259,7 @@ int flattenInstancesOf(char *name, int fnum, char *instance)
struct nlist *ChildCell;
struct objlist *tmp, *ob2, *ob3;
int notdone, rnodenum;
char tmpstr[200];
char tmpstr[1024];
int nextnode, oldmax, numflat = 0;
#if !OLDPREFIX
int prefixlength;
@@ -1166,7 +1166,7 @@ struct nlist *cleanuppins(struct hashlist *p, void *clientdata)
while (ob && obt && (ob->type > FIRSTPIN || ob == firstpin) &&
ob->model.class != NULL) {
nob = ob->next;
if ((obt->type == PORT) && (obt->node == -1)) {
if ((obt->type == PORT) && (obt->node == -2)) {
/* Remove this pin */
@@ -1238,7 +1238,7 @@ int CleanupPins(char *name, int filenum)
for (ob = ThisCell->cell; ob != NULL; ob = ob->next) {
if (ob->type != PORT) break;
if (ob->node == -1) {
if (ob->node == -2) {
needscleanup = 1;
break;
}
@@ -1265,7 +1265,7 @@ int CleanupPins(char *name, int filenum)
}
else if (ob->type != PORT) break;
nob = ob->next;
if (ob->node == -1) {
if (ob->node == -2) {
if (lob == NULL) {
ThisCell->cell = ob->next;
}
@@ -1539,7 +1539,7 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
/* (it without regard to cell1) improves the matching. */
else if ((ecomp->num1 != ecomp->num2) && (ecomp->cell2 != NULL) &&
(ecomp->cell2->class == CLASS_SUBCKT)) {
(ecomp->num2 != 0) && (ecomp->cell2->class == CLASS_SUBCKT)) {
ecomp->add2 = -ecomp->num2;
match = 1;
for (ob2 = ecomp->cell2->cell; ob2; ob2 = ob2->next) {
@@ -1597,7 +1597,7 @@ PrematchLists(char *name1, int file1, char *name2, int file2)
/* (it without regard to cell1) improves the matching. */
else if ((ecomp->num1 != ecomp->num2) && (ecomp->cell1 != NULL) &&
(ecomp->cell1->class == CLASS_SUBCKT)) {
(ecomp->num1 != 0) && (ecomp->cell1->class == CLASS_SUBCKT)) {
ecomp->add1 = -ecomp->num1;
match = 1;
for (ob2 = ecomp->cell1->cell; ob2; ob2 = ob2->next) {
+274 -164
View File
@@ -151,6 +151,10 @@ static struct NodeList *NodeListFreeList = NULL;
struct nlist *Circuit1;
struct nlist *Circuit2;
/* global variables to handle the output line width */
int left_col_end = 43;
int right_col_end = 87;
/* if TRUE, always partition ALL classes */
int ExhaustiveSubdivision = 0;
@@ -1147,12 +1151,16 @@ void FormatIllegalElementClasses()
struct FormattedList **elist1, **elist2;
struct ElementClass *escan;
int found, numlists1, numlists2, n1, n2, n, f1, f2, i, maxf;
char ostr[89];
char *ostr;
char *estr;
char permname[80];
char permcount[80];
char *permname;
char *permcount;
int bytesleft;
ostr = CALLOC(right_col_end + 2, sizeof(char));
permname = CALLOC(right_col_end + 2, sizeof(char));
permcount = CALLOC(right_col_end + 2, sizeof(char));
found = 0;
for (escan = ElementClasses; escan != NULL; escan = escan->next)
if (!(escan->legalpartition)) {
@@ -1164,14 +1172,14 @@ void FormatIllegalElementClasses()
/* Print in side-by-side format */
*(ostr + 43) = '|';
*(ostr + 87) = '\n';
*(ostr + 88) = '\0';
for (i = 0; i < 43; i++) *(ostr + i) = ' ';
for (i = 44; i < 87; i++) *(ostr + i) = ' ';
snprintf(ostr, 43, "Circuit 1: %s", Circuit1->name);
snprintf(ostr + 44, 43, "Circuit 2: %s", Circuit2->name);
for (i = 0; i < 88; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
*(ostr + left_col_end) = '|';
*(ostr + right_col_end) = '\n';
*(ostr + right_col_end + 1) = '\0';
for (i = 0; i < left_col_end; i++) *(ostr + i) = ' ';
for (i = left_col_end + 1; i < right_col_end; i++) *(ostr + i) = ' ';
snprintf(ostr, left_col_end, "Circuit 1: %s", Circuit1->name);
snprintf(ostr + left_col_end + 1, left_col_end, "Circuit 2: %s", Circuit2->name);
for (i = 0; i < right_col_end + 1; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
Fprintf(stdout, ostr);
}
found = 1;
@@ -1196,6 +1204,9 @@ void FormatIllegalElementClasses()
if (check_interrupt()) {
FreeFormattedLists(elist1, n1);
FreeFormattedLists(elist2, n2);
FREE(ostr);
FREE(permname);
FREE(permcount);
return;
}
#endif
@@ -1212,31 +1223,31 @@ void FormatIllegalElementClasses()
for (n = 0; n < ((n1 > n2) ? n1 : n2); n++) {
if (n != 0) {
for (i = 0; i < 43; i++) *(ostr + i) = ' ';
for (i = 44; i < 87; i++) *(ostr + i) = ' ';
for (i = 0; i < left_col_end; i++) *(ostr + i) = ' ';
for (i = left_col_end + 1; i < right_col_end; i++) *(ostr + i) = ' ';
Fprintf(stdout, ostr);
} else {
for (i = 0; i < 87; i++) *(ostr + i) = '-';
for (i = 0; i < right_col_end; i++) *(ostr + i) = '-';
Fprintf(stdout, ostr);
*(ostr + 43) = '|';
*(ostr + left_col_end) = '|';
}
for (i = 0; i < 43; i++) *(ostr + i) = ' ';
for (i = 44; i < 87; i++) *(ostr + i) = ' ';
for (i = 0; i < left_col_end; i++) *(ostr + i) = ' ';
for (i = left_col_end + 1; i < right_col_end; i++) *(ostr + i) = ' ';
if (n < n1) {
estr = elist1[n]->name;
if (*estr == '/') estr++; // Remove leading slash, if any
snprintf(ostr, 43, "Instance: %s", estr);
snprintf(ostr, left_col_end, "Instance: %s", estr);
}
else
snprintf(ostr, 43, "(no matching instance)");
snprintf(ostr, left_col_end, "(no matching instance)");
if (n < n2) {
estr = elist2[n]->name;
if (*estr == '/') estr++; // Remove leading slash, if any
snprintf(ostr + 44, 43, "Instance: %s", estr);
snprintf(ostr + left_col_end + 1, left_col_end, "Instance: %s", estr);
}
else
snprintf(ostr + 44, 43, "(no matching instance)");
for (i = 0; i < 88; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
snprintf(ostr + left_col_end + 1, left_col_end, "(no matching instance)");
for (i = 0; i < right_col_end + 1; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
Fprintf(stdout, ostr);
if (n >= n1)
@@ -1249,12 +1260,12 @@ void FormatIllegalElementClasses()
f1 = f2 = 0;
while ((f1 < maxf) || (f2 < maxf)) {
for (i = 0; i < 43; i++) *(ostr + i) = ' ';
for (i = 44; i < 87; i++) *(ostr + i) = ' ';
for (i = 0; i < left_col_end; i++) *(ostr + i) = ' ';
for (i = left_col_end + 1; i < right_col_end; i++) *(ostr + i) = ' ';
if (n < n1) {
if (f1 < elist1[n]->fanout) {
if (elist1[n]->flist[f1].permute == (char)1) {
snprintf(ostr, 43, " %s = %d", elist1[n]->flist[f1].name,
snprintf(ostr, left_col_end, " %s = %d", elist1[n]->flist[f1].name,
elist1[n]->flist[f1].count);
}
else {
@@ -1276,7 +1287,7 @@ void FormatIllegalElementClasses()
sprintf(value, "%d", elist1[n]->flist[f1].count);
strcat(permcount, value);
strcat(permcount, ")");
snprintf(ostr, 43, " %s = %s", permname, permcount);
snprintf(ostr, left_col_end, " %s = %s", permname, permcount);
}
}
}
@@ -1284,7 +1295,7 @@ void FormatIllegalElementClasses()
if (n < n2) {
if (f2 < elist2[n]->fanout) {
if (elist2[n]->flist[f2].permute == (char)1) {
snprintf(ostr + 44, 43, " %s = %d", elist2[n]->flist[f2].name,
snprintf(ostr + left_col_end + 1, left_col_end, " %s = %d", elist2[n]->flist[f2].name,
elist2[n]->flist[f2].count);
}
else {
@@ -1306,22 +1317,26 @@ void FormatIllegalElementClasses()
sprintf(value, "%d", elist2[n]->flist[f2].count);
strcat(permcount, value);
strcat(permcount, ")");
snprintf(ostr + 44, 43, " %s = %s", permname, permcount);
snprintf(ostr + left_col_end + 1, left_col_end, " %s = %s", permname, permcount);
}
}
}
f2++;
for (i = 0; i < 88; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
for (i = 0; i < right_col_end + 1; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
Fprintf(stdout, ostr);
}
}
FreeFormattedLists(elist1, numlists1);
FreeFormattedLists(elist2, numlists2);
for (i = 0; i < 87; i++) *(ostr + i) = '-';
for (i = 0; i < right_col_end; i++) *(ostr + i) = '-';
Fprintf(stdout, ostr);
*(ostr + 43) = '|';
*(ostr + left_col_end) = '|';
}
FREE(ostr);
FREE(permname);
FREE(permcount);
}
/*
@@ -1502,8 +1517,9 @@ void FormatIllegalNodeClasses()
struct FormattedList **nlists1, **nlists2;
struct NodeClass *nscan;
int found, numlists1, numlists2, n1, n2, n, f, i, maxf;
char ostr[89];
char *ostr;
ostr = CALLOC(right_col_end + 2, sizeof(char));
found = 0;
for (nscan = NodeClasses; nscan != NULL; nscan = nscan->next)
@@ -1515,14 +1531,14 @@ void FormatIllegalNodeClasses()
Fprintf(stdout, "Class fragments follow (with fanout counts):\n");
/* Print in side-by-side format */
*(ostr + 43) = '|';
*(ostr + 87) = '\n';
*(ostr + 88) = '\0';
for (i = 0; i < 43; i++) *(ostr + i) = ' ';
for (i = 44; i < 87; i++) *(ostr + i) = ' ';
snprintf(ostr, 43, "Circuit 1: %s", Circuit1->name);
snprintf(ostr + 44, 43, "Circuit 2: %s", Circuit2->name);
for (i = 0; i < 88; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
*(ostr + left_col_end) = '|';
*(ostr + right_col_end) = '\n';
*(ostr + right_col_end + 1) = '\0';
for (i = 0; i < left_col_end; i++) *(ostr + i) = ' ';
for (i = left_col_end + 1; i < right_col_end; i++) *(ostr + i) = ' ';
snprintf(ostr, left_col_end, "Circuit 1: %s", Circuit1->name);
snprintf(ostr + left_col_end + 1, left_col_end, "Circuit 2: %s", Circuit2->name);
for (i = 0; i < right_col_end + 1; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
Fprintf(stdout, ostr);
}
found = 1;
@@ -1545,6 +1561,7 @@ void FormatIllegalNodeClasses()
if (check_interrupt()) {
FreeFormattedLists(nlists1, n1);
FreeFormattedLists(nlists2, n2);
FREE(ostr);
return;
}
#endif
@@ -1561,25 +1578,25 @@ void FormatIllegalNodeClasses()
for (n = 0; n < ((n1 > n2) ? n1 : n2); n++) {
if (n != 0) {
for (i = 0; i < 43; i++) *(ostr + i) = ' ';
for (i = 44; i < 87; i++) *(ostr + i) = ' ';
for (i = 0; i < left_col_end; i++) *(ostr + i) = ' ';
for (i = left_col_end + 1; i < right_col_end; i++) *(ostr + i) = ' ';
Fprintf(stdout, ostr);
} else {
for (i = 0; i < 87; i++) *(ostr + i) = '-';
for (i = 0; i < right_col_end; i++) *(ostr + i) = '-';
Fprintf(stdout, ostr);
*(ostr + 43) = '|';
*(ostr + left_col_end) = '|';
}
for (i = 0; i < 43; i++) *(ostr + i) = ' ';
for (i = 44; i < 87; i++) *(ostr + i) = ' ';
for (i = 0; i < left_col_end; i++) *(ostr + i) = ' ';
for (i = left_col_end + 1; i < right_col_end; i++) *(ostr + i) = ' ';
if (n < n1)
snprintf(ostr, 43, "Net: %s", nlists1[n]->name);
snprintf(ostr, left_col_end, "Net: %s", nlists1[n]->name);
else
snprintf(ostr, 43, "(no matching net)");
snprintf(ostr, left_col_end, "(no matching net)");
if (n < n2)
snprintf(ostr + 44, 43, "Net: %s", nlists2[n]->name);
snprintf(ostr + left_col_end + 1, left_col_end, "Net: %s", nlists2[n]->name);
else
snprintf(ostr + 44, 43, "(no matching net)");
for (i = 0; i < 88; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
snprintf(ostr + left_col_end + 1, left_col_end, "(no matching net)");
for (i = 0; i < right_col_end + 1; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
Fprintf(stdout, ostr);
if (n >= n1)
@@ -1591,17 +1608,17 @@ void FormatIllegalNodeClasses()
nlists1[n]->fanout : nlists2[n]->fanout;
for (f = 0; f < maxf; f++) {
for (i = 0; i < 43; i++) *(ostr + i) = ' ';
for (i = 44; i < 87; i++) *(ostr + i) = ' ';
for (i = 0; i < left_col_end; i++) *(ostr + i) = ' ';
for (i = left_col_end + 1; i < right_col_end; i++) *(ostr + i) = ' ';
if (n < n1)
if (f < nlists1[n]->fanout) {
if (nlists1[n]->flist[f].permute <= 1)
snprintf(ostr, 43, " %s/%s = %d",
snprintf(ostr, left_col_end, " %s/%s = %d",
nlists1[n]->flist[f].model,
nlists1[n]->flist[f].name,
nlists1[n]->flist[f].count);
else {
snprintf(ostr, 43, " %s/(%s) = %d",
snprintf(ostr, left_col_end, " %s/(%s) = %d",
nlists1[n]->flist[f].model,
nlists1[n]->flist[f].name,
nlists1[n]->flist[f].count);
@@ -1611,29 +1628,30 @@ void FormatIllegalNodeClasses()
if (n < n2)
if (f < nlists2[n]->fanout) {
if (nlists2[n]->flist[f].permute <= 1)
snprintf(ostr + 44, 43, " %s/%s = %d",
snprintf(ostr + left_col_end + 1, left_col_end, " %s/%s = %d",
nlists2[n]->flist[f].model,
nlists2[n]->flist[f].name,
nlists2[n]->flist[f].count);
else {
snprintf(ostr + 44, 43, " %s/(%s) = %d",
snprintf(ostr + left_col_end + 1, left_col_end, " %s/(%s) = %d",
nlists2[n]->flist[f].model,
nlists2[n]->flist[f].name,
nlists2[n]->flist[f].count);
FREE(nlists2[n]->flist[f].name);
}
}
for (i = 0; i < 88; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
for (i = 0; i < right_col_end + 1; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
Fprintf(stdout, ostr);
}
}
FreeFormattedLists(nlists1, numlists1);
FreeFormattedLists(nlists2, numlists2);
for (i = 0; i < 87; i++) *(ostr + i) = '-';
for (i = 0; i < right_col_end; i++) *(ostr + i) = '-';
Fprintf(stdout, ostr);
*(ostr + 43) = '|';
*(ostr + left_col_end) = '|';
}
FREE(ostr);
}
/*
@@ -2770,26 +2788,28 @@ int FirstElementPass(struct Element *E, int noflat, int dolist)
struct NodeList *n;
struct nlist *tp1, *tp2, *tp;
int C1, C2, i;
char ostr[89];
char *ostr;
int needflat = 0;
#ifdef TCL_NETGEN
Tcl_Obj *clist1, *clist2;
#endif
ostr = CALLOC(right_col_end + 2, sizeof(char));
if (Debug == 0) {
Fprintf(stdout, "\nSubcircuit summary:\n");
*(ostr + 43) = '|';
*(ostr + 87) = '\n';
*(ostr + 88) = '\0';
for (i = 0; i < 43; i++) *(ostr + i) = ' ';
for (i = 44; i < 87; i++) *(ostr + i) = ' ';
*(ostr + left_col_end) = '|';
*(ostr + right_col_end) = '\n';
*(ostr + right_col_end + 1) = '\0';
for (i = 0; i < left_col_end; i++) *(ostr + i) = ' ';
for (i = left_col_end + 1; i < right_col_end; i++) *(ostr + i) = ' ';
snprintf(ostr, 43, "Circuit 1: %s", Circuit1->name);
snprintf(ostr + 44, 43, "Circuit 2: %s", Circuit2->name);
for (i = 0; i < 88; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
snprintf(ostr, left_col_end, "Circuit 1: %s", Circuit1->name);
snprintf(ostr + left_col_end + 1, left_col_end, "Circuit 2: %s", Circuit2->name);
for (i = 0; i < right_col_end + 1; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
Fprintf(stdout, ostr);
for (i = 0; i < 43; i++) *(ostr + i) = '-';
for (i = 44; i < 87; i++) *(ostr + i) = '-';
for (i = 0; i < left_col_end; i++) *(ostr + i) = '-';
for (i = left_col_end + 1; i < right_col_end; i++) *(ostr + i) = '-';
Fprintf(stdout, ostr);
}
@@ -2841,16 +2861,16 @@ int FirstElementPass(struct Element *E, int noflat, int dolist)
if (Debug == 0) {
for (i = 0; i < 43; i++) *(ostr + i) = ' ';
for (i = 44; i < 87; i++) *(ostr + i) = ' ';
snprintf(ostr, 43, "%s (%d)", Esrch->object->model.class, C1);
for (i = 0; i < left_col_end; i++) *(ostr + i) = ' ';
for (i = left_col_end + 1; i < right_col_end; i++) *(ostr + i) = ' ';
snprintf(ostr, left_col_end, "%s (%d)", Esrch->object->model.class, C1);
if (C2 > 0)
snprintf(ostr + 44, 43, "%s (%d)%s", tp2->name, C2,
snprintf(ostr + left_col_end + 1, left_col_end, "%s (%d)%s", tp2->name, C2,
(C2 == C1) ? "" : " **Mismatch**");
else {
snprintf(ostr + 44, 43, "(no matching element)");
snprintf(ostr + left_col_end + 1, left_col_end, "(no matching element)");
}
for (i = 0; i < 88; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
for (i = 0; i < right_col_end + 1; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
Fprintf(stdout, ostr);
}
#ifdef TCL_NETGEN
@@ -2908,11 +2928,11 @@ int FirstElementPass(struct Element *E, int noflat, int dolist)
}
if (Debug == 0) {
for (i = 0; i < 43; i++) *(ostr + i) = ' ';
for (i = 44; i < 87; i++) *(ostr + i) = ' ';
snprintf(ostr, 43, "(no matching element)");
snprintf(ostr + 44, 43, "%s (%d)", Esrch->object->model.class, C2);
for (i = 0; i < 88; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
for (i = 0; i < left_col_end; i++) *(ostr + i) = ' ';
for (i = left_col_end + 1; i < right_col_end; i++) *(ostr + i) = ' ';
snprintf(ostr, left_col_end, "(no matching element)");
snprintf(ostr + left_col_end + 1, left_col_end, "%s (%d)", Esrch->object->model.class, C2);
for (i = 0; i < right_col_end + 1; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
Fprintf(stdout, ostr);
}
#ifdef TCL_NETGEN
@@ -2957,13 +2977,13 @@ int FirstElementPass(struct Element *E, int noflat, int dolist)
C1, C2);
}
else {
for (i = 0; i < 43; i++) *(ostr + i) = ' ';
for (i = 44; i < 87; i++) *(ostr + i) = ' ';
snprintf(ostr, 43, "Number of devices: %d%s", C1, (C1 == C2) ? "" :
for (i = 0; i < left_col_end; i++) *(ostr + i) = ' ';
for (i = left_col_end + 1; i < right_col_end; i++) *(ostr + i) = ' ';
snprintf(ostr, left_col_end, "Number of devices: %d%s", C1, (C1 == C2) ? "" :
" **Mismatch**");
snprintf(ostr + 44, 43, "Number of devices: %d%s", C2, (C1 == C2) ? "" :
snprintf(ostr + left_col_end + 1, left_col_end, "Number of devices: %d%s", C2, (C1 == C2) ? "" :
" **Mismatch**");
for (i = 0; i < 88; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
for (i = 0; i < right_col_end + 1; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
Fprintf(stdout, ostr);
}
@@ -2983,6 +3003,7 @@ int FirstElementPass(struct Element *E, int noflat, int dolist)
}
#endif
FREE(ostr);
return 0;
}
@@ -3006,24 +3027,28 @@ void FirstNodePass(struct Node *N, int dolist)
Fprintf(stderr, "Net Mismatch: Circuit 1 has %d, Circuit 2 has %d.\n",C1,C2);
}
else {
char ostr[89];
char *ostr;
int i;
*(ostr + 43) = '|';
*(ostr + 87) = '\n';
*(ostr + 88) = '\0';
ostr = CALLOC(right_col_end + 2, sizeof(char));
for (i = 0; i < 43; i++) *(ostr + i) = ' ';
for (i = 44; i < 87; i++) *(ostr + i) = ' ';
snprintf(ostr, 43, "Number of nets: %d%s", C1, (C1 == C2) ? "" :
*(ostr + left_col_end) = '|';
*(ostr + right_col_end) = '\n';
*(ostr + right_col_end + 1) = '\0';
for (i = 0; i < left_col_end; i++) *(ostr + i) = ' ';
for (i = left_col_end + 1; i < right_col_end; i++) *(ostr + i) = ' ';
snprintf(ostr, left_col_end, "Number of nets: %d%s", C1, (C1 == C2) ? "" :
" **Mismatch**");
snprintf(ostr + 44, 43, "Number of nets: %d%s", C2, (C1 == C2) ? "" :
snprintf(ostr + left_col_end + 1, left_col_end, "Number of nets: %d%s", C2, (C1 == C2) ? "" :
" **Mismatch**");
for (i = 0; i < 88; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
for (i = 0; i < right_col_end + 1; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
Fprintf(stdout, ostr);
for (i = 0; i < 87; i++) *(ostr + i) = '-';
for (i = 0; i < right_col_end; i++) *(ostr + i) = '-';
Fprintf(stdout, ostr);
FREE(ostr);
}
#ifdef TCL_NETGEN
@@ -3120,7 +3145,9 @@ void DescendCountQueue(struct nlist *tc, int *level, int loclevel)
if (ob->type == FIRSTPIN) {
/* First check if there is a class equivalent */
tcsub = LookupCellFile(ob->model.class, tc->file);
if (!tcsub || (tcsub->class != CLASS_SUBCKT)) continue;
/* Module (black-box) class needs pin checking */
if (!tcsub || ((tcsub->class != CLASS_SUBCKT) &&
(tcsub->class != CLASS_MODULE))) continue;
else if (tcsub == tc) continue;
DescendCountQueue(tcsub, level, loclevel + 1);
}
@@ -3213,7 +3240,8 @@ void DescendCompareQueue(struct nlist *tc, struct nlist *tctop, int stoplevel,
tcsub = NULL;
if (ob->type == FIRSTPIN) {
tcsub = LookupCellFile(ob->model.class, tc->file);
if (!tcsub || (tcsub->class != CLASS_SUBCKT)) continue;
if (!tcsub || ((tcsub->class != CLASS_SUBCKT) &&
(tcsub->class != CLASS_MODULE))) continue;
else if (tcsub == tc) continue;
DescendCompareQueue(tcsub, tctop, stoplevel, loclevel + 1, flip);
}
@@ -3800,6 +3828,51 @@ void series_sort(struct objlist *ob1, struct nlist *tp1, int idx1, int run)
}
obp->next = obn; /* Restore last link */
// In series runs, all records after the first start with tag "+".
// If the tag got moved to the first record, then move it down to
// the record that is missing the tag.
obn = ob1->next;
if (!strcmp(obn->instance.props[0].key, "_tag")) {
char *tmpkey;
struct valuelist *kv2;
int l;
if (!strcmp(obn->instance.props[0].value.string, "+")) {
/* Remove this property tag "+" */
FREE(obn->instance.props[0].key);
FREE(obn->instance.props[0].value.string);
for (p = 0;; p++) {
obn->instance.props[p].key = obn->instance.props[p + 1].key;
obn->instance.props[p].type = obn->instance.props[p + 1].type;
obn->instance.props[p].value = obn->instance.props[p + 1].value;
if (obn->instance.props[p].type == PROP_ENDLIST) break;
}
for (i = 1; i < run; i++) {
obn = obn->next;
if (strcmp(obn->instance.props[0].key, "_tag")) {
for (p = 1;; p++)
if (obn->instance.props[p].type == PROP_ENDLIST) break;
/* Create a new property record to hold all the existing */
/* properties plus the tag at the beginning. */
kv2 = (struct valuelist *)MALLOC((p + 2) * sizeof(struct valuelist));
kv2->key = strsave("_tag");
kv2->type = PROP_STRING;
kv2->value.string = (char *)MALLOC(2);
kv2->value.string[0] = '+';
kv2->value.string[1] = '\0';
for (l = 0; l <= p; l++)
kv2[l + 1] = obn->instance.props[l];
FREE(obn->instance.props);
obn->instance.props = kv2;
break;
}
}
}
}
FREE(proplist);
}
@@ -3860,6 +3933,7 @@ void parallel_sort(struct objlist *ob1, struct nlist *tp1, int idx1, int run)
cval = 0.0;
for (i = 0; i < run; i++) {
merge_type = MERGE_NONE;
ml = NULL;
for (p = 0;; p++) {
vl = &(obp->instance.props[p]);
if (vl->type == PROP_ENDLIST) break;
@@ -3888,11 +3962,11 @@ void parallel_sort(struct objlist *ob1, struct nlist *tp1, int idx1, int run)
}
if (merge_type == MERGE_P_ADD) {
proplist[i].value = cval * (double)mval;
ml->value.ival = 1;
if (ml) ml->value.ival = 1;
}
else if (merge_type == MERGE_P_PAR) {
proplist[i].value = cval / (double)mval;
ml->value.ival = 1;
if (ml) ml->value.ival = 1;
}
proplist[i].idx = i;
proplist[i].ob = obp;
@@ -3904,6 +3978,7 @@ void parallel_sort(struct objlist *ob1, struct nlist *tp1, int idx1, int run)
/* and recalculate all the proplist values. */
mval = 1;
obp = obn;
ml = NULL;
merge_type = MERGE_NONE;
for (i = 0; i < run; i++) {
for (p = 0;; p++) {
@@ -3935,11 +4010,11 @@ void parallel_sort(struct objlist *ob1, struct nlist *tp1, int idx1, int run)
}
if (merge_type == MERGE_P_ADD) {
proplist[i].value = cval * (double)mval;
ml->value.ival = 1;
if (ml) ml->value.ival = 1;
}
else if (merge_type == MERGE_P_PAR) {
proplist[i].value = cval / (double)mval;
ml->value.ival = 1;
if (ml) ml->value.ival = 1;
}
obp = obp->next;
}
@@ -4108,8 +4183,8 @@ void PropertySortAndCombine(struct objlist *pre1, struct nlist *tp1,
max2 = 0;
for (c2 = netwk2; ; c2++) {
if (*c2 == 'D') {
cnt++;
run++;
cnt++;
}
else {
if (run > max2) {
@@ -4391,7 +4466,7 @@ int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int series,
// Now combine records with same properties by summing M (S).
if (comb == FALSE) {
for (i = 0; i < run - 1; i++) {
for (j = 1; j < run; j++) {
for (j = i + 1; j < run; j++) {
pmatch = 0;
for (p = 1; p < pcount; p++) {
kl = plist[p];
@@ -4409,12 +4484,13 @@ int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int series,
if (vl == NULL) {
if (kl->type != vlist[p][j]->type)
PromoteProperty(kl, vl2);
vl = &dfltvl;
}
else {
if (kl->type != vlist[p][i]->type)
PromoteProperty(kl, vl);
vl2 = &dfltvl;
}
vl = &dfltvl;
dfltvl.type = kl->type;
switch (kl->type) {
case PROP_STRING:
@@ -4530,7 +4606,6 @@ int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int series,
vlist[0][j]->value.ival = 0;
}
}
else j++;
}
}
}
@@ -5211,8 +5286,10 @@ PropertyMatch(struct objlist *ob1, struct objlist *ob2, int do_print,
obn1 = tp1;
for (tp2 = ob2->next; (tp2 != NULL) && tp2->type > FIRSTPIN; tp2 = tp2->next)
obn2 = tp2;
if (tp1 && (tp1->type == FIRSTPIN)) tp1 = NULL; /* tp1 had no properties */
if (tp2 && (tp2->type == FIRSTPIN)) tp2 = NULL; /* tp2 had no properties */
if (tp1 && ((tp1->type == FIRSTPIN) || (tp1->type == NODE)))
tp1 = NULL; /* tp1 had no properties */
if (tp2 && ((tp2->type == FIRSTPIN) || (tp2->type == NODE)))
tp2 = NULL; /* tp2 had no properties */
/* Check if there are any properties to match */
@@ -5613,21 +5690,20 @@ int ResolveAutomorphsByPin()
struct Node *N;
int C1, C2;
unsigned long newhash, orighash;
struct nlist *tc1, *tc2;
struct objlist *tob, *ob1, *ob2;
int portnum;
/* Diagnostic */
Fprintf(stdout, "Resolving automorphisms by pin name.\n");
for (NC = NodeClasses; NC != NULL; NC = NC->next) {
struct Node *N1, *N2;
C1 = C2 = 0;
N1 = N2 = NULL;
for (N = NC->nodes; N != NULL; N = N->next) {
if (N->graph == Circuit1->file) {
if (N->graph == Circuit1->file)
C1++;
}
else {
else
C2++;
}
}
if (C1 == C2 && C1 != 1) {
@@ -5639,7 +5715,6 @@ int ResolveAutomorphsByPin()
orighash = NC->nodes->hashval;
for (N1 = NC->nodes; N1 != NULL; N1 = N1->next) {
if (N1->hashval != orighash) continue;
ob1 = N1->object;
for (N2 = N1->next; N2 != NULL; N2 = N2->next) {
if ((N2->graph != N1->graph) &&
(*matchfunc)(N2->object->name, N1->object->name)) {
@@ -5677,6 +5752,9 @@ int ResolveAutomorphsByProperty()
int C1, C2, result, badmatch;
unsigned long orighash, newhash;
/* Diagnostic */
Fprintf(stdout, "Resolving automorphisms by property value.\n");
for (EC = ElementClasses; EC != NULL; EC = EC->next) {
struct Element *E1, *E2;
C1 = C2 = 0;
@@ -5713,7 +5791,6 @@ int ResolveAutomorphsByProperty()
badmatch = FALSE;
for (E2 = E1->next; E2 != NULL; E2 = E2->next) {
if (E2->hashval != orighash) continue;
if (E2->graph == E1->graph) continue;
if (E1->graph == Circuit1->file)
PropertyMatch(E1->object, E2->object, FALSE, FALSE, &result);
else
@@ -5797,9 +5874,23 @@ int ResolveAutomorphisms()
}
if (C1 == C2 && C1 != 1) {
unsigned long newhash;
Magic(newhash);
E1->hashval = newhash;
E2->hashval = newhash;
/* Do all of them at once. */
/* NOTE: If this were to fail for some reason, it would */
/* probably be necessary to do this the original slow way */
/* which is to rehash one pair at a time and iterate to */
/* convergence, and repeat. */
E1 = E2 = EC->elements;
while (E1 != NULL) {
while (E1->graph != Circuit1->file) E1 = E1->next;
while (E2->graph != Circuit2->file) E2 = E2->next;
Magic(newhash);
E1->hashval = newhash;
E2->hashval = newhash;
E1 = E1->next;
E2 = E2->next;
}
goto converge;
}
}
@@ -5820,9 +5911,23 @@ int ResolveAutomorphisms()
}
if (C1 == C2 && C1 != 1) {
unsigned long newhash;
Magic(newhash);
N1->hashval = newhash;
N2->hashval = newhash;
/* Do all of them at once */
/* NOTE: If this were to fail for some reason, it would */
/* probably be necessary to do this the original slow way */
/* which is to rehash one pair at a time and iterate to */
/* convergence, and repeat. */
N1 = N2 = NC->nodes;
while (N1 != NULL) {
while (N1->graph != Circuit1->file) N1 = N1->next;
while (N2->graph != Circuit2->file) N2 = N2->next;
Magic(newhash);
N1->hashval = newhash;
N2->hashval = newhash;
N1 = N1->next;
N2 = N2->next;
}
goto converge;
}
}
@@ -6542,7 +6647,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
int result = 1, haspins = 0;
int hasproxy1 = 0, hasproxy2 = 0;
int needclean1 = 0, needclean2 = 0;
char ostr[89];
char *ostr;
#ifdef TCL_NETGEN
Tcl_Obj *mlist, *plist1, *plist2;
#endif
@@ -6581,20 +6686,22 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
}
#endif
ostr = CALLOC(right_col_end + 2, sizeof(char));
if (Debug == 0) {
/* Format side-by-side comparison of pins */
Fprintf(stdout, "\nSubcircuit pins:\n");
*(ostr + 43) = '|';
*(ostr + 87) = '\n';
*(ostr + 88) = '\0';
for (i = 0; i < 43; i++) *(ostr + i) = ' ';
for (i = 44; i < 87; i++) *(ostr + i) = ' ';
snprintf(ostr, 43, "Circuit 1: %s", tc1->name);
snprintf(ostr + 44, 43, "Circuit 2: %s", tc2->name);
for (i = 0; i < 88; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
*(ostr + left_col_end) = '|';
*(ostr + right_col_end) = '\n';
*(ostr + right_col_end + 1) = '\0';
for (i = 0; i < left_col_end; i++) *(ostr + i) = ' ';
for (i = left_col_end + 1; i < right_col_end; i++) *(ostr + i) = ' ';
snprintf(ostr, left_col_end, "Circuit 1: %s", tc1->name);
snprintf(ostr + left_col_end + 1, left_col_end, "Circuit 2: %s", tc2->name);
for (i = 0; i < right_col_end + 1; i++) if (*(ostr + i) == '\0') *(ostr + i) = ' ';
Fprintf(stdout, ostr);
for (i = 0; i < 43; i++) *(ostr + i) = '-';
for (i = 44; i < 87; i++) *(ostr + i) = '-';
for (i = 0; i < left_col_end; i++) *(ostr + i) = '-';
for (i = left_col_end + 1; i < right_col_end; i++) *(ostr + i) = '-';
Fprintf(stdout, ostr);
}
@@ -6625,6 +6732,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
}
#endif
FREE(ostr);
return 1;
}
@@ -6634,14 +6742,14 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
if ((IsPort(ob2))
&& (*matchfunc)(ob2->name, obp->name)) {
if (Debug == 0) {
for (m = 0; m < 43; m++) *(ostr + m) = ' ';
for (m = 44; m < 87; m++) *(ostr + m) = ' ';
snprintf(ostr, 43, "%s", obn->name);
for (m = 0; m < left_col_end; m++) *(ostr + m) = ' ';
for (m = left_col_end + 1; m < right_col_end; m++) *(ostr + m) = ' ';
snprintf(ostr, left_col_end, "%s", obn->name);
if ((*matchfunc)(obn->name, obp->name))
snprintf(ostr + 44, 43, "%s", obp->name);
snprintf(ostr + left_col_end + 1, left_col_end, "%s", obp->name);
else
snprintf(ostr + 44, 43, "%s **Mismatch**", obp->name);
for (m = 0; m < 88; m++)
snprintf(ostr + left_col_end + 1, left_col_end, "%s **Mismatch**", obp->name);
for (m = 0; m < right_col_end + 1; m++)
if (*(ostr + m) == '\0') *(ostr + m) = ' ';
Fprintf(stdout, ostr);
}
@@ -6672,11 +6780,11 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
// so don't print out the "no pins" entry.
if (strcmp(obn->name, "(no pins)")) {
for (m = 0; m < 43; m++) *(ostr + m) = ' ';
for (m = 44; m < 87; m++) *(ostr + m) = ' ';
for (m = 0; m < left_col_end; m++) *(ostr + m) = ' ';
for (m = left_col_end + 1; m < right_col_end; m++) *(ostr + m) = ' ';
snprintf(ostr, 32, "%s", obn->name);
snprintf(ostr + 44, 43, "(no matching pin)");
for (m = 0; m < 88; m++)
snprintf(ostr + left_col_end + 1, left_col_end, "(no matching pin)");
for (m = 0; m < right_col_end + 1; m++)
if (*(ostr + m) == '\0') *(ostr + m) = ' ';
Fprintf(stdout, ostr);
}
@@ -6699,7 +6807,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
/* Make a pass through circuit 1 to find out if */
/* the pin really is connected to anything, or */
/* has been left orphaned after flattening. If */
/* disconnected, set its node number to -1. */
/* disconnected, set its node number to -2. */
for (obt = ob1->next; obt; obt = obt->next) {
if (obt->type >= FIRSTPIN)
@@ -6707,7 +6815,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
break;
}
if (obt == NULL) {
ob1->node = -1; // Will run this through cleanuppins
ob1->node = -2; // Will run this through cleanuppins
needclean1 = 1;
}
}
@@ -6717,11 +6825,11 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
if (ob1 == NULL) {
if (Debug == 0) {
for (m = 0; m < 43; m++) *(ostr + m) = ' ';
for (m = 44; m < 87; m++) *(ostr + m) = ' ';
snprintf(ostr, 43, "%s", obn->name);
snprintf(ostr + 44, 43, "(no matching pin)");
for (m = 0; m < 88; m++)
for (m = 0; m < left_col_end; m++) *(ostr + m) = ' ';
for (m = left_col_end + 1; m < right_col_end; m++) *(ostr + m) = ' ';
snprintf(ostr, left_col_end, "%s", obn->name);
snprintf(ostr + left_col_end + 1, left_col_end, "(no matching pin)");
for (m = 0; m < right_col_end + 1; m++)
if (*(ostr + m) == '\0') *(ostr + m) = ' ';
Fprintf(stdout, ostr);
}
@@ -6771,11 +6879,11 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
*(cover + i) = (char)1;
if (Debug == 0) {
for (m = 0; m < 43; m++) *(ostr + m) = ' ';
for (m = 44; m < 87; m++) *(ostr + m) = ' ';
snprintf(ostr, 43, "%s", ob1->name);
snprintf(ostr + 44, 43, "%s", ob2->name);
for (m = 0; m < 88; m++)
for (m = 0; m < left_col_end; m++) *(ostr + m) = ' ';
for (m = left_col_end + 1; m < right_col_end; m++) *(ostr + m) = ' ';
snprintf(ostr, left_col_end, "%s", ob1->name);
snprintf(ostr + left_col_end + 1, left_col_end, "%s", ob2->name);
for (m = 0; m < right_col_end + 1; m++)
if (*(ostr + m) == '\0') *(ostr + m) = ' ';
Fprintf(stdout, ostr);
}
@@ -6821,11 +6929,11 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
if (Debug == 0) {
// See above for reverse case
if (strcmp(ob2->name, "(no pins)")) {
for (m = 0; m < 43; m++) *(ostr + m) = ' ';
for (m = 44; m < 87; m++) *(ostr + m) = ' ';
snprintf(ostr, 43, "(no matching pin)");
snprintf(ostr + 44, 43, "%s", ob2->name);
for (m = 0; m < 88; m++)
for (m = 0; m < left_col_end; m++) *(ostr + m) = ' ';
for (m = left_col_end + 1; m < right_col_end; m++) *(ostr + m) = ' ';
snprintf(ostr, left_col_end, "(no matching pin)");
snprintf(ostr + left_col_end + 1, left_col_end, "%s", ob2->name);
for (m = 0; m < right_col_end + 1; m++)
if (*(ostr + m) == '\0') *(ostr + m) = ' ';
Fprintf(stdout, ostr);
}
@@ -6854,7 +6962,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
break;
}
if (obt == NULL) {
ob2->node = -1; // Will run this through cleanuppins
ob2->node = -2; // Will run this through cleanuppins
needclean2 = 1;
continue;
}
@@ -6956,6 +7064,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
else if (ob1 != NULL && ob1->type == PORT) {
/* Disconnected node was not meaningful, has no pin match in */
/* the compared circuit, and so should be discarded. */
ob1->node = -2;
needclean1 = 1;
/* Adjust numbering around removed node */
@@ -6968,7 +7077,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
FREE(cover);
if (Debug == 0) {
for (i = 0; i < 87; i++) *(ostr + i) = '-';
for (i = 0; i < right_col_end; i++) *(ostr + i) = '-';
Fprintf(stdout, ostr);
}
@@ -7075,6 +7184,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
}
#endif
FREE(ostr);
return result;
}
@@ -7276,7 +7386,7 @@ int Compare(char *cell1, char *cell2)
/* arbitrarily resolve automorphisms */
Fprintf(stdout, "\n");
Fprintf(stdout, "Arbitrarily resolving automorphisms:\n");
Fprintf(stdout, "Resolving automorphisms by arbitrary symmetry breaking:\n");
while ((automorphisms = ResolveAutomorphisms()) > 0) ;
if (automorphisms == -1) {
MatchFail(cell1, cell2);
+3
View File
@@ -8,6 +8,9 @@ extern struct nlist *Circuit2;
extern int ExhaustiveSubdivision;
extern int left_col_end;
extern int right_col_end;
#ifdef TCL_NETGEN
#include <tcl.h>
extern int InterruptPending;
+264 -32
View File
@@ -47,6 +47,18 @@ static FILE *outfile;
static int Graph = 0;
int File;
/*------------------------------------------------------*/
/* Structure for stacking nested `if[n]def in verilog */
/*------------------------------------------------------*/
struct ifstack {
int invert;
struct property *kl;
struct ifstack *next;
};
struct ifstack *condstack = NULL;
extern char *SetExtension(char *buffer, char *path, char *extension)
/* add 'extension' to 'path' (overwriting previous extension, if any),
write it into buffer (if buffer is null, malloc a buffer).
@@ -191,11 +203,14 @@ struct filestack {
static struct filestack *OpenFiles = NULL;
struct hashdict *definitions = (struct hashdict *)NULL;
#define WHITESPACE_DELIMITER " \t\n\r"
/*----------------------------------------------------------------------*/
/* TrimQuoted() --- */
/* Remove spaces from inside single- or double-quoted strings. */
/* Ignore verilog constant bits (e.g., "1'b0") when parsing. */
/*----------------------------------------------------------------------*/
void TrimQuoted(char *line)
@@ -211,6 +226,13 @@ void TrimQuoted(char *line)
{
changed = FALSE;
qstart = strchr(lptr, '\'');
if (qstart && (qstart > lptr)) {
if (isdigit(*(qstart - 1))) {
lptr = qstart + 1;
changed = TRUE;
continue;
}
}
if (qstart)
{
qend = strchr(qstart + 1, '\'');
@@ -251,7 +273,6 @@ void TrimQuoted(char *line)
}
}
}
}
/*----------------------------------------------------------------------*/
@@ -265,39 +286,216 @@ void TrimQuoted(char *line)
int GetNextLineNoNewline(char *delimiter)
{
char *newbuf;
int testc;
char *newbuf;
int testc;
int nested = 0;
int llen;
if (feof(infile)) return -1;
if (feof(infile)) return -1;
// This is more reliable than feof() ...
testc = getc(infile);
if (testc == -1) return -1;
ungetc(testc, infile);
while (1) { /* May loop indefinitely in an `if[n]def conditional */
if (linesize == 0) {
/* Allocate memory for line */
linesize = 500;
line = (char *)MALLOC(linesize);
linetok = (char *)MALLOC(linesize);
}
fgets(line, linesize, infile);
while (strlen(line) == linesize - 1) {
newbuf = (char *)MALLOC(linesize + 500);
strcpy(newbuf, line);
FREE(line);
line = newbuf;
fgets(line + linesize - 1, 501, infile);
linesize += 500;
FREE(linetok);
linetok = (char *)MALLOC(linesize);
}
linenum++;
strcpy(linetok, line);
TrimQuoted(linetok);
// This is more reliable than feof() ...
testc = getc(infile);
if (testc == -1) return -1;
ungetc(testc, infile);
nexttok = strdtok(linetok, WHITESPACE_DELIMITER, delimiter);
return 0;
if (linesize == 0) {
/* Allocate memory for line */
linesize = 2000;
line = (char *)MALLOC(linesize + 1);
linetok = (char *)MALLOC(linesize + 1);
}
fgets(line, linesize, infile);
/* Immediately resolve backslash-EOL */
llen = strlen(line);
while ((llen > 1) && (llen < linesize - 1) && *(line + llen - 2) == '\\') {
*(line + llen - 2) = '\n';
fgets(line + llen - 1, linesize - llen + 1, infile);
llen = strlen(line);
}
while (llen == linesize - 1) {
newbuf = (char *)MALLOC(linesize + 501);
strcpy(newbuf, line);
FREE(line);
line = newbuf;
fgets(line + linesize - 1, 501, infile);
llen = strlen(line);
while ((llen > 1) && (llen < linesize - 1) && *(line + llen - 2) == '\\') {
*(line + llen - 2) = '\n';
fgets(line + llen - 1, linesize - llen + 1, infile);
llen = strlen(line);
}
linesize += 500;
FREE(linetok);
linetok = (char *)MALLOC(linesize + 1);
}
/* Check for substitutions (verilog only). Make sure linetok is */
/* large enough to hold the entire line after substitutions. */
if (definitions != NULL) {
char *s, *w, e;
struct property *kl;
int len, dlen, vlen, addin = 0;
unsigned char found = FALSE;
for (s = line; *s != '\0'; s++) {
if (*s == '`') {
w = s + 1;
while (isalnum(*w) || (*w == '_') || (*w == '$')) w++;
e = *w;
*w = '\0';
kl = (struct property *)HashLookup(s + 1, definitions);
if (kl != NULL) {
dlen = strlen(s);
if (kl->type == PROP_STRING) {
vlen = strlen(kl->pdefault.string);
}
else vlen = 12; /* Leave room for numeric conversion */
addin += vlen - dlen + 1;
found = TRUE;
}
*w = e;
}
}
if (found) {
len = strlen(line);
if (len + addin > linesize) {
while (len + addin > linesize) linesize += 500;
FREE(linetok);
linetok = (char *)MALLOC(linesize);
}
}
}
/* Make definition substitutions (verilog only) */
if (definitions != NULL) {
char *s, *t, *w, e;
struct property *kl;
t = linetok;
for (s = line; *s != '\0'; s++) {
if (*s == '`') {
w = s + 1;
while (isalnum(*w) || (*w == '_') || (*w == '$')) w++;
e = *w;
*w = '\0';
kl = (struct property *)HashLookup(s + 1, definitions);
if (kl != NULL) {
if (kl->type == PROP_STRING)
strcpy(t, kl->pdefault.string);
else if (kl->type == PROP_INTEGER)
sprintf(t, "%d", kl->pdefault.ival);
else if (kl->type == PROP_DOUBLE)
sprintf(t, "%g", kl->pdefault.dval);
t += strlen(t);
s = w - 1;
}
else *t++ = *s;
*w = e;
}
else *t++ = *s;
}
*t = '\0';
}
else
strcpy(linetok, line);
TrimQuoted(linetok);
linenum++;
nexttok = strdtok(linetok, WHITESPACE_DELIMITER, delimiter);
if (nexttok == NULL) return 0;
/* Handle `ifdef, `ifndef, `elsif, `else, and `endif (verilog */
/* only, where indicated by a non-NULL "definitions") */
if (definitions == NULL) return 0;
/* If currently skipping through a section, handle conditionals differently */
if (condstack) {
if (((condstack->invert == 0) && (condstack->kl == NULL))
|| ((condstack->invert == 1) && (condstack->kl != NULL))) {
if (match(nexttok, "`ifdef") || match(nexttok, "`ifndef")) {
nested++;
continue;
}
else if (nested > 0) {
if (match(nexttok, "`endif")) nested--;
continue;
}
else if (nexttok[0] != '`') continue;
}
}
/* Handle conditionals (that is not being skipped over) */
if (match(nexttok, "`endif")) {
if (condstack == NULL) {
fprintf(stderr, "Error: `endif without corresponding `if[n]def\n");
}
else {
struct ifstack *iftop = condstack;
condstack = condstack->next;
FREE(iftop);
}
}
/* Note that `if[n]def may be nested. */
else if (match(nexttok, "`ifdef") || match(nexttok, "`ifndef") ||
match(nexttok, "`elsif") || match(nexttok, "`else")) {
/* Every `ifdef or `ifndef increases condstack by 1 */
if (nexttok[1] == 'i') {
struct ifstack *newif = (struct ifstack *)MALLOC(sizeof(struct ifstack));
newif->next = condstack;
condstack = newif;
}
if (condstack == NULL) {
fprintf(stderr, "Error: %s without `if[n]def\n", nexttok);
break;
}
else {
if (match(nexttok, "`else")) {
/* Invert the sense of the if[n]def scope */
condstack->invert = (condstack->invert == 1) ? 0 : 1;
}
else if (match(nexttok, "`elsif")) {
nexttok = strdtok(NULL, WHITESPACE_DELIMITER, delimiter);
if (nexttok == NULL) {
fprintf(stderr, "Error: `elsif with no conditional.\n");
return 0;
}
/* Keep the same scope but redefine the parameter */
condstack->invert = 0;
condstack->kl = (struct property *)HashLookup(nexttok, definitions);
}
else {
condstack->invert = (nexttok[3] == 'n') ? 1 : 0;
nexttok = strdtok(NULL, WHITESPACE_DELIMITER, delimiter);
if (nexttok == NULL) {
fprintf(stderr, "Error: %s with no conditional.\n", nexttok);
return 0;
}
condstack->kl = (struct property *)HashLookup(nexttok, definitions);
}
}
}
else if (condstack) {
if (((condstack->invert == 0) && (condstack->kl == NULL))
|| ((condstack->invert == 1) && (condstack->kl != NULL)))
continue;
else
break;
}
else
break;
}
return 0;
}
/*----------------------------------------------------------------------*/
@@ -312,6 +510,24 @@ void GetNextLine(char *delimiter)
} while (nexttok == NULL);
}
/*----------------------------------------------------------------------*/
/* Return a pointer to the line at the position of nexttok */
/* This is used only when returning the entire line, untokenized, and */
/* is only called by the verilog read routine when reading the value of */
/* a `define statement. */
/*----------------------------------------------------------------------*/
char *GetLineAtTok()
{
char *lpos;
if (nexttok == NULL) return NULL;
if (line == NULL) return NULL;
lpos = strstr(line, nexttok);
return lpos;
}
/*----------------------------------------------------------------------*/
/* if nexttok is already NULL, force scanner to read new line */
/*----------------------------------------------------------------------*/
@@ -478,9 +694,20 @@ char *strdtok(char *pstring, char *delim1, char *delim2)
/* space character becomes part of the verilog name. The remainder of the */
/* name is parsed according to the rules of "delim2". */
/* Special verilog rule exception: To handle the problems caused by */
/* translating verilog backslash-escaped names into other netlist formats */
/* like SPICE where the convention is strictly prohibited, I have used the */
/* convention in qflow scripts to replace the trailing space with another */
/* backslash, so the name is effectively delimited by a pair of back- */
/* slashes. Therefore check for a space or another backslash, whichever */
/* comes first. That will satisfy both methods. Technically this routine */
/* should know whether it is parsing SPICE or verilog and handle the syntax */
/* accordingly (needs to be done). */
if (*s == '\\') {
s++;
while (*s != '\0') {
if (*s == ' ') {
if ((*s == ' ') || (*s == '\\')) {
s++;
break;
}
@@ -571,7 +798,7 @@ int OpenParseFile(char *name, int fnum)
FILE *locfile;
struct filestack *newfile;
locfile = fopen(name,"r");
locfile = fopen(name, "r");
linenum = 0;
/* reset the token scanner */
nexttok = NULL;
@@ -656,7 +883,12 @@ char *ReadNetlist(char *fname, int *fnum)
{SPICE_EXTENSION, ReadSpice},
{SPICE_EXT2, ReadSpice},
{SPICE_EXT3, ReadSpice},
{SPICE_EXT4, ReadSpice},
{SPICE_EXT5, ReadSpice},
{SPICE_EXT6, ReadSpice},
{SPICE_EXT7, ReadSpice},
{VERILOG_EXTENSION, ReadVerilog},
{SYS_VERILOG_EXTENSION, ReadVerilog},
{NETGEN_EXTENSION, ReadNetgenFile},
{NULL, NULL}
};
+9 -1
View File
@@ -9,11 +9,16 @@
#define SIM_EXTENSION ".sim"
#define SPICE_EXTENSION ".spice"
#define SPICE_EXT2 ".spc"
#define SPICE_EXT3 ".fspc"
#define SPICE_EXT3 ".sp"
#define SPICE_EXT4 ".spi"
#define SPICE_EXT5 ".fspc"
#define SPICE_EXT6 ".cir"
#define SPICE_EXT7 ".ckt"
#define NETGEN_EXTENSION ".ntg"
#define CCODE_EXTENSION ".c.code"
#define ESACAP_EXTENSION ".esa"
#define VERILOG_EXTENSION ".v"
#define SYS_VERILOG_EXTENSION ".sv"
#define LINELENGTH 80
@@ -24,14 +29,17 @@ extern void FlushString (char *format, ...);
extern char *SetExtension(char *buffer, char *path, char *extension);
extern int File;
extern struct hashdict *definitions;
/* input routines */
extern char *nexttok;
#define SKIPTO(a) do {SkipTok(NULL);} while (!match(nexttok,a))
extern char *strdtok(char *pstring, char *delim1, char *delim2);
extern char *GetLineAtTok();
extern void SkipTok(char *delimiter);
extern void SkipTokNoNewline(char *delimiter);
extern void SkipTokComments(char *delimiter);
extern void SkipNewLine(char *delimiter);
extern void SpiceTokNoNewline(void); /* handles SPICE "+" continuation line */
extern void SpiceSkipNewLine(void); /* handles SPICE "+" continuation line */
+7 -4
View File
@@ -801,9 +801,12 @@ void DescribeInstance(char *name, int file)
{
if (ob->node > nodemax) nodemax = ob->node;
else if ((ob->node == -1) && (ob->model.port != PROXY)) {
if (disconnectednodes == 0) Fprintf(stderr, "\n");
disconnectednodes++;
Fprintf(stderr, "Cell %s disconnected node: %s\n", tp->name, ob->name);
if (!(tp->flags & CELL_PLACEHOLDER))
{
if (disconnectednodes == 0) Fprintf(stderr, "\n");
disconnectednodes++;
Fprintf(stderr, "Cell %s disconnected node: %s\n", tp->name, ob->name);
}
}
}
instlist = (unsigned char *) CALLOC((nodemax + 1), sizeof(unsigned char));
@@ -1063,7 +1066,7 @@ void Query(void)
ActelLib();
break;
case 'S':
promptstring("Read SPICE (.ckt) file? ", repstr);
promptstring("Read SPICE (.spice) file? ", repstr);
ReadSpice(repstr, &filenum);
break;
case 'V':
+21 -10
View File
@@ -1883,14 +1883,21 @@ char *ReadSpiceTop(char *fname, int *fnum, int blackbox)
CurrentCell = NULL;
if ((filenum = OpenParseFile(fname, *fnum)) < 0) {
char name[100];
SetExtension(name, fname, SPICE_EXTENSION);
if ((filenum = OpenParseFile(name, *fnum)) < 0) {
Fprintf(stderr,"Error in SPICE file read: No file %s\n",name);
if (strrchr(fname, '.') == NULL) {
char name[1024];
SetExtension(name, fname, SPICE_EXTENSION);
if ((filenum = OpenParseFile(name, *fnum)) < 0) {
Fprintf(stderr, "Error in SPICE file read: No file %s\n", name);
*fnum = filenum;
return NULL;
}
}
else {
Fprintf(stderr, "Error in SPICE file read: No file %s\n", fname);
*fnum = filenum;
return NULL;
}
}
}
/* Make sure all SPICE file reading is case insensitive */
@@ -1980,14 +1987,18 @@ void IncludeSpice(char *fname, int parent, struct cellstack **CellStackPtr,
/* helps, if the file didn't have an extension. But */
/* really, we're getting desperate at this point. */
if (strchr(fname, '.') == NULL) {
if (strrchr(fname, '.') == NULL) {
SetExtension(name, fname, SPICE_EXTENSION);
filenum = OpenParseFile(name, parent);
}
if (filenum < 0) {
Fprintf(stderr,"Error in SPICE file include: No file %s\n",name);
return;
if (filenum < 0) {
Fprintf(stderr, "Error in SPICE file include: No file %s\n", name);
return;
}
}
else {
Fprintf(stderr, "Error in SPICE file include: No file %s\n", fname);
return;
}
}
}
ReadSpiceFile(fname, parent, CellStackPtr, blackbox);
+445 -251
View File
File diff suppressed because it is too large Load Diff
+7 -7
View File
@@ -2,11 +2,11 @@ NETGENDIR = ..
include ${NETGENDIR}/defs.mak
MANDIRS = $(DESTDIR)${MANDIR} $(DESTDIR)${MANDIR}/man1
DOCDIRS = $(DESTDIR)${DOCDIR}
MANDIRS = $(DESTDIR)${INSTALL_MANDIR} $(DESTDIR)${INSTALL_MANDIR}/man1
DOCDIRS = $(DESTDIR)${INSTALL_DOCDIR}
MANFILES =
DOCFILES = $(DESTDIR)${DOCDIR}/netgen.doc
DOCFILES = $(DESTDIR)${INSTALL_DOCDIR}/netgen.doc
install-tcl: ${DOCDIRS} ${DOCFILES}
@@ -23,8 +23,8 @@ make-doc-dirs:
${SCRIPTS}/mkdirs ${DOCDIRS}
# This file does not actually exist. . .
$(DESTDIR)${MANDIR}/man1/netgen.1: netgen.1 ${MANDIRS}
${CP} netgen.1 $(DESTDIR)${MANDIR}/man1/netgen.1
$(DESTDIR)${INSTALL_MANDIR}/man1/netgen.1: netgen.1 ${MANDIRS}
${CP} netgen.1 $(DESTDIR)${INSTALL_MANDIR}/man1/netgen.1
$(DESTDIR)${DOCDIR}/netgen.doc: netgen.doc ${DOCDIRS}
${CP} netgen.doc $(DESTDIR)${DOCDIR}/netgen.doc
$(DESTDIR)${INSTALL_DOCDIR}/netgen.doc: netgen.doc ${DOCDIRS}
${CP} netgen.doc $(DESTDIR)${INSTALL_DOCDIR}/netgen.doc
+6 -6
View File
@@ -4,14 +4,14 @@ include ${NETGENDIR}/defs.mak
LIB_FILES = ntk2adl.sh spice spice.bot spice.top
LIB_INST_FILES= $(LIB_FILES:%=$(DESTDIR)${LIBDIR}/netgen/%)
BIN_INST_FILES= $(BIN_FILES:%=$(DESTDIR)${BINDIR}/%)
LIB_INST_FILES= $(LIB_FILES:%=$(DESTDIR)${INSTALL_LIBDIR}/netgen/%)
BIN_INST_FILES= $(BIN_FILES:%=$(DESTDIR)${INSTALL_BINDIR}/%)
install-tcl: ${LIB_INST_FILES}
install: ${LIB_INST_FILES}
$(DESTDIR)${LIBDIR}/netgen/%: %
../scripts/mkdirs $(DESTDIR)${LIBDIR}/netgen
${RM} $(DESTDIR)${LIBDIR}/netgen/$*
${CP} $* $(DESTDIR)${LIBDIR}/netgen/$*
$(DESTDIR)${INSTALL_LIBDIR}/netgen/%: %
../scripts/mkdirs $(DESTDIR)${INSTALL_LIBDIR}/netgen
${RM} $(DESTDIR)${INSTALL_LIBDIR}/netgen/$*
${CP} $* $(DESTDIR)${INSTALL_LIBDIR}/netgen/$*
+12 -12
View File
@@ -25,23 +25,23 @@ tclnetgen${SHDLIB_EXT}: ${EXTRA_LIBS}
${LD_RUN_PATH} ${EXTRA_LIBS} ${LD_EXTRA_LIBS} \
-lc ${LIBS} ${LIB_SPECS} ${LDFLAGS}
$(DESTDIR)${BINDIR}/netgen:
$(DESTDIR)${INSTALL_BINDIR}/netgen:
${RM} $@
${CP} netgen $@
$(DESTDIR)${BINDIR}/ntk2adl:
$(DESTDIR)${INSTALL_BINDIR}/ntk2adl:
${RM} $@
${CP} ntk2adl $@
$(DESTDIR)${BINDIR}/ntk2xnf:
$(DESTDIR)${INSTALL_BINDIR}/ntk2xnf:
${RM} $@
${CP} ntk2xnf $@
$(DESTDIR)${BINDIR}/netcomp:
$(DESTDIR)${INSTALL_BINDIR}/netcomp:
${RM} $@
${CP} netcomp $@
$(DESTDIR)${BINDIR}/inetcomp:
$(DESTDIR)${INSTALL_BINDIR}/inetcomp:
${RM} $@
${CP} inetcomp $@
@@ -61,14 +61,14 @@ ntk2xnf: ntk2xnf.c
${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS} ntk2xnf.c -o $@ ${EXTRA_LIBS} \
${LIBS} ${LDFLAGS}
install: $(DESTDIR)${BINDIR}/netgen $(DESTDIR)${BINDIR}/netcomp \
$(DESTDIR)${BINDIR}/inetcomp $(DESTDIR)${BINDIR}/ntk2adl \
$(DESTDIR)${BINDIR}/ntk2xnf
install: $(DESTDIR)${INSTALL_BINDIR}/netgen $(DESTDIR)${INSTALL_BINDIR}/netcomp \
$(DESTDIR)${INSTALL_BINDIR}/inetcomp $(DESTDIR)${INSTALL_BINDIR}/ntk2adl \
$(DESTDIR)${INSTALL_BINDIR}/ntk2xnf
install-tcl: $(DESTDIR)${TCLDIR} $(DESTDIR)${TCLDIR}/tclnetgen${SHDLIB_EXT}
install-tcl: $(DESTDIR)${INSTALL_TCLDIR} $(DESTDIR)${INSTALL_TCLDIR}/tclnetgen${SHDLIB_EXT}
$(DESTDIR)${TCLDIR}/tclnetgen${SHDLIB_EXT}: tclnetgen${SHDLIB_EXT}
${RM} $(DESTDIR)${TCLDIR}/tclnetgen${SHDLIB_EXT}
${CP} tclnetgen${SHDLIB_EXT} $(DESTDIR)${TCLDIR}/tclnetgen${SHDLIB_EXT}
$(DESTDIR)${INSTALL_TCLDIR}/tclnetgen${SHDLIB_EXT}: tclnetgen${SHDLIB_EXT}
${RM} $(DESTDIR)${INSTALL_TCLDIR}/tclnetgen${SHDLIB_EXT}
${CP} tclnetgen${SHDLIB_EXT} $(DESTDIR)${INSTALL_TCLDIR}/tclnetgen${SHDLIB_EXT}
include ${NETGENDIR}/rules.mak
+12 -12
View File
@@ -4,7 +4,7 @@ SRCS =
SCRIPTS = consoletext.py helpwindow.py lvs_manager.py treeviewsplit.py
SCRIPTS += tksimpledialog.py tooltip.py lvs_help.txt
SCRIPTINSTALL = $(DESTDIR)${PYDIR}
SCRIPTINSTALL = $(DESTDIR)${INSTALL_PYDIR}
include ${NETGENDIR}/defs.mak
@@ -12,11 +12,11 @@ main: lvs_manager.py
tcl-main: lvs_manager.py
$(DESTDIR)${PYDIR}/consoletext.py:
$(DESTDIR)${INSTALL_PYDIR}/consoletext.py:
${RM} $@
${CP} consoletext.py $@
$(DESTDIR)${PYDIR}/helpwindow.py:
$(DESTDIR)${INSTALL_PYDIR}/helpwindow.py:
${RM} $@
${CP} helpwindow.py $@
@@ -24,31 +24,31 @@ lvs_manager.py: lvs_manager.py.in
sed -e '/SUBST_SCRIPT_DIR/s#SUBST_SCRIPT_DIR#$(SCRIPTINSTALL)#' \
lvs_manager.py.in > lvs_manager.py
$(DESTDIR)${PYDIR}/lvs_manager.py: lvs_manager.py
$(DESTDIR)${INSTALL_PYDIR}/lvs_manager.py: lvs_manager.py
${RM} $@
${CP} lvs_manager.py $@
$(DESTDIR)${PYDIR}/treeviewsplit.py: treeviewsplit.py
$(DESTDIR)${INSTALL_PYDIR}/treeviewsplit.py: treeviewsplit.py
${RM} $@
${CP} treeviewsplit.py $@
$(DESTDIR)${PYDIR}/tksimpledialog.py: tksimpledialog.py
$(DESTDIR)${INSTALL_PYDIR}/tksimpledialog.py: tksimpledialog.py
${RM} $@
${CP} tksimpledialog.py $@
$(DESTDIR)${PYDIR}/tooltip.py: tooltip.py
$(DESTDIR)${INSTALL_PYDIR}/tooltip.py: tooltip.py
${RM} $@
${CP} tooltip.py $@
$(DESTDIR)${PYDIR}/lvs_help.txt: lvs_help.txt
$(DESTDIR)${INSTALL_PYDIR}/lvs_help.txt: lvs_help.txt
${RM} $@
${CP} lvs_help.txt $@
install: install-tcl
install-tcl: $(DESTDIR)${PYDIR} $(DESTDIR)${PYDIR}/consoletext.py \
$(DESTDIR)${PYDIR}/helpwindow.py $(DESTDIR)${PYDIR}/lvs_manager.py \
$(DESTDIR)${PYDIR}/treeviewsplit.py $(DESTDIR)${PYDIR}/tksimpledialog.py \
$(DESTDIR)${PYDIR}/tooltip.py $(DESTDIR)${PYDIR}/lvs_help.txt
install-tcl: $(DESTDIR)${INSTALL_PYDIR} $(DESTDIR)${INSTALL_PYDIR}/consoletext.py \
$(DESTDIR)${INSTALL_PYDIR}/helpwindow.py $(DESTDIR)${INSTALL_PYDIR}/lvs_manager.py \
$(DESTDIR)${INSTALL_PYDIR}/treeviewsplit.py $(DESTDIR)${INSTALL_PYDIR}/tksimpledialog.py \
$(DESTDIR)${INSTALL_PYDIR}/tooltip.py $(DESTDIR)${INSTALL_PYDIR}/lvs_help.txt
include ${NETGENDIR}/rules.mak
+22
View File
@@ -633,6 +633,7 @@ gr_srcs
gr_libs
gr_dflags
gr_cflags
DIST_DIR
cadinstall
programs
unused
@@ -734,6 +735,7 @@ ac_subst_files=''
ac_user_opts='
enable_option_checking
with_gnu_ld
with_distdir
with_interpreter
with_tcl
with_tk
@@ -1372,6 +1374,7 @@ Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
--with-distdir=DIR install into location DIR for distribution
--with-interpreter=arg enable interpreter
--with-tcl=DIR Find tclConfig.sh in DIR
--with-tk=DIR Find tkConfig.sh in DIR
@@ -4798,6 +4801,24 @@ usingTcl=1
usingX11=
# For distributed installs, where the run-time files are installed in a
# place that is a temporary staging area, like DESTDIR, but unlike DESTDIR,
# the prefix is replaced by the destination directory, rather than appended
# to it.
DIST_DIR="\${exec_prefix}"
# Check whether --with-distdir was given.
if test "${with_distdir+set}" = set; then :
withval=$with_distdir;
if test "$withval" = "no" -o "$withval" = "NO" ; then
DIST_DIR="\${exec_prefix}"
else
DIST_DIR=${withval}
fi
fi
# Check whether --with-interpreter was given.
if test "${with_interpreter+set}" = set; then :
@@ -6587,6 +6608,7 @@ fi
ac_config_files="$ac_config_files defs.mak"
+15
View File
@@ -249,6 +249,20 @@ usingX11=
dnl Compile-time options below. . .
# For distributed installs, where the run-time files are installed in a
# place that is a temporary staging area, like DESTDIR, but unlike DESTDIR,
# the prefix is replaced by the destination directory, rather than appended
# to it.
DIST_DIR="\${exec_prefix}"
AC_ARG_WITH(distdir,
[ --with-distdir=DIR install into location DIR for distribution], [
if test "$withval" = "no" -o "$withval" = "NO" ; then
DIST_DIR="\${exec_prefix}"
else
DIST_DIR=${withval}
fi
], )
AC_ARG_WITH(interpreter,
[ --with-interpreter=[arg] enable interpreter], [
if test "$withval" = "no" -o "$withval" = "NO"; then
@@ -1272,6 +1286,7 @@ AC_SUBST(modules)
AC_SUBST(unused)
AC_SUBST(programs)
AC_SUBST(cadinstall)
AC_SUBST(DIST_DIR)
AC_SUBST(gr_cflags)
AC_SUBST(gr_dflags)
File diff suppressed because it is too large Load Diff
+7
View File
@@ -35,6 +35,13 @@ DOCDIR = ${libdir}/netgen/doc
TCLDIR = ${libdir}/netgen/tcl
PYDIR = ${libdir}/netgen/python
INSTALL_BINDIR = @DIST_DIR@/bin
INSTALL_MANDIR = @DIST_DIR@/share/man
INSTALL_LIBDIR = @DIST_DIR@/lib
INSTALL_DOCDIR = ${INSTALL_LIBDIR}/netgen/doc
INSTALL_TCLDIR = ${INSTALL_LIBDIR}/netgen/tcl
INSTALL_PYDIR = ${INSTALL_LIBDIR}/netgen/python
MAIN_EXTRA_LIBS = @extra_libs@
LD_EXTRA_LIBS = @ld_extra_libs@
LD_SHARED = @ld_extra_objs@
+14 -14
View File
@@ -12,20 +12,20 @@ CLEANS += netgen.sh netgen.tcl netgenexec${EXEEXT}
CFLAGS += -I${NETGENDIR}/base
TCL_FILES = \
$(DESTDIR)${TCLDIR}/tkcon.tcl \
$(DESTDIR)${TCLDIR}/console.tcl \
$(DESTDIR)${TCLDIR}/netgen.tcl
$(DESTDIR)${INSTALL_TCLDIR}/tkcon.tcl \
$(DESTDIR)${INSTALL_TCLDIR}/console.tcl \
$(DESTDIR)${INSTALL_TCLDIR}/netgen.tcl
tcl-main: netgenexec${EXEEXT} netgen.tcl netgen.sh
install-tcl: netgenexec${EXEEXT} $(DESTDIR)${BINDIR}/netgen.sh ${TCL_FILES}
${RM} $(DESTDIR)${TCLDIR}/netgenexec${EXEEXT}
${CP} netgenexec${EXEEXT} $(DESTDIR)${TCLDIR}/netgenexec${EXEEXT}
install-tcl: netgenexec${EXEEXT} $(DESTDIR)${INSTALL_BINDIR}/netgen.sh ${TCL_FILES}
${RM} $(DESTDIR)${INSTALL_TCLDIR}/netgenexec${EXEEXT}
${CP} netgenexec${EXEEXT} $(DESTDIR)${INSTALL_TCLDIR}/netgenexec${EXEEXT}
netgenexec${EXEEXT}: netgenexec.c
${CC} ${CFLAGS} ${CPPFLAGS} ${DFLAGS_NOSTUB} netgenexec.c \
-o netgenexec${EXEEXT} \
${LDFLAGS} ${LIBS} ${LIB_SPECS_NOSTUB}
${LIB_SPECS_NOSTUB} ${LDFLAGS} ${LIBS} ${GR_LIBS}
netgen.tcl: netgen.tcl.in
sed -e 's%TCL_DIR%${TCLDIR}%g' \
@@ -39,13 +39,13 @@ netgen.sh: netgen.sh.in
-e 's%WISH_EXE%${WISH_EXE}%g' \
netgen.sh.in > netgen.sh
$(DESTDIR)${TCLDIR}/%: %
${RM} $(DESTDIR)${TCLDIR}/$*
${CP} $* $(DESTDIR)${TCLDIR}/$*
$(DESTDIR)${INSTALL_TCLDIR}/%: %
${RM} $(DESTDIR)${INSTALL_TCLDIR}/$*
${CP} $* $(DESTDIR)${INSTALL_TCLDIR}/$*
$(DESTDIR)${BINDIR}/netgen.sh: netgen.sh
${RM} $(DESTDIR)${BINDIR}/netgen.sh $(DESTDIR)${BINDIR}/netgen
${CP} netgen.sh $(DESTDIR)${BINDIR}/netgen
(cd $(DESTDIR)${BINDIR}; chmod 0755 netgen)
$(DESTDIR)${INSTALL_BINDIR}/netgen.sh: netgen.sh
${RM} $(DESTDIR)${INSTALL_BINDIR}/netgen.sh $(DESTDIR)${INSTALL_BINDIR}/netgen
${CP} netgen.sh $(DESTDIR)${INSTALL_BINDIR}/netgen
(cd $(DESTDIR)${INSTALL_BINDIR}; chmod 0755 netgen)
include ${NETGENDIR}/rules.mak
+7 -7
View File
@@ -138,7 +138,7 @@ proc netgen::convert_to_json {filename lvs_final} {
foreach net $cktval {
incr nidx
puts $fjson " \["
set netname [string map {"\\" ""} [lindex $net 0]]
set netname [string map {"\\" "\\\\"} [lindex $net 0]]
puts $fjson " \"$netname\","
puts $fjson " \["
set netconn [lindex $net 1]
@@ -169,7 +169,7 @@ proc netgen::convert_to_json {filename lvs_final} {
foreach net $cktval {
incr nidx
puts $fjson " \["
set netname [string map {"\\" ""} [lindex $net 0]]
set netname [string map {"\\" "\\\\"} [lindex $net 0]]
puts $fjson " \"$netname\","
puts $fjson " \["
set netconn [lindex $net 1]
@@ -221,7 +221,7 @@ proc netgen::convert_to_json {filename lvs_final} {
foreach inst $cktval {
incr iidx
puts $fjson " \["
set instname [lindex $inst 0]
set instname [string map {"\\" "\\\\"} [lindex $inst 0]]
puts $fjson " \"$instname\","
puts $fjson " \["
set instpins [lindex $inst 1]
@@ -250,7 +250,7 @@ proc netgen::convert_to_json {filename lvs_final} {
foreach inst $cktval {
incr iidx
puts $fjson " \["
set instname [lindex $inst 0]
set instname [string map {"\\" "\\\\"} [lindex $inst 0]]
puts $fjson " \"$instname\","
puts $fjson " \["
set instpins [lindex $inst 1]
@@ -292,8 +292,8 @@ proc netgen::convert_to_json {filename lvs_final} {
foreach instance $value {
incr pidx
puts $fjson " \["
set instnames [lindex $instance 0]
set instname0 [lindex $instnames 0]
set instnames [string map {"\\" "\\\\"} [lindex $instance 0]]
set instname0 [string map {"\\" "\\\\"} [lindex $instnames 0]]
puts $fjson " \["
puts $fjson " \"${instname0}\","
puts $fjson " \["
@@ -310,7 +310,7 @@ proc netgen::convert_to_json {filename lvs_final} {
puts $fjson " \[\"${propname}\", \"${propval}\"\]"
puts $fjson " \]"
puts $fjson " \],"
set instname1 [lindex $instnames 1]
set instname1 [string map {"\\" "\\\\"} [lindex $instnames 1]]
puts $fjson " \["
puts $fjson " \"${instname1}\","
puts $fjson " \["
+85 -7
View File
@@ -85,6 +85,7 @@ int _netcmp_compare(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_iterate(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_summary(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_print(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_format(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_run(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_verify(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
int _netcmp_automorphs(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST objv[]);
@@ -199,6 +200,9 @@ Command netcmp_cmds[] = {
{"print", _netcmp_print,
"\n "
"print netcomp internal data structure"},
{"format", _netcmp_format,
"<col1_width> <col2_width>\n "
"set width of formatted output"},
{"run", _netcmp_run,
"[converge|resolve]\n "
"converge: run netcomp to completion (convergence)\n "
@@ -1971,6 +1975,61 @@ _netgen_printmem(ClientData clientData,
}
#endif
/*------------------------------------------------------*/
/* Function name: _netcmp_format */
/* Syntax: */
/* netgen::format [col1_width [col2_width]] */
/* Formerly: (none) */
/* Results: */
/* Side Effects: */
/*------------------------------------------------------*/
int
_netcmp_format(ClientData clientData,
Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])
{
int col1_width = 41, col2_width = 41;
if (objc > 1) {
if (Tcl_GetIntFromObj(interp, objv[1], &col1_width) != TCL_OK)
return TCL_ERROR;
if (objc > 2) {
if (Tcl_GetIntFromObj(interp, objv[2], &col2_width) != TCL_OK)
return TCL_ERROR;
} else {
/* If only one argument is given, then apply it to both columns */
col2_width = col1_width;
}
if (col1_width <= 0 || col2_width <= 0) {
Tcl_SetResult(interp, "Column width cannot be zero or less\n", NULL);
}
// Default values for left and right columns are 43 and 87
left_col_end = col1_width + 2;
right_col_end = left_col_end + col2_width + 3;
}
else if (objc == 1) {
Tcl_Obj *lobj, *tobj;
col1_width = left_col_end - 2;
col2_width = right_col_end - col1_width - 5;
lobj = Tcl_NewListObj(0, NULL);
tobj = Tcl_NewIntObj(col1_width);
Tcl_ListObjAppendElement(interp, lobj, Tcl_NewIntObj(col1_width));
Tcl_ListObjAppendElement(interp, lobj, Tcl_NewIntObj(col2_width));
Tcl_SetObjResult(interp, lobj);
return TCL_OK;
}
else {
Tcl_WrongNumArgs(interp, 1, objv, "[col1_width [col2_width]]");
return TCL_ERROR;
}
}
/*------------------------------------------------------*/
/* The following code breaks up the NETCOMP() command */
/* from netcmp.c into individual functions w/arguments */
@@ -2900,15 +2959,34 @@ _netcmp_equate(ClientData clientData,
case PINS_IDX:
if ((ElementClasses == NULL) && (auto_blackbox == FALSE)) {
if (CurrentCell == NULL)
if (CurrentCell == NULL) {
Fprintf(stderr, "Equate elements: no current cell.\n");
Fprintf(stderr, "Equate pins: cell %s and/or %s has no elements.\n",
name1, name2);
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
return TCL_OK;
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
return TCL_OK;
}
else if ((tp1->flags & CELL_PLACEHOLDER) ||
(tp2->flags & CELL_PLACEHOLDER)) {
if (tp1->flags & CELL_PLACEHOLDER) {
Fprintf(stdout, "Warning: Equate pins: cell %s "
"has no definition, treated as a black box.\n", name1);
}
if (tp2->flags & CELL_PLACEHOLDER) {
Fprintf(stdout, "Warning: Equate pins: cell %s "
"has no definition, treated as a black box.\n", name2);
}
// If a cell in either circuit is marked as a black box, then
// the cells in both circuits should be marked as a black box.
tp1->flags |= CELL_PLACEHOLDER;
tp2->flags |= CELL_PLACEHOLDER;
}
else {
Fprintf(stdout, "Equate pins: cell %s and/or %s "
"has no elements.\n", name1, name2);
/* This is not necessarily an error, so go ahead and match pins. */
}
}
else if (ElementClasses == NULL) {
/* This has been called outside of a netlist compare, */
if (ElementClasses == NULL) {
/* This may have been called outside of a netlist compare, */
/* probably to force name matching of pins on black-box */
/* devices. But MatchPins only works if tp1 == Circuit1 */
/* and tp2 == Circuit2, so preserve these values and */