1.任务和函数
任务和函数与verilog中相同,但SV增加了在静态任务和函数中声明自动变量以及在自动任务和函数中声明静态变量的能力
1.1 task
- 端口默认为输入,除非声明为其他类型;
- 数据类型默认为logic,除非声明为其他类型;
- 可以存在多个语句,而不用begin end 做开始结尾;
- 利用return语句终止task;
- wire类型数据不可以在端口使用;
1 module task_intro ();
2
3 initial begin
4 #1 doInit(4,5);
5 #1 doInit(9,6);
6 #1 $finish;
7 end
8
9 task doInit (input bit [3:0] count, delay);
10 automatic reg [7:0] a;
11 if (count > 5) begin
12 $display ("@%g Returning from task", $time);
13 return;
14 end
15 #(delay) $display ("@%g Value passed is %d", $time, count);
16 endtask
17
18 endmodule
19
20 //compile result
21
22 @6 Value passed is 4
23 @7 Returning from task
1.2 function
- 端口默认为输入,除非声明为其他类型;
- 数据类型默认为logic,除非声明为其他类型;
- 可以存在多个语句,而不用begin end 做开始结尾;
- 利用return语句终止task;
- wire类型数据不可以在端口使用;
- 允许将函数声明为void类型;
1 module task_intro ();
2
3 bit a ;
4
5 initial begin
6 #1 a = doInit(4,5);
7 #1 a = doInit(9,6);
8 #1 $finish;
9 end
10
11 function bit unsigned doInit (bit [3:0] count, add);
12 automatic reg [7:0] b;
13 if (count > 5) begin
14 $display ("@%g Returning from function", $time);
15 return 0;
16 end
17 b = add;
18 $display ("@%g Value passed is %d", $time, count + b);
19 doInit = 1;
20 endfunction
21
22 endmodule
23
24 //compile result
25
26 @1 Value passed is 9
27 @2 Returning from function
1.3 Discarding function return values
使用以下方法可以避免为变量分配返回值
1 void'(call_function(with_params));
1 module function_discard ();
2
3 bit a ;
4
5 initial begin
6 #1 void'(doInit(4,5));
7 #1 void'(doInit(9,6));
8 #1 $finish;
9 end
10
11 function bit unsigned doInit (input bit [3:0] count, add);
12 automatic reg [7:0] b;
13 if (count > 5) begin
14 $display ("@%g Returning from function", $time);
15 return 0;
16 end
17 b = add;
18 $display ("@%g Value passed is %d", $time, count + b);
19 doInit = 1;
20 endfunction
21
22 endmodule
23
24 //compile result
25 @1 Value passed is 9
26 @2 Returning from function
2. 参数传递
- Pass by value
- Pass by reference
- Pass by name
- Pass by position
- default values
- Optional arguments.
2.1 按值传递
1 module function_by_value ();
2
3 reg [7:0] data ;
4 reg parity_out;
5 integer i ;
6
7 function parity;
8 input [31:0] data;
9 integer i;
10 begin
11 parity = 0;
12 for (i= 0; i < 32; i = i + 1) begin
13 parity = parity ^ data[i];
14 end
15 end
16 endfunction
17
18 initial begin
19 parity_out = 0;
20 data = 0;
21 for (i=250; i<256; i = i + 1) begin
22 #5 data = i;
23 parity_out = parity (data);
24 $display ("Data = %b, Parity = %b", data, parity_out);
25 end
26 #10 $finish;
27 end
28
29 endmodule
30
31 //compile result
32 Data = 11111010, Parity = 0
33 Data = 11111011, Parity = 1
34 Data = 11111100, Parity = 0
35 Data = 11111101, Parity = 1
36 Data = 11111110, Parity = 1
37 Data = 11111111, Parity = 0
2.2 按引用传递
按引用传递参数,参数的改变对子例程和方法都是可见的。
1 module function_by_ref ();
2
3 reg [7:0] data ;
4 reg parity_out;
5
6 time ltime;
7
8 function reg parity (ref reg [7:0] idata, const ref time tdata);
9 parity = 0;
10 for (int i= 0; i < 8; i ++) begin
11 parity = parity ^ idata[i];
12 end
13 // We can modify the data passed through reference
14 idata ++ ;
15 // Something that is passed as const ref, can not be modified
16 // tdata ++ ; This is wrong
17 endfunction
18
19 initial begin
20 parity_out = 0;
21 data = 0;
22 for (int i=250; i<256; i ++) begin
23 #5 data = i;
24 ltime = $time;
25 parity_out = parity (data, ltime);
26 $display ("Data = %00000000b, Parity = %b, Modified data : %b",
27 i, parity_out, data);
28 end
29 #10 $finish;
30 end
31
32 endmodule
33
34 //compile result
35
36 Data = 11111010, Parity = 0, Modified data : 11111011
37 Data = 11111011, Parity = 1, Modified data : 11111100
38 Data = 11111100, Parity = 0, Modified data : 11111101
39 Data = 11111101, Parity = 1, Modified data : 11111110
40 Data = 11111110, Parity = 1, Modified data : 11111111
41 Data = 11111111, Parity = 0, Modified data : 00000000
2.3 按名字和位置传递
按名称和位置传递参数可以混合使用,值要顺序可以匹配即可;
1 module function_by_name ();
2
3 reg [7:0] data ;
4 reg parity_out;
5
6 time ltime;
7
8 function automatic reg parity (ref reg [7:0] idata, ref time itime);
9 parity = 0;
10 for (int i= 0; i < 8; i ++) begin
11 parity = parity ^ idata[i];
12 end
13 // We can modify the data passed through reference
14 idata ++ ;
15 // Something that is passed as const ref, can not be modified
16 // tdata ++ ; This is wrong
17 endfunction
18
19 initial begin
20 parity_out = 0;
21 data = 0;
22 for (int i=250; i<256; i ++) begin
23 #5 data = i;
24 ltime = $time;
25 // By Name
26 parity_out = parity (.idata(data), .itime(ltime));
27 // By position and name
28 parity_out = parity (data, .itime(ltime));
29 // This is wrong, by name should not be before position
30 //parity_out = parity (.idata(data), ltime);
31 $display ("Data = %00000000b, Parity = %b, Modified data : %b",
32 i, parity_out, data);
33 end
34 #10 $finish;
35 end
36
37 endmodule
38
39 //compile result
40
41 Data = 11111010, Parity = 1, Modified data : 11111100
42 Data = 11111011, Parity = 0, Modified data : 11111101
43 Data = 11111100, Parity = 1, Modified data : 11111110
44 Data = 11111101, Parity = 1, Modified data : 11111111
45 Data = 11111110, Parity = 0, Modified data : 00000000
46 Data = 11111111, Parity = 0, Modified data : 00000001
2.4 默认参数值
为了处理常见情况或允许使用未使用的参数,SV允许任务和函数声明时为参数指定默认值;括号中定义参数的使用是可选的;
1 module function_default_value ();
2
3 reg [7:0] data ;
4 reg parity_out;
5 time ltime;
6
7 function reg parity (reg [7:0] a, time b = 0, time c = 0);
8 parity = 0;
9 for (int i= 0; i < 8; i ++) begin
10 parity = parity ^ a[i];
11 end
12 endfunction
13
14 initial begin
15 parity_out = 0;
16 data = 0;
17 for (int i=250; i<256; i ++) begin
18 #5 data = i;
19 ltime = $time;
20 parity_out = parity (data);
21 parity_out = parity (data,,);
22 parity_out = parity (data,,10);
23 parity_out = parity (data,ltime,);
24 $display ("Data = %00000000b, Parity = %b", i, parity_out);
25 end
26 #10 $finish;
27 end
28
29 endmodule
30
31 //compile result
32 Data = 11111010, Parity = 0
33 Data = 11111011, Parity = 1
34 Data = 11111100, Parity = 0
35 Data = 11111101, Parity = 1
36 Data = 11111110, Parity = 1
37 Data = 11111111, Parity = 0