SystemVerilog: Dynamic Array Pass-by-value problem

Hello All,

Please consider the code below. This code is supposed to print all 3 element combinations from an array of 5 elements.

module test;
    int A[5] = {1, 2, 3, 4, 5};
    function automatic void comb(int start, int howMany, int S[]);
        if(howMany == 0) begin
            $display("ARR = %p", S);
        end
        else begin
            for(int i = start; i <= 5-howMany; i++) begin
                automatic int X = howMany-1;
                automatic int I = i+1;
                S = new[S.size+1](S);
                S[3-howMany] = A[i];
                comb(I, X, S);
            end
        end
    endfunction
    initial begin
        int S[];
        comb(0, 3, S);
    end
endmodule

Output is:
ARR = '{1, 2, 3}
ARR = '{1, 2, 4, 0}
ARR = '{1, 2, 5, 0, 0}
ARR = '{1, 3, 4, 0}
ARR = '{1, 3, 5, 0, 0}
ARR = '{1, 4, 5, 0, 0}
ARR = '{2, 3, 4, 0}
ARR = '{2, 3, 5, 0, 0}
ARR = '{2, 4, 5, 0, 0}
ARR = '{3, 4, 5, 0, 0}

Notice how extra 0s are in the display. The array size increases and I cannot put my finger on what is going on. Automatic functions are supposed to copy by value arrays and have their own copies. I made following modification for the code below.

module test;
    int A[5] = {1, 2, 3, 4, 5};
    function automatic void comb(int start, int howMany, int S[]);
        if(howMany == 0) begin
            $display("ARR = %p", S);
        end
        else begin
            for(int i = start; i <= 5-howMany; i++) begin
                automatic int X = howMany-1;
                automatic int I = i+1;
                int K [] = new[S.size+1](S); //
                K[3-howMany] = A[I];         //
                comb(I, X, K);               //
            end
        end
    endfunction

    initial begin
        int S[];
        comb(0, 3, S);
    end
endmodule

Output:
ARR = '{1, 2, 3}
ARR = '{1, 2, 4}
ARR = '{1, 2, 5}
ARR = '{1, 3, 4}
ARR = '{1, 3, 5}
ARR = '{1, 4, 5}
ARR = '{2, 3, 4}
ARR = '{2, 3, 5}
ARR = '{2, 4, 5}
ARR = '{3, 4, 5}

Now this problem isnt just restricted to dynamic arrays. I se it with queues and even with INT(When I use INT to accumulate different elements)

The problem is that you are increasing the size of S beyond homMany.
here is the solution.


``` verilog

module test;
    int A[5] = {1, 2, 3, 4, 5};
	static int howManyStat=3;
    function automatic void comb(int start, int howMany, int S[]);
        if(howMany == 0) begin
            $display("ARR = %p", S);
	        return;
        end
        else begin
            for(int i = start; i <= 5-howMany; i++) begin
                automatic int X = howMany-1;
                automatic int I = i+1;
                S[howManyStat-howMany] = A[i];
                comb(I, X, S);
            end
        end
    endfunction
    initial begin
        static int S[]=new[howManyStat];
        comb(0, howManyStat, S);
	    $finish;
    end
endmodule


Here are the results
ARR = '{1, 2, 3}
ARR = '{1, 2, 4}
ARR = '{1, 2, 5}
ARR = '{1, 3, 4}
ARR = '{1, 3, 5}
ARR = '{1, 4, 5}
ARR = '{2, 3, 4}
ARR = '{2, 3, 5}
ARR = '{2, 4, 5}
ARR = '{3, 4, 5}

Thanks shimonc,

I dont believe I am going beyond howMany. If howmany starts at 3, we go from 3,2,1 where we incremented the size. Also when I fixed it using a new dynamic array, it got the size from the first one and that way it should face the same problem, isnt it?

I debug it, you do go beyond howMany.
You can see it nicely using your output.
ARR = '{1, 2, 3}
ARR = '{1, 2, 4, 0}
ARR = '{1, 2, 5, 0, 0}

You can see that the assignment of A[i] are well placed, but arr sized increased at each iteration.