Task with clock-triggered behavior causes unexpected signal update timing

Hi,
when I simulate the below code and view the waveform , I got the following waveform.

    reg clk;
    reg signed [ 7:0] a [3:0];
    reg signed [10:0] b [3:0];

    always_ff @(posedge clk) begin
        for (int i = 0; i < 4; i = i + 1) begin
            b[i] <= a[i];
        end
    end

    task automatic randomrize(ref reg signed [7:0] reg_array[3:0]);
        @(posedge clk);
        for (int i = 0; i < 4; i = i + 1) begin
            reg_array[i] = $random % 255;
        end
    endtask


    initial begin
        a = '{default: '0};
        @(posedge clk);
        @(posedge clk);
        randomrize(a);
        @(posedge clk);
        randomrize(a);
        repeat (10) @(posedge clk);
        $finish;
    end


waveform

There are two points that puzzle me:

  1. Why does “a” change only once, while “b” changes twice?
  2. Why does “b” change first and “a” change later? It seems that “b” obtains the future value of “a” in advance.
    Can someone please explain reasons in detail?

You did not post a complete example and I can’t re-create the results you’re getting. There is a race condition in that you’re making an assignment to a via the ref argument of the task in the same posedge that you’re reading it and the always_ff block. But that would not explain what you are seeing.