在我们认为中,function和task主要是用在SV中,主要用于验证,而不是综合;那是不是Verilog的综合语句不能使用function和task呢?
任务task:一般用于编写测试class中;或者用于行为描述可综合的模块;其中可以包含时间控制(#delay,@,wait);也可以包含input,output和inout端口定义和参数;也可以调用其他的任务或函数。Task可以包含时间控制,但加入时间控制则该task不可综合,此时是用于写测试task;
函数function:主要用于计算–用来代替纯组合逻辑。函数中肯定是不能包含时间语句;函数在零时间执行;函数只有input变量,虽没有output变量,但可以通过函数名返回一个值。可以调用其他的函数,但不可以调用任务。因为函数不包含时间控制语句,所以可综合,主要用在模块中的组合逻辑,方便复用和调用;
接下来主要是讨论function和task在Verilog可综合语句中的用法;
function 主要用于计算并返回一个值。它可以在表达式中调用,并且不能包含任何延迟或时间控制语句。function 通常用于执行简单的计算或数据转换。函数在模块内部定义,通常在本模块中调用,也能根据按模块层次分级命名的函数名从其他模块调用。
function [返回类型] 函数名;
input [参数类型] 参数名1;
input [参数类型] 参数名2;
// 更多输入参数...
begin
// 函数体
函数名 = 表达式;
end
endfunction
//demo
//function 实现
function integer clogb2 (input integer bit_depth);
begin
for(clogb2=0; bit_depth>0; clogb2=clogb2+1)
bit_depth = bit_depth >> 1;
end
endfunction
// 使用案例
localparam integer C_TRANSACTIONS_NUM = clogb2(C_M_AXI_BURST_LEN-1);
reg [C_TRANSACTIONS_NUM : 0] write_index;
reg [C_TRANSACTIONS_NUM : 0] read_index;
task 用于执行一系列操作,但不返回值。它可以包含延迟或时间控制语句,适合用于描述复杂的行为或控制流程。task 通常用于执行硬件操作或与外部设备通信。
task 任务名;
input [参数类型] 参数名1;
input [参数类型] 参数名2;
// 更多输入参数...
begin
// 任务体
end
endtask
//--Demo
module traffic_lights;
reg clock,red,amber,green;
parameter on =1, off = 0, red_tics = 350,amber_tics = 30,green_tics = 200;
initial red = off;
initial amber = off;
initial green = off;
always //交通灯初始化
begin
red = on; //开红灯
light(red,red_tics); //调用等待任务
green = on; //开绿灯
light(green,green_tics); //等待
amber = on; //开黄灯
light(amber,amber_tics); //等灯
end
always begin //产生时钟脉冲的always块
#100 clock = 0;
#100 clock = 1;
end
//定义交通灯开启时间的任务
task light(color,tics);
output reg color;
input [31:0] tics;
begin
@(posedge clk) begin
color <= off;
end
end
endtask
endmodule
【Note】
function 必须有一个返回值,而 task 没有返回值。
function 不能包含延迟或时间控制语句,而 task 可以。
function 可以在表达式中调用,而 task 不能。
通过使用 function 和 task,你可以将复杂的代码分解成更小的、可重用的单元,从而提高代码的可读性和可维护性。
module example_combined;
reg [7:0] a, b, sum, product;
initial begin
a = 8'd5;
b = 8'd3;
// 使用函数计算加法
sum = add(a, b);
$display("Sum of %d and %d is %d", a, b, sum);
// 使用任务初始化寄存器
initialize_registers(a, b);
$display("Initialized values: a = %d, b = %d", a, b);
// 使用函数计算乘法
product = multiply(a, b);
$display("Product of %d and %d is %d", a, b, product);
end
// 函数:计算两个数的加法
function [7:0] add;
input [7:0] x, y;
begin
add = x + y;
end
endfunction
// 任务:初始化寄存器
task initialize_registers;
output [7:0] reg_a, reg_b;
begin
reg_a <= 8'd10;
reg_b <= 8'd20;
end
endtask
// 函数:计算两个数的乘法
function [7:0] multiply;
input [7:0] x, y;
begin
multiply = x * y;
end
endfunction
endmodule
【ref】
https://fpga.eetrend.com/blog/2022/100564212.html