aboutsummaryrefslogtreecommitdiffstats
path: root/frontends/verilog/verilog_parser.y
diff options
context:
space:
mode:
Diffstat (limited to 'frontends/verilog/verilog_parser.y')
-rw-r--r--frontends/verilog/verilog_parser.y104
1 files changed, 63 insertions, 41 deletions
diff --git a/frontends/verilog/verilog_parser.y b/frontends/verilog/verilog_parser.y
index 8bd58d24c..dc7ec8348 100644
--- a/frontends/verilog/verilog_parser.y
+++ b/frontends/verilog/verilog_parser.y
@@ -277,7 +277,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode)
%token TOK_SUPPLY0 TOK_SUPPLY1 TOK_TO_SIGNED TOK_TO_UNSIGNED
%token TOK_POS_INDEXED TOK_NEG_INDEXED TOK_PROPERTY TOK_ENUM TOK_TYPEDEF
%token TOK_RAND TOK_CONST TOK_CHECKER TOK_ENDCHECKER TOK_EVENTUALLY
-%token TOK_INCREMENT TOK_DECREMENT TOK_UNIQUE TOK_PRIORITY
+%token TOK_INCREMENT TOK_DECREMENT TOK_UNIQUE TOK_UNIQUE0 TOK_PRIORITY
%token TOK_STRUCT TOK_PACKED TOK_UNSIGNED TOK_INT TOK_BYTE TOK_SHORTINT TOK_UNION
%token TOK_OR_ASSIGN TOK_XOR_ASSIGN TOK_AND_ASSIGN TOK_SUB_ASSIGN
@@ -286,7 +286,7 @@ static void rewriteAsMemoryNode(AstNode *node, AstNode *rangeNode)
%type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id hierarchical_type_id integral_number
%type <string> type_name
%type <ast> opt_enum_init enum_type struct_type non_wire_data_type
-%type <boolean> opt_signed opt_property unique_case_attr always_comb_or_latch always_or_always_ff
+%type <boolean> opt_signed opt_property always_comb_or_latch always_or_always_ff
%type <al> attr case_attr
%type <ast> struct_union
@@ -609,12 +609,17 @@ interface_body_stmt:
param_decl | localparam_decl | typedef_decl | defparam_decl | wire_decl | always_stmt | assign_stmt |
modport_stmt;
+mintypmax_expr:
+ expr { delete $1; } |
+ expr ':' expr ':' expr { delete $1; delete $3; delete $5; };
+
non_opt_delay:
'#' TOK_ID { delete $2; } |
'#' TOK_CONSTVAL { delete $2; } |
'#' TOK_REALVAL { delete $2; } |
- '#' '(' expr ')' { delete $3; } |
- '#' '(' expr ':' expr ':' expr ')' { delete $3; delete $5; delete $7; };
+ '#' '(' mintypmax_expr ')' |
+ '#' '(' mintypmax_expr ',' mintypmax_expr ')' |
+ '#' '(' mintypmax_expr ',' mintypmax_expr ',' mintypmax_expr ')';
delay:
non_opt_delay | %empty;
@@ -770,6 +775,7 @@ module_body:
module_body module_body_stmt |
/* the following line makes the generate..endgenrate keywords optional */
module_body gen_stmt |
+ module_body gen_block |
module_body ';' |
%empty;
@@ -1490,10 +1496,10 @@ enum_base_type: type_atom type_signing
| %empty { astbuf1->is_reg = true; addRange(astbuf1); }
;
-type_atom: TOK_INTEGER { astbuf1->is_reg = true; addRange(astbuf1); } // 4-state signed
- | TOK_INT { astbuf1->is_reg = true; addRange(astbuf1); } // 2-state signed
- | TOK_SHORTINT { astbuf1->is_reg = true; addRange(astbuf1, 15, 0); } // 2-state signed
- | TOK_BYTE { astbuf1->is_reg = true; addRange(astbuf1, 7, 0); } // 2-state signed
+type_atom: TOK_INTEGER { astbuf1->is_reg = true; astbuf1->is_signed = true; addRange(astbuf1); } // 4-state signed
+ | TOK_INT { astbuf1->is_reg = true; astbuf1->is_signed = true; addRange(astbuf1); } // 2-state signed
+ | TOK_SHORTINT { astbuf1->is_reg = true; astbuf1->is_signed = true; addRange(astbuf1, 15, 0); } // 2-state signed
+ | TOK_BYTE { astbuf1->is_reg = true; astbuf1->is_signed = true; addRange(astbuf1, 7, 0); } // 2-state signed
;
type_vec: TOK_REG { astbuf1->is_reg = true; } // unsigned
@@ -1783,7 +1789,13 @@ wire_name:
}
rewriteAsMemoryNode(node, $2);
}
- if (current_function_or_task == NULL) {
+ if (current_function_or_task) {
+ if (node->is_input || node->is_output)
+ node->port_id = current_function_or_task_port_id++;
+ } else if (ast_stack.back()->type == AST_GENBLOCK) {
+ if (node->is_input || node->is_output)
+ frontend_verilog_yyerror("Cannot declare module port `%s' within a generate block.", $1->c_str());
+ } else {
if (do_not_require_port_stubs && (node->is_input || node->is_output) && port_stubs.count(*$1) == 0) {
port_stubs[*$1] = ++port_counter;
}
@@ -1798,9 +1810,6 @@ wire_name:
if (node->is_input || node->is_output)
frontend_verilog_yyerror("Module port `%s' is not declared in module header.", $1->c_str());
}
- } else {
- if (node->is_input || node->is_output)
- node->port_id = current_function_or_task_port_id++;
}
//FIXME: for some reason, TOK_ID has a location which always points to one column *after* the real last column...
SET_AST_NODE_LOC(node, @1, @1);
@@ -2459,6 +2468,16 @@ behavioral_stmt:
exitTypeScope();
if ($4 != NULL && $8 != NULL && *$4 != *$8)
frontend_verilog_yyerror("Begin label (%s) and end label (%s) don't match.", $4->c_str()+1, $8->c_str()+1);
+ AstNode *node = ast_stack.back();
+ // In SystemVerilog, unnamed blocks with block item declarations
+ // create an implicit hierarchy scope
+ if (sv_mode && node->str.empty())
+ for (const AstNode* child : node->children)
+ if (child->type == AST_WIRE || child->type == AST_MEMORY || child->type == AST_PARAMETER
+ || child->type == AST_LOCALPARAM || child->type == AST_TYPEDEF) {
+ node->str = "$unnamed_block$" + std::to_string(autoidx++);
+ break;
+ }
SET_AST_NODE_LOC(ast_stack.back(), @2, @8);
delete $4;
delete $8;
@@ -2473,6 +2492,7 @@ behavioral_stmt:
ast_stack.back()->children.push_back($7);
} ';' simple_behavioral_stmt ')' {
AstNode *block = new AstNode(AST_BLOCK);
+ block->str = "$for_loop$" + std::to_string(autoidx++);
ast_stack.back()->children.push_back(block);
ast_stack.push_back(block);
} behavioral_stmt {
@@ -2539,20 +2559,21 @@ behavioral_stmt:
ast_stack.pop_back();
};
-unique_case_attr:
- %empty {
- $$ = false;
+case_attr:
+ attr {
+ $$ = $1;
} |
- TOK_PRIORITY case_attr {
- $$ = $2;
+ attr TOK_UNIQUE0 {
+ (*$1)[ID::parallel_case] = AstNode::mkconst_int(1, false);
+ $$ = $1;
} |
- TOK_UNIQUE case_attr {
- $$ = true;
- };
-
-case_attr:
- attr unique_case_attr {
- if ($2) (*$1)[ID::parallel_case] = AstNode::mkconst_int(1, false);
+ attr TOK_PRIORITY {
+ (*$1)[ID::full_case] = AstNode::mkconst_int(1, false);
+ $$ = $1;
+ } |
+ attr TOK_UNIQUE {
+ (*$1)[ID::full_case] = AstNode::mkconst_int(1, false);
+ (*$1)[ID::parallel_case] = AstNode::mkconst_int(1, false);
$$ = $1;
};
@@ -2722,6 +2743,7 @@ single_arg:
module_gen_body:
module_gen_body gen_stmt_or_module_body_stmt |
+ module_gen_body gen_block |
%empty;
gen_stmt_or_module_body_stmt:
@@ -2747,12 +2769,7 @@ gen_stmt:
ast_stack.back()->children.push_back(node);
ast_stack.push_back(node);
ast_stack.back()->children.push_back($3);
- AstNode *block = new AstNode(AST_GENBLOCK);
- ast_stack.back()->children.push_back(block);
- ast_stack.push_back(block);
- } gen_stmt_block {
- ast_stack.pop_back();
- } opt_gen_else {
+ } gen_stmt_block opt_gen_else {
SET_AST_NODE_LOC(ast_stack.back(), @1, @7);
ast_stack.pop_back();
} |
@@ -2765,6 +2782,18 @@ gen_stmt:
SET_AST_NODE_LOC(ast_stack.back(), @1, @7);
ast_stack.pop_back();
} |
+ TOK_MSG_TASKS {
+ AstNode *node = new AstNode(AST_TECALL);
+ node->str = *$1;
+ delete $1;
+ ast_stack.back()->children.push_back(node);
+ ast_stack.push_back(node);
+ } opt_arg_list ';'{
+ SET_AST_NODE_LOC(ast_stack.back(), @1, @3);
+ ast_stack.pop_back();
+ };
+
+gen_block:
TOK_BEGIN {
enterTypeScope();
} opt_label {
@@ -2774,22 +2803,15 @@ gen_stmt:
ast_stack.push_back(node);
} module_gen_body TOK_END opt_label {
exitTypeScope();
+ if ($3 != NULL && $7 != NULL && *$3 != *$7)
+ frontend_verilog_yyerror("Begin label (%s) and end label (%s) don't match.", $3->c_str()+1, $7->c_str()+1);
delete $3;
delete $7;
SET_AST_NODE_LOC(ast_stack.back(), @1, @7);
ast_stack.pop_back();
- } |
- TOK_MSG_TASKS {
- AstNode *node = new AstNode(AST_TECALL);
- node->str = *$1;
- delete $1;
- ast_stack.back()->children.push_back(node);
- ast_stack.push_back(node);
- } opt_arg_list ';'{
- SET_AST_NODE_LOC(ast_stack.back(), @1, @3);
- ast_stack.pop_back();
};
+// result is wrapped in a genblock only if necessary
gen_stmt_block:
{
AstNode *node = new AstNode(AST_GENBLOCK);
@@ -2798,7 +2820,7 @@ gen_stmt_block:
} gen_stmt_or_module_body_stmt {
SET_AST_NODE_LOC(ast_stack.back(), @2, @2);
ast_stack.pop_back();
- };
+ } | gen_block;
opt_gen_else:
TOK_ELSE gen_stmt_block | %empty %prec FAKE_THEN;