🔧 Task and Function in Verilog#
Tasks and functions are used to avoid code repetition and to encapsulate reusable logic. They improve code readability and maintainability, especially in simulation and testbench designs.
📌 task
#
Tasks are procedural blocks that can have:
- Multiple inputs and outputs
- Timing controls like
#
,@
,wait
- Can call other tasks or functions
- Can be used to drive global variables (unless overridden by local declarations)
- Cannot be used inside
assign
expressions
✅ Example:#
task convert;
input [7:0] adc_in;
output [7:0] out;
begin
out = (9/5) * (adc_in + 32);
end
endtask
🔔 Usage:#
always @(adc_a) convert(adc_a, adc_a_conv);
📌 function
#
Functions are pure logic blocks that:
- Must execute in zero simulation time
- Can only return one value
- Cannot include delays (
#
,@
,wait
,posedge
, etc.) - Can call other functions, but cannot call tasks
- Can be used in expressions, such as inside
assign
✅ Example:#
function [7:0] myfunction;
input [3:0] a, b, c, d;
begin
myfunction = ((a + b) + (c - d));
end
endfunction
🔔 Usage:#
assign f = myfunction(a, b, c, d) ? e : 8'd0;
🧠 Comparison Table#
Feature | task | function |
---|---|---|
Return value | Via output ports (can be multiple) | Single return value only |
Timing control | Allowed (e.g., # , @ , wait ) | Not allowed |
Expression use | ❌ Cannot be used in expressions | ✅ Can be used |
Calls | Can call other tasks/functions | Can only call functions |
Usage | Complex sequences, simulations | Combinational logic |
Delays/events | Allowed | Forbidden |
⚠️ Best Practices#
- Use
task
for time-dependent or procedural operations.- Use
function
for pure, combinational calculations.
module tb_task_function;
reg [7:0] adc_a = 8'd50;
wire [7:0] adc_a_conv;
wire [7:0] f;
reg [3:0] a = 1, b = 2, c = 5, d = 3, e = 8;
// Task usage
reg [7:0] adc_conv_result;
always @(*) convert(adc_a, adc_conv_result);
assign adc_a_conv = adc_conv_result;
// Function usage
assign f = myfunction(a, b, c, d) ? e : 8'd0;
// Task definition
task convert;
input [7:0] adc_in;
output [7:0] out;
begin
out = (9/5) * (adc_in + 32);
end
endtask
// Function definition
function [7:0] myfunction;
input [3:0] a, b, c, d;
begin
myfunction = ((a + b) + (c - d));
end
endfunction
endmodule