diff --git a/ivtest/ivltests/br_gh191_break.v b/ivtest/ivltests/br_gh191_break.v index 932a4277b..2a876a135 100644 --- a/ivtest/ivltests/br_gh191_break.v +++ b/ivtest/ivltests/br_gh191_break.v @@ -35,6 +35,18 @@ module main; $finish; end + idx = 0; + do begin + if (idx >= 2) + break; + idx += 1; + end while (idx < 5); + + if (idx != 2) begin + $display("FAILED -- break from do-while loop"); + $finish; + end + idx = 0; repeat (5) begin if (idx >= 2) diff --git a/ivtest/ivltests/br_gh191_continue.v b/ivtest/ivltests/br_gh191_continue.v index 3945e017c..a8fd4aa56 100644 --- a/ivtest/ivltests/br_gh191_continue.v +++ b/ivtest/ivltests/br_gh191_continue.v @@ -51,6 +51,21 @@ module main; $finish; end + idx = 0; + do begin + idx += 1; + if (idx < 2) + continue; + if (idx < 2) begin + $display("FAILED -- continue in do-while loop"); + $finish; + end + end while (idx < 5); + if (idx != 5) begin + $display("FAILED -- break from do-while loop"); + $finish; + end + idx = 0; repeat (5) begin idx += 1; diff --git a/tgt-vvp/vvp_priv.h b/tgt-vvp/vvp_priv.h index 6d96a1096..f6857e24f 100644 --- a/tgt-vvp/vvp_priv.h +++ b/tgt-vvp/vvp_priv.h @@ -285,5 +285,6 @@ extern int show_stmt_forever(ivl_statement_t net, ivl_scope_t sscope); extern int show_stmt_forloop(ivl_statement_t net, ivl_scope_t sscope); extern int show_stmt_repeat(ivl_statement_t net, ivl_scope_t sscope); extern int show_stmt_while(ivl_statement_t net, ivl_scope_t sscope); +extern int show_stmt_do_while(ivl_statement_t net, ivl_scope_t sscope); #endif /* IVL_vvp_priv_H */ diff --git a/tgt-vvp/vvp_proc_loops.c b/tgt-vvp/vvp_proc_loops.c index c44f863f9..c5bf5831c 100644 --- a/tgt-vvp/vvp_proc_loops.c +++ b/tgt-vvp/vvp_proc_loops.c @@ -220,3 +220,40 @@ int show_stmt_while(ivl_statement_t net, ivl_scope_t sscope) return rc; } + +int show_stmt_do_while(ivl_statement_t net, ivl_scope_t sscope) +{ + int rc = 0; + + unsigned top_label = local_count++; + unsigned cont_label = local_count++; + unsigned out_label = local_count++; + + unsigned save_break_label, save_continue_label; + PUSH_JUMPS(out_label, cont_label); + + show_stmt_file_line(net, "Do/While statement."); + + /* Start the loop. The top of the loop starts a basic block + because it can be entered from above or from the bottom of + the loop. */ + fprintf(vvp_out, "T_%u.%u ;\n", thread_count, top_label); + + /* Draw the body of the loop. */ + rc += show_statement(ivl_stmt_sub_stmt(net), sscope); + + fprintf(vvp_out, "T_%u.%u ;\n", thread_count, cont_label); + + /* Draw the evaluation of the condition expression, and test + the result. If the expression evaluates to true, then + branch to the top label. */ + int use_flag = draw_eval_condition(ivl_stmt_cond_expr(net)); + fprintf(vvp_out, " %%jmp/1 T_%u.%u, %d;\n", + thread_count, top_label, use_flag); + clr_flag(use_flag); + fprintf(vvp_out, "T_%u.%u ;\n", thread_count, out_label); + + POP_JUMPS; + + return rc; +} diff --git a/tgt-vvp/vvp_process.c b/tgt-vvp/vvp_process.c index 1fe111332..d4389aab7 100644 --- a/tgt-vvp/vvp_process.c +++ b/tgt-vvp/vvp_process.c @@ -1355,33 +1355,6 @@ static int show_stmt_disable(ivl_statement_t net, ivl_scope_t sscope) return rc; } -static int show_stmt_do_while(ivl_statement_t net, ivl_scope_t sscope) -{ - int rc = 0; - - unsigned top_label = local_count++; - - show_stmt_file_line(net, "Do/While statement."); - - /* Start the loop. The top of the loop starts a basic block - because it can be entered from above or from the bottom of - the loop. */ - fprintf(vvp_out, "T_%u.%u ;\n", thread_count, top_label); - - /* Draw the body of the loop. */ - rc += show_statement(ivl_stmt_sub_stmt(net), sscope); - - /* Draw the evaluation of the condition expression, and test - the result. If the expression evaluates to true, then - branch to the top label. */ - int use_flag = draw_eval_condition(ivl_stmt_cond_expr(net)); - fprintf(vvp_out, " %%jmp/1 T_%u.%u, %d;\n", - thread_count, top_label, use_flag); - clr_flag(use_flag); - - return rc; -} - static int show_stmt_force(ivl_statement_t net) { ivl_expr_t rval;