Merge branch 'master' into netgen-1.5
This commit is contained in:
commit
39b8e3d14a
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
||||||
163
base/verilog.c
163
base/verilog.c
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue