关闭 fork join 某个子进程:
- fork…join:内部所有线程同时开始运行,直到内部所有线程运行完毕后才跳出fork…join块
- fork…join_any:内部所有线程同时开始运行,只要有一个线程运行结束就跳出 fork…join_any块。当跳
出fork…join_any块后,fork里没完的线程和块外的线程并行运行- fork…join_none:运行开始后,里面的子线程和块外的线程并行运行
-
如何关闭 fork 里某个子进程?
disable :用于在多进程的场景终止一个或多个进程
-
disable语句可以用在task或者块中去终止指定的task或块,包括终止disable语句所在的块或者task。
-
disable也可以用在function中去终止task或者块,但不能用于终止function。
-
当在function中用dsiable语句终止了一个task或者块,而这个task或者块刚好又是这个function的caller,这种情况的结果是未知的。
通常会这么写fork:
// disable + 块名 终止子进程
fork
begin: block_0
$display("block_0 start");
disable block_0;
$display("block_0 finish"); // 该句将不会执行
end
begin: block_1
......
end
join/join_none/join_any/
方法:给每个begin end块起个名字,然后就可以在该begin end中关闭该子进程
// disable 关闭task
// 用于在task中提前跳出task
task proc_a;
begin
...
...
if (a == 0)
disable proc_a; // return if true
...
...
end
endtask
关闭 fork join 全部子进程:
disable fork :终止当前进程未执行的所有子进程,包括所有子孙后代进程
如果是fork...join_none后接disable fork,里面的线程会全部被杀掉
// disable fork :终止当前进程的所有子进程,包括所有子孙后代进程
task get_first( output int adr );
fork
wait_device( 1, adr );
wait_device( 7, adr );
wait_device( 13, adr );
join_any
disable fork;
endtask
// disable fork :终止当前进程的所有子进程,包括所有子孙后代进程
task get_first( output int adr );
fork: p1
wait_device( 1, adr );
wait_device( 7, adr );
wait_device( 13, adr );
join_any
disable p1;
endtask
wait fork 等待所有子进程执行完毕:
wait fork :等待当前进程所有子进程,但不包括子进程的子进程,执行完后才会往下执行。
wait fork
- wait fork 会引起调用进程阻塞,直到它的所有子进程结束
- wait fork 目的是用来确保所有子进程执行结束
- wait fork 作用父进程下的子进程,而不包括子进程下的子进程
// do_test 需要等到 exec1...exec4 等4个子进程全部返回后才会返回到 do_test 的 caller
task do_test;
fork
exec1();
exec2();
join_any
fork
exec3();
exec4();
join_none
wait fork; // 等 exec1...exec4 等4个子进程执行完
endtask
SV 的 break continue return跳转
system verilog增加了类似C语言的跳转声明:break,continue和return,system verilog不包含C语言中的goto语句
disable声明适用于所有现行的task或者block的invocation,然而break,continue和return只适用于当前的执行流程
continue
logic [15:0] array [0:255];
always_comb begin
for (int i = 0; i <= 255; i++) begin : loop
if (array[i] == 0)
continue; // skip empty elements
transform_function(array[i]);
end // end of loop
end
break
system verilog中的break声明与C语言中的break语句用法相同。
C语音也会使用break语句从switch语句中退出。而system verilog不会使用break声明从case语句中离开,因为verilog中case声明会在某个分支执行后自动退出,不需要break语句。
// find first bit set within a range of bits
always_comb begin
first_bit = 0;
for (int i=0; i<=63; i=i+1) begin
if (i < start_range) continue;
if (i > end_range) break; // exit loop
if ( data[i] ) begin
first_bit = i;
break; // exit loop
end
end // end of the loop
... // process data based on first bit set
end
return
return声明可以用来从 任务 或 函数 提前退出
verilog中disable声明只能从 任务 中提前退出,而不能用在函数中
// return 从 任务 提前退出
task add_up_to_max (input [ 5:0] max, output [63:0] result);
result = 1;
if (max == 0)
return; // exit task
for (int i=1; i<=63; i=i+1) begin
result = result + result;
if (i == max)
return; // exit task
end
endtask
// return从 任务 函数 提前退出
function automatic int log2 (input int n);
if (n <=1)
return 1; // exit function early
log2 = 0;
while (n > 1) begin
n = n/2;
log2++;
end
return log2;
endfunction
注意在任务或者void函数中,return关键字后不能跟随表达式;
在非void函数中,return关键字后必须跟随表达式
break,continue和return跳转声明是可综合的结构。综合结果与verilog中使用disable实现同样功能时综合结构相同