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
|
|
@ -5613,7 +5613,7 @@ NetProc* PForeach::elaborate_static_array_(Design*des, NetScope*scope,
|
||||||
*
|
*
|
||||||
* - index variable (name1_) (optional)
|
* - index variable (name1_) (optional)
|
||||||
* - initial value (expr1_) (only if name1_ is present)
|
* - initial value (expr1_) (only if name1_ is present)
|
||||||
* - condition expression (cond_)
|
* - condition expression (cond_) (optional)
|
||||||
* - step statement (step_) (optional)
|
* - step statement (step_) (optional)
|
||||||
* - sub-statement (statement_)
|
* - sub-statement (statement_)
|
||||||
*
|
*
|
||||||
|
|
@ -5693,13 +5693,16 @@ NetProc* PForStatement::elaborate(Design*des, NetScope*scope) const
|
||||||
// Elaborate the condition expression. Try to evaluate it too,
|
// Elaborate the condition expression. Try to evaluate it too,
|
||||||
// in case it is a constant. This is an interesting case
|
// in case it is a constant. This is an interesting case
|
||||||
// worthy of a warning.
|
// worthy of a warning.
|
||||||
NetExpr*ce = elab_and_eval(des, scope, cond_, -1);
|
NetExpr*ce = nullptr;
|
||||||
|
if (cond_) {
|
||||||
|
ce = elab_and_eval(des, scope, cond_, -1);
|
||||||
if (!ce)
|
if (!ce)
|
||||||
error_flag = true;
|
error_flag = true;
|
||||||
if (dynamic_cast<NetEConst*>(ce)) {
|
if (dynamic_cast<NetEConst*>(ce)) {
|
||||||
cerr << get_fileline() << ": warning: condition expression "
|
cerr << get_fileline() << ": warning: condition expression "
|
||||||
"of for-loop is constant." << endl;
|
"of for-loop is constant." << endl;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Error recovery - if we failed to elaborate any of the loop
|
// Error recovery - if we failed to elaborate any of the loop
|
||||||
// expressions, give up now. Error counts where handled elsewhere.
|
// expressions, give up now. Error counts where handled elsewhere.
|
||||||
|
|
|
||||||
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_notifier timeskew_fullskew_opt_event_based_flag
|
||||||
%type <spec_optional_args> timeskew_fullskew_opt_remain_active_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> expr_primary_or_typename expr_primary
|
||||||
%type <expr> class_new dynamic_array_new
|
%type <expr> class_new dynamic_array_new
|
||||||
%type <expr> var_decl_initializer_opt initializer_opt
|
%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 statements are kinds of statements. */
|
||||||
|
|
||||||
loop_statement /* IEEE1800-2005: A.6.8 */
|
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
|
statement_or_null
|
||||||
{ PForStatement*tmp = new PForStatement($3, $5, $7, $9, $11);
|
{ PForStatement*tmp = new PForStatement($3, $5, $7, $9, $11);
|
||||||
FILE_NAME(tmp, @1);
|
FILE_NAME(tmp, @1);
|
||||||
|
|
@ -1762,7 +1762,7 @@ loop_statement /* IEEE1800-2005: A.6.8 */
|
||||||
}
|
}
|
||||||
|
|
||||||
// The initialization statement is optional.
|
// The initialization statement is optional.
|
||||||
| K_for '(' ';' expression ';' for_step_opt ')'
|
| K_for '(' ';' expression_opt ';' for_step_opt ')'
|
||||||
statement_or_null
|
statement_or_null
|
||||||
{ PForStatement*tmp = new PForStatement(nullptr, nullptr, $4, $6, $8);
|
{ PForStatement*tmp = new PForStatement(nullptr, nullptr, $4, $6, $8);
|
||||||
FILE_NAME(tmp, @1);
|
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
|
// statement in a synthetic named block. We can name the block
|
||||||
// after the variable that we are creating, that identifier is
|
// after the variable that we are creating, that identifier is
|
||||||
// safe in the controlling scope.
|
// 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;
|
{ static unsigned for_counter = 0;
|
||||||
char for_block_name [64];
|
char for_block_name [64];
|
||||||
snprintf(for_block_name, sizeof for_block_name, "$ivl_for_loop%u", for_counter);
|
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. */
|
/* Error forms for loop statements. */
|
||||||
|
|
||||||
| K_for '(' lpvalue '=' expression ';' expression ';' error ')'
|
| K_for '(' lpvalue '=' expression ';' expression_opt ';' error ')'
|
||||||
statement_or_null
|
statement_or_null
|
||||||
{ $$ = 0;
|
{ $$ = 0;
|
||||||
yyerror(@1, "error: Error in for loop step assignment.");
|
yyerror(@1, "error: Error in for loop step assignment.");
|
||||||
|
|
@ -3682,6 +3682,11 @@ expression
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
expression_opt
|
||||||
|
: expression { $$ = $1; }
|
||||||
|
| { $$ = nullptr; }
|
||||||
|
;
|
||||||
|
|
||||||
expr_mintypmax
|
expr_mintypmax
|
||||||
: expression
|
: expression
|
||||||
{ $$ = $1; }
|
{ $$ = $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 CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||||
* Copyright (c) 2016 CERN Michele Castellana (michele.castellana@cern.ch)
|
* 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_;
|
return net->u_.while_.cond_;
|
||||||
|
|
||||||
case IVL_ST_FORLOOP:
|
case IVL_ST_FORLOOP:
|
||||||
assert(net->u_.forloop_.condition); // XXXX
|
|
||||||
return net->u_.forloop_.condition;
|
return net->u_.forloop_.condition;
|
||||||
|
|
||||||
default:
|
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. */
|
/* Top of the loop, draw the condition test. */
|
||||||
fprintf(vvp_out, "T_%u.%u ; Top of for-loop\n", thread_count, top_label);
|
fprintf(vvp_out, "T_%u.%u ; Top of for-loop\n", thread_count, top_label);
|
||||||
|
if (ivl_stmt_cond_expr(net)) {
|
||||||
int use_flag = draw_eval_condition(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",
|
fprintf(vvp_out, " %%jmp/0xz T_%u.%u, %d;\n",
|
||||||
thread_count, out_label, use_flag);
|
thread_count, out_label, use_flag);
|
||||||
clr_flag(use_flag);
|
clr_flag(use_flag);
|
||||||
|
}
|
||||||
|
|
||||||
/* Draw the body of the loop. */
|
/* Draw the body of the loop. */
|
||||||
rc += show_statement(ivl_stmt_sub_stmt(net), scope);
|
rc += show_statement(ivl_stmt_sub_stmt(net), scope);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue