mirror of
https://github.com/RTimothyEdwards/netgen.git
synced 2026-08-23 06:27:07 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1b2cd1497c | ||
|
|
71ad228d8d | ||
|
|
339a0d5d4e | ||
|
|
9cebb76787 | ||
|
|
d9d5a46c6e | ||
|
|
251622c8bc | ||
|
|
d73b711e3a | ||
|
|
18739235a9 | ||
|
|
07c493c796 | ||
|
|
cca0e4b3f3 | ||
|
|
1428580109 | ||
|
|
fb0e1d10b0 | ||
|
|
6f81e1d294 | ||
|
|
cec6d89474 | ||
|
|
210dfb25c3 | ||
|
|
9bcca3ac21 | ||
|
|
27f2ab8b3f | ||
|
|
6ae6a246e9 | ||
|
|
d985ea340e | ||
|
|
5ea7916ff1 | ||
|
|
cf9dedb2f7 | ||
|
|
da667c3b17 | ||
|
|
1be00bbd99 | ||
|
|
36aa373fb2 | ||
|
|
18f230fc46 | ||
|
|
03b241a5d4 | ||
|
|
0f5a618353 | ||
|
|
43cebd1ef9 | ||
|
|
983c654086 | ||
|
|
515fccc633 | ||
|
|
0490959b07 | ||
|
|
7d94a7d5f6 | ||
|
|
39b3bb4d96 | ||
|
|
44673a04b6 | ||
|
|
a34f08b20a | ||
|
|
240a276431 | ||
|
|
dc841f3293 | ||
|
|
f7037fc9e6 | ||
|
|
23fb9356f4 | ||
|
|
05bcfede69 | ||
|
|
027b4ae468 | ||
|
|
72ed78e55a | ||
|
|
59bb8a89c0 | ||
|
|
08a442fda2 | ||
|
|
9bdaee652e | ||
|
|
9879b58f83 | ||
|
|
cc0cc512c0 | ||
|
|
9e3b705fcc | ||
|
|
d2c9129242 | ||
|
|
e9c0596dfe | ||
|
|
9a1e295367 | ||
|
|
942f421fa3 | ||
|
|
6bc948d8ba | ||
|
|
d7272e4ea1 | ||
|
|
7f4b5817e2 | ||
|
|
b5ab38d5d7 | ||
|
|
c1ad37f05a | ||
|
|
9edefe7d59 | ||
|
|
bf671937b9 | ||
|
|
a16086d2e9 | ||
|
|
f6b9629521 | ||
|
|
7b2e01f2af | ||
|
|
0e03f0bf97 | ||
|
|
224050f153 | ||
|
|
74e8c3e168 | ||
|
|
f12d03fcff | ||
|
|
95a29fcd8c | ||
|
|
723a950fd3 | ||
|
|
f04c72b984 | ||
|
|
e3368cb22a | ||
|
|
f06e6548bb | ||
|
|
d38bd77825 | ||
|
|
ea4083893c | ||
|
|
72ed19ff36 |
@@ -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
|
||||
|
||||
+6
-6
@@ -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
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
+244
-97
@@ -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).
|
||||
@@ -198,6 +210,7 @@ struct hashdict *definitions = (struct hashdict *)NULL;
|
||||
/*----------------------------------------------------------------------*/
|
||||
/* TrimQuoted() --- */
|
||||
/* Remove spaces from inside single- or double-quoted strings. */
|
||||
/* Ignore verilog constant bits (e.g., "1'b0") when parsing. */
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
||||
void TrimQuoted(char *line)
|
||||
@@ -213,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, '\'');
|
||||
@@ -253,7 +273,6 @@ void TrimQuoted(char *line)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
@@ -267,112 +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);
|
||||
}
|
||||
// This is more reliable than feof() ...
|
||||
testc = getc(infile);
|
||||
if (testc == -1) return -1;
|
||||
ungetc(testc, infile);
|
||||
|
||||
/* Check for substitutions (verilog only). Make sure linetok is */
|
||||
/* large enough to hold the entire line after substitutions. */
|
||||
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);
|
||||
}
|
||||
|
||||
if (definitions != NULL) {
|
||||
char *s, *w, e;
|
||||
struct property *kl;
|
||||
int len, dlen, vlen, addin = 0;
|
||||
unsigned char found = FALSE;
|
||||
/* Check for substitutions (verilog only). Make sure linetok is */
|
||||
/* large enough to hold the entire line after substitutions. */
|
||||
|
||||
for (s = line; *s != '\0'; s++) {
|
||||
if (*s == '`') {
|
||||
w = s + 1;
|
||||
while (isalnum(*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);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (definitions != NULL) {
|
||||
char *s, *w, e;
|
||||
struct property *kl;
|
||||
int len, dlen, vlen, addin = 0;
|
||||
unsigned char found = FALSE;
|
||||
|
||||
/* Make definition substitutions (verilog only) */
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (definitions != NULL) {
|
||||
char *s, *t, *w, e;
|
||||
struct property *kl;
|
||||
int len, dlen, vlen, addin = 0;
|
||||
/* Make definition substitutions (verilog only) */
|
||||
|
||||
t = linetok;
|
||||
for (s = line; *s != '\0'; s++) {
|
||||
if (*s == '`') {
|
||||
w = s + 1;
|
||||
while (isalnum(*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);
|
||||
if (definitions != NULL) {
|
||||
char *s, *t, *w, e;
|
||||
struct property *kl;
|
||||
|
||||
TrimQuoted(linetok);
|
||||
linenum++;
|
||||
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);
|
||||
|
||||
nexttok = strdtok(linetok, WHITESPACE_DELIMITER, delimiter);
|
||||
return 0;
|
||||
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;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------*/
|
||||
@@ -387,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 */
|
||||
/*----------------------------------------------------------------------*/
|
||||
@@ -564,6 +705,7 @@ char *strdtok(char *pstring, char *delim1, char *delim2)
|
||||
/* accordingly (needs to be done). */
|
||||
|
||||
if (*s == '\\') {
|
||||
s++;
|
||||
while (*s != '\0') {
|
||||
if ((*s == ' ') || (*s == '\\')) {
|
||||
s++;
|
||||
@@ -656,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;
|
||||
@@ -741,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}
|
||||
};
|
||||
|
||||
+8
-1
@@ -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
|
||||
|
||||
@@ -31,8 +36,10 @@ extern struct hashdict *definitions;
|
||||
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
@@ -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
@@ -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);
|
||||
|
||||
+410
-171
@@ -98,6 +98,31 @@ struct bus *NewBus()
|
||||
return (wb);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Find a character c in a string, assuming that string may contain
|
||||
// verilog names, where anything, including char c, may appear in the
|
||||
// string if it is a backslash-escaped name. Only the position of
|
||||
// character c outside of a verilog name is reported.
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
char *strvchr(char *string, char c)
|
||||
{
|
||||
char *s;
|
||||
|
||||
for (s = string; *s != '\0'; s++) {
|
||||
if (*s == '\\') {
|
||||
while (*s != '\0' && *s != ' ') s++;
|
||||
if (*s == '\0') {
|
||||
Fprintf(stderr, "Error: Verilog backslash-escaped name"
|
||||
" does not end with a space.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*s == c) return s;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Get bus indexes from the notation name[a:b]. If there is only "name"
|
||||
// then look up the name in the bus hash list and return the index bounds.
|
||||
@@ -123,6 +148,17 @@ int GetBusTok(struct bus *wb)
|
||||
|
||||
result = sscanf(nexttok, "%d", &start);
|
||||
if (result != 1) {
|
||||
char *aptr = NULL;
|
||||
char addin;
|
||||
|
||||
// Check for "+/-(n)" at end of a parameter name
|
||||
aptr = strrchr(nexttok, '+');
|
||||
if (aptr == NULL) aptr = strrchr(nexttok, '-');
|
||||
if (aptr != NULL) {
|
||||
addin = *aptr;
|
||||
*aptr = '\0';
|
||||
}
|
||||
|
||||
// Is name in the parameter list?
|
||||
kl = (struct property *)HashLookup(nexttok, &verilogparams);
|
||||
if (kl == NULL) {
|
||||
@@ -156,6 +192,15 @@ int GetBusTok(struct bus *wb)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (aptr != NULL) {
|
||||
int addval;
|
||||
*aptr = addin;
|
||||
if (sscanf(aptr + 1, "%d", &addval) != 1) {
|
||||
Printf("Unable to parse parameter increment '%s'\n", aptr);
|
||||
return 1;
|
||||
}
|
||||
start += (addin == '+') ? addval : -addval;
|
||||
}
|
||||
}
|
||||
SkipTokComments(VLOG_DELIMITERS);
|
||||
if (match(nexttok, "]")) {
|
||||
@@ -171,6 +216,17 @@ int GetBusTok(struct bus *wb)
|
||||
|
||||
result = sscanf(nexttok, "%d", &end);
|
||||
if (result != 1) {
|
||||
char *aptr = NULL;
|
||||
char addin;
|
||||
|
||||
// Check for "+/-(n)" at end of a parameter name
|
||||
aptr = strrchr(nexttok, '+');
|
||||
if (aptr == NULL) aptr = strrchr(nexttok, '-');
|
||||
if (aptr != NULL) {
|
||||
addin = *aptr;
|
||||
*aptr = '\0';
|
||||
}
|
||||
|
||||
// Is name in the parameter list?
|
||||
kl = (struct property *)HashLookup(nexttok, &verilogparams);
|
||||
if (kl == NULL) {
|
||||
@@ -205,6 +261,15 @@ int GetBusTok(struct bus *wb)
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (aptr != NULL) {
|
||||
int addval;
|
||||
*aptr = addin;
|
||||
if (sscanf(aptr + 1, "%d", &addval) != 1) {
|
||||
Printf("Unable to parse parameter increment '%s'\n", aptr);
|
||||
return 1;
|
||||
}
|
||||
end += (addin == '+') ? addval : -addval;
|
||||
}
|
||||
}
|
||||
}
|
||||
wb->start = start;
|
||||
@@ -243,7 +308,7 @@ int GetBusTok(struct bus *wb)
|
||||
|
||||
int GetBus(char *astr, struct bus *wb)
|
||||
{
|
||||
char *colonptr, *brackstart, *brackend, *sigend, sdelim;
|
||||
char *colonptr, *brackstart, *brackend, *sigend, sdelim, *aastr;
|
||||
int result, start, end;
|
||||
|
||||
if (wb == NULL) return 0;
|
||||
@@ -262,8 +327,8 @@ int GetBus(char *astr, struct bus *wb)
|
||||
astr++;
|
||||
wb->end = 0;
|
||||
while((*astr != '\0') && (*astr != '}')) {
|
||||
sigend = strchr(astr, ',');
|
||||
if (sigend == NULL) sigend = strchr(astr, '}');
|
||||
sigend = strvchr(astr, ',');
|
||||
if (sigend == NULL) sigend = strvchr(astr, '}');
|
||||
if (sigend == NULL) {
|
||||
Printf("Badly formed wire bundle \"%s\"\n", astr - 1);
|
||||
return 1;
|
||||
@@ -285,15 +350,22 @@ int GetBus(char *astr, struct bus *wb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
brackstart = strchr(astr, '[');
|
||||
// Delimiters may appear in backslash-escaped names. . . ignore these.
|
||||
aastr = astr;
|
||||
if (*aastr == '\\') {
|
||||
aastr++;
|
||||
while (*aastr != ' ' && *aastr != '\\' && *aastr != '\0') aastr++;
|
||||
}
|
||||
|
||||
brackstart = strvchr(aastr, '[');
|
||||
if (brackstart != NULL) {
|
||||
brackend = strchr(astr, ']');
|
||||
brackend = strvchr(aastr, ']');
|
||||
if (brackend == NULL) {
|
||||
Printf("Badly formed array notation \"%s\"\n", astr);
|
||||
return 1;
|
||||
}
|
||||
*brackend = '\0';
|
||||
colonptr = strchr(astr, ':');
|
||||
colonptr = strvchr(aastr, ':');
|
||||
if (colonptr) *colonptr = '\0';
|
||||
result = sscanf(brackstart + 1, "%d", &start);
|
||||
if (colonptr) *colonptr = ':';
|
||||
@@ -560,7 +632,7 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||
instname[255] = '\0';
|
||||
in_module = (char)0;
|
||||
in_param = (char)0;
|
||||
|
||||
|
||||
while (!EndParseFile()) {
|
||||
|
||||
SkipTokComments(VLOG_DELIMITERS); /* get the next token */
|
||||
@@ -585,6 +657,81 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||
}
|
||||
}
|
||||
|
||||
/* Handle parameters by treating as a localparam or definition. */
|
||||
/* Currently anything other than a constant value is not handled */
|
||||
/* and so will flag a warning. */
|
||||
|
||||
else if (match(nexttok, "parameter") || match(nexttok, "localparam")) {
|
||||
char *paramkey = NULL;
|
||||
char *paramval = NULL;
|
||||
|
||||
// Pick up key = value pairs and store in current cell. Look only
|
||||
// at the keyword before "=". Then set the definition as everything
|
||||
// remaining in the line, excluding comments, until the end-of-statement
|
||||
|
||||
while (nexttok != NULL)
|
||||
{
|
||||
struct property *kl = NULL;
|
||||
|
||||
/* Parse for parameters used in expressions. Save */
|
||||
/* parameters in the "verilogparams" hash table. */
|
||||
|
||||
SkipTok(VLOG_DELIMITERS);
|
||||
if ((nexttok == NULL) || (nexttok[0] == '\0')) break;
|
||||
if (match(nexttok, "=")) {
|
||||
/* Pick up remainder of statement */
|
||||
while (nexttok != NULL) {
|
||||
SkipTokNoNewline("X///**/X;,");
|
||||
if (nexttok == NULL) break;
|
||||
if (match(nexttok, ";") || match(nexttok, ",")) break;
|
||||
if (paramval == NULL) paramval = strsave(nexttok);
|
||||
else {
|
||||
char *paramlast;
|
||||
/* Append nexttok to paramval */
|
||||
paramlast = paramval;
|
||||
paramval = (char *)MALLOC(strlen(paramlast) + strlen(nexttok)
|
||||
+ 2);
|
||||
sprintf(paramval, "%s %s", paramlast, nexttok);
|
||||
FREE(paramlast);
|
||||
}
|
||||
}
|
||||
|
||||
kl = NewProperty();
|
||||
kl->key = strsave(paramkey);
|
||||
kl->idx = 0;
|
||||
kl->merge = MERGE_NONE;
|
||||
|
||||
if (ConvertStringToInteger(paramval, &ival) == 1) {
|
||||
kl->type = PROP_INTEGER;
|
||||
kl->slop.ival = 0;
|
||||
kl->pdefault.ival = ival;
|
||||
}
|
||||
else if (ConvertStringToFloat(paramval, &dval) == 1) {
|
||||
kl->type = PROP_DOUBLE;
|
||||
kl->slop.dval = 0.01;
|
||||
kl->pdefault.dval = dval;
|
||||
}
|
||||
else {
|
||||
kl->type = PROP_STRING;
|
||||
kl->slop.dval = 0.0;
|
||||
kl->pdefault.string = strsave(paramval);
|
||||
}
|
||||
|
||||
HashPtrInstall(paramkey, kl, &verilogparams);
|
||||
FREE(paramval);
|
||||
paramval = NULL;
|
||||
|
||||
if ((nexttok == NULL) || match(nexttok, ";")) break;
|
||||
}
|
||||
else {
|
||||
if (paramkey != NULL) FREE(paramkey);
|
||||
paramkey = strsave(nexttok);
|
||||
}
|
||||
}
|
||||
if (paramval != NULL) FREE(paramval);
|
||||
if (paramkey != NULL) FREE(paramkey);
|
||||
}
|
||||
|
||||
else if (match(nexttok, "module")) {
|
||||
InitializeHashTable(&buses, OBJHASHSIZE);
|
||||
SkipTokNoNewline(VLOG_DELIMITERS);
|
||||
@@ -661,7 +808,7 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||
inlined_decls = (char)0;
|
||||
|
||||
if (tp != NULL) {
|
||||
struct bus wb;
|
||||
struct bus wb, *nb;
|
||||
|
||||
PushStack(tp->name, CellStackPtr);
|
||||
|
||||
@@ -725,7 +872,8 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||
else {
|
||||
if (!match(nexttok, "input") && !match(nexttok, "output") &&
|
||||
!match(nexttok, "inout") && !match(nexttok, "real") &&
|
||||
!match(nexttok, "logic") && !match(nexttok, "integer")) {
|
||||
!match(nexttok, "wire") && !match(nexttok, "logic") &&
|
||||
!match(nexttok, "integer")) {
|
||||
if (match(nexttok, "[")) {
|
||||
if (GetBusTok(&wb) != 0) {
|
||||
// Didn't parse as a bus, so wing it
|
||||
@@ -747,6 +895,12 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||
Port(portname);
|
||||
}
|
||||
}
|
||||
/* Also register this port as a bus */
|
||||
nb = NewBus();
|
||||
nb->start = wb.start;
|
||||
nb->end = wb.end;
|
||||
HashPtrInstall(nexttok, nb, &buses);
|
||||
|
||||
wb.start = wb.end = -1;
|
||||
}
|
||||
else {
|
||||
@@ -790,7 +944,7 @@ skip_endmodule:
|
||||
}
|
||||
else if (match(nexttok, "input") || match(nexttok, "output")
|
||||
|| match(nexttok, "inout")) {
|
||||
struct bus wb;
|
||||
struct bus wb, *nb;
|
||||
|
||||
// Parsing of ports as statements not in the module pin list.
|
||||
wb.start = wb.end = -1;
|
||||
@@ -823,6 +977,11 @@ skip_endmodule:
|
||||
Port(portname);
|
||||
}
|
||||
}
|
||||
/* Also register this port as a bus */
|
||||
nb = NewBus();
|
||||
nb->start = wb.start;
|
||||
nb->end = wb.end;
|
||||
HashPtrInstall(nexttok, nb, &buses);
|
||||
wb.start = wb.end = -1;
|
||||
}
|
||||
else {
|
||||
@@ -936,6 +1095,13 @@ skip_endmodule:
|
||||
kl->pdefault.ival = 1;
|
||||
kl->slop.ival = 0;
|
||||
}
|
||||
else if (nexttok[0] == '(') {
|
||||
/* For now, the netgen verilog parser doesn't handle `define f(X) ... */
|
||||
SkipNewLine(VLOG_DELIMITERS);
|
||||
FREE(kl->key);
|
||||
FREE(kl);
|
||||
kl = NULL;
|
||||
}
|
||||
else if (ConvertStringToInteger(nexttok, &ival) == 1) {
|
||||
/* Parameter parses as an integer */
|
||||
kl->type = PROP_INTEGER;
|
||||
@@ -949,12 +1115,19 @@ skip_endmodule:
|
||||
kl->slop.dval = 0.01; // One percent default
|
||||
}
|
||||
else {
|
||||
/* Treat the parameter as a string */
|
||||
char *toks;
|
||||
|
||||
/* Treat the parameter as a string; BUT pull everything to */
|
||||
/* EOL, not just the current token. */
|
||||
toks = GetLineAtTok();
|
||||
|
||||
kl->type = PROP_STRING;
|
||||
kl->pdefault.string = strsave(nexttok);
|
||||
kl->pdefault.string = strsave(toks);
|
||||
kl->slop.dval = 0.0;
|
||||
|
||||
SkipNewLine(VLOG_DELIMITERS);
|
||||
}
|
||||
HashPtrInstall(kl->key, kl, &verilogdefs);
|
||||
if (kl) HashPtrInstall(kl->key, kl, &verilogdefs);
|
||||
}
|
||||
else if (match(nexttok, "`undef")) {
|
||||
struct property *kl = NULL;
|
||||
@@ -972,84 +1145,13 @@ skip_endmodule:
|
||||
}
|
||||
/* Presumably it is not an error to undefine an undefined keyword */
|
||||
}
|
||||
else if (match(nexttok, "localparam")) {
|
||||
// Pick up key = value pairs and store in current cell
|
||||
while (nexttok != NULL)
|
||||
{
|
||||
struct property *kl = NULL;
|
||||
|
||||
/* Parse for parameters used in expressions. Save */
|
||||
/* parameters in the "verilogparams" hash table. */
|
||||
|
||||
SkipTokNoNewline(VLOG_DELIMITERS);
|
||||
if ((nexttok == NULL) || (nexttok[0] == '\0')) break;
|
||||
if ((eqptr = strchr(nexttok, '=')) != NULL) {
|
||||
*eqptr = '\0';
|
||||
kl = NewProperty();
|
||||
kl->key = strsave(nexttok);
|
||||
kl->idx = 0;
|
||||
kl->merge = MERGE_NONE;
|
||||
|
||||
if (ConvertStringToInteger(eqptr + 1, &ival) == 1) {
|
||||
kl->type = PROP_INTEGER;
|
||||
kl->slop.ival = 0;
|
||||
kl->pdefault.ival = ival;
|
||||
}
|
||||
else if (ConvertStringToFloat(eqptr + 1, &dval) == 1) {
|
||||
kl->type = PROP_DOUBLE;
|
||||
kl->slop.dval = 0.01;
|
||||
kl->pdefault.dval = dval;
|
||||
}
|
||||
else {
|
||||
kl->type = PROP_STRING;
|
||||
kl->slop.dval = 0.0;
|
||||
kl->pdefault.string = strsave(eqptr + 1);
|
||||
}
|
||||
HashPtrInstall(nexttok, kl, &verilogparams);
|
||||
}
|
||||
}
|
||||
else if (match(nexttok, "real") || match(nexttok, "integer")) {
|
||||
Printf("Ignoring '%s' in module '%s'\n", nexttok, model);
|
||||
/* Do not skip to end of module, as these can be in the middle of */
|
||||
/* I/O assignments, which need to be parsed. */
|
||||
while (!match(nexttok, ";")) SkipTok("X///**/X,;");
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Process conditions. Note that conditionals may be nested. */
|
||||
|
||||
else if (match(nexttok, "`ifdef") || match(nexttok, "`ifndef") ||
|
||||
match(nexttok, "`elsif") || match(nexttok, "`else")) {
|
||||
struct property *kl;
|
||||
int nested = 0;
|
||||
int invert = (nexttok[3] == 'n') ? 1 : 0;
|
||||
|
||||
SkipTokNoNewline(VLOG_DELIMITERS);
|
||||
|
||||
/* To be done: Handle boolean arithmetic on conditionals */
|
||||
|
||||
kl = (struct property *)HashLookup(nexttok, &verilogdefs);
|
||||
while (((invert == 0) && (kl == NULL))
|
||||
|| ((invert == 1) && (kl != NULL))) {
|
||||
/* Skip to matching `endif, `elsif, or `else */
|
||||
while (1) {
|
||||
SkipNewLine(VLOG_DELIMITERS);
|
||||
SkipTokComments(VLOG_DELIMITERS);
|
||||
if (EndParseFile()) break;
|
||||
if (match(nexttok, "`ifdef") || match(nexttok, "`ifndef")) {
|
||||
nested++;
|
||||
}
|
||||
else if (match(nexttok, "`endif") || match(nexttok, "`elsif") ||
|
||||
match(nexttok, "`else")) {
|
||||
if (nested == 0)
|
||||
break;
|
||||
else
|
||||
nested--;
|
||||
}
|
||||
}
|
||||
if (match(nexttok, "`elsif")) {
|
||||
SkipTokComments(VLOG_DELIMITERS);
|
||||
invert = 0;
|
||||
kl = (struct property *)HashLookup(nexttok, &verilogdefs);
|
||||
}
|
||||
else break;
|
||||
}
|
||||
}
|
||||
|
||||
else if (match(nexttok, "wire") || match(nexttok, "assign")) { /* wire = node */
|
||||
struct bus wb, wb2, *nb;
|
||||
char nodename[128], noderoot[100];
|
||||
@@ -1114,7 +1216,7 @@ skip_endmodule:
|
||||
else { /* "assign" */
|
||||
SkipTokComments(VLOG_PIN_CHECK_DELIMITERS);
|
||||
if (GetBus(nexttok, &wb) == 0) {
|
||||
char *aptr = strchr(nexttok, '[');
|
||||
char *aptr = strvchr(nexttok, '[');
|
||||
if (aptr != NULL) {
|
||||
*aptr = '\0';
|
||||
/* Find object of first net in bus */
|
||||
@@ -1123,9 +1225,11 @@ skip_endmodule:
|
||||
lhs = LookupObject(nodename, CurrentCell);
|
||||
*aptr = '[';
|
||||
}
|
||||
else strcpy(noderoot, nexttok);
|
||||
}
|
||||
else {
|
||||
lhs = LookupObject(nexttok, CurrentCell);
|
||||
strcpy(noderoot, nexttok);
|
||||
}
|
||||
SkipTokComments(VLOG_DELIMITERS);
|
||||
if (lhs && ((!nexttok) || (!match(nexttok, "=")))) {
|
||||
@@ -1168,7 +1272,7 @@ skip_endmodule:
|
||||
}
|
||||
else {
|
||||
if (GetBus(nexttok, &wb2) == 0) {
|
||||
char *aptr = strchr(nexttok, '[');
|
||||
char *aptr = strvchr(nexttok, '[');
|
||||
j = wb2.start;
|
||||
if (aptr != NULL) {
|
||||
*aptr = '\0';
|
||||
@@ -1179,14 +1283,26 @@ skip_endmodule:
|
||||
}
|
||||
}
|
||||
else {
|
||||
j = -1;
|
||||
rhs = LookupObject(nexttok, CurrentCell);
|
||||
}
|
||||
if ((lhs == NULL) || (rhs == NULL)) {
|
||||
/* Not parsable, probably behavioral verilog? */
|
||||
Printf("Module '%s' is not structural verilog, "
|
||||
"making black-box.\n", model);
|
||||
SetClass(CLASS_MODULE);
|
||||
goto skip_endmodule;
|
||||
if (rhs != NULL) {
|
||||
Printf("Improper assignment; left-hand side cannot "
|
||||
"be parsed.\n");
|
||||
Printf("Right-hand side is \"%s\".\n", rhs->name);
|
||||
break;
|
||||
}
|
||||
if (lhs != NULL) {
|
||||
Printf("Improper assignment; right-hand side cannot "
|
||||
"be parsed.\n");
|
||||
Printf("Left-hand side is \"%s\".\n", lhs->name);
|
||||
/* Not parsable, probably behavioral verilog? */
|
||||
Printf("Module '%s' is not structural verilog, "
|
||||
"making black-box.\n", model);
|
||||
SetClass(CLASS_MODULE);
|
||||
goto skip_endmodule;
|
||||
}
|
||||
}
|
||||
while (1) {
|
||||
/* Assign bits in turn from bundle in RHS to bits of LHS */
|
||||
@@ -1219,12 +1335,15 @@ skip_endmodule:
|
||||
// No action---new module is started with next 'module' statement,
|
||||
// if any.
|
||||
SkipNewLine(VLOG_DELIMITERS);
|
||||
in_module = (char)0; /* Should have been done already */
|
||||
}
|
||||
else if (nexttok[0] == '`') {
|
||||
// Ignore any other directive starting with a backtick
|
||||
// Ignore any other directive starting with a backtick (e.g., `timescale)
|
||||
SkipNewLine(VLOG_DELIMITERS);
|
||||
}
|
||||
else if (match(nexttok, "reg") || match(nexttok, "always")) {
|
||||
else if (match(nexttok, "reg") || match(nexttok, "always") ||
|
||||
match(nexttok, "specify") || match(nexttok, "initial")) {
|
||||
Printf("Behavioral keyword '%s' found in source.\n", nexttok);
|
||||
Printf("Module '%s' is not structural verilog, making black-box.\n", model);
|
||||
// To be done: Remove any contents (but may not be necessary)
|
||||
// Recast as module
|
||||
@@ -1234,6 +1353,7 @@ skip_endmodule:
|
||||
else { /* module instances */
|
||||
char instancename[100], modulename[100];
|
||||
int itype, arraystart, arrayend, arraymax, arraymin;
|
||||
char ignore;
|
||||
|
||||
instancename[99] = '\0';
|
||||
modulename[99] = '\0';
|
||||
@@ -1241,6 +1361,7 @@ skip_endmodule:
|
||||
struct portelement {
|
||||
char *name; // Name of port in subcell
|
||||
char *net; // Name of net connecting to port in the parent
|
||||
int width; // Width of port, if port is a bus
|
||||
struct portelement *next;
|
||||
};
|
||||
|
||||
@@ -1248,14 +1369,33 @@ skip_endmodule:
|
||||
struct objlist *obptr;
|
||||
|
||||
strncpy(modulename, nexttok, 99);
|
||||
|
||||
/* If module name is a verilog primitive, then treat the module as a */
|
||||
/* black box (this is not a complete list. Preferable to use hash */
|
||||
/* function instead of lots of strcmp() calls). */
|
||||
|
||||
if (!strcmp(modulename, "buf") || !strcmp(modulename, "notif1") ||
|
||||
!strcmp(modulename, "not") || !strcmp(modulename, "and") ||
|
||||
!strcmp(modulename, "or") || !strcmp(modulename, "bufif0") ||
|
||||
!strcmp(modulename, "bufif1") || !strcmp(modulename, "notif0")) {
|
||||
|
||||
Printf("Module contains verilog primitive '%s'.\n", nexttok);
|
||||
Printf("Module '%s' is not structural verilog, making black-box.\n", model);
|
||||
SetClass(CLASS_MODULE);
|
||||
goto skip_endmodule;
|
||||
}
|
||||
|
||||
if (!(*CellStackPtr)) {
|
||||
CellDef(fname, filenum);
|
||||
PushStack(fname, CellStackPtr);
|
||||
}
|
||||
|
||||
SkipTokComments(VLOG_DELIMITERS);
|
||||
|
||||
nextinst:
|
||||
ignore = FALSE;
|
||||
head = NULL;
|
||||
tail = NULL;
|
||||
SkipTokComments(VLOG_DELIMITERS);
|
||||
|
||||
// Next token must be '#(' (parameters) or an instance name
|
||||
|
||||
@@ -1328,23 +1468,26 @@ skip_endmodule:
|
||||
// Read the pin list
|
||||
while (nexttok != NULL) {
|
||||
SkipTokComments(VLOG_DELIMITERS);
|
||||
// NOTE: Deal with `ifdef et al. properly. Ignoring for now.
|
||||
while (nexttok[0] == '`') {
|
||||
SkipNewLine(VLOG_DELIMITERS);
|
||||
SkipTokComments(VLOG_DELIMITERS);
|
||||
}
|
||||
if (match(nexttok, ")")) break;
|
||||
else if (match(nexttok, ",")) continue;
|
||||
|
||||
// We need to look for pins of the type ".name(value)"
|
||||
|
||||
if (nexttok[0] != '.') {
|
||||
Printf("Badly formed subcircuit pin line at \"%s\"\n", nexttok);
|
||||
SkipNewLine(VLOG_DELIMITERS);
|
||||
Printf("Warning: Ignoring subcircuit with no pin names "
|
||||
"at \"%s\"\n", nexttok);
|
||||
InputParseError(stderr);
|
||||
while (nexttok != NULL) {
|
||||
SkipTokComments(VLOG_DELIMITERS);
|
||||
if (match(nexttok, ";")) break;
|
||||
}
|
||||
ignore = TRUE;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
new_port = (struct portelement *)CALLOC(1, sizeof(struct portelement));
|
||||
new_port->name = strsave(nexttok + 1);
|
||||
new_port->width = -1;
|
||||
SkipTokComments(VLOG_DELIMITERS);
|
||||
if (!match(nexttok, "(")) {
|
||||
Printf("Badly formed subcircuit pin line at \"%s\"\n", nexttok);
|
||||
@@ -1355,30 +1498,36 @@ skip_endmodule:
|
||||
char localnet[100];
|
||||
// Empty parens, so create a new local node
|
||||
savetok = (char)1;
|
||||
sprintf(localnet, "_noconnect_%d_", localcount++);
|
||||
if (arraystart != -1) {
|
||||
/* No-connect on an instance array must also be an array */
|
||||
sprintf(localnet, "_noconnect_%d_[%d:%d]", localcount++,
|
||||
arraystart, arrayend);
|
||||
}
|
||||
else
|
||||
sprintf(localnet, "_noconnect_%d_", localcount++);
|
||||
new_port->net = strsave(localnet);
|
||||
}
|
||||
else {
|
||||
if (!strcmp(nexttok, "{")) {
|
||||
char *in_line_net = (char *)MALLOC(1);
|
||||
char *new_in_line_net = NULL;
|
||||
*in_line_net = '\0';
|
||||
/* In-line array---read to "}" */
|
||||
char *wire_bundle = (char *)MALLOC(1);
|
||||
char *new_wire_bundle = NULL;
|
||||
*wire_bundle = '\0';
|
||||
/* Wire bundle---read to "}" */
|
||||
while (nexttok) {
|
||||
new_in_line_net = (char *)MALLOC(strlen(in_line_net) +
|
||||
new_wire_bundle = (char *)MALLOC(strlen(wire_bundle) +
|
||||
strlen(nexttok) + 1);
|
||||
/* Roundabout way to do realloc() becase there is no REALLOC() */
|
||||
strcpy(new_in_line_net, in_line_net);
|
||||
strcat(new_in_line_net, nexttok);
|
||||
FREE(in_line_net);
|
||||
in_line_net = new_in_line_net;
|
||||
strcpy(new_wire_bundle, wire_bundle);
|
||||
strcat(new_wire_bundle, nexttok);
|
||||
FREE(wire_bundle);
|
||||
wire_bundle = new_wire_bundle;
|
||||
if (!strcmp(nexttok, "}")) break;
|
||||
SkipTokComments(VLOG_PIN_CHECK_DELIMITERS);
|
||||
}
|
||||
if (!nexttok) {
|
||||
Printf("Unterminated net in pin %s\n", in_line_net);
|
||||
Printf("Unterminated net in pin %s\n", wire_bundle);
|
||||
}
|
||||
new_port->net = in_line_net;
|
||||
new_port->net = wire_bundle;
|
||||
}
|
||||
else
|
||||
new_port->net = strsave(nexttok);
|
||||
@@ -1415,10 +1564,21 @@ skip_endmodule:
|
||||
else {
|
||||
Printf("Expected to find instance pin block but got \"%s\"\n", nexttok);
|
||||
}
|
||||
/* Instance should end with a semicolon */
|
||||
if (ignore == TRUE) continue; /* moving along. . . */
|
||||
|
||||
/* Verilog allows multiple instances of a single cell type to be chained */
|
||||
/* together with commas. */
|
||||
|
||||
SkipTokComments(VLOG_DELIMITERS);
|
||||
if (!match(nexttok, ";")) {
|
||||
if (match(nexttok, ",")) {
|
||||
goto nextinst;
|
||||
}
|
||||
|
||||
/* Otherwise, instance must end with a semicolon */
|
||||
|
||||
else if (!match(nexttok, ";")) {
|
||||
Printf("Expected to find end of instance but got \"%s\"\n", nexttok);
|
||||
InputParseError(stderr);
|
||||
}
|
||||
|
||||
/* Check for ignored class */
|
||||
@@ -1469,19 +1629,40 @@ skip_endmodule:
|
||||
// Check if net name is a wire bus or portion of a bus
|
||||
if (GetBus(scan->net, &wb) == 0) {
|
||||
int range;
|
||||
|
||||
// This takes care of three situations:
|
||||
// (1) The signal bus length matches the number of instances:
|
||||
// apply one signal per instance.
|
||||
// (2) The signal bus length is a multiple of the number of instances:
|
||||
// apply a signal sub-bus to each instance.
|
||||
// (3) The number of instances is a multiple of the signal bus length:
|
||||
// apply the same signal to each instance.
|
||||
|
||||
if ((arrayend - arraystart) == (wb.end - wb.start)) {
|
||||
// Net is a bus, but net is split over arrayed instances
|
||||
Port(scan->name);
|
||||
}
|
||||
else if (wb.start > wb.end) {
|
||||
range = wb.start - wb.end;
|
||||
if ((arraystart - arrayend) > (wb.start - wb.end))
|
||||
range = (((arraystart - arrayend) + 1) /
|
||||
((wb.start - wb.end) + 1)) - 1;
|
||||
else
|
||||
range = (((wb.start - wb.end) + 1) /
|
||||
((arraystart - arrayend) + 1)) - 1;
|
||||
|
||||
for (i = range; i >= 0; i--) {
|
||||
sprintf(defport, "%s[%d]", scan->name, i);
|
||||
Port(defport);
|
||||
}
|
||||
}
|
||||
else {
|
||||
range = wb.end - wb.start;
|
||||
if ((arrayend - arraystart) > (wb.end - wb.start))
|
||||
range = (((arrayend - arraystart) + 1) /
|
||||
((wb.end - wb.start) + 1)) - 1;
|
||||
else
|
||||
range = (((wb.end - wb.start) + 1) /
|
||||
((arrayend - arraystart) + 1)) - 1;
|
||||
|
||||
for (i = 0; i <= range; i++) {
|
||||
sprintf(defport, "%s[%d]", scan->name, i);
|
||||
Port(defport);
|
||||
@@ -1533,7 +1714,12 @@ skip_endmodule:
|
||||
int j, result;
|
||||
struct objlist *bobj;
|
||||
char *bptr;
|
||||
int minnet, maxnet, testidx;
|
||||
int minnet, maxnet, testidx, width;
|
||||
|
||||
width = portstart - portend;
|
||||
if (width < 0) width = -width;
|
||||
width++;
|
||||
scan->width = width;
|
||||
|
||||
result = GetBus(scan->net, &wb);
|
||||
if (result == -1) {
|
||||
@@ -1547,7 +1733,7 @@ skip_endmodule:
|
||||
|
||||
for (bobj = CurrentCell->cell; bobj; bobj = bobj->next) {
|
||||
if (bobj->type == PORT) {
|
||||
if ((bptr = strchr(bobj->name, '[')) != NULL) {
|
||||
if ((bptr = strvchr(bobj->name, '[')) != NULL) {
|
||||
*bptr = '\0';
|
||||
if (!strcmp(bobj->name, scan->net)) {
|
||||
*bptr = '[';
|
||||
@@ -1559,7 +1745,7 @@ skip_endmodule:
|
||||
}
|
||||
}
|
||||
else if (bobj->type == NODE) {
|
||||
if ((bptr = strchr(bobj->name, '[')) != NULL) {
|
||||
if ((bptr = strvchr(bobj->name, '[')) != NULL) {
|
||||
*bptr = '\0';
|
||||
if (!strcmp(bobj->name, scan->net)) {
|
||||
if (sscanf(bptr + 1, "%d", &testidx) == 1) {
|
||||
@@ -1585,17 +1771,31 @@ skip_endmodule:
|
||||
}
|
||||
|
||||
if (result == 0) {
|
||||
if (((wb.start - wb.end) != (portstart - portend)) &&
|
||||
((wb.start - wb.end) != (portend - portstart))) {
|
||||
if (((wb.start - wb.end) != (arraystart - arrayend)) &&
|
||||
((wb.start - wb.end) != (arrayend - arraystart))) {
|
||||
Fprintf(stderr, "Error: Net %s bus width does not match "
|
||||
"port %s bus width.\n", scan->net, scan->name);
|
||||
}
|
||||
// Otherwise, net is bit-sliced across array of instances.
|
||||
int match = 0;
|
||||
int wblen, arraylen;
|
||||
|
||||
arraylen = arraystart - arrayend;
|
||||
wblen = wb.start - wb.end;
|
||||
|
||||
if (arraylen < 0) arraylen = -arraylen;
|
||||
if (wblen < 0) wblen = -wblen;
|
||||
|
||||
arraylen++;
|
||||
wblen++;
|
||||
|
||||
if ((scan->width * arraylen) == wblen) match = 1;
|
||||
else if (wblen == scan->width) match = 1;
|
||||
else if (wblen == arraylen) match = 1;
|
||||
else {
|
||||
Fprintf(stderr, "Warning: Net %s bus width (%d) does not match "
|
||||
"port %s bus width (%d) or array width (%d).\n",
|
||||
scan->net, wblen, scan->name, scan->width, arraylen);
|
||||
}
|
||||
else if (wb.start > wb.end) {
|
||||
char *bptr, *cptr, cchar, *netname;
|
||||
|
||||
// Net is bit-sliced across array of instances.
|
||||
|
||||
if (wb.start > wb.end) {
|
||||
char *bptr = NULL, *cptr = NULL, cchar, *netname;
|
||||
unsigned char is_bundle = 0;
|
||||
struct bus wbb;
|
||||
|
||||
@@ -1606,8 +1806,8 @@ skip_endmodule:
|
||||
if (*netname == '{') {
|
||||
is_bundle = 1;
|
||||
netname++;
|
||||
cptr = strchr(netname, ',');
|
||||
if (cptr == NULL) cptr = strchr(netname, '}');
|
||||
cptr = strvchr(netname, ',');
|
||||
if (cptr == NULL) cptr = strvchr(netname, '}');
|
||||
if (cptr == NULL) cptr = netname + strlen(netname) - 1;
|
||||
cchar = *cptr;
|
||||
*cptr = '\0';
|
||||
@@ -1616,14 +1816,12 @@ skip_endmodule:
|
||||
// Remove indexed part of scan->net
|
||||
if (GetBus(netname, &wbb) == 0) {
|
||||
i = wbb.start;
|
||||
if ((bptr = strchr(netname, '[')) != NULL)
|
||||
if ((bptr = strvchr(netname, '[')) != NULL)
|
||||
*bptr = '\0';
|
||||
}
|
||||
else
|
||||
i = -1;
|
||||
|
||||
if (is_bundle) *cptr = cchar; /* Restore bundle delimiter */
|
||||
|
||||
while (1) {
|
||||
new_port = (struct portelement *)CALLOC(1,
|
||||
sizeof(struct portelement));
|
||||
@@ -1634,6 +1832,7 @@ skip_endmodule:
|
||||
else
|
||||
sprintf(vname, "%s[%d]", netname, i);
|
||||
new_port->net = strsave(vname);
|
||||
new_port->width = scan->width;
|
||||
|
||||
if (last == NULL)
|
||||
head = new_port;
|
||||
@@ -1647,8 +1846,10 @@ skip_endmodule:
|
||||
|
||||
if (portstart > portend) j--;
|
||||
else j++;
|
||||
if (wbb.start > wbb.end) i--;
|
||||
else i++;
|
||||
if (i != -1) {
|
||||
if (wbb.start > wbb.end) i--;
|
||||
else i++;
|
||||
}
|
||||
|
||||
if (is_bundle &&
|
||||
((i == -1) ||
|
||||
@@ -1657,24 +1858,24 @@ skip_endmodule:
|
||||
if (bptr) *bptr = '[';
|
||||
|
||||
netname = cptr + 1;
|
||||
cptr = strchr(netname, ',');
|
||||
if (cptr == NULL) cptr = strchr(netname, '}');
|
||||
if (cptr) *cptr = cchar; /* Restore previous bundle delimiter */
|
||||
cptr = strvchr(netname, ',');
|
||||
if (cptr == NULL) cptr = strvchr(netname, '}');
|
||||
if (cptr == NULL) cptr = netname + strlen(netname) - 1;
|
||||
cchar = *cptr;
|
||||
*cptr = '\0';
|
||||
|
||||
if (GetBus(netname, &wbb) == 0) {
|
||||
i = wbb.start;
|
||||
if ((bptr = strchr(netname, '[')) != NULL)
|
||||
if ((bptr = strvchr(netname, '[')) != NULL)
|
||||
*bptr = '\0';
|
||||
}
|
||||
else i = -1;
|
||||
|
||||
*cptr = cchar; /* Restore delimiter */
|
||||
}
|
||||
}
|
||||
FREE(scan);
|
||||
scan = last;
|
||||
if (cptr) *cptr = cchar; /* Restore bundle delimiter */
|
||||
}
|
||||
}
|
||||
else if (portstart != portend) {
|
||||
@@ -1704,7 +1905,7 @@ skip_endmodule:
|
||||
obptr = LookupInstance(locinst, CurrentCell);
|
||||
if (obptr != NULL) {
|
||||
do {
|
||||
struct bus wb;
|
||||
struct bus wb, wb2;
|
||||
char *obpinname;
|
||||
int obpinidx;
|
||||
|
||||
@@ -1726,14 +1927,19 @@ skip_endmodule:
|
||||
scan = scan->next;
|
||||
}
|
||||
if (scan == NULL) {
|
||||
Fprintf(stderr, "Error: No match in call for pin %s\n", obpinname);
|
||||
break;
|
||||
}
|
||||
char localnet[100];
|
||||
|
||||
if (GetBus(scan->net, &wb) == 0) {
|
||||
/* Assume an implicit unconnected pin */
|
||||
sprintf(localnet, "_noconnect_%d_", localcount++);
|
||||
Node(localnet);
|
||||
join(localnet, obptr->name);
|
||||
Fprintf(stderr, "Note: Implicit pin %s\n", obpinname);
|
||||
}
|
||||
else if (GetBus(scan->net, &wb) == 0) {
|
||||
char *bptr2;
|
||||
char *scanroot;
|
||||
scanroot = strsave(scan->net);
|
||||
brackptr = strchr(scanroot, '[');
|
||||
brackptr = strvchr(scanroot, '[');
|
||||
if (brackptr) *brackptr = '\0';
|
||||
|
||||
if (arraystart == -1) {
|
||||
@@ -1765,15 +1971,37 @@ skip_endmodule:
|
||||
else {
|
||||
// Instance must be an array
|
||||
char netname[128];
|
||||
int slice;
|
||||
if (wb.start > wb.end && arraystart > arrayend)
|
||||
slice = wb.start - (arraystart - i);
|
||||
else if (wb.start < wb.end && arraystart > arrayend)
|
||||
slice = wb.start + (arraystart - i);
|
||||
else if (wb.start > wb.end && arraystart < arrayend)
|
||||
slice = wb.start - (arraystart + i);
|
||||
else // (wb.start < wb.end && arraystart < arrayend)
|
||||
slice = wb.start + (arraystart + i);
|
||||
int slice, portlen, siglen;
|
||||
|
||||
/* Get the array size of the port for bit slicing */
|
||||
portlen = (scan->width < 0) ? 1 : scan->width;
|
||||
|
||||
/* Get the full array size of the connecting bus */
|
||||
GetBus(scanroot, &wb2);
|
||||
siglen = wb2.start - wb2.end;
|
||||
if (siglen < 0) siglen = -siglen;
|
||||
siglen++;
|
||||
|
||||
// If signal array is smaller than the portlength *
|
||||
// length of instance array, then the signal wraps.
|
||||
|
||||
if (wb2.start >= wb2.end && arraystart >= arrayend) {
|
||||
slice = wb.start - (arraystart - i) * portlen;
|
||||
while (slice < wb2.end) slice += siglen;
|
||||
}
|
||||
else if (wb2.start < wb2.end && arraystart > arrayend) {
|
||||
slice = wb.start + (arraystart - i) * portlen;
|
||||
while (slice > wb2.end) slice -= siglen;
|
||||
}
|
||||
else if (wb2.start > wb2.end && arraystart < arrayend) {
|
||||
slice = wb.start - (arraystart + i) * portlen;
|
||||
while (slice < wb2.end) slice += siglen;
|
||||
}
|
||||
else { // (wb2.start < wb2.end && arraystart < arrayend)
|
||||
slice = wb.start + (arraystart + i) * portlen;
|
||||
while (slice > wb2.end) slice -= siglen;
|
||||
}
|
||||
|
||||
sprintf(netname, "%s[%d]", scanroot, slice);
|
||||
if (LookupObject(netname, CurrentCell) == NULL) Node(netname);
|
||||
join(netname, obptr->name);
|
||||
@@ -1841,14 +2069,21 @@ char *ReadVerilogTop(char *fname, int *fnum, int blackbox)
|
||||
CurrentCell = NULL;
|
||||
|
||||
if ((filenum = OpenParseFile(fname, *fnum)) < 0) {
|
||||
char name[100];
|
||||
|
||||
SetExtension(name, fname, VERILOG_EXTENSION);
|
||||
if ((filenum = OpenParseFile(name, *fnum)) < 0) {
|
||||
Fprintf(stderr,"Error in Verilog file read: No file %s\n",name);
|
||||
*fnum = filenum;
|
||||
return NULL;
|
||||
if (strchr(fname, '.') == NULL) {
|
||||
char name[1024];
|
||||
SetExtension(name, fname, VERILOG_EXTENSION);
|
||||
if ((filenum = OpenParseFile(name, *fnum)) < 0) {
|
||||
Fprintf(stderr, "Error in Verilog file read: No file %s\n", name);
|
||||
*fnum = filenum;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
Fprintf(stderr, "Error in Verilog file read: No file %s\n", fname);
|
||||
*fnum = filenum;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* All Verilog file reading is case sensitive. However: if */
|
||||
@@ -1946,11 +2181,15 @@ void IncludeVerilog(char *fname, int parent, struct cellstack **CellStackPtr,
|
||||
if (strchr(fname, '.') == NULL) {
|
||||
SetExtension(name, fname, VERILOG_EXTENSION);
|
||||
filenum = OpenParseFile(name, parent);
|
||||
if (filenum < 0) {
|
||||
fprintf(stderr,"Error in Verilog file include: No file %s\n", name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (filenum < 0) {
|
||||
else {
|
||||
fprintf(stderr,"Error in Verilog file include: No file %s\n", fname);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ReadVerilogFile(fname, parent, CellStackPtr, blackbox);
|
||||
|
||||
+7
-7
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
Vendored
+22
@@ -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"
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user