•4:59 AM
Tasks and Functions helps the designer to break up large behavioral designs into smaller
pieces. The designer has to abstract the similar pieces in the
description and replace them either Functions or tasks. This also
improves the readability of the code, and hence easier to debug.
function <range_or_type> function_name;
input_port_declaration (s) ;
local_variable_declaration (s) ;
statement_or_block
function_name = (expression);
endfunction
Example : 01: Parity Generator
module parity;
....
reg [31:0] addr;
reg parity;
initial begin
…
end
always @(addr)
begin
parity = calc_parity(addr);
$display("Parity calculated = %b", calc_parity(addr) );
end
function calc_parity;
input [31:0] address;
begin
calc_parity = ^address;
end
endfunction
endmodule
Example : 02: Controllable Shifter
module shifter;
`define LEFT_SHIFT 1'b0
`define RIGHT_SHIFT 1'b1
.......
reg [31:0] addr, left_addr, right_addr;
reg control;
initial
begin
…
end
always @(addr)
begin
left_addr = shift (addr, `LEFT_SHIFT);
right_addr = shift (addr,`RIGHT_SHIFT);
end
function [31:0] shift;
input [31:0] address;
input control;
begin
shift = (control==`LEFT_SHIFT) ?(address<<1) : (address>>1);
end
endfunction
endmodule
task task_name ;
port_declaration (s);
local_variable_declaration (s);
statement_or_block;
endtask
Example : 01: Use of input and output arguments
module operation;
parameter delay = 10;
.......
reg [15:0] A, B;
reg [15:0] AB_AND, AB_OR, AB_XOR;
initial
$monitor( …);
initial
begin
…
end
always @(A or B)
begin
bitwise_oper(AB_AND, AB_OR, AB_XOR, A, B);
end
task bitwise_oper;
output [15:0] ab_and, ab_or, ab_xor;
input [15:0] a, b;
begin
#delay
ab_and = a & b;
ab_or = a | b;
ab_xor = a ^ b;
end
endtask
endmodule
Example : 02 : Use of module local variables
module sequence;
.....
reg clock;
initial
begin
…
end
initial
init_sequence;
always
asymmetric_sequence;
task init_sequence;
clock = 1'b0;
endtask
task asymmetric_sequence;
begin
#12 clock = 1'b0;
#5 clock = 1'b1;
#3 clock = 1'b0;
#10 clock = 1'b1;
end
endtask
endmodule
Functions :
- Keywords: function , endfunction
- Can be used if the procedure
- Does not have any timing control constructs ; i.e Must execute in Zero-Time.
- Returns exactly a single value
- Has at-least one input argument declaration
function <range_or_type> function_name;
input_port_declaration (s) ;
local_variable_declaration (s) ;
statement_or_block
function_name = (expression);
endfunction
Example : 01: Parity Generator
module parity;
....
reg [31:0] addr;
reg parity;
initial begin
…
end
always @(addr)
begin
parity = calc_parity(addr);
$display("Parity calculated = %b", calc_parity(addr) );
end
function calc_parity;
input [31:0] address;
begin
calc_parity = ^address;
end
endfunction
endmodule
Example : 02: Controllable Shifter
module shifter;
`define LEFT_SHIFT 1'b0
`define RIGHT_SHIFT 1'b1
.......
reg [31:0] addr, left_addr, right_addr;
reg control;
initial
begin
…
end
always @(addr)
begin
left_addr = shift (addr, `LEFT_SHIFT);
right_addr = shift (addr,`RIGHT_SHIFT);
end
function [31:0] shift;
input [31:0] address;
input control;
begin
shift = (control==`LEFT_SHIFT) ?(address<<1) : (address>>1);
end
endfunction
endmodule
Tasks:
- Keywords: task, endtask
- Must be used if the procedure has
- any timing control constructs ; i.e @( ..) , #delay , wait e.t.c
- zero or more than one output arguments
- no input arguments
task task_name ;
port_declaration (s);
local_variable_declaration (s);
statement_or_block;
endtask
Example : 01: Use of input and output arguments
module operation;
parameter delay = 10;
.......
reg [15:0] A, B;
reg [15:0] AB_AND, AB_OR, AB_XOR;
initial
$monitor( …);
initial
begin
…
end
always @(A or B)
begin
bitwise_oper(AB_AND, AB_OR, AB_XOR, A, B);
end
task bitwise_oper;
output [15:0] ab_and, ab_or, ab_xor;
input [15:0] a, b;
begin
#delay
ab_and = a & b;
ab_or = a | b;
ab_xor = a ^ b;
end
endtask
endmodule
Example : 02 : Use of module local variables
module sequence;
.....
reg clock;
initial
begin
…
end
initial
init_sequence;
always
asymmetric_sequence;
task init_sequence;
clock = 1'b0;
endtask
task asymmetric_sequence;
begin
#12 clock = 1'b0;
#5 clock = 1'b1;
#3 clock = 1'b0;
#10 clock = 1'b1;
end
endtask
endmodule
Difference between Tasks and Functions
- A function can enable (call) just another function (not task) ; A task can enable other tasks and functions.
- A function execute in 0 simulation time ; A task can execute in non-zero simulation time.
- A function no timing control statements allowed ; A task may contain any timing control statements
- A function must have at-least one input argument ; A task can have arbitrary input, output, or inout
- A function return only a single value ; A task do not return any value
- Tasks and Functions are defined in a module
- Tasks and Functions are local to the module
- Tasks and Functions can have local variables (registers, but not nets) and events
- Tasks and Functions contain only behavioral statements
- Tasks and Functions do not contain initial or always statements
- Tasks and Functions are called from initial or always statements or other tasks or functions.
- Functions are purely combinational , typically used for conversions and commonly used calculations ; Tasks can be used for common Verilog code.
0 comments: