Merge branch 'master' into netgen-1.5

This commit is contained in:
Tim Edwards 2020-03-28 03:00:24 -04:00
commit 27f2ab8b3f
2 changed files with 114 additions and 42 deletions

View File

@ -1 +1 @@
1.5.145 1.5.146

View File

@ -919,7 +919,7 @@ skip_endmodule:
} }
else if (match(nexttok, "input") || match(nexttok, "output") else if (match(nexttok, "input") || match(nexttok, "output")
|| match(nexttok, "inout")) { || match(nexttok, "inout")) {
struct bus wb; struct bus wb, *nb;
// Parsing of ports as statements not in the module pin list. // Parsing of ports as statements not in the module pin list.
wb.start = wb.end = -1; wb.start = wb.end = -1;
@ -952,6 +952,11 @@ skip_endmodule:
Port(portname); 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; wb.start = wb.end = -1;
} }
else { else {
@ -1065,6 +1070,13 @@ skip_endmodule:
kl->pdefault.ival = 1; kl->pdefault.ival = 1;
kl->slop.ival = 0; 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) { else if (ConvertStringToInteger(nexttok, &ival) == 1) {
/* Parameter parses as an integer */ /* Parameter parses as an integer */
kl->type = PROP_INTEGER; kl->type = PROP_INTEGER;
@ -1083,7 +1095,7 @@ skip_endmodule:
kl->pdefault.string = strsave(nexttok); kl->pdefault.string = strsave(nexttok);
kl->slop.dval = 0.0; kl->slop.dval = 0.0;
} }
HashPtrInstall(kl->key, kl, &verilogdefs); if (kl) HashPtrInstall(kl->key, kl, &verilogdefs);
} }
else if (match(nexttok, "`undef")) { else if (match(nexttok, "`undef")) {
struct property *kl = NULL; struct property *kl = NULL;
@ -1315,6 +1327,7 @@ skip_endmodule:
struct portelement { struct portelement {
char *name; // Name of port in subcell char *name; // Name of port in subcell
char *net; // Name of net connecting to port in the parent char *net; // Name of net connecting to port in the parent
int width; // Width of port, if port is a bus
struct portelement *next; struct portelement *next;
}; };
@ -1322,6 +1335,22 @@ skip_endmodule:
struct objlist *obptr; struct objlist *obptr;
strncpy(modulename, nexttok, 99); 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)) { if (!(*CellStackPtr)) {
CellDef(fname, filenum); CellDef(fname, filenum);
PushStack(fname, CellStackPtr); PushStack(fname, CellStackPtr);
@ -1424,6 +1453,7 @@ nextinst:
else { else {
new_port = (struct portelement *)CALLOC(1, sizeof(struct portelement)); new_port = (struct portelement *)CALLOC(1, sizeof(struct portelement));
new_port->name = strsave(nexttok + 1); new_port->name = strsave(nexttok + 1);
new_port->width = -1;
SkipTokComments(VLOG_DELIMITERS); SkipTokComments(VLOG_DELIMITERS);
if (!match(nexttok, "(")) { if (!match(nexttok, "(")) {
Printf("Badly formed subcircuit pin line at \"%s\"\n", nexttok); Printf("Badly formed subcircuit pin line at \"%s\"\n", nexttok);
@ -1445,25 +1475,25 @@ nextinst:
} }
else { else {
if (!strcmp(nexttok, "{")) { if (!strcmp(nexttok, "{")) {
char *in_line_net = (char *)MALLOC(1); char *wire_bundle = (char *)MALLOC(1);
char *new_in_line_net = NULL; char *new_wire_bundle = NULL;
*in_line_net = '\0'; *wire_bundle = '\0';
/* In-line array---read to "}" */ /* Wire bundle---read to "}" */
while (nexttok) { while (nexttok) {
new_in_line_net = (char *)MALLOC(strlen(in_line_net) + new_wire_bundle = (char *)MALLOC(strlen(wire_bundle) +
strlen(nexttok) + 1); strlen(nexttok) + 1);
/* Roundabout way to do realloc() becase there is no REALLOC() */ /* Roundabout way to do realloc() becase there is no REALLOC() */
strcpy(new_in_line_net, in_line_net); strcpy(new_wire_bundle, wire_bundle);
strcat(new_in_line_net, nexttok); strcat(new_wire_bundle, nexttok);
FREE(in_line_net); FREE(wire_bundle);
in_line_net = new_in_line_net; wire_bundle = new_wire_bundle;
if (!strcmp(nexttok, "}")) break; if (!strcmp(nexttok, "}")) break;
SkipTokComments(VLOG_PIN_CHECK_DELIMITERS); SkipTokComments(VLOG_PIN_CHECK_DELIMITERS);
} }
if (!nexttok) { 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 else
new_port->net = strsave(nexttok); new_port->net = strsave(nexttok);
@ -1650,7 +1680,12 @@ nextinst:
int j, result; int j, result;
struct objlist *bobj; struct objlist *bobj;
char *bptr; 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); result = GetBus(scan->net, &wb);
if (result == -1) { if (result == -1) {
@ -1702,17 +1737,31 @@ nextinst:
} }
if (result == 0) { if (result == 0) {
if (((wb.start - wb.end) != (portstart - portend)) && int match = 0;
((wb.start - wb.end) != (portend - portstart))) { int wblen, arraylen;
if (((wb.start - wb.end) != (arraystart - arrayend)) &&
((wb.start - wb.end) != (arrayend - arraystart))) { arraylen = arraystart - arrayend;
Fprintf(stderr, "Error: Net %s bus width does not match " wblen = wb.start - wb.end;
"port %s bus width.\n", scan->net, scan->name);
} if (arraylen < 0) arraylen = -arraylen;
// Otherwise, net is bit-sliced across array of instances. 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, *cptr = NULL, cchar, *netname;
unsigned char is_bundle = 0; unsigned char is_bundle = 0;
struct bus wbb; struct bus wbb;
@ -1739,8 +1788,6 @@ nextinst:
else else
i = -1; i = -1;
if (is_bundle) *cptr = cchar; /* Restore bundle delimiter */
while (1) { while (1) {
new_port = (struct portelement *)CALLOC(1, new_port = (struct portelement *)CALLOC(1,
sizeof(struct portelement)); sizeof(struct portelement));
@ -1751,6 +1798,7 @@ nextinst:
else else
sprintf(vname, "%s[%d]", netname, i); sprintf(vname, "%s[%d]", netname, i);
new_port->net = strsave(vname); new_port->net = strsave(vname);
new_port->width = scan->width;
if (last == NULL) if (last == NULL)
head = new_port; head = new_port;
@ -1764,8 +1812,10 @@ nextinst:
if (portstart > portend) j--; if (portstart > portend) j--;
else j++; else j++;
if (wbb.start > wbb.end) i--; if (i != -1) {
else i++; if (wbb.start > wbb.end) i--;
else i++;
}
if (is_bundle && if (is_bundle &&
((i == -1) || ((i == -1) ||
@ -1774,6 +1824,7 @@ nextinst:
if (bptr) *bptr = '['; if (bptr) *bptr = '[';
netname = cptr + 1; netname = cptr + 1;
if (cptr) *cptr = cchar; /* Restore previous bundle delimiter */
cptr = strchr(netname, ','); cptr = strchr(netname, ',');
if (cptr == NULL) cptr = strchr(netname, '}'); if (cptr == NULL) cptr = strchr(netname, '}');
if (cptr == NULL) cptr = netname + strlen(netname) - 1; if (cptr == NULL) cptr = netname + strlen(netname) - 1;
@ -1786,12 +1837,11 @@ nextinst:
*bptr = '\0'; *bptr = '\0';
} }
else i = -1; else i = -1;
*cptr = cchar; /* Restore delimiter */
} }
} }
FREE(scan); FREE(scan);
scan = last; scan = last;
if (cptr) *cptr = cchar; /* Restore bundle delimiter */
} }
} }
else if (portstart != portend) { else if (portstart != portend) {
@ -1821,7 +1871,7 @@ nextinst:
obptr = LookupInstance(locinst, CurrentCell); obptr = LookupInstance(locinst, CurrentCell);
if (obptr != NULL) { if (obptr != NULL) {
do { do {
struct bus wb; struct bus wb, wb2;
char *obpinname; char *obpinname;
int obpinidx; int obpinidx;
@ -1848,6 +1898,7 @@ nextinst:
} }
if (GetBus(scan->net, &wb) == 0) { if (GetBus(scan->net, &wb) == 0) {
char *bptr2;
char *scanroot; char *scanroot;
scanroot = strsave(scan->net); scanroot = strsave(scan->net);
brackptr = strchr(scanroot, '['); brackptr = strchr(scanroot, '[');
@ -1882,16 +1933,37 @@ nextinst:
else { else {
// Instance must be an array // Instance must be an array
char netname[128]; char netname[128];
int slice; int slice, portlen, siglen;
if (wb.start >= wb.end && arraystart >= arrayend)
slice = wb.start - (arraystart - i); /* Get the array size of the port for bit slicing */
else if (wb.start < wb.end && arraystart > arrayend) portlen = (scan->width < 0) ? 1 : scan->width;
slice = wb.start + (arraystart - i);
else if (wb.start > wb.end && arraystart < arrayend) /* Get the full array size of the connecting bus */
slice = wb.start - (arraystart + i); GetBus(scanroot, &wb2);
else // (wb.start < wb.end && arraystart < arrayend) siglen = wb2.start - wb2.end;
slice = wb.start + (arraystart + i); 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); sprintf(netname, "%s[%d]", scanroot, slice);
if (LookupObject(netname, CurrentCell) == NULL) Node(netname); if (LookupObject(netname, CurrentCell) == NULL) Node(netname);
join(netname, obptr->name); join(netname, obptr->name);