关闭 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实现同样功能时综合结构相同