Verilog - Task

2023-06-28
Verilog

task 可以像function一樣有input/output,也能放會消耗simulation的時間的statement,例如 @, posedge 等等
下面是一些task放在local/global的範例,還有一些不同格式的寫法

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// global task
task sum1(input [7:0] a, b, output [7:0] sum);
sum = a + b;
#1 $display("time:%0d, a:%0d, b:%0d, sum:%0d",$time(), a, b, sum);
endtask

// global task
task sum2;
input [7:0] a, b;
output [7:0] sum;
begin
sum = a + b;
end
#1 $display("time:%0d, a:%0d, b:%0d, sum:%0d",$time(), a, b, sum);
endtask

module testModule();
// task in a testModule
task sum3(input [7:0] a, b, output [7:0] sum);
sum = a + b;
#1 $display("time:%0d, a:%0d, b:%0d, sum:%0d",$time(), a, b, sum);
endtask
endmodule

module tb();
int outSum;
testModule mod();
task sum4(input [7:0] a, b, output [7:0] sum);
sum = a + b;
#1 $display("time:%0d, a:%0d, b:%0d, sum:%0d",$time(), a, b, sum);
endtask

initial begin
sum1(1, 2, outSum);
$display("time:%0d, sum1 output:%0d",$time(), outSum);

sum2(3, 4, outSum);
$display("time:%0d, sum2 output:%0d",$time(), outSum);

mod.sum3(5, 6, outSum);
$display("time:%0d, sum3 output:%0d",$time(), outSum);

sum4(7, 8, outSum);
$display("time:%0d, sum4 output:%0d",$time(), outSum);
end
endmodule

Output:

# run 10000
# time:1, a:1, b:2, sum:3
# time:1, sum1 output:3
# time:2, a:3, b:4, sum:7
# time:2, sum2 output:7
# time:3, a:5, b:6, sum:11
# time:3, sum3 output:11
# time:4, a:7, b:8, sum:15
# time:4, sum4 output:15
#  quit -f

Static Task 和 Automatic Task

Task預設就是static task,但如果task裡面有宣告變數的話,那task前面就要加Automatic,這樣在每次使用這個task的時候,simulation就會重新allocate一塊memory來跑這個新的task。
或者是要把變數宣告成Automatic,這樣每次initial這個變數的時候simulation就會重新allocate一塊memory給這個變數使用。

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
module tb();

initial counter();
initial counter();
initial counter();
initial counter_auto();
initial counter_auto();
initial counter_auto();

task counter();
// integer i = 0; // .\task2.sv(11): (vlog-2244) Variable 'i' is implicitly static. You must either explicitly declare it as static or automatic or remove the initialization in the declaration of variable.
automatic integer i = 0;
i = i + 1;
$display("time:%0d, i:%0d",$time(), i);
endtask

task automatic counter_auto();
integer i = 0;
i = i + 1;
$display("time:%0d, i:%0d",$time(), i);
endtask

endmodule

Output

# run 10000
# time:0, i:1
# time:0, i:1
# time:0, i:1
# time:0, i:1
# time:0, i:1
# time:0, i:1
#  quit -f

Disable Task/ Disable Block in a Task

Task還可以用 disable 來disable這個task執行,也可以取消掉一個task的某個block

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
module tb;

initial begin
$display("t:%0t Start disable task block", $time);
#5 disable display.BLOCK_1;
$display("t:%0t End disable task block", $time);

$display("t:%0t Start disable task", $time);
#15 disable display;
$display("t:%0t End disable task", $time);
end

initial display();

task display();
begin: BLOCK_1
$display("t:%0t BLOCK_1 start", $time);
#10;
$display("t:%0t BLOCK_1 end", $time);
end

begin: BLOCK_2
#10;
$display("t:%0t BLOCK_2 start", $time);
#10;
$display("t:%0t BLOCK_2 end", $time);
end

begin: BLOCK_3
#10;
$display("t:%0t BLOCK_3 start", $time);
#10;
$display("t:%0t BLOCK_3 end", $time);
end
endtask
endmodule

Output

# t:0 Start disable task block
# t:0 BLOCK_1 start
# t:5 End disable task block
# t:5 Start disable task
# t:15 BLOCK_2 start
# t:20 End disable task
#  quit -f

#5的時候用disable display.BLOCK_1把這個block的task disable掉
#20的時候用disable display把整個task disable掉