mirror of
https://github.com/RTimothyEdwards/netgen.git
synced 2026-08-22 14:07:07 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aee4b846e2 | ||
|
|
004378be11 | ||
|
|
dc42e98ab9 | ||
|
|
58d7e17231 |
+4
-4
@@ -4915,7 +4915,7 @@ PropertyCheckMismatch(struct objlist *tp1, struct nlist *tc1,
|
||||
case PROP_STRING:
|
||||
islop = (int)(MAX(kl1->slop.dval, kl2->slop.dval) + 0.5);
|
||||
if (islop == 0) {
|
||||
if (strcasecmp(vl1->value.string, vl2->value.string)) {
|
||||
if (!(*matchfunc)(vl1->value.string, vl2->value.string)) {
|
||||
if (do_print) {
|
||||
if (mismatches == 0)
|
||||
Fprintf(stdout, "%s vs. %s:\n", inst1, inst2);
|
||||
@@ -5172,7 +5172,7 @@ PropertyMatch(struct objlist *ob1, struct objlist *ob2, int do_print,
|
||||
kl2 = (struct property *)HashLookup(vl2->key, &(tc2->propdict));
|
||||
if (kl2 != NULL) {
|
||||
// Allowed for one instance to be missing "M" or "S".
|
||||
if (strcasecmp(vl2->key, "M") && strcasecmp(vl2->key, "S"))
|
||||
if (!(*matchfunc)(vl2->key, "M") && !(*matchfunc)(vl2->key, "S"))
|
||||
break; // Property is required
|
||||
}
|
||||
}
|
||||
@@ -5223,7 +5223,7 @@ PropertyMatch(struct objlist *ob1, struct objlist *ob2, int do_print,
|
||||
kl1 = (struct property *)HashLookup(vl1->key, &(tc1->propdict));
|
||||
if (kl1 != NULL) {
|
||||
// Allowed for one instance to be missing "M" or "S".
|
||||
if (strcasecmp(vl1->key, "M") && strcasecmp(vl1->key, "S"))
|
||||
if (!(*matchfunc)(vl1->key, "M") && !(*matchfunc)(vl1->key, "S"))
|
||||
break; // Property is required
|
||||
}
|
||||
}
|
||||
@@ -6508,7 +6508,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
|
||||
for (m = 0; m < 43; m++) *(ostr + m) = ' ';
|
||||
for (m = 44; m < 87; m++) *(ostr + m) = ' ';
|
||||
snprintf(ostr, 43, "%s", obn->name);
|
||||
if (!strcasecmp(obn->name, obp->name))
|
||||
if ((*matchfunc)(obn->name, obp->name))
|
||||
snprintf(ostr + 44, 43, "%s", obp->name);
|
||||
else
|
||||
snprintf(ostr + 44, 43, "%s **Mismatch**", obp->name);
|
||||
|
||||
@@ -290,6 +290,7 @@ void InitCellHashTable(void)
|
||||
{
|
||||
hashfunc = hash;
|
||||
matchfunc = match;
|
||||
matchintfunc = matchfile;
|
||||
InitializeHashTable(&cell_dict, CELLHASHSIZE);
|
||||
}
|
||||
|
||||
|
||||
+159
-95
@@ -371,7 +371,7 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||
char devtype, in_module, in_comment, in_param;
|
||||
char *eqptr, *parptr, *matchptr;
|
||||
struct keyvalue *kvlist = NULL;
|
||||
char inst[256], model[256], instname[256];
|
||||
char inst[256], model[256], instname[256], portname[256];
|
||||
struct nlist *tp;
|
||||
struct objlist *parent, *sobj, *nobj, *lobj, *pobj;
|
||||
|
||||
@@ -477,6 +477,7 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||
inlined_decls = (char)0;
|
||||
|
||||
if (tp != NULL) {
|
||||
struct bus wb;
|
||||
|
||||
PushStack(tp->name, CellStackPtr);
|
||||
|
||||
@@ -507,6 +508,7 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||
}
|
||||
}
|
||||
|
||||
wb.start = wb.end = -1;
|
||||
while ((nexttok != NULL) && (nexttok[0] != ';')) {
|
||||
if (in_param) {
|
||||
if (!strcmp(nexttok, ")")) {
|
||||
@@ -536,7 +538,33 @@ void ReadVerilogFile(char *fname, int filenum, struct cellstack **CellStackPtr,
|
||||
if (!match(nexttok, "input") && !match(nexttok, "output") &&
|
||||
!match(nexttok, "inout") && !match(nexttok, "real") &&
|
||||
!match(nexttok, "logic") && !match(nexttok, "integer")) {
|
||||
Port(nexttok);
|
||||
if (nexttok[0] == '[') {
|
||||
if (GetBus(nexttok, &wb) != 0) {
|
||||
// Didn't parse as a bus, so wing it
|
||||
wb.start = wb.end = -1;
|
||||
Port(nexttok);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (wb.start != -1) {
|
||||
if (wb.start > wb.end) {
|
||||
for (i = wb.start; i >= wb.end; i--) {
|
||||
sprintf(portname, "%s[%d]", nexttok, i);
|
||||
Port(portname);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = wb.start; i <= wb.end; i++) {
|
||||
sprintf(portname, "%s[%d]", nexttok, i);
|
||||
Port(portname);
|
||||
}
|
||||
}
|
||||
wb.start = wb.end = -1;
|
||||
}
|
||||
else {
|
||||
Port(nexttok);
|
||||
}
|
||||
}
|
||||
hasports = 1;
|
||||
}
|
||||
}
|
||||
@@ -652,9 +680,9 @@ skip_endmodule:
|
||||
// Eliminate any single or double quotes around the filename
|
||||
iptr = iname;
|
||||
quotptr = iptr;
|
||||
while (*quotptr != '\'' && *quotptr != '\"' && *quotptr != '`' &&
|
||||
while (*quotptr != '\'' && *quotptr != '\"' &&
|
||||
*quotptr != '\0' && *quotptr != '\n') quotptr++;
|
||||
if (*quotptr == '\'' || *quotptr == '\"' || *quotptr == '`') *quotptr = '\0';
|
||||
if (*quotptr == '\'' || *quotptr == '\"') *quotptr = '\0';
|
||||
|
||||
IncludeVerilog(iptr, filenum, CellStackPtr, blackbox);
|
||||
FREE(iname);
|
||||
@@ -698,13 +726,15 @@ skip_endmodule:
|
||||
if (wb.start > wb.end) {
|
||||
for (i = wb.end; i <= wb.start; i++) {
|
||||
sprintf(nodename, "%s[%d]", nexttok, i);
|
||||
Node(nodename);
|
||||
if (LookupObject(nodename, CurrentCell) == NULL)
|
||||
Node(nodename);
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i = wb.start; i <= wb.end; i++) {
|
||||
sprintf(nodename, "%s[%d]", nexttok, i);
|
||||
Node(nodename);
|
||||
if (LookupObject(nodename, CurrentCell) == NULL)
|
||||
Node(nodename);
|
||||
}
|
||||
}
|
||||
nb = NewBus();
|
||||
@@ -713,7 +743,8 @@ skip_endmodule:
|
||||
HashPtrInstall(nexttok, nb, &buses);
|
||||
}
|
||||
else {
|
||||
Node(nexttok);
|
||||
if (LookupObject(nexttok, CurrentCell) == NULL)
|
||||
Node(nexttok);
|
||||
}
|
||||
SkipTokNoNewline(VLOG_DELIMITERS);
|
||||
}
|
||||
@@ -748,7 +779,7 @@ skip_endmodule:
|
||||
struct portelement *next;
|
||||
};
|
||||
|
||||
struct portelement *head, *tail, *scan, *scannext;
|
||||
struct portelement *head, *tail, *scan, *last, *scannext;
|
||||
struct objlist *obptr;
|
||||
|
||||
strncpy(modulename, nexttok, 99);
|
||||
@@ -845,7 +876,8 @@ skip_endmodule:
|
||||
while (nexttok != NULL) {
|
||||
if (savetok == (char)0) SkipTok(VLOG_DELIMITERS2);
|
||||
savetok = (char)0;
|
||||
while (match(nexttok, "//")) {
|
||||
// NOTE: Deal with `ifdef et al. properly. Ignoring for now.
|
||||
while (match(nexttok, "//") || (nexttok[0] == '`')) {
|
||||
SkipNewLine(VLOG_DELIMITERS);
|
||||
SkipTok(VLOG_DELIMITERS2);
|
||||
}
|
||||
@@ -920,7 +952,7 @@ skip_endmodule:
|
||||
}
|
||||
|
||||
if (head == NULL) {
|
||||
Fprintf(stderr, "Warning: Cell %s has no pins\n", scan->name);
|
||||
Fprintf(stderr, "Warning: Cell %s has no pins\n", modulename);
|
||||
}
|
||||
|
||||
/* Check that the module exists. If not, generate an empty */
|
||||
@@ -928,7 +960,7 @@ skip_endmodule:
|
||||
|
||||
tp = LookupCellFile(modulename, filenum);
|
||||
if (tp == NULL) {
|
||||
struct bus wb;
|
||||
struct bus wb, pb;
|
||||
char defport[128];
|
||||
|
||||
Fprintf(stdout, "Creating placeholder cell definition for "
|
||||
@@ -966,10 +998,91 @@ skip_endmodule:
|
||||
Port((char *)NULL); // Must have something for pin 1
|
||||
}
|
||||
SetClass(CLASS_MODULE);
|
||||
tp = CurrentCell;
|
||||
EndCell();
|
||||
ReopenCellDef((*CellStackPtr)->cellname, filenum); /* Reopen */
|
||||
}
|
||||
|
||||
/* Work through scan list and expand ports/nets that are arrays */
|
||||
|
||||
last = (struct portelement *)NULL;
|
||||
scan = head;
|
||||
while (scan != NULL) {
|
||||
int portstart, portend, portnum;
|
||||
|
||||
scannext = scan->next;
|
||||
portstart = -1;
|
||||
|
||||
for (obptr = tp->cell; obptr && obptr->type == PORT; obptr = obptr->next) {
|
||||
char *delimiter;
|
||||
if ((delimiter = strrchr(obptr->name, '[')) != NULL) {
|
||||
*delimiter = '\0';
|
||||
if ((*matchfunc)(obptr->name, scan->name)) {
|
||||
if (sscanf(delimiter + 1, "%d", &portnum) == 1) {
|
||||
if (portstart == -1)
|
||||
portstart = portnum;
|
||||
else
|
||||
portend = portnum;
|
||||
}
|
||||
}
|
||||
*delimiter = '[';
|
||||
}
|
||||
}
|
||||
if (portstart != -1) {
|
||||
struct bus wb;
|
||||
struct portelement *new_port;
|
||||
char vname[256];
|
||||
int j;
|
||||
|
||||
if (GetBus(scan->net, &wb) == 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.
|
||||
}
|
||||
else if (wb.start > wb.end) {
|
||||
i = wb.start;
|
||||
j = portstart;
|
||||
while (1) {
|
||||
new_port = (struct portelement *)CALLOC(1,
|
||||
sizeof(struct portelement));
|
||||
sprintf(vname, "%s[%d]", scan->name, j);
|
||||
new_port->name = strsave(vname);
|
||||
sprintf(vname, "%s[%d]", scan->net, i);
|
||||
new_port->net = strsave(vname);
|
||||
|
||||
if (last == NULL)
|
||||
head = new_port;
|
||||
else
|
||||
last->next = new_port;
|
||||
|
||||
new_port->next = scannext;
|
||||
last = new_port;
|
||||
|
||||
if (j == portend) break;
|
||||
|
||||
if (portstart > portend) j--;
|
||||
else j++;
|
||||
if (wb.start > wb.end) i--;
|
||||
else i++;
|
||||
}
|
||||
FREE(scan);
|
||||
scan = last;
|
||||
}
|
||||
}
|
||||
else if (portstart != portend) {
|
||||
Fprintf(stderr, "Error: Single net %s is connected to bus port %s\n",
|
||||
scan->net, scan->name);
|
||||
}
|
||||
}
|
||||
last = scan;
|
||||
scan = scannext;
|
||||
}
|
||||
|
||||
arraymax = (arraystart > arrayend) ? arraystart : arrayend;
|
||||
arraymin = (arraystart > arrayend) ? arrayend : arraystart;
|
||||
|
||||
@@ -987,10 +1100,33 @@ skip_endmodule:
|
||||
|
||||
obptr = LookupInstance(locinst, CurrentCell);
|
||||
if (obptr != NULL) {
|
||||
scan = head;
|
||||
if (scan != NULL)
|
||||
do {
|
||||
struct bus wb;
|
||||
char *obpinname;
|
||||
int obpinidx;
|
||||
|
||||
// NOTE: Verilog allows any order of pins, since both the
|
||||
// instance and cell pin names are given. So for each pin
|
||||
// in obptr (which defines the pin order) , we have to find
|
||||
// the corresponding pin in the scan list.
|
||||
|
||||
obpinname = strrchr(obptr->name, '/');
|
||||
if (!obpinname) break;
|
||||
obpinname++;
|
||||
|
||||
scan = head;
|
||||
obpinidx = -1;
|
||||
while (scan != NULL) {
|
||||
if (match(obpinname, scan->name)) {
|
||||
break;
|
||||
}
|
||||
scan = scan->next;
|
||||
}
|
||||
if (scan == NULL) {
|
||||
Fprintf(stderr, "Error: No match in call for pin %s\n", obpinname);
|
||||
break;
|
||||
}
|
||||
|
||||
if (GetBus(scan->net, &wb) == 0) {
|
||||
char *scanroot;
|
||||
scanroot = strsave(scan->net);
|
||||
@@ -1003,7 +1139,7 @@ skip_endmodule:
|
||||
char pinname[128];
|
||||
|
||||
// Check if port is an array
|
||||
if (strchr(obptr->name, '[') == NULL) {
|
||||
if (obpinidx == -1) {
|
||||
if (wb.start != wb.end) {
|
||||
Printf("Error: Bus connected to single port\n");
|
||||
}
|
||||
@@ -1014,67 +1150,13 @@ skip_endmodule:
|
||||
join(pinname, obptr->name);
|
||||
if (brackptr) *brackptr = '[';
|
||||
}
|
||||
else if (wb.start > wb.end) {
|
||||
range = wb.start - wb.end;
|
||||
for (j = range; j >= 0; j--) {
|
||||
sprintf(pinname, "%s[%d]", scanroot, j);
|
||||
if (LookupObject(pinname, CurrentCell) == NULL)
|
||||
Node(pinname);
|
||||
join(pinname, obptr->name);
|
||||
if (j == 0) break;
|
||||
if (obptr->next && (brackptr =
|
||||
strchr(obptr->next->name, '[')) != NULL) {
|
||||
if (strncmp(obptr->next->name, obptr->name,
|
||||
(int)(brackptr - obptr->next->name))) {
|
||||
Printf("Error: More bits in net than in port!\n");
|
||||
break;
|
||||
}
|
||||
obptr = obptr->next;
|
||||
}
|
||||
else {
|
||||
Printf("Error: More bits in net than in port!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Are there port bits left over?
|
||||
while (obptr->next && ((brackptr =
|
||||
strchr(obptr->next->name, '[')) != NULL) &&
|
||||
(!strncmp(obptr->next->name, obptr->name,
|
||||
(int)(brackptr - obptr->next->name)))) {
|
||||
Printf("Error: More bits in port than in net!\n");
|
||||
obptr = obptr->next;
|
||||
}
|
||||
}
|
||||
else {
|
||||
range = wb.end - wb.start;
|
||||
for (j = 0; j <= range; j++) {
|
||||
sprintf(pinname, "%s[%d]", scanroot, j);
|
||||
if (LookupObject(pinname, CurrentCell) == NULL)
|
||||
Node(pinname);
|
||||
join(pinname, obptr->name);
|
||||
if (j == range) break;
|
||||
if (obptr->next && (brackptr =
|
||||
strchr(obptr->next->name, '[')) != NULL) {
|
||||
if (strncmp(obptr->next->name, obptr->name,
|
||||
(int)(brackptr - obptr->next->name))) {
|
||||
Printf("Error: More bits in net than in port!\n");
|
||||
break;
|
||||
}
|
||||
obptr = obptr->next;
|
||||
}
|
||||
else {
|
||||
Printf("Error: More bits in net than in port!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Are there port bits left over?
|
||||
while (obptr->next && ((brackptr =
|
||||
strchr(obptr->next->name, '[')) != NULL) &&
|
||||
(!strncmp(obptr->next->name, obptr->name,
|
||||
(int)(brackptr - obptr->next->name)))) {
|
||||
Printf("Error: More bits in port than in net!\n");
|
||||
obptr = obptr->next;
|
||||
}
|
||||
// NOTE: Making unsupportable assumption that
|
||||
// pin and port indexes match---need to fix this!
|
||||
sprintf(pinname, "%s[%d]", scanroot, obpinidx);
|
||||
if (LookupObject(pinname, CurrentCell) == NULL)
|
||||
Node(pinname);
|
||||
join(pinname, obptr->name);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1100,27 +1182,9 @@ skip_endmodule:
|
||||
join(scan->net, obptr->name);
|
||||
}
|
||||
obptr = obptr->next;
|
||||
scan = scan->next;
|
||||
} while (obptr != NULL && obptr->type > FIRSTPIN && scan != NULL);
|
||||
|
||||
if ((obptr == NULL && scan != NULL) ||
|
||||
(obptr != NULL && scan == NULL && obptr->type > FIRSTPIN)) {
|
||||
if (warnings <= 100) {
|
||||
Fprintf(stderr,"Parameter list mismatch in %s: ", instancename);
|
||||
|
||||
if (obptr == NULL)
|
||||
Fprintf(stderr, "Too many parameters in call!\n");
|
||||
else if (scan == NULL)
|
||||
Fprintf(stderr, "Not enough parameters in call!\n");
|
||||
InputParseError(stderr);
|
||||
if (warnings == 100)
|
||||
Fprintf(stderr, "Too many warnings. . . will not "
|
||||
"report any more.\n");
|
||||
}
|
||||
warnings++;
|
||||
}
|
||||
}
|
||||
if (i == -1) break; /* No array */
|
||||
} while (obptr != NULL && obptr->type > FIRSTPIN);
|
||||
}
|
||||
if (i == -1) break; /* No array */
|
||||
}
|
||||
DeleteProperties(&kvlist);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user