summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--frontends/ast/ast.cc1
-rw-r--r--frontends/ast/ast.h1
-rw-r--r--frontends/ast/simplify.cc16
-rw-r--r--frontends/verilog/parser.y26
4 files changed, 33 insertions, 11 deletions
diff --git a/frontends/ast/ast.cc b/frontends/ast/ast.cc
index 160e9c42..e5db5a94 100644
--- a/frontends/ast/ast.cc
+++ b/frontends/ast/ast.cc
@@ -77,6 +77,7 @@ std::string AST::type2str(AstNodeType type)
X(AST_CONSTANT)
X(AST_CELLTYPE)
X(AST_IDENTIFIER)
+ X(AST_PREFIX)
X(AST_FCALL)
X(AST_TO_SIGNED)
X(AST_TO_UNSIGNED)
diff --git a/frontends/ast/ast.h b/frontends/ast/ast.h
index f7c9328c..cdc56fba 100644
--- a/frontends/ast/ast.h
+++ b/frontends/ast/ast.h
@@ -56,6 +56,7 @@ namespace AST
AST_CONSTANT,
AST_CELLTYPE,
AST_IDENTIFIER,
+ AST_PREFIX,
AST_FCALL,
AST_TO_SIGNED,
diff --git a/frontends/ast/simplify.cc b/frontends/ast/simplify.cc
index cb8b1043..33776d65 100644
--- a/frontends/ast/simplify.cc
+++ b/frontends/ast/simplify.cc
@@ -103,7 +103,7 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage)
}
// activate const folding if this is anything that must be evaluated statically (ranges, parameters, attributes, etc.)
- if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_PARASET || type == AST_RANGE)
+ if (type == AST_WIRE || type == AST_PARAMETER || type == AST_LOCALPARAM || type == AST_PARASET || type == AST_RANGE || type == AST_PREFIX)
const_fold = true;
if (type == AST_IDENTIFIER && current_scope.count(str) > 0 && (current_scope[str]->type == AST_PARAMETER || current_scope[str]->type == AST_LOCALPARAM))
const_fold = true;
@@ -179,6 +179,8 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage)
break;
if (type == AST_GENIF && i >= 1)
break;
+ if (type == AST_PREFIX && i >= 1)
+ break;
while (did_something_here && i < children.size()) {
bool const_fold_here = const_fold, in_lvalue_here = in_lvalue;
if (i == 0 && type == AST_REPLICATE)
@@ -217,6 +219,18 @@ bool AstNode::simplify(bool const_fold, bool at_zero, bool in_lvalue, int stage)
if (type == AST_MODULE)
current_scope.clear();
+ // resolve constant prefixes
+ if (type == AST_PREFIX) {
+ if (children[0]->type != AST_CONSTANT) {
+ dumpAst(NULL, "> ", NULL);
+ log_error("Index in generate block prefix syntax at %s:%d is not constant!\n", filename.c_str(), linenum);
+ }
+ assert(children[1]->type == AST_IDENTIFIER);
+ newNode = children[1]->clone();
+ newNode->str = stringf("%s[%d].%s", str.c_str(), children[0]->integer, children[1]->str.c_str());
+ goto apply_newNode;
+ }
+
// annotate constant ranges
if (type == AST_RANGE) {
bool old_range_valid = range_valid;
diff --git a/frontends/verilog/parser.y b/frontends/verilog/parser.y
index 010af478..6e0b238e 100644
--- a/frontends/verilog/parser.y
+++ b/frontends/verilog/parser.y
@@ -105,7 +105,7 @@ static void free_attr(std::map<std::string, AstNode*> *al)
%token TOK_SYNOPSYS_FULL_CASE TOK_SYNOPSYS_PARALLEL_CASE
%token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED
-%type <ast> wire_type range expr basic_expr concat_list lvalue lvalue_concat_list
+%type <ast> wire_type range expr basic_expr concat_list rvalue lvalue lvalue_concat_list
%type <string> opt_label tok_prim_wrapper
%type <boolean> opt_signed
%type <al> attr
@@ -802,13 +802,21 @@ case_expr_list:
ast_stack.back()->children.push_back($3);
};
-lvalue:
+rvalue:
+ TOK_ID '[' expr ']' '.' rvalue {
+ $$ = new AstNode(AST_PREFIX, $3, $6);
+ $$->str = *$1;
+ delete $1;
+ } |
TOK_ID range {
- $$ = new AstNode(AST_IDENTIFIER);
+ $$ = new AstNode(AST_IDENTIFIER, $2);
$$->str = *$1;
- if ($2)
- $$->children.push_back($2);
delete $1;
+ };
+
+lvalue:
+ rvalue {
+ $$ = $1;
} |
'{' lvalue_concat_list '}' {
$$ = $2;
@@ -894,6 +902,9 @@ expr:
};
basic_expr:
+ rvalue {
+ $$ = $1;
+ } |
TOK_CONST {
$$ = const2ast(*$1, case_type_stack.size() == 0 ? 0 : case_type_stack.back());
delete $1;
@@ -913,11 +924,6 @@ basic_expr:
$$->str = str;
delete $1;
} |
- TOK_ID range {
- $$ = new AstNode(AST_IDENTIFIER, $2);
- $$->str = *$1;
- delete $1;
- } |
TOK_ID attr {
AstNode *node = new AstNode(AST_FCALL);
node->str = *$1;