Added support for verilog genblock[index].member syntax
authorClifford Wolf <clifford@clifford.at>
Tue, 26 Feb 2013 12:18:22 +0000 (13:18 +0100)
committerClifford Wolf <clifford@clifford.at>
Tue, 26 Feb 2013 12:18:22 +0000 (13:18 +0100)
frontends/ast/ast.cc
frontends/ast/ast.h
frontends/ast/simplify.cc
frontends/verilog/parser.y

index 160e9c4295d3c2b4410cdf4eef1c1539a80901cb..e5db5a94b0575f10e761ba752a2ce66c9598a46a 100644 (file)
@@ -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)
index f7c9328c28853cfc1aca20f480071747c6e1eede..cdc56fba467c8ea93ea1a749e6ea8bf4ed5e8605 100644 (file)
@@ -56,6 +56,7 @@ namespace AST
                AST_CONSTANT,
                AST_CELLTYPE,
                AST_IDENTIFIER,
+               AST_PREFIX,
 
                AST_FCALL,
                AST_TO_SIGNED,
index cb8b1043f2f95220e0c17ce231f53676368d8670..33776d6550c44376daeda965836484f44d5d454e 100644 (file)
@@ -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;
index 010af478775a2b4590f89eacde689bb4fe47c275..6e0b238e0af96614f37e9fb5020e21c75873d9fd 100644 (file)
@@ -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;