Help with SystemVerilog task to write AXIS stream to file

I am trying to test a block that has its AXI-Stream output connected to an interface and I am trying to dump the stream to a file. I am getting this issue where certain data words are getting written to the file twice and I cannot figure out why, maybe the SV code (below) I wrote isn’t quite correct? I feel like the actual RTL module is working correctly based on the waveform, but I am open to any suggestions.


// Toggle the TREADY signal at random intervals to simulate back pressure:
fork
    forever @(posedge vntsc_resampler_if.clk) begin
        if (enable_random_delays == 1) begin
            random_interval = $urandom_range(0,5000); // number of clock cycles between forcing tready low
            random_delay = $urandom_range(0,200); // number of clock cycles to force tready low for
            vntsc_resampler_if.tready = 0;
            #(10*random_delay);
            vntsc_resampler_if.tready = 1;
            #(10*random_interval);
        end
    end
join_none

// Write the output stream to a file:
forever @(posedge vntsc_resampler_if.clk) begin
    if(vntsc_resampler_if.tvalid == 1'b1 && vntsc_resampler_if.tready == 1'b1 && pixel_count < i_frame_width*i_frame_height) begin
        $fwrite(output_file_handler, "%u", vntsc_resampler_if.tdata[31:0]);
        pixel_count++; 
    end
    if(pixel_count == i_frame_width*i_frame_height) begin
        $display("[%0t]: Writting AXIS stream to file complete", $time);
        $fclose(output_file_handler);
        break;
    end
end

In the first forever block, I am randomly toggling the tready signal to simulate backpressure, and in the second forever block I am writing the output to a file. In this screenshot, you can see the data word 0x00510000 gets written to the file twice, but looking at the waveform, I it does not look like it should be written twice. Can anyone provide some advice?

In reply to ianmurph:

By using # delays, you aren’t synchronizing tready with the interface clock, likely resulting in the values not being sampled correctly.

Try the following:


// Toggle the TREADY signal at random intervals to simulate back pressure:
fork
  forever @(posedge vntsc_resampler_if.clk) begin
    if (enable_random_delays == 1) begin
      random_interval = $urandom_range(0,5000); // number of clock cycles between forcing tready low
      random_delay = $urandom_range(0,200); // number of clock cycles to force tready low for
      vntsc_resampler_if.tready = 0;
      repeat (random_delay) @(posedge vntsc_resampler_if.clk);
      vntsc_resampler_if.tready = 1;
      repeat (random_interval) @(posedge vntsc_resampler_if.clk);
    end
  end
join_none


In reply to cgales:

Thank you very much! This did resolve my issue. I thought by having it in the “forever @(posedge clk)” block everything would be synchronous, but I guess not. Thanks again for the tip

In reply to cgales:

Hi cgales, can you please explain what ‘back pressure’ means?