一个任务可以包括参数定义、输出参数、输出参数、输入输出参数、寄存器、事件和若干条行为语句。任务可以分类为自动任务(automatic task)和静态任务(static task)。两者的区别在于存储的不同,静态任务调用时共享存储空间,自动任务则为每次任务调用分配单独的栈存储。
systemverilog允许:
module sv_task;
int x ;
//task to add two integer numbers
task sum(input int a, b, output int c);
c = a + b;
endtask
initial begin
sum(10, 5, x);
$display("\t Value of x = %0d", x);
end
endmodule
其输出结果为:
函数可以包括范围声明,返回值类型,参数,输入参数,寄存器和事件。函数若没有位宽和返回值类型,返回1bit值。任何表达式都可以作为函数的参数,函数不可以拥有任何的事件控制语句。函数不能调用task,并且函数只可以返回一个值。
函数也分为两类,静态函数和动态函数。前者所有的调用共享相同的存储空间,后者对于每次函数调用,都会分配相应的堆栈空间。
module sv_function;
int x ;
//function to add two integer numbers
function int sum(input int a, b);
sum = a + b;
endfunction
initial begin
x = sum(10, 5);
$display("\t Value of x = %0d", x);
end
endmodule
其输出结果是:
下面举一个没有返回值的例子:
module sv_function;
int x ;
//void function to display current simulation time
function void current_time;
$display("\t Current simulation time is %0d", $time);
endfunction
initial begin
#10;
current_time();
#20;
current_time();
end
endmodule
其输出结果是:
对于任务和函数,有四种传递参数的方式:
module argument_passing;
int x ;
int y ;
int z ;
//function to add two integers numbers
function int sum(int x, y);
x = x + y;
return x+y;
endfunction
initial begin
x = 20 ;
y = 30 ;
z = sum(x,y);
$display("-------------------------------------------------");
$display("\t Value of x = %0d", x);
$display("\t Value of y = %0d", y);
$display("\t Value of z = %0d", z);
$display("-------------------------------------------------");
end
endmodule
其输出结果是:
由此可见在函数内部修改参数的值并不会影响外面。
通过引用传递,可以修改传入函数内部的变量,需要在参数声明上添加reg。但是如果不希望修改,则可以在前面添加const。
module argument_passing;
int x ;
int y ;
int z ;
//function to add two integers numbers
function automatic int sum(ref int x, y);
x = x + y;
return x+y;
endfunction
initial begin
x = 20 ;
y = 30 ;
z = sum(x,y);
$display("-------------------------------------------------");
$display("\t Value of x = %0d", x);
$display("\t Value of y = %0d", y);
$display("\t Value of z = %0d", z);
$display("-------------------------------------------------");
end
endmodule
其输出结果是:
可以看出x的值被更改,如果不想修改,可以在ref前面添加修饰const,如果尝试修改,则编译器会给出如下的报错:
按照名字传递,和verilogd的模板例化一样。
其输出结果就是:
Value of x = 2016, y = Hello World