Support for loops with no loop condition.
SystemVerilog makes all of the initialisation, condition, and step components of a for loop optional. We already support this for the initialisation and step components.
This commit is contained in:
parent
5cbdff202e
commit
a204af04a5
17
elaborate.cc
17
elaborate.cc
|
|
@ -5613,7 +5613,7 @@ NetProc* PForeach::elaborate_static_array_(Design*des, NetScope*scope,
|
|||
*
|
||||
* - index variable (name1_) (optional)
|
||||
* - initial value (expr1_) (only if name1_ is present)
|
||||
* - condition expression (cond_)
|
||||
* - condition expression (cond_) (optional)
|
||||
* - step statement (step_) (optional)
|
||||
* - sub-statement (statement_)
|
||||
*
|
||||
|
|
@ -5693,12 +5693,15 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
|
|||
// Elaborate the condition expression. Try to evaluate it too,
|
||||
// in case it is a constant. This is an interesting case
|
||||
// worthy of a warning.
|
||||
NetExpr*ce = elab_and_eval(des, scope, cond_, -1);
|
||||
if (!ce)
|
||||
error_flag = true;
|
||||
if (dynamic_cast<NetEConst*>(ce)) {
|
||||
cerr << get_fileline() << ": warning: condition expression "
|
||||
"of for-loop is constant." << endl;
|
||||
NetExpr*ce = nullptr;
|
||||
if (cond_) {
|
||||
ce = elab_and_eval(des, scope, cond_, -1);
|
||||
if (!ce)
|
||||
error_flag = true;
|
||||
if (dynamic_cast<NetEConst*>(ce)) {
|
||||
cerr << get_fileline() << ": warning: condition expression "
|
||||
"of for-loop is constant." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// Error recovery - if we failed to elaborate any of the loop
|
||||
|
|
|
|||
15
parse.y
15
parse.y
|
|
@ -728,7 +728,7 @@ Module::port_t *module_declare_port(const YYLTYPE&loc, char *id,
|
|||
%type <spec_optional_args> timeskew_fullskew_opt_notifier timeskew_fullskew_opt_event_based_flag
|
||||
%type <spec_optional_args> timeskew_fullskew_opt_remain_active_flag
|
||||
|
||||
%type <expr> assignment_pattern expression expr_mintypmax
|
||||
%type <expr> assignment_pattern expression expression_opt expr_mintypmax
|
||||
%type <expr> expr_primary_or_typename expr_primary
|
||||
%type <expr> class_new dynamic_array_new
|
||||
%type <expr> var_decl_initializer_opt initializer_opt
|
||||
|
|
@ -1754,7 +1754,7 @@ lifetime_opt /* IEEE1800-2005: A.2.1.3 */
|
|||
/* Loop statements are kinds of statements. */
|
||||
|
||||
loop_statement /* IEEE1800-2005: A.6.8 */
|
||||
: K_for '(' lpvalue '=' expression ';' expression ';' for_step_opt ')'
|
||||
: K_for '(' lpvalue '=' expression ';' expression_opt ';' for_step_opt ')'
|
||||
statement_or_null
|
||||
{ PForStatement*tmp = new PForStatement($3, $5, $7, $9, $11);
|
||||
FILE_NAME(tmp, @1);
|
||||
|
|
@ -1762,7 +1762,7 @@ loop_statement /* IEEE1800-2005: A.6.8 */
|
|||
}
|
||||
|
||||
// The initialization statement is optional.
|
||||
| K_for '(' ';' expression ';' for_step_opt ')'
|
||||
| K_for '(' ';' expression_opt ';' for_step_opt ')'
|
||||
statement_or_null
|
||||
{ PForStatement*tmp = new PForStatement(nullptr, nullptr, $4, $6, $8);
|
||||
FILE_NAME(tmp, @1);
|
||||
|
|
@ -1773,7 +1773,7 @@ loop_statement /* IEEE1800-2005: A.6.8 */
|
|||
// statement in a synthetic named block. We can name the block
|
||||
// after the variable that we are creating, that identifier is
|
||||
// safe in the controlling scope.
|
||||
| K_for '(' K_var_opt data_type IDENTIFIER '=' expression ';' expression ';' for_step_opt ')'
|
||||
| K_for '(' K_var_opt data_type IDENTIFIER '=' expression ';' expression_opt ';' for_step_opt ')'
|
||||
{ static unsigned for_counter = 0;
|
||||
char for_block_name [64];
|
||||
snprintf(for_block_name, sizeof for_block_name, "$ivl_for_loop%u", for_counter);
|
||||
|
|
@ -1858,7 +1858,7 @@ loop_statement /* IEEE1800-2005: A.6.8 */
|
|||
|
||||
/* Error forms for loop statements. */
|
||||
|
||||
| K_for '(' lpvalue '=' expression ';' expression ';' error ')'
|
||||
| K_for '(' lpvalue '=' expression ';' expression_opt ';' error ')'
|
||||
statement_or_null
|
||||
{ $$ = 0;
|
||||
yyerror(@1, "error: Error in for loop step assignment.");
|
||||
|
|
@ -3682,6 +3682,11 @@ expression
|
|||
}
|
||||
;
|
||||
|
||||
expression_opt
|
||||
: expression { $$ = $1; }
|
||||
| { $$ = nullptr; }
|
||||
;
|
||||
|
||||
expr_mintypmax
|
||||
: expression
|
||||
{ $$ = $1; }
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2000-2021 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2024 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2016 CERN Michele Castellana (michele.castellana@cern.ch)
|
||||
*
|
||||
|
|
@ -2822,7 +2822,6 @@ extern "C" ivl_expr_t ivl_stmt_cond_expr(ivl_statement_t net)
|
|||
return net->u_.while_.cond_;
|
||||
|
||||
case IVL_ST_FORLOOP:
|
||||
assert(net->u_.forloop_.condition); // XXXX
|
||||
return net->u_.forloop_.condition;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -121,10 +121,12 @@ int show_stmt_forloop(ivl_statement_t net, ivl_scope_t scope)
|
|||
|
||||
/* Top of the loop, draw the condition test. */
|
||||
fprintf(vvp_out, "T_%u.%u ; Top of for-loop\n", thread_count, top_label);
|
||||
int use_flag = draw_eval_condition(ivl_stmt_cond_expr(net));
|
||||
fprintf(vvp_out, " %%jmp/0xz T_%u.%u, %d;\n",
|
||||
thread_count, out_label, use_flag);
|
||||
clr_flag(use_flag);
|
||||
if (ivl_stmt_cond_expr(net)) {
|
||||
int use_flag = draw_eval_condition(ivl_stmt_cond_expr(net));
|
||||
fprintf(vvp_out, " %%jmp/0xz T_%u.%u, %d;\n",
|
||||
thread_count, out_label, use_flag);
|
||||
clr_flag(use_flag);
|
||||
}
|
||||
|
||||
/* Draw the body of the loop. */
|
||||
rc += show_statement(ivl_stmt_sub_stmt(net), scope);
|
||||
|
|
|
|||
Loading…
Reference in New Issue