UVM pipelined driver cookbook

In reply to rag123:

I have tried to modify original code for 2 stage. ( Please consider in terms of concept )
And if each phase is not depends on each other you can remove pipe_limit + pipe_lock_get/put.
I hope it helps.



task run_phase(uvm_phase phase);

fork
  data_1();
  data_2();
join_none

forever begin
    seq_item_port.get(req);
    .........
    .........
    m_bfm.begin_transfer(req);
    pipeline.push_back(req);
  end
endtask : run_phase

.........
.........
.........
int pipe_limite = 0;
mbus_seq_item data_1[$];
mbus_seq_item data_2[$];

task begin_transfer(mbus_seq_item req);
  while(pipe_limite == 2) @(posedge MCLK);
  command_phase(req);
endtask: begin_transfer

task command_phase(mbus_seq_item req);
........
........
pipe_limite ++;
data_1.push_back(req);
endtask: command_phase

task data_1();
  mbus_seq_item data_1_req;
  forever begin
    while(data_1.size() > 0) begin
      data_1_req = data_1.pop_front();
      ..........
      ..........
      pipeline_lock_get();
      data_2.push_back(data_1_req);  ​
   ​end
   ​@(posedge MCLK);
 ​end
endtask : data_1

task data_2();
 ​mbus_seq_item data_2_req;
 ​forever begin
   ​while(data_2.size() > 0) begin
     pipeline_lock_put(); // End of data phase: release semaphore
     data_2_req = data_2.pop_front();
     .........
     .........
     .........
     proxy.end_transfer(current_tr);
   ​end 
  ​@(posedge MCLK);
 ​end
endtask : data_2

function void pipeline_lock_put();
  pipe_limite -= 1;
  pipeline_lock = 0;
endfunction: pipeline_lock_put

Thanks,
Harsh