How to run a "sequence" on multiple sequencers in Parallel?

Hi,

I need to run a sequence on all the sequencers in parallel at the same time.
I did try something like below but i know i will be ending up in running the “sequence” sequentially on all the sequencers one after the other.

task body();
uvm_info("SEQ",$sformatf("Starting %s sequence",get_full_name()),UVM_MEDIUM); fork begin for (int i = 0; i < p_sequencer.cfg.a_devices; i = i + 1) begin a_seq[i] = wr_rd_random_v_seq::type_id::create($psprintf("SEQ[%0d]",i)); a_seq[i].start(p_sequencer.a_vseqr[i]); fork begin uvm_do_on(a_seq[i],p_sequencer.a_vseqr[i]);
end
join_none
end
end
begin
if (p_sequencer.cfg.b_devices > 0) begin // {
`uvm_do_on(b_seq,p_sequencer.b_vseqr);
end
end

  join 

endtask : body

Can anyboy please help me. Thank you in advance.

Regards,
Ravi.

In reply to ravi_1822:

The issue is that you are calling the for loop inside the fork, which means that the for loop is one branch of the fork.

I am not sure if you can call a “forked for loop” in SystemVerilog like you are trying to. This is something that I think I saw either in Cuda or OpenCL.

You will have to modify the code so that each call of the for loop is a fork branch such as:

for (int i = 0; i < p_sequencer.cfg.a_devices; i = i + 1) begin
fork begin
a_seq[i] = wr_rd_random_v_seq::type_id::create($psprintf(“SEQ[%0d]”,i));
a_seq[i].start(p_sequencer.a_vseqr[i]);
end
join_none
end

In reply to janv:

Janv,

Correction in your code:

for (int i = 0; i < p_sequencer.cfg.a_devices; i = i + 1)
begin
automatic int j = i;
fork
begin
a_seq[j] = wr_rd_random_v_seq::type_id::create($psprintf(“SEQ[%0d]”,j));
a_seq[j].start(p_sequencer.a_vseqr[j]);
end
join_none
end

In reply to vipra:

The automatic variable declaration needs to go inside the fork/join_none. See the last example in section 9.3.2 Parallel blocks of the IEEE 1800-2012 LRM

In reply to dave_59:

ravi_1822,

Could you please try with both and update us with your results for each?

In reply to vipra:

Yeah sure i’ll update the results to you.Thank you.

In reply to ravi_1822:

I did Try something like below, as automatic variable needs to be declatred inside fork…jone_none.
According to the below print msgs it looks like the things are happening in parallel but I got FATAL errors something like below.
Can you help me in resolving this.

  fork 
     begin 
        for (int i = 0; i < p_sequencer.cfg.a_devices; i = i + 1) begin 
       $display(" 11 SAN_@@ a_devices %0d iteration %0d at time %0t",p_sequencer.cfg.a_devices,i,$time);
           ram_seq[i] = wr_rd_random_v_seq::type_id::create($psprintf("SEQ[%0d]",i));

           fork
            begin 
              automatic int j =i;  
             `uvm_do_on(a_seq[j],p_sequencer.a_vseqr[j]);
           end 
           join_none
        end 
     end

11 SAN_@@ a_devices 2 iteration 0 at time 0
11 SAN_@@ a_devices 2 iteration 1 at time 0
UVM_FATAL ramb_wr_rd_v_seq.sv(3) @ 0: ********.a_seq[j] [DCLPSQ] *****.a_seq[j] Error casting p_sequencer, please verify that this sequence/sequence item is intended to execute on this type of sequencer
UVM_FATAL ramb_wr_rd_v_seq.sv(3) @ 0: ********.a_seq[j] [DCLPSQ] *****.a_seq[j] Error casting p_sequencer, please verify that this sequence/sequence item is intended to execute on this type of sequencer

where i have defined “wr_rd_random_v_seq” as below

class wr_rd_random_v_seq extends wr_rd_v_seq ;

uvm_object_utils(wr_rd_random_v_seq) uvm_declare_p_sequencer(a_wr_rd_v_seqr)

wr_rd_random_seq seq_port0;
wr_rd_random_seq seq_port1;

function new (string name = “wr_rd_random_v_seq”); // {
super.new(name);
endfunction : new // }

virtual task body(); // {
uvm_info ("SEQ","Starting Sequence wr_rd_random_v_seq",UVM_MEDIUM); fork // { begin // { uvm_do_on(seq_port0,p_sequencer.port_seqr[0]);
end // }
begin // {
`uvm_do_on(seq_port1,p_sequencer.port_seqr[1]);
end // }
join // }
endtask : body // }

endclass : wr_rd_random_v_seq // }

In reply to ravi_1822:

Now It is working fine, after changing the code to like below

fork
begin
for (int i = 0; i < p_sequencer.cfg.a_devices; i = i + 1) begin
$display(" 11 SAN_@@ a_devices %0d iteration %0d at time %0t",p_sequencer.cfg.a_devices,i,$time);
ram_seq[i] = wr_rd_random_v_seq::type_id::create($psprintf(“SEQ[%0d]”,i));

fork
automatic int j =i;

begin
$display(" 22 SAN_@@ a_devices %0d iteration %0d at time %0t",a_devices,j,$time);
`uvm_do_on(a_seq[j],p_sequencer.a_vseqr[j]);
end
join_none
end
end

I could see the above display messages in the irun.log file as
11 SAN_@@ a_devices 2 iteration 0 at time 0
11 SAN_@@ a_devices 2 iteration 1 at time 0
22 SAN_@@ a_devices 2 iteration 1 at time 0
22 SAN_@@ a_devices 2 iteration 0 at time 0

Thank you to Dave,vipra and janv…

In reply to ravi_1822:

You need to do it something like below…This is working absolutely fine…

fork
begin
for (int i = 0; i < p_sequencer.cfg.a_devices; i = i + 1) begin

fork
automatic int j =i;
a_seq[i] = wr_rd_random_v_seq::type_id::create($psprintf(“SEQ[%0d]”,i));
a_seq[j].start(p_sequencer.a_vseqr[j]);
end
join_none
wait fork;

end
end