summaryrefslogtreecommitdiff
path: root/frontends
diff options
context:
space:
mode:
Diffstat (limited to 'frontends')
-rw-r--r--frontends/ast/ast.cc1
-rw-r--r--frontends/ast/ast.h1
-rw-r--r--frontends/ast/simplify.cc25
-rw-r--r--frontends/verilog/parser.y7
4 files changed, 34 insertions, 0 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index 105645f9..0780f7b5 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -127,6 +127,7 @@ std::string AST::type2str(AstNodeType type)
X(AST_ASSIGN)
X(AST_CELL)
X(AST_PRIMITIVE)
+ X(AST_CELLARRAY)
X(AST_ALWAYS)
X(AST_INITIAL)
X(AST_BLOCK)
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index 3e69e3bc..802bf98f 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -107,6 +107,7 @@ namespace AST
AST_ASSIGN,
AST_CELL,
AST_PRIMITIVE,
+ AST_CELLARRAY,
AST_ALWAYS,
AST_INITIAL,
AST_BLOCK,
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index e5e8980a..fc040baa 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -878,6 +878,31 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage,
did_something = true;
}
+ // unroll cell arrays
+ if (type == AST_CELLARRAY)
+ {
+ if (!children.at(0)->range_valid)
+ log_error("Non-constant array range on cell array at %s:%d.\n", filename.c_str(), linenum);
+
+ newNode = new AstNode(AST_GENBLOCK);
+ int num = std::max(children.at(0)->range_left, children.at(0)->range_right) - std::min(children.at(0)->range_left, children.at(0)->range_right) + 1;
+
+ for (int i = 0; i < num; i++) {
+ int idx = children.at(0)->range_left > children.at(0)->range_right ? children.at(0)->range_right + i : children.at(0)->range_right - i;
+ AstNode *new_cell = children.at(1)->clone();
+ newNode->children.push_back(new_cell);
+ new_cell->str += stringf("[%d]", idx);
+ if (new_cell->type == AST_PRIMITIVE) {
+ log_error("Cell arrays of primitives are currently not supported at %s:%d.\n", filename.c_str(), linenum);
+ } else {
+ log_assert(new_cell->children.at(0)->type == AST_CELLTYPE);
+ new_cell->children.at(0)->str = stringf("$array:%d:%d:%s", i, num, new_cell->children.at(0)->str.c_str());
+ }
+ }
+
+ goto apply_newNode;
+ }
+
// replace primitives with assignmens
if (type == AST_PRIMITIVE)
{
diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y
index 42a8f91c..f422258c 100644
--- a/frontends/verilog/parser.y
+++ b/frontends/verilog/parser.y
@@ -634,6 +634,13 @@ single_cell:
astbuf2->str = *$1;
delete $1;
ast_stack.back()->children.push_back(astbuf2);
+ } '(' cell_port_list ')' |
+ TOK_ID non_opt_range {
+ astbuf2 = astbuf1->clone();
+ if (astbuf2->type != AST_PRIMITIVE)
+ astbuf2->str = *$1;
+ delete $1;
+ ast_stack.back()->children.push_back(new AstNode(AST_CELLARRAY, $2, astbuf2));
} '(' cell_port_list ')';
prim_list: