System Verilog tasks can have multiple statements.

The begin/end block that wraps the statements can be implicit.
This commit is contained in:
Stephen Williams 2011-11-06 10:07:43 -08:00
parent fc44658dad
commit aa662e1ae1
1 changed files with 45 additions and 7 deletions

52
parse.y
View File

@ -253,6 +253,19 @@ static long check_enum_seq_value(const YYLTYPE&loc, verinum *arg, bool zero_ok)
return value; return value;
} }
static void current_task_set_statement(vector<Statement*>*s)
{
assert(s && s->size() > 0);
if (s->size() == 1) {
current_task->set_statement((*s)[0]);
return;
}
PBlock*tmp = new PBlock(PBlock::BL_SEQ);
tmp->set_statement(*s);
current_task->set_statement(tmp);
}
%} %}
%union { %union {
@ -491,7 +504,7 @@ static long check_enum_seq_value(const YYLTYPE&loc, verinum *arg, bool zero_ok)
%type <event_expr> event_expression %type <event_expr> event_expression
%type <event_statement> event_control %type <event_statement> event_control
%type <statement> statement statement_or_null compressed_statement %type <statement> statement statement_or_null compressed_statement
%type <statement_list> statement_list %type <statement_list> statement_list statement_or_null_list
%type <statement> analog_statement %type <statement> analog_statement
@ -2835,13 +2848,17 @@ module_item
current_task = pform_push_task_scope(@1, $3, $2); current_task = pform_push_task_scope(@1, $3, $2);
} }
task_item_list_opt task_item_list_opt
statement_or_null statement_or_null_list
K_endtask K_endtask
{ current_task->set_ports($6); { current_task->set_ports($6);
current_task->set_statement($7); current_task_set_statement($7);
pform_pop_scope(); pform_pop_scope();
current_task = 0; current_task = 0;
delete[]$3; delete[]$3;
if ($7->size() > 1 && !gn_system_verilog()) {
yyerror(@7, "error: Task body with multiple statements requres SystemVerilog.");
}
delete $7;
} }
| K_task automatic_opt IDENTIFIER '(' | K_task automatic_opt IDENTIFIER '('
@ -2850,13 +2867,17 @@ module_item
} }
task_port_decl_list ')' ';' task_port_decl_list ')' ';'
block_item_decls_opt block_item_decls_opt
statement_or_null statement_or_null_list
K_endtask K_endtask
{ current_task->set_ports($6); { current_task->set_ports($6);
current_task->set_statement($10); current_task_set_statement($10);
pform_pop_scope(); pform_pop_scope();
current_task = 0; current_task = 0;
delete[]$3; delete[]$3;
if ($10->size() > 1 && !gn_system_verilog()) {
yyerror(@10, "error: Task body with multiple statements requres SystemVerilog.");
}
delete $10;
} }
| K_task automatic_opt IDENTIFIER '(' ')' ';' | K_task automatic_opt IDENTIFIER '(' ')' ';'
@ -2864,15 +2885,19 @@ module_item
current_task = pform_push_task_scope(@1, $3, $2); current_task = pform_push_task_scope(@1, $3, $2);
} }
block_item_decls_opt block_item_decls_opt
statement_or_null statement_or_null_list
K_endtask K_endtask
{ current_task->set_ports(0); { current_task->set_ports(0);
current_task->set_statement($9); current_task_set_statement($9);
pform_pop_scope(); pform_pop_scope();
current_task = 0; current_task = 0;
cerr << @3 << ": warning: task definition for \"" << $3 cerr << @3 << ": warning: task definition for \"" << $3
<< "\" has an empty port declaration list!" << endl; << "\" has an empty port declaration list!" << endl;
delete[]$3; delete[]$3;
if ($9->size() > 1 && !gn_system_verilog()) {
yyerror(@9, "error: Task body with multiple statements requres SystemVerilog.");
}
delete $9;
} }
| K_task automatic_opt IDENTIFIER error K_endtask | K_task automatic_opt IDENTIFIER error K_endtask
@ -4672,6 +4697,19 @@ statement_or_null
{ $$ = 0; } { $$ = 0; }
; ;
statement_or_null_list
: statement_or_null_list statement_or_null
{ vector<Statement*>*tmp = $1;
tmp->push_back($2);
$$ = tmp;
}
| statement_or_null
{ vector<Statement*>*tmp = new vector<Statement*>(1);
tmp->at(0) = $1;
$$ = tmp;
}
;
analog_statement analog_statement
: branch_probe_expression K_CONTRIBUTE expression ';' : branch_probe_expression K_CONTRIBUTE expression ';'
{ $$ = pform_contribution_statement(@2, $1, $3); } { $$ = pform_contribution_statement(@2, $1, $3); }