Using fork-join_none in a loop to generate Multiple streams

Hello,

I need to create multiple streams which will generate traffic to incrementing address locations.
I created the following code based on the previous examples seen in this forum =>

initial begin
      num_streams = 3;
     
      for (int ii = 0; ii < num_streams; ii++) begin
         automatic int mm = ii; 
         fork
            begin: isolating_thread
               addr         = $random();
               addr_offset  = $urandom_range(4,1);
               num_xactions = $urandom_range(7,3);
               for (int jj = 0; jj < num_xactions; jj++) begin: for_loop
                  automatic int kk = jj; 
                  fork 
                     begin
                        gen_addr = addr + (kk * addr_offset);
                        $display("Stream %0d, Loop %0d: Generated Address = %0h\n", mm,kk,gen_addr);
                     end
                  join_none
               end: for_loop
               wait fork;
            end // block: isolating_thread
         join
      end // for (int ii = 0; ii < num_streams; ii++)
      
   end // initial begin

This is the result =>

# Stream 0, Loop 2: Generated Address = 12153528
# 
# Stream 0, Loop 1: Generated Address = 12153526
# 
# Stream 0, Loop 0: Generated Address = 12153524
# 
# Stream 1, Loop 4: Generated Address = fc0895e8d
# 
# Stream 1, Loop 3: Generated Address = fc0895e8a
# 
# Stream 1, Loop 2: Generated Address = fc0895e87
:
:
# Stream 2, Loop 6: Generated Address = f8484d615
# 
# Stream 2, Loop 5: Generated Address = f8484d613
:

I wanted the address across the streams to get mixed together to generate mixed traffic.
For example something like the following transactions =>

# Stream 0, Loop 0: Generated Address = 12153524
# Stream 2, Loop 0: Generated Address = f8484d609
# Stream 2, Loop 1: Generated Address = f8484d60b
# Stream 0, Loop 1: Generated Address = 12153526
# Stream 1, Loop 0: Generated Address = fc0895e81
# Stream 2, Loop 2: Generated Address = f8484d60d
:
:

I don’t want it to generate the transactions for each stream sequentially like how it is happening at present.
Any suggestions?
P.S: I will be replacing the “gen_addr and $display” statements with `uvm_do_on_with() macro to generate traffic once I get the logic working.

If these streams are being sent to the same sequencer, then selecting the SEQ_ARB_STRICT arbitration mode will take care of this for you. See the DVCon paper Sequence, Sequence on the Wall – Who’s the Fairest of Them All?

Otherwise you will need to explain more about the relationship to the streams.

In reply to dave_59:

Hi Dave,

Thanks for the reply.
All the streams are going to the same master sequencer (controlled through a virtual sequencer).
Based on the example in the Sequence related DVCon Paper, I changed the arbitration mode of the master sequencer to =>

virtual_sequencer_h.mst_sequencer.set_arbitration(SEQ_ARB_STRICT_RANDOM);

However I still don’t see the sequences in the fork join_none getting mixed up.
Following is the sequences that I see =>

UVM_INFO @ 1345 ns: FIRING MASTER SEQUENCE COMMAND ADDR=0x005214580

UVM_INFO @ 1348 ns: FIRING MASTER SEQUENCE COMMAND ADDR=0x005214680

UVM_INFO @ 1353 ns: FIRING MASTER SEQUENCE COMMAND ADDR=0x005214780

:
:

UVM_INFO @ 1870 ns: FIRING MASTER SEQUENCE COMMAND ADDR=0x004c00180

UVM_INFO @ 1898 ns: FIRING MASTER SEQUENCE COMMAND ADDR=0x004c00280

UVM_INFO @ 1901 ns: FIRING MASTER SEQUENCE COMMAND ADDR=0x004c00380

:
:

UVM_INFO @ 3173 ns: FIRING MASTER SEQUENCE COMMAND ADDR=0x00b196800

UVM_INFO @ 3282 ns: FIRING MASTER SEQUENCE COMMAND ADDR=0x00b196880

UVM_INFO @ 3344 ns: FIRING MASTER SEQUENCE COMMAND ADDR=0x00b196900

UVM_INFO @ 3347 ns: FIRING MASTER SEQUENCE COMMAND ADDR=0x00b196980


Is there something else that I can try?

In reply to alih:

HI, this is a example. Hope i can help you!


int size = 10;
int shuffle_da[];
event da[];


initial begin

  shuffle_da = new[size];
  da = new[size];

  foreach (shuffle_da[i]) begin
    shuffle_da[i] = i;
  end

  for (int j=0;j<size;j++) begin
    automatic int jj = j;
    fork begin
      @(da[jj]);
      $display("Process:%d\t", jj);
    end join_none
  end

  #0;

  shuffle_da.shuffle();

  foreach (shuffle_da[i]) begin
    ->da[shuffle_da[i]];
  end
end


In reply to haitao73:

Thanks Haitao. I modified the example you gave for my needs and it worked fine.