mirror of
https://github.com/RTimothyEdwards/netgen.git
synced 2026-08-22 14:07: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 |
@@ -9,7 +9,7 @@ MODULES = base
|
||||
MAKEFLAGS =
|
||||
INSTALL_CAD_DIRS = lib doc
|
||||
|
||||
include defs.mak
|
||||
-include defs.mak
|
||||
|
||||
all: $(ALL_TARGET)
|
||||
|
||||
|
||||
+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) {
|
||||
|
||||
+268
-160
@@ -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);
|
||||
}
|
||||
|
||||
@@ -4110,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) {
|
||||
@@ -4393,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];
|
||||
@@ -4411,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:
|
||||
@@ -4532,7 +4606,6 @@ int PropertyOptimize(struct objlist *ob, struct nlist *tp, int run, int series,
|
||||
vlist[0][j]->value.ival = 0;
|
||||
}
|
||||
}
|
||||
else j++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5213,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 */
|
||||
|
||||
@@ -5615,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) {
|
||||
|
||||
@@ -5641,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)) {
|
||||
@@ -5679,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;
|
||||
@@ -5715,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
|
||||
@@ -5799,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;
|
||||
}
|
||||
}
|
||||
@@ -5822,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;
|
||||
}
|
||||
}
|
||||
@@ -6544,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
|
||||
@@ -6583,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);
|
||||
}
|
||||
|
||||
@@ -6627,6 +6732,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
|
||||
TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
|
||||
}
|
||||
#endif
|
||||
FREE(ostr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -6636,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);
|
||||
}
|
||||
@@ -6674,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);
|
||||
}
|
||||
@@ -6701,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)
|
||||
@@ -6709,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;
|
||||
}
|
||||
}
|
||||
@@ -6719,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);
|
||||
}
|
||||
@@ -6773,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);
|
||||
}
|
||||
@@ -6823,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);
|
||||
}
|
||||
@@ -6856,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;
|
||||
}
|
||||
@@ -6958,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 */
|
||||
@@ -6970,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);
|
||||
}
|
||||
|
||||
@@ -7077,6 +7184,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
|
||||
}
|
||||
#endif
|
||||
|
||||
FREE(ostr);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -7278,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;
|
||||
|
||||
+47
-9
@@ -289,6 +289,7 @@ int GetNextLineNoNewline(char *delimiter)
|
||||
char *newbuf;
|
||||
int testc;
|
||||
int nested = 0;
|
||||
int llen;
|
||||
|
||||
if (feof(infile)) return -1;
|
||||
|
||||
@@ -301,20 +302,33 @@ int GetNextLineNoNewline(char *delimiter)
|
||||
|
||||
if (linesize == 0) {
|
||||
/* Allocate memory for line */
|
||||
linesize = 500;
|
||||
line = (char *)MALLOC(linesize);
|
||||
linetok = (char *)MALLOC(linesize);
|
||||
linesize = 2000;
|
||||
line = (char *)MALLOC(linesize + 1);
|
||||
linetok = (char *)MALLOC(linesize + 1);
|
||||
}
|
||||
fgets(line, linesize, infile);
|
||||
while (strlen(line) == linesize - 1) {
|
||||
newbuf = (char *)MALLOC(linesize + 500);
|
||||
/* 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);
|
||||
linetok = (char *)MALLOC(linesize + 1);
|
||||
}
|
||||
|
||||
/* Check for substitutions (verilog only). Make sure linetok is */
|
||||
@@ -329,7 +343,7 @@ int GetNextLineNoNewline(char *delimiter)
|
||||
for (s = line; *s != '\0'; s++) {
|
||||
if (*s == '`') {
|
||||
w = s + 1;
|
||||
while (isalnum(*w)) w++;
|
||||
while (isalnum(*w) || (*w == '_') || (*w == '$')) w++;
|
||||
e = *w;
|
||||
*w = '\0';
|
||||
kl = (struct property *)HashLookup(s + 1, definitions);
|
||||
@@ -365,7 +379,7 @@ int GetNextLineNoNewline(char *delimiter)
|
||||
for (s = line; *s != '\0'; s++) {
|
||||
if (*s == '`') {
|
||||
w = s + 1;
|
||||
while (isalnum(*w)) w++;
|
||||
while (isalnum(*w) || (*w == '_') || (*w == '$')) w++;
|
||||
e = *w;
|
||||
*w = '\0';
|
||||
kl = (struct property *)HashLookup(s + 1, definitions);
|
||||
@@ -496,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 */
|
||||
/*----------------------------------------------------------------------*/
|
||||
@@ -673,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++;
|
||||
@@ -765,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;
|
||||
@@ -850,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}
|
||||
};
|
||||
|
||||
+7
-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,6 +36,7 @@ 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);
|
||||
|
||||
+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);
|
||||
|
||||
+223
-74
@@ -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.
|
||||
@@ -283,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;
|
||||
@@ -302,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;
|
||||
@@ -325,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 = ':';
|
||||
@@ -912,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;
|
||||
@@ -945,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 {
|
||||
@@ -1058,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;
|
||||
@@ -1071,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;
|
||||
@@ -1165,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 */
|
||||
@@ -1174,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, "=")))) {
|
||||
@@ -1219,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';
|
||||
@@ -1308,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;
|
||||
};
|
||||
|
||||
@@ -1315,6 +1369,22 @@ 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);
|
||||
@@ -1417,6 +1487,7 @@ nextinst:
|
||||
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);
|
||||
@@ -1438,25 +1509,25 @@ nextinst:
|
||||
}
|
||||
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);
|
||||
@@ -1558,19 +1629,40 @@ nextinst:
|
||||
// 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);
|
||||
@@ -1622,7 +1714,12 @@ nextinst:
|
||||
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) {
|
||||
@@ -1636,7 +1733,7 @@ nextinst:
|
||||
|
||||
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 = '[';
|
||||
@@ -1648,7 +1745,7 @@ nextinst:
|
||||
}
|
||||
}
|
||||
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) {
|
||||
@@ -1674,17 +1771,31 @@ nextinst:
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@@ -1695,8 +1806,8 @@ nextinst:
|
||||
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';
|
||||
@@ -1705,14 +1816,12 @@ nextinst:
|
||||
// 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));
|
||||
@@ -1723,6 +1832,7 @@ nextinst:
|
||||
else
|
||||
sprintf(vname, "%s[%d]", netname, i);
|
||||
new_port->net = strsave(vname);
|
||||
new_port->width = scan->width;
|
||||
|
||||
if (last == NULL)
|
||||
head = new_port;
|
||||
@@ -1736,8 +1846,10 @@ nextinst:
|
||||
|
||||
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) ||
|
||||
@@ -1746,24 +1858,24 @@ nextinst:
|
||||
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) {
|
||||
@@ -1793,7 +1905,7 @@ nextinst:
|
||||
obptr = LookupInstance(locinst, CurrentCell);
|
||||
if (obptr != NULL) {
|
||||
do {
|
||||
struct bus wb;
|
||||
struct bus wb, wb2;
|
||||
char *obpinname;
|
||||
int obpinidx;
|
||||
|
||||
@@ -1815,14 +1927,19 @@ nextinst:
|
||||
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) {
|
||||
@@ -1854,16 +1971,37 @@ nextinst:
|
||||
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);
|
||||
@@ -1931,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 */
|
||||
@@ -2036,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);
|
||||
|
||||
+1
-1
@@ -25,7 +25,7 @@ install-tcl: netgenexec${EXEEXT} $(DESTDIR)${INSTALL_BINDIR}/netgen.sh ${TCL_FIL
|
||||
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' \
|
||||
|
||||
+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