- Subroutines contain delay, event, or sequential control statement structures
- No output or the number of output variables is greater than 1
- no input variable
You must use tasks .
Automatic (reentrant) tasks:
Tasks are static in nature, the address space of all declared items in the task is statically allocated, and multiple tasks executing concurrently share these memory areas. So if this task is called in two places at the same time, both tasks will operate on the same block of addresses. To avoid this problem, [Verilog] makes the task reentrant by adding the automatic keyword in front of the task keyword, the storage space is dynamically allocated, and each call has an independent address space.
module top; reg [15:0] cd_xor, ef_xor; reg [15:0] c, d, e, f; task bitwise_xor; output [15:0] ab_xor; input [15:0] a,b; begin ab_xor = a^b; end end task always @(posedge clk or negedge rstn) begin bitwise_xor(ef_xor, e, f); end always @(posedge clk or negedge rstn) begin bitwise_xor(cd_xor, c, d); end ... - endmodule
- Contains no delays, timing, or control structures within subroutines
- Subroutine has only one return value
- at least one input variable
- No output or bidirectional variable
- Does not contain a non-blocking assignment statement
Functions can be used .
A function call is made by specifying the function name and its input variables. When declaring a function, it implicitly declares a register type variable with the same name as the function name. The output of the function will also be passed back through this register.
module parity; ... reg [31:0] addr; reg parity; always@(addr) begin parity = calc_parity(addr); $display("Parity calculated = %b", calc_parity(addr)); end functioin calc_parity; input [31:0] address; begin calc_parity = ^address; end endfunction ... endmodule
When the function is called for the first time, its return value is used to set the register variable parity, and when the function is called for the second time, its return value is directly displayed using the system task $display. From this it can be seen that the return value of the function is used where the function is called.
[The calc_parity function implicitly defines a 1-bit calc_parity register variable. To return a multi-bit variable, then: functioin [N:0] calc_parity;]
Automatic (recursive) function:
There are automatic tasks, and similarly there are automatic functions. Also use the keyword automatic . Dynamically allocate storage space.