Merge branch 'master' into netgen-1.5

This commit is contained in:
Tim Edwards 2019-09-09 03:00:10 -04:00
commit 39b8e3d14a
3 changed files with 137 additions and 106 deletions

View File

@ -191,6 +191,8 @@ struct filestack {
static struct filestack *OpenFiles = NULL; static struct filestack *OpenFiles = NULL;
struct hashdict *definitions = (struct hashdict *)NULL;
#define WHITESPACE_DELIMITER " \t\n\r" #define WHITESPACE_DELIMITER " \t\n\r"
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
@ -292,9 +294,82 @@ int GetNextLineNoNewline(char *delimiter)
FREE(linetok); FREE(linetok);
linetok = (char *)MALLOC(linesize); linetok = (char *)MALLOC(linesize);
} }
linenum++;
strcpy(linetok, line); /* Check for substitutions (verilog only). Make sure linetok is */
/* large enough to hold the entire line after substitutions. */
if (definitions != NULL) {
char *s, *w, e;
struct property *kl;
int len, dlen, vlen, addin = 0;
unsigned char found = FALSE;
for (s = line; *s != '\0'; s++) {
if (*s == '`') {
w = s + 1;
while (isalnum(*w)) w++;
e = *w;
*w = '\0';
kl = (struct property *)HashLookup(s + 1, definitions);
if (kl != NULL) {
dlen = strlen(s);
if (kl->type == PROP_STRING) {
vlen = strlen(kl->pdefault.string);
}
else vlen = 12; /* Leave room for numeric conversion */
addin += vlen - dlen + 1;
found = TRUE;
}
*w = e;
}
}
if (found) {
len = strlen(line);
if (len + addin > linesize) {
while (len + addin > linesize) linesize += 500;
FREE(linetok);
linetok = (char *)MALLOC(linesize);
}
}
}
/* Make definition substitutions (verilog only) */
if (definitions != NULL) {
char *s, *t, *w, e;
struct property *kl;
int len, dlen, vlen, addin = 0;
t = linetok;
for (s = line; *s != '\0'; s++) {
if (*s == '`') {
w = s + 1;
while (isalnum(*w)) w++;
e = *w;
*w = '\0';
kl = (struct property *)HashLookup(s + 1, definitions);
if (kl != NULL) {
if (kl->type == PROP_STRING)
strcpy(t, kl->pdefault.string);
else if (kl->type == PROP_INTEGER)
sprintf(t, "%d", kl->pdefault.ival);
else if (kl->type == PROP_DOUBLE)
sprintf(t, "%g", kl->pdefault.dval);
t += strlen(t);
s = w - 1;
}
else *t++ = *s;
*w = e;
}
else *t++ = *s;
}
*t = '\0';
}
else
strcpy(linetok, line);
TrimQuoted(linetok); TrimQuoted(linetok);
linenum++;
nexttok = strdtok(linetok, WHITESPACE_DELIMITER, delimiter); nexttok = strdtok(linetok, WHITESPACE_DELIMITER, delimiter);
return 0; return 0;

View File

@ -24,6 +24,7 @@ extern void FlushString (char *format, ...);
extern char *SetExtension(char *buffer, char *path, char *extension); extern char *SetExtension(char *buffer, char *path, char *extension);
extern int File; extern int File;
extern struct hashdict *definitions;
/* input routines */ /* input routines */

View File

@ -121,19 +121,22 @@ int GetBusTok(struct bus *wb)
if (match(nexttok, "[")) { if (match(nexttok, "[")) {
SkipTokComments(VLOG_DELIMITERS); SkipTokComments(VLOG_DELIMITERS);
// Check for parameter names and substitute values if found. result = sscanf(nexttok, "%d", &start);
if (nexttok[0] == '`') { if (result != 1) {
kl = (struct property *)HashLookup(nexttok + 1, &verilogdefs); // Is name in the parameter list?
kl = (struct property *)HashLookup(nexttok, &verilogparams);
if (kl == NULL) { if (kl == NULL) {
Printf("Unknown definition %s found in array notation.\n", nexttok); Printf("Array value %s is not a number or a parameter.\n",
nexttok);
return 1;
} }
else { else {
if (kl->type == PROP_STRING) { if (kl->type == PROP_STRING) {
result = sscanf(kl->pdefault.string, "%d", &start); result = sscanf(kl->pdefault.string, "%d", &start);
if (result != 1) { if (result != 1) {
Printf("Cannot parse first digit from parameter %s value %s\n", Printf("Parameter %s has value %s that cannot be parsed"
nexttok, kl->pdefault.string); " as an integer.\n", nexttok, kl->pdefault.string);
return 1; return 1;
} }
} }
else if (kl->type == PROP_INTEGER) { else if (kl->type == PROP_INTEGER) {
@ -142,53 +145,15 @@ int GetBusTok(struct bus *wb)
else if (kl->type == PROP_DOUBLE) { else if (kl->type == PROP_DOUBLE) {
start = (int)kl->pdefault.dval; start = (int)kl->pdefault.dval;
if ((double)start != kl->pdefault.dval) { if ((double)start != kl->pdefault.dval) {
Printf("Cannot parse first digit from parameter %s value %g\n", Printf("Parameter %s has value %g that cannot be parsed"
nexttok, kl->pdefault.dval);
return 1;
}
}
else {
Printf("Parameter %s has unknown type; don't know how to parse.\n",
nexttok);
return 1;
}
}
}
else {
result = sscanf(nexttok, "%d", &start);
if (result != 1) {
// Is name in the parameter list?
kl = (struct property *)HashLookup(nexttok, &verilogparams);
if (kl == NULL) {
Printf("Array value %s is not a number or a parameter.\n",
nexttok);
return 1;
}
else {
if (kl->type == PROP_STRING) {
result = sscanf(kl->pdefault.string, "%d", &start);
if (result != 1) {
Printf("Parameter %s has value %s that cannot be parsed"
" as an integer.\n", nexttok, kl->pdefault.string);
return 1;
}
}
else if (kl->type == PROP_INTEGER) {
start = kl->pdefault.ival;
}
else if (kl->type == PROP_DOUBLE) {
start = (int)kl->pdefault.dval;
if ((double)start != kl->pdefault.dval) {
Printf("Parameter %s has value %g that cannot be parsed"
" as an integer.\n", nexttok, kl->pdefault.dval); " as an integer.\n", nexttok, kl->pdefault.dval);
return 1; return 1;
}
} }
else { }
Printf("Parameter %s has unknown type; don't know how" else {
Printf("Parameter %s has unknown type; don't know how"
" to parse.\n", nexttok); " to parse.\n", nexttok);
return 1; return 1;
}
} }
} }
} }
@ -204,18 +169,22 @@ int GetBusTok(struct bus *wb)
else { else {
SkipTokComments(VLOG_DELIMITERS); SkipTokComments(VLOG_DELIMITERS);
// Check for parameter names and substitute values if found. result = sscanf(nexttok, "%d", &end);
if (nexttok[0] == '`') { if (result != 1) {
kl = (struct property *)HashLookup(nexttok + 1, &verilogdefs); // Is name in the parameter list?
kl = (struct property *)HashLookup(nexttok, &verilogparams);
if (kl == NULL) { if (kl == NULL) {
Printf("Unknown definition %s found in array notation.\n", nexttok); Printf("Array value %s is not a number or a parameter.\n",
nexttok);
return 1;
} }
else { else {
if (kl->type == PROP_STRING) { if (kl->type == PROP_STRING) {
result = sscanf(kl->pdefault.string, "%d", &end); result = sscanf(kl->pdefault.string, "%d", &end);
if (result != 1) { if (result != 1) {
Printf("Cannot parse second digit from parameter " Printf("Parameter %s has value %s that cannot be parsed"
"%s value %s\n", nexttok, kl->pdefault.string); " as an integer.\n", nexttok,
kl->pdefault.string);
return 1; return 1;
} }
} }
@ -232,47 +201,8 @@ int GetBusTok(struct bus *wb)
} }
else { else {
Printf("Parameter %s has unknown type; don't know how" Printf("Parameter %s has unknown type; don't know how"
" to parse.\n", nexttok);
return 1;
}
}
}
else {
result = sscanf(nexttok, "%d", &end);
if (result != 1) {
// Is name in the parameter list?
kl = (struct property *)HashLookup(nexttok, &verilogparams);
if (kl == NULL) {
Printf("Array value %s is not a number or a parameter.\n",
nexttok);
return 1;
}
else {
if (kl->type == PROP_STRING) {
result = sscanf(kl->pdefault.string, "%d", &end);
if (result != 1) {
Printf("Parameter %s has value %s that cannot be parsed"
" as an integer.\n", nexttok,
kl->pdefault.string);
return 1;
}
}
else if (kl->type == PROP_INTEGER) {
end = kl->pdefault.ival;
}
else if (kl->type == PROP_DOUBLE) {
end = (int)kl->pdefault.dval;
if ((double)end != kl->pdefault.dval) {
Printf("Cannot parse second digit from parameter "
"%s value %g\n", nexttok, kl->pdefault.dval);
return 1;
}
}
else {
Printf("Parameter %s has unknown type; don't know how"
" to parse.\n", nexttok); " to parse.\n", nexttok);
return 1; return 1;
}
} }
} }
} }
@ -1026,6 +956,22 @@ skip_endmodule:
} }
HashPtrInstall(kl->key, kl, &verilogdefs); HashPtrInstall(kl->key, kl, &verilogdefs);
} }
else if (match(nexttok, "`undef")) {
struct property *kl = NULL;
SkipTokNoNewline(VLOG_DELIMITERS);
if ((nexttok == NULL) || (nexttok[0] == '\0')) break;
kl = HashLookup(nexttok, &verilogdefs);
if (kl != NULL) {
HashDelete(nexttok, &verilogdefs);
if (kl->type == PROP_STRING)
if (kl->pdefault.string != NULL)
FREE(kl->pdefault.string);
FREE(kl->key);
}
/* Presumably it is not an error to undefine an undefined keyword */
}
else if (match(nexttok, "localparam")) { else if (match(nexttok, "localparam")) {
// Pick up key = value pairs and store in current cell // Pick up key = value pairs and store in current cell
while (nexttok != NULL) while (nexttok != NULL)
@ -1064,10 +1010,10 @@ skip_endmodule:
} }
} }
/* Note: This is just the most basic processing of conditionals, */ /* Process conditions. Note that conditionals may be nested. */
/* although it does handle nested conditionals. */
else if (match(nexttok, "`ifdef") || match(nexttok, "`ifndef")) { else if (match(nexttok, "`ifdef") || match(nexttok, "`ifndef") ||
match(nexttok, "`elsif") || match(nexttok, "`else")) {
struct property *kl; struct property *kl;
int nested = 0; int nested = 0;
int invert = (nexttok[3] == 'n') ? 1 : 0; int invert = (nexttok[3] == 'n') ? 1 : 0;
@ -1077,9 +1023,9 @@ skip_endmodule:
/* To be done: Handle boolean arithmetic on conditionals */ /* To be done: Handle boolean arithmetic on conditionals */
kl = (struct property *)HashLookup(nexttok, &verilogdefs); kl = (struct property *)HashLookup(nexttok, &verilogdefs);
if (((invert == 0) && (kl == NULL)) while (((invert == 0) && (kl == NULL))
|| ((invert == 1) && (kl != NULL))) { || ((invert == 1) && (kl != NULL))) {
/* Skip to matching `endif */ /* Skip to matching `endif, `elsif, or `else */
while (1) { while (1) {
SkipNewLine(VLOG_DELIMITERS); SkipNewLine(VLOG_DELIMITERS);
SkipTokComments(VLOG_DELIMITERS); SkipTokComments(VLOG_DELIMITERS);
@ -1087,13 +1033,20 @@ skip_endmodule:
if (match(nexttok, "`ifdef") || match(nexttok, "`ifndef")) { if (match(nexttok, "`ifdef") || match(nexttok, "`ifndef")) {
nested++; nested++;
} }
else if (match(nexttok, "`endif")) { else if (match(nexttok, "`endif") || match(nexttok, "`elsif") ||
match(nexttok, "`else")) {
if (nested == 0) if (nested == 0)
break; break;
else else
nested--; nested--;
} }
} }
if (match(nexttok, "`elsif")) {
SkipTokComments(VLOG_DELIMITERS);
invert = 0;
kl = (struct property *)HashLookup(nexttok, &verilogdefs);
}
else break;
} }
} }
@ -1909,6 +1862,7 @@ char *ReadVerilogTop(char *fname, int *fnum, int blackbox)
InitializeHashTable(&verilogparams, OBJHASHSIZE); InitializeHashTable(&verilogparams, OBJHASHSIZE);
InitializeHashTable(&verilogdefs, OBJHASHSIZE); InitializeHashTable(&verilogdefs, OBJHASHSIZE);
definitions = &verilogdefs;
/* Add the pre-defined key "LVS" to verilogdefs */ /* Add the pre-defined key "LVS" to verilogdefs */
@ -1931,6 +1885,7 @@ char *ReadVerilogTop(char *fname, int *fnum, int blackbox)
HashKill(&verilogparams); HashKill(&verilogparams);
RecurseHashTable(&verilogdefs, freeprop); RecurseHashTable(&verilogdefs, freeprop);
HashKill(&verilogdefs); HashKill(&verilogdefs);
definitions = (struct hashdict *)NULL;
// Record the top level file. // Record the top level file.
if (LookupCellFile(fname, filenum) == NULL) CellDef(fname, filenum); if (LookupCellFile(fname, filenum) == NULL) CellDef(fname, filenum);