From 7889e2ae73227feead3375f404ebe095e4a61a1b Mon Sep 17 00:00:00 2001 From: Tim Edwards Date: Mon, 21 Jan 2019 20:29:42 -0500 Subject: [PATCH] Small typo, large effect; wrong reference to ob1 (instead of ob2) in flatten.c can cause a segfault when analyzing whether flattening cells generates a better circuit match. --- base/flatten.c | 2 +- base/verilog.c | 38 ++++++++++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/base/flatten.c b/base/flatten.c index 6e4233a..96bfdce 100644 --- a/base/flatten.c +++ b/base/flatten.c @@ -1919,7 +1919,7 @@ PrematchLists(char *name1, int file1, char *name2, int file2) char *dstr = NULL; tc2 = LookupCellFile(ob2->model.class, ecomp0X->cell2->file); if (tc2->flags & CELL_DUPLICATE) { - dstr = strstr(ob1->model.class, "[["); + dstr = strstr(ob2->model.class, "[["); if (dstr) *dstr = '\0'; } ncomp = (ECompare *)HashInt2Lookup(ob2->model.class, diff --git a/base/verilog.c b/base/verilog.c index 3e3e39f..78d70b1 100644 --- a/base/verilog.c +++ b/base/verilog.c @@ -1062,14 +1062,25 @@ skip_endmodule: } } - else if (match(nexttok, "wire")) { /* wire = node */ + else if (match(nexttok, "wire") || match(nexttok, "assign")) { /* wire = node */ struct bus wb, *nb; char nodename[128]; + int is_assignment = FALSE; + struct objlist *lhs, *rhs; + + // Several allowed uses of "assign": + // "assign a = b" joins two nets. + // "assign a = {b, c, ...}" creates a bus from components. + // "assign" using any boolean arithmetic is not structural verilog. + SkipTokNoNewline(VLOG_DELIMITERS); if (match(nexttok, "real")) SkipTokNoNewline(VLOG_DELIMITERS); while (nexttok != NULL) { - /* Handle bus notation */ - if (GetBusTok(&wb) == 0) { + if (match(nexttok, "=")) { + is_assignment = TRUE; + } + else if (GetBusTok(&wb) == 0) { + /* Handle bus notation */ SkipTokNoNewline(VLOG_DELIMITERS); if (wb.start > wb.end) { for (i = wb.end; i <= wb.start; i++) { @@ -1091,8 +1102,24 @@ skip_endmodule: HashPtrInstall(nexttok, nb, &buses); } else { - if (LookupObject(nexttok, CurrentCell) == NULL) + if (is_assignment) { + /* Handle assignment statements */ + /* To be done: Handle where both are bus names, and */ + /* where lhs is a bus name and rhs is a list of nets */ + if ((rhs = LookupObject(nexttok, CurrentCell)) != NULL) { + join(lhs->name, rhs->name); + } + else { + Printf("Module '%s' is not structural verilog, " + "making black-box.\n", model); + SetClass(CLASS_MODULE); + goto skip_endmodule; + } + is_assignment = FALSE; + } + else if (LookupObject(nexttok, CurrentCell) == NULL) Node(nexttok); + lhs = LookupObject(nexttok, CurrentCell); } do { SkipTokNoNewline(VLOG_DELIMITERS); @@ -1108,8 +1135,7 @@ skip_endmodule: // Ignore any other directive starting with a backtick SkipNewLine(VLOG_DELIMITERS); } - else if (match(nexttok, "reg") || match(nexttok, "assign") - || match(nexttok, "always")) { + else if (match(nexttok, "reg") || match(nexttok, "always")) { Printf("Module '%s' is not structural verilog, making black-box.\n", model); // To be done: Remove any contents (but may not be necessary) // Recast as module