在verilog中,使用disable声明来从执行流程中的某一点跳转到另一点。特别地,disable声明使执行流程跳转到标注名字的声明组末尾,或者一个任务的末尾。
verilog中的disable命令用法有很多,下面是一个简单的例子,解释了disable的作用范围:
1 // find first bit set within a range of bits 2 always @* begin 3 begin: loop 4 integer i; 5 first_bit = 0; 6 for (i=0; i<=63; i=i+1) begin: pass 7 if (i < start_range) 8 disable pass; // continue loop 9 if (i > end_range) 10 disable loop; // break out of loop 11 if ( data[i] ) begin 12 first_bit = i; 13 disable loop; // break out of loop 14 end 15 end // end of one pass of loop 16 end // end of the loop 17 // process data based on first bit set 18 ... 19 end
在begin块和for循环块中加入名字,然后在disable声明中使用,就可以明确指定跳出的位置。
disable声明同样可以用于在task中所有声明执行完之前提前跳出task:
1 task add_up_to_max (input [ 5:0] max, 2 output [63:0] result); 3 integer i; 4 begin 5 result = 1; 6 if (max == 0) 7 disable add_up_to_max; // exit task 8 for (i=1; i<=63; i=i+1) begin 9 result = result + result; 10 if (i == max) 11 disable add_up_to_max; // exit task 12 end 13 end 14 endtask // add_up_to_max
disable声明同样可以用来从外部关闭一个并行的进程或者task。不过外部的disable不可综合。
system verilog增加了类似C语言的跳转声明:break,continue和return。这些跳转声明可以使代码更加intuitive和concise。system verilog不包含C语言中的goto语句。
verilog的disable声明和这些新的跳转声明的一个重要区别是:disable声明适用于所有现行的task或者block的invocation,然而break,continue和return只适用于当前的执行流程。
continue声明
类C语言的continue声明跳转到循环的末尾并执行循环的控制。使用continue声明时,不需要对代码添加命名的begin...end块,而这在使用disable声明时是必要的。
1 logic [15:0] array [0:255]; 2 always_comb begin 3 for (int i = 0; i <= 255; i++) begin : loop 4 if (array[i] == 0) 5 continue; // skip empty elements 6 transform_function(array[i]); 7 end // end of loop 8 end
break声明
类C语言的break声明立即结束循环操作。循环不会重新执行,除非执行流程重新到达循环的起点。break的例子如下:
1 // find first bit set within a range of bits 2 always_comb begin 3 first_bit = 0; 4 for (int i=0; i<=63; i=i+1) begin 5 if (i < start_range) continue; 6 if (i > end_range) break; // exit loop 7 if ( data[i] ) begin 8 first_bit = i; 9 break; // exit loop 10 end 11 end // end of the loop 12 ... // process data based on first bit set 13 end
system verilog中的break声明与C语言中的break语句用法相同。C语音也会使用break语句从switch语句中退出。而system verilog不会使用break声明从case语句中离开,因为verilog中case声明会在某个分支执行后自动退出,不需要break语句。
return声明
system verilog增加了类C语言的return声明,用于从一个非void函数中返回数值或者从一个void函数或任务返回。return声明可以在任务或函数执行流程的任意一点执行。当return声明执行后,任务或者函数立即退出而不需要执行到任务或者函数的末尾。
1 task add_up_to_max (input [ 5:0] max, 2 output [63:0] result); 3 result = 1; 4 if (max == 0) return; // exit task 5 for (int i=1; i<=63; i=i+1) begin 6 result = result + result; 7 if (i == max) return; // exit task 8 end 9 endtask
return声明可以用来从任务或函数提前退出。verilog中disable声明只能从任务中提前退出,而不能用在函数中。
1 function automatic int log2 (input int n); 2 if (n <=1) return 1; // exit function early 3 log2 = 0; 4 while (n > 1) begin 5 n = n/2; 6 log2++; 7 end 8 return log2; 9 endfunction // log2
注意在任务或者void函数中,return关键字后不能跟随表达式;而在非void函数中,return关键字后必须跟随表达式。
综合规则
break,continue和return跳转声明是可综合的结构。综合结果与verilog中使用disable实现同样功能时综合结构相同。