Merge branch 'master' into netgen-1.5
This commit is contained in:
commit
27f2ab8b3f
152
base/verilog.c
152
base/verilog.c
|
|
@ -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,15 +1933,36 @@ 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);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue