Merge pull request #937 from larsclausen/continue-break-const-func

Support continue/break in constant functions
This commit is contained in:
Cary R 2023-06-11 09:38:31 -07:00 committed by GitHub
commit 3780cb2da2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 294 additions and 1 deletions

View File

@ -0,0 +1,39 @@
// Check that break and continue are supported in constant functions in for
// loops
module test;
function automatic integer f1(integer x);
integer j = 0;
for (integer i = 0; i < 10; i++) begin
if (i >= x) begin
break;
end
j++;
end
return j;
endfunction
function automatic integer f2(integer x);
integer j = 0;
for (integer i = 0; i < x; i++) begin
if (i % 2 == 0) begin
continue;
end
j++;
end
return j;
endfunction
reg [f1(3):0] x;
reg [f2(6):0] y;
initial begin
if ($bits(x) === 4 && $bits(y) === 4) begin
$display("PASSED");
end else begin
$display("FAILED");
end
end
endmodule

View File

@ -0,0 +1,43 @@
// Check that break and continue are supported in constant functions in while
// loops
module test;
function automatic integer f1(integer x);
integer j = 0;
integer i = 0;
while (i < 10) begin
if (i >= x) begin
break;
end
j++;
i++;
end
return j;
endfunction
function automatic integer f2(integer x);
integer j = 0;
integer i = 0;
while (i < x) begin
i++;
if (i % 2 == 0) begin
continue;
end
j++;
end
return j;
endfunction
reg [f1(3):0] x;
reg [f2(6):0] y;
initial begin
if ($bits(x) === 4 && $bits(y) === 4) begin
$display("PASSED");
end else begin
$display("FAILED");
end
end
endmodule

View File

@ -0,0 +1,41 @@
// Check that break and continue are supported in constant functions in repeat
// loops
module test;
function automatic integer f1(integer x);
integer j = 0;
repeat(10) begin
if (j >= x) begin
break;
end
j++;
end
return j;
endfunction
function automatic integer f2(integer x);
integer j = 0;
integer i = 0;
repeat(x) begin
i++;
if (i % 2 == 0) begin
continue;
end
j++;
end
return j;
endfunction
reg [f1(3):0] x;
reg [f2(6):0] y;
initial begin
if ($bits(x) === 4 && $bits(y) === 4) begin
$display("PASSED");
end else begin
$display("FAILED");
end
end
endmodule

View File

@ -0,0 +1,43 @@
// Check that break and continue are supported in constant functions in do-while
// loops
module test;
function automatic integer f1(integer x);
integer j = 0;
integer i = 0;
do begin
if (i >= x) begin
break;
end
j++;
i++;
end while (i < 10);
return j;
endfunction
function automatic integer f2(integer x);
integer j = 0;
integer i = 0;
do begin
i++;
if (i % 2 == 0) begin
continue;
end
j++;
end while (i < x);
return j;
endfunction
reg [f1(3):0] x;
reg [f2(6):0] y;
initial begin
if ($bits(x) === 4 && $bits(y) === 4) begin
$display("PASSED");
end else begin
$display("FAILED");
end
end
endmodule

View File

@ -0,0 +1,32 @@
// Check that break and continue are supported in constant functions in forever
// loops
module test;
function automatic integer f(integer x);
integer j = 0;
integer i = 0;
forever begin
i++;
if (i == x) begin
break;
end
if (i % 2 == 0) begin
continue;
end
j++;
end
return j;
endfunction
reg [f(10):0] x;
initial begin
if ($bits(x) === 6) begin
$display("PASSED");
end else begin
$display("FAILED");
end
end
endmodule

View File

@ -10,6 +10,11 @@ case2 vvp_tests/case2.json
case2-S vvp_tests/case2-S.json
case3 vvp_tests/case3.json
casex_synth vvp_tests/casex_synth.json
constfunc16 vvp_tests/constfunc16.json
constfunc17 vvp_tests/constfunc17.json
constfunc18 vvp_tests/constfunc18.json
constfunc19 vvp_tests/constfunc19.json
constfunc20 vvp_tests/constfunc20.json
dffsynth vvp_tests/dffsynth.json
dffsynth-S vvp_tests/dffsynth-S.json
dffsynth2 vvp_tests/dffsynth2.json

View File

@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "constfunc16.v",
"iverilog-args" : [ "-g2009" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "constfunc17.v",
"iverilog-args" : [ "-g2009" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "constfunc18.v",
"iverilog-args" : [ "-g2009" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "constfunc19.v",
"iverilog-args" : [ "-g2009" ]
}

View File

@ -0,0 +1,5 @@
{
"type" : "normal",
"source" : "constfunc20.v",
"iverilog-args" : [ "-g2009" ]
}

View File

@ -32,6 +32,8 @@ using namespace std;
* to the target block.
*/
static const NetScope*disable = 0;
static bool loop_break;
static bool loop_continue;
static NetExpr* fix_assign_value(const NetNet*lhs, NetExpr*rhs)
{
@ -534,7 +536,7 @@ bool NetBlock::evaluate_function(const LineInfo&loc,
bool cur_flag = cur->evaluate_function(loc, use_context_map);
flag = flag && cur_flag;
} while (cur != last_ && !disable);
} while (cur != last_ && !disable && !loop_break && !loop_continue);
if (debug_eval_tree) {
cerr << get_fileline() << ": NetBlock::evaluate_function: "
@ -710,6 +712,30 @@ bool NetDisable::evaluate_function(const LineInfo&,
return true;
}
bool NetBreak::evaluate_function(const LineInfo&,
map<perm_string, LocalVar>&) const
{
loop_break = true;
if (debug_eval_tree) {
cerr << get_fileline() << ": NetBreak::evaluate_function" << endl;
}
return true;
}
bool NetContinue::evaluate_function(const LineInfo&,
map<perm_string, LocalVar>&) const
{
loop_continue = true;
if (debug_eval_tree) {
cerr << get_fileline() << ": NetContinue::evaluate_function" << endl;
}
return true;
}
bool NetDoWhile::evaluate_function(const LineInfo&loc,
map<perm_string,LocalVar>&context_map) const
{
@ -726,6 +752,13 @@ bool NetDoWhile::evaluate_function(const LineInfo&loc,
if (! flag)
break;
if (loop_break) {
loop_break = false;
break;
}
loop_continue = false;
// Evaluate the condition expression to try and get the
// condition for the loop.
NetExpr*cond = cond_->evaluate_function(loc, context_map);
@ -765,6 +798,13 @@ bool NetForever::evaluate_function(const LineInfo&loc,
while (flag && !disable) {
flag = flag && statement_->evaluate_function(loc, context_map);
if (loop_break) {
loop_break = false;
break;
}
loop_continue = false;
}
if (debug_eval_tree) {
@ -818,6 +858,13 @@ bool NetForLoop::evaluate_function(const LineInfo&loc,
if (disable)
break;
if (loop_break) {
loop_break = false;
break;
}
loop_continue = false;
tmp_flag = step_statement_->evaluate_function(loc, context_map);
flag &= tmp_flag;
}
@ -854,6 +901,13 @@ bool NetRepeat::evaluate_function(const LineInfo&loc,
while ((count > 0) && flag && !disable) {
flag = flag && statement_->evaluate_function(loc, context_map);
count -= 1;
if (loop_break) {
loop_break = false;
break;
}
loop_continue = false;
}
if (debug_eval_tree) {
@ -905,6 +959,13 @@ bool NetWhile::evaluate_function(const LineInfo&loc,
bool tmp_flag = proc_->evaluate_function(loc, context_map);
if (! tmp_flag)
flag = false;
if (loop_break) {
loop_break = false;
break;
}
loop_continue = false;
}
if (debug_eval_tree) {

View File

@ -3068,6 +3068,8 @@ class NetBreak : public NetProc {
public:
virtual void dump(std::ostream&, unsigned ind) const;
virtual bool emit_proc(struct target_t*) const;
bool evaluate_function(const LineInfo &loc,
std::map<perm_string,LocalVar> &ctx) const final;
};
/*
@ -3222,6 +3224,8 @@ class NetContinue : public NetProc {
public:
virtual void dump(std::ostream&, unsigned ind) const;
virtual bool emit_proc(struct target_t*) const;
bool evaluate_function(const LineInfo &loc,
std::map<perm_string,LocalVar> &ctx) const final;
};
/*