In a part of my verilog project, I am assigning a data to register M[i] by reading from register N[j]. I have written and simulated the code in verilog without any problem. As this particular pattern is repeated many times in a module, I'd like to convert it into a task.
But I'm getting compilation errors when using a 2D array of registers as input and output of the task. Below is a sample code that illustrates the problem.
`timescale 1 ns/100 ps
module test(clk, rst_n);
input clk, rst_n;
reg [1:0] idx1;
reg [2:0] idx2;
reg [15:0] M[3:0];
reg [15:0] N[7:0];
always @(posedge clk or negedge rst_n) begin
idx1 <= rst_n ? (idx1 + 1) : 0;
idx2 <= rst_n ? (idx2 + 1) : 0;
end
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin : reset_registers
integer i;
for(i = 0; i < 4; i = i+1) M[i] = 0;
for(i = 0; i < 8; i = i+1) N[i] = i;
end
else begin
M[idx1] <= N[idx2];
end
end
endmodule
The module compiles and simulates as expected now. I would like to convert the segment M[idx1] <= N[idx2];
to a task. So, the new code using a task is:
`timescale 1 ns/100 ps
module test(clk, rst_n);
input clk, rst_n;
reg [1:0] idx1;
reg [2:0] idx2;
reg [15:0] M[3:0];
reg [15:0] N[7:0];
always @(posedge clk or negedge rst_n) begin
idx1 <= rst_n ? (idx1 + 1) : 0;
idx2 <= rst_n ? (idx2 + 1) : 0;
end
always @(posedge clk or negedge rst_n) begin
if(~rst_n) begin : reset_registers
integer i;
for(i = 0; i < 4; i = i+1) M[i] = 0;
for(i = 0; i < 8; i = i+1) N[i] = i;
end
else begin
copy(idx1, idx2, M, N);
end
end
task copy;
input [1:0] x1;
input [2:0] x2;
output reg [15:0] A[3:0];
input [15:0] B[7:0];
begin
A[x1] <= B[x2];
end
endtask
endmodule
I am getting the following errors when trying to compile it using modelsim:
# -- Compiling module test
# ** Error: D:\projects\test.v(21): Illegal task output argument.
# ** Error: D:\projects\test.v(21): (vlog-2110) Illegal reference to memory "B".
#
# ** Error: D:\projects\test.v(21): Illegal LHS of assignment.
# ** Error: D:\projects\test.v(21): (vlog-2110) Illegal reference to memory "N".
#
# C:/modeltech64_10.2c/win64/vlog failed.
Can someone please advise how to use the registers properly in a task? Exactly what is making the statements illegal? Is it even possible to something like this using a task, or is there other way around?
Thank you.
Best Answer
You need to be using SystemVerilog to have unpacked arrays as arguments to a task. And the task as you have written it does not do the same thing as the code without the task. That is because the output array
A
is uninitialized and you are only setting the value indexed byx1
.