SystemVerilog ----任务—task
在 SystemVerilog 中,task 是一种用于封装可复用代码块的结构,类似于其他编程语言中的“函数”或“子程序”。但与 function 不同,task 可以包含时序控制(如 #delay, @posedge),并且可以没有返回值。task 通常用于描述需要多个步骤完成的操作,例如总线事务、数据包处理等。
1. task 的基本语法
task task_name(input/output/inout arguments);
// 声明局部变量
begin
// 任务实现代码
end
endtask
task 可以包含:
输入 (input):传递值给任务。
输出 (output):任务返回的值。
双向 (inout):既可输入又可输出。
局部变量:仅在任务内部使用。
时序控制(#, @, wait 等)。
2. task 的特点
特性 | task | function |
---|---|---|
返回值 | 可以没有viold | 必须有返回值 |
时间控制 | 支持(#,@,wait) | 不支持 |
调用方式 | 作为语句调用 (task_name(arges);) | 作为表达式调用 (y= func(args);) |
用途 | 复杂操作(如总线事物) | 纯计算(如数学运算) |
3. task 的示例
(1) 基本 task(无参数)
task print_hello;
$display("Hello, SystemVerilog!");
endtask
initial begin
print_hello(); // 调用任务
end
输出:
Hello, SystemVerilog!
(2) 带输入/输出的 task
task add(input int a, input int b, output int sum);
sum = a + b;
endtask
initial begin
int x, y, z;
x = 10;
y = 20;
add(x, y, z); // z 将存储计算结果
$display("Sum = %d", z);
end
输出:
Sum = 30
(3) 带时序控制的 task
task delay_print(input string msg, input int delay_ns);
#delay_ns; // 延迟 delay_ns 纳秒
$display("%s", msg);
endtask
initial begin
delay_print("Message after 10ns", 10);
delay_print("Message after 5ns", 5);
end
输出(仿真时间):
#5 Message after 5ns
#10 Message after 10ns
(4) task 使用 inout 参数
task swap(inout int a, inout int b);
int temp;
temp = a;
a = b;
b = temp;
endtask
initial begin
int x = 100, y = 200;
swap(x, y);
$display("x = %d, y = %d", x, y);
end
输出:
x = 200, y = 100
4. task 的自动(automatic)与静态(static)
默认静态(static):
所有调用共享同一组变量(可能导致递归调用冲突)。
自动(automatic):
每次调用都有独立的变量存储(适用于递归或并行调用)。
task automatic recursive_task(input int n);
if (n > 0) begin
$display("n = %d", n);
recursive_task(n - 1); // 递归调用
end
endtask
initial begin
recursive_task(3);
end
输出:
n = 3
n = 2
n = 1
5. task 与 function 对比
场景 | 使用task | 使用function |
---|---|---|
需要延迟或时间触发 | √(#10,@posedge clk) | × 不能有时许控制 |
需要返回值 | × (通常用output 参数) | √ 必须返回一个值 |
纯计算操作 | 可通,但推荐function | 如数学计算 |
递归调用 | 需要声明 automatic | 默认支持 |
6. 总结
task 适用于:
需要时序控制的操作(如等待信号、延迟);
需要多个输入/输出的复杂操作(如总线事务);
不需要返回值的代码块。
function 适用于:
纯计算操作(如数学运算);
需要返回单个值的场景。
在验证环境中,task 常用于 UVM 序列(Sequences) 和 总线驱动(Drivers),而 function 更多用于 记分板(Scoreboard) 和 覆盖率计算。