Verilog · Chapter 15.2 · Tasks & Functions
Tasks in Verilog — Procedures with Any I/O and Optional Timing
A task packages a reusable procedure, a sequence of statements with any number of inputs, outputs, and bidirectional ports, or none at all. Where a function returns a single value instantly, a task is the more general tool. It can produce several outputs at once, it can contain delays and event controls so it can consume simulation time, and it is called as a standalone statement rather than inside an expression. That makes it the natural fit for multi-step or timed work such as driving a bus transaction across several clock cycles or applying a reset sequence. A task is synthesizable only when it contains no timing. Add timing and it becomes a simulation and testbench construct. This lesson covers defining a task, calling it, the timing rule, and its use for procedures and stimulus.
Foundation12 min readVerilogtaskProcedureTestbenchStimulus
Chapter 15 · Section 15.2 · Tasks & Functions
1. The Engineering Problem
A repeated procedure — a multi-cycle bus write, a reset sequence, a computation with several outputs — needs packaging, and a function can't do it (one value, no timing). A task can:
A task is a procedure with any number of inputs/outputs/inouts and optional timing, called as a statement — the tool for multi-step and timed operations.
This page drills the task.
2. Mental Model — A Procedure with Arbitrary I/O and Optional Timing
3. Defining a Task
// a task with inputs and outputs (no timing → synthesizable):
task minmax;
input [7:0] a, b;
output [7:0] mn, mx; // multiple outputs
begin
mn = (a < b) ? a : b;
mx = (a < b) ? b : a;
end
endtask
// a timed task (testbench bus write — simulation-only):
task do_write;
input [7:0] addr, data;
begin
bus_addr = addr; bus_data = data; we = 1;
@(posedge clk); // timing → simulation-only
we = 0;
end
endtask- A task declares its inputs, outputs, and inouts; results come back through the output arguments.
- The body is a sequence of statements (in
begin...end). - Timing (
@(posedge clk)) makes a task simulation-only; without it, the task is synthesizable.
4. Calling a Task
// as a statement, with arguments mapped to the task's I/O:
minmax(x, y, low, high); // low, high receive the outputs
// a timed task in a testbench:
initial begin
do_write(8'h10, 8'hA5);
do_write(8'h11, 8'h3C);
$finish;
endA task is called as a statement; its arguments map to the task's inputs (passed in) and outputs (received back). Timed tasks are the backbone of testbench stimulus — a do_write / do_read pair turns a bus protocol into reusable calls (Chapter 9.5).
Visual A — a task is a callable procedure
task — any I/O, optional timing, a statement
data flow5. Task vs Function — Recap
- Function (15.1) — one return value, no timing, in an expression; combinational reuse.
- Task — any I/O, optional timing, a statement; procedure reuse.
- A task can call functions and tasks; a function can call only functions.
- A synthesizable task has no timing; a timed task is testbench-only.
Choose a task when you need multiple outputs, timing, or a multi-step procedure; choose a function for a single value computed instantly.
6. Common Mistakes
- Using a function where multiple outputs are needed — use a task (§5).
- Expecting a synthesizable task with timing — timing makes it simulation-only (§3).
- Calling a task in an expression — tasks are statements, not expressions (§4).
- Static task corrupted by concurrent calls — use
automaticfor reentrancy (15.3/15.4).
7. Debugging Lab
One task debug post-mortem
8. Interview Q&A
9. Exercises
Exercise 1 — Write a task
Write a synthesizable task swap that takes two 8-bit inputs and returns them swapped via two outputs.
Exercise 2 — Testbench task
Write a timed task do_read that drives a read on a bus and captures the result one clock edge later.
Exercise 3 — Task or function?
For (a) computing a CRC value and (b) applying a 3-cycle reset, which construct fits each?
10. Summary
A task is a reusable procedure:
- Any I/O — multiple inputs/outputs/inouts; results via output arguments.
- Optional timing — can consume simulation time (
#/@/wait); synthesizable only without timing. - Called as a statement —
do_write(addr, data);. - Use for procedures, multi-output operations, and testbench stimulus.
The next sub-topic covers storage behaviour: Chapter 15.3 Static & Automatic Behaviour drills how task/function locals are shared (static) or per-call (automatic).
Related Tutorials
- Function — Chapter 15.1; the value-returning construct (contrast).
- Tasks & Functions — Chapter 15 overview; task vs function.
- Testbench Creation Techniques — Chapter 9.5; tasks structuring stimulus.
- Timing Controls — Chapter 14.4; the timing a task may contain.