# Support back to back transactions in UVM driver

**URL:** <https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840>\
**Category:** UVM\
**Tags:** UVM, driver, back-to-back, b2b\
**Created:** [July 16, 2020, 4:13am UTC](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840 "2020-07-16T04:13:42Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![AidyLandoRabinovits](https://verificationacademy.com/forums/letter_avatar_proxy/v4/letter/a/e480ec/32.png) [@AidyLandoRabinovits](https://verificationacademy.com/forums/u/AidyLandoRabinovits)\
**Post date:** [July 16, 2020, 4:13am UTC](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/1 "2020-07-16T04:13:42Z")

</div>

Hello,

I have a simple driver that handle an interface with 1-cycle valid and data.  
after the transaction ends valid should de-assert.

my\_driver.sv:

```verilog

virtual taskmain_phase(uvm_phase phase);
   super.main_phase(phase);

   forever begin
      seq_item_port.get_next_item(req);
      drive_data(reg);
      seq_item_port.item_done();
   end
endtask : main_phase

// --------------------------------------

virtual protected task drive_data(item curr_item);

   // start transaction 
   @(posedge vif.clk);
   vif.valid <= 1;
   vif.data <= curr_item.data;

   // release the bus 
   @ (posedge vif.clk);
   vif.valid <= 0;
   vif.data <= $random();

endtask:drive_data

```

The driver handle each transaction with 2 clock cycles:  
1 cycle driving and second cycle to release.

Now I want to work with full bandwidth,  
I mean that valid shouldn’t de-assert between transactions

How can I do it ?

---

<div class="post-metadata">

**Author:** ![shanthi](https://verificationacademy.com/forums/letter_avatar_proxy/v4/letter/s/54ee81/32.png) [@shanthi](https://verificationacademy.com/forums/u/shanthi)\
**Post date:** [July 16, 2020, 4:43am UTC](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/2 "2020-07-16T04:43:33Z")

</div>

_In reply to [AL\_verif](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840):_  
You can control it from the sequence by giving the constraints and you can make the driver as reusable

```verilog

//sequence 

task body()
  req = item::type_id::create("req");
 // By Cange the loop limit you can control the no.of data to be driven continuously 
  repeat(10)
  begin
  start_item(req);
  assert(req.randomize() with{ valid == 1;});
  finish_item(req);
  end
  // After driving data making valid as 0
  start_item(req);
  assert(req.randomize() with{ valid == 0;});
  finish_item(req);
endtask

// Now in driver you need not to do any changes 
virtual task main_phase(uvm_phase phase);
   super.main_phase(phase);
 
   forever begin
      seq_item_port.get_next_item(req);
      drive_data(reg);
      seq_item_port.item_done();
   end
endtask : main_phase
 
 
// --------------------------------------
 
virtual protected task drive_data(item curr_item);
 
   // start transaction 
   @(posedge vif.clk);
   vif.valid <= 1;
   vif.data <= curr_item.data;
 

endtask:drive_data

```

Regards,  
Shanthi  
[www.maven-silicon.com](http://www.maven-silicon.com)

---

<div class="post-metadata">

**Author:** ![chr\_sue](https://verificationacademy.com/forums/user_avatar/verificationacademy.com/chr_sue/32/1199_2.png) [@chr\_sue](https://verificationacademy.com/forums/u/chr_sue)\
**Post date:** [July 16, 2020, 5:28am UTC](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/3 "2020-07-16T05:28:12Z")

</div>

_In reply to [shanthi](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/2):_

valid is a controö signal you should never put it to the seq\_item/transaction. But you could have 2 different operational modes, one for the standars and another one for the full band-width.

---

<div class="post-metadata">

**Author:** ![AidyLandoRabinovits](https://verificationacademy.com/forums/letter_avatar_proxy/v4/letter/a/e480ec/32.png) [@AidyLandoRabinovits](https://verificationacademy.com/forums/u/AidyLandoRabinovits)\
**Post date:** [July 16, 2020, 6:09am UTC](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/4 "2020-07-16T06:09:05Z")

</div>

_In reply to [chr\_sue](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/3):_

2 different modes of what ? 2 modes in driver and add in the seq\_item additional field to handle it ?

We can’t solve it in driver ?

---

<div class="post-metadata">

**Author:** ![AidyLandoRabinovits](https://verificationacademy.com/forums/letter_avatar_proxy/v4/letter/a/e480ec/32.png) [@AidyLandoRabinovits](https://verificationacademy.com/forums/u/AidyLandoRabinovits)\
**Post date:** [July 16, 2020, 6:17am UTC](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/5 "2020-07-16T06:17:13Z")

</div>

_In reply to [chr\_sue](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/4):_

I tried support it in driver and this is working, but I think it is little dangerous the way I did it :

my\_driver.sv:

```verilog

bit new_req;

virtual taskmain_phase(uvm_phase phase);
   super.main_phase(phase);
 
   forever begin
      seq_item_port.get_next_item(req);
      new_req = 1;
      drive_data(reg);
      new_req = 0;
      seq_item_port.item_done();
   end
endtask : main_phase
 
 
// --------------------------------------
 
virtual protected task drive_data(item curr_item);
 
   // start transaction 
   @(posedge vif.clk);
   vif.valid <= 1;
   vif.data <= curr_item.data;
 
   fork 
      begin
         // release the bus 
         #0; // To be done last in simulation tick 
         if (new_req == 0 ) begin
            @ (posedge vif.clk);
            vif.valid <= 0;
            vif.data <= $random();
         end
       end
   join_none
endtask:drive_data

```

I added a new signal new\_req that used as a flag to indicates if new req assert when the current item still didn’t release the bus.

I’m worried from raise issues on this signal.

---

<div class="post-metadata">

**Author:** ![shanthi](https://verificationacademy.com/forums/letter_avatar_proxy/v4/letter/s/54ee81/32.png) [@shanthi](https://verificationacademy.com/forums/u/shanthi)\
**Post date:** [July 16, 2020, 6:18am UTC](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/6 "2020-07-16T06:18:21Z")

</div>

_In reply to [AL\_verif](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/5):_  
If you don’t want to consider the control signal in the sequence item, you can do this way. In transaction class declare data as a dynamic array & constraint the size of the array from the sequence.

```verilog

//sequence 
 
task body()
  req = item::type_id::create("req");

 //for single transfer
  begin
  start_item(req);
  assert(req.randomize() with{ data.size == 1;});
  finish_item(req);
  end
  //for multiple transfersi.e.,full band width
  start_item(req);
  assert(req.randomize() with{data.size == 10/*or any other values per your requirement*/;});
  finish_item(req);
endtask
 
// Now in driver you need not to do any changes 
virtual task main_phase(uvm_phase phase);
   super.main_phase(phase);
 
   forever begin
      seq_item_port.get_next_item(req);
      drive_data(reg);
      seq_item_port.item_done();
   end
endtask : main_phase
 
 
// --------------------------------------
 
virtual protected task drive_data(item curr_item);
 
   // start transaction 
   foreach(curr_item.data[i])
   begin
   @(posedge vif.clk);
   vif.valid <= 1;
   vif.data <= curr_item.data[i];
   end
   
   // release the bus 
   @ (posedge vif.clk);
   vif.valid <= 0;
   vif.data <= $random();

 
endtask:drive_data

```

Regards,  
Shanthi  
[www.maven-silicon.com](http://www.maven-silicon.com)

---

<div class="post-metadata">

**Author:** ![AidyLandoRabinovits](https://verificationacademy.com/forums/letter_avatar_proxy/v4/letter/a/e480ec/32.png) [@AidyLandoRabinovits](https://verificationacademy.com/forums/u/AidyLandoRabinovits)\
**Post date:** [July 16, 2020, 6:42am UTC](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/7 "2020-07-16T06:42:21Z")

</div>

_In reply to [shanthi](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/6):_

Thank you. your solution is nice.

but the issue is that I don’t have only “data” in my item, I have some fields.  
and I don’t think it’s a good Idea to handle some queues or a queue of struct.

I believe that there is a simple solution to be done in driver.  
we just need to find it.

---

<div class="post-metadata">

**Author:** ![yasaswi93](https://verificationacademy.com/forums/letter_avatar_proxy/v4/letter/y/919ad9/32.png) [@yasaswi93](https://verificationacademy.com/forums/u/yasaswi93)\
**Post date:** [October 22, 2020, 8:34am UTC](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/8 "2020-10-22T08:34:13Z")

</div>

_In reply to [AL\_verif](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/7):_

I have a similar issue. Were you able to fix this problem?

---

<div class="post-metadata">

**Author:** ![chr\_sue](https://verificationacademy.com/forums/user_avatar/verificationacademy.com/chr_sue/32/1199_2.png) [@chr\_sue](https://verificationacademy.com/forums/u/chr_sue)\
**Post date:** [October 22, 2020, 8:43am UTC](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/9 "2020-10-22T08:43:52Z")

</div>

_In reply to [AL\_verif](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/8):_

Could you please show how your seq\_item looks like?

---

<div class="post-metadata">

**Author:** ![yasaswi93](https://verificationacademy.com/forums/letter_avatar_proxy/v4/letter/y/919ad9/32.png) [@yasaswi93](https://verificationacademy.com/forums/u/yasaswi93)\
**Post date:** [October 22, 2020, 4:56pm UTC](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/10 "2020-10-22T16:56:53Z")

</div>

_In reply to [chr\_sue](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/9):_

Hi Chris,

My Sequence body looks like this:  
// Sequence body

```verilog

task some_seq::body();
 // Start item
  start_item(item_h);
  // finish item
  finish_item(item_h);
  // wait reponse
  get_response(item_h);
endtask

```

My Driver looks like this:

```verilog

task drv::run_phase(uvm_phase phase);
  @(m_vif.drv_cb iff (m_vif.rst_n === 0));
  // Reset signals
  reset_signals();
  @(m_vif.drv_cb iff (m_vif.rst_n === 1));
 // Start driving 
  get_and_drive();
endtask : run_phase

task drv::get_and_drive();
  process main_thread;
  process rst_mon_thread;

  forever begin
   //Don't drive during reset
   while(m_vif.rst_n !== 1)
     @(m_vif.drv_cb iff (m_vif.rst_n === 1));

   //Get the next item from the sequencer
   seq_item_port.get_next_item(req);
   if(!$cast(rsp, req.clone())) begin
     `uvm_fatal(get_type_name(), "run_phase::Cast rsp<-req failed!")
   end

   rsp.set_id_info(req);

   //Drive current transaction
   fork 
     //Drive the transaction
     begin
       main_thread=process::self();
       drive_item(rsp);
       if(rst_mon_thread) rst_mon_thread.kill();
     end
     // Monitor the reset signal
     begin
       rst_mon_thread=process::self();
       @(negedge m_vif.rst_n) begin
         if(main_thread) main_thread.kill();
         //Do reset
         reset_signals();
       end
     end
   join_any

   //Send item_done and a response to the sequencer
   seq_item_port.item_done();
   seq_item_port.put_response(rsp);
  end // forever
endtask : get_and_drive

task drv::drive_item(ref item_t item_h);
 //Drive the req
 if(item_h.m_trans_type == FIRST_TYPE) begin 
   automatic int delay_cycles = $urandom_range(m_cfg_h.min_dly,m_cfg_h.max_dly);
   repeat (delay_cycles)
     @(m_vif.drv_cb);
   if(some_condition) begin
    m_vif.drv_cb.One_Valid <= 1;
    m_vif.drv_cb.One_Hdr <= item_h.m_hdr;
   end
   else begin
     automatic item_t auto_item_h = item_h;
     check_one_credits_and_drive(auto_item_h); //time consuming task
   end
    @(m_vif.drv_cb);
    m_vif.drv_cb.One_Valid <= 0;
  end
 else if(item_h.m_trans_type == SECOND_TYPE) begin
   automatic int delay_cycles = $urandom_range(m_cfg_h.min_dly,m_cfg_h.max_dly);
   repeat (delay_cycles)
   if(some_condition) begin
     m_vif.drv_cb.Second_Valid <= 1;
     m_vif.drv_cb.Second_Hdr <= item_h.m_hdr;
     m_vif.drv_cb.Second_Data <= item_h.m_data;
   end
   else begin
     automatic item_t auto_item_h = item_h;
     check_two_credits_and_drive(auto_item_h); //time consuming task
   end
   @(m_vif.drv_cb);
   m_vif.drv_cb.Second_Valid <= 0;
 end 
endtask :drive_item

```

---

<div class="post-metadata">

**Author:** ![chr\_sue](https://verificationacademy.com/forums/user_avatar/verificationacademy.com/chr_sue/32/1199_2.png) [@chr\_sue](https://verificationacademy.com/forums/u/chr_sue)\
**Post date:** [October 22, 2020, 5:46pm UTC](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/11 "2020-10-22T17:46:12Z")

</div>

_In reply to [yasaswi93](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/10):_

Thanks for sharing your code. Unfortunately the interesting piece of code was missing. item\_t.  
Please provide it.  
Another remarks:  
(1) Using the process variables is not relevant in the UVM. You can remove it. This makes your code more easy.  
(2) Do you have low-active reset. The namimg looks like this. In the code your reset is considered as highh active.  
(3) You could randomize the delay \_cycles outside of theh driver, by putting it to the seq\_item item\_t.

---

<div class="post-metadata">

**Author:** ![yasaswi93](https://verificationacademy.com/forums/letter_avatar_proxy/v4/letter/y/919ad9/32.png) [@yasaswi93](https://verificationacademy.com/forums/u/yasaswi93)\
**Post date:** [October 22, 2020, 7:32pm UTC](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/12 "2020-10-22T19:32:55Z")

</div>

_In reply to [chr\_sue](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/11):_

> _In reply to [yasaswi93](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/11):_  
> Thanks for sharing your code. Unfortunately the interesting piece of code was missing. item\_t.  
> Please provide it.  
> It is this:

```verilog

class item extends uvm_sequence_item;
rand trans_type_e m_trans_type;
rand hdr_t m_hdr;
rand logic [127:0] m_data;
`uvm_object_utils(item)
extern function new(string name="item");
endclass : item

```

Another remarks:  
(1) Using the process variables is not relevant in the UVM. You can remove it. This makes your code more easy.  
-Sure.  
(2) Do you have low-active reset. The namimg looks like this. In the code your reset is considered as high active.  
-It’s active low and there is no issue in the reset logic I think.  
(3) You could randomize the delay \_cycles outside of the driver, by putting it to the seq\_item item\_t.  
-But these delay parameters are from cfg class. So having cfg handle in every transaction didn’t seem to be good idea to me.

---

<div class="post-metadata">

**Author:** ![chr\_sue](https://verificationacademy.com/forums/user_avatar/verificationacademy.com/chr_sue/32/1199_2.png) [@chr\_sue](https://verificationacademy.com/forums/u/chr_sue)\
**Post date:** [October 23, 2020, 9:10am UTC](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/13 "2020-10-23T09:10:55Z")

</div>

_In reply to [yasaswi93](https://verificationacademy.com/forums/t/support-back-to-back-transactions-in-uvm-driver/37840/12):_

We should go ahead step-by-step.  
First mdify your sequence body task like this:

```verilog
task some_seq::body();
 // Start item
  start_item(item_h);
  item_h.randomize() with { <your constraints here> };
  finish_item(item_h);
  // wait reponse
  get_response(item_h);
endtask

```

You can pass the constraints from the config object and use it here.  
This randomizes your seq\_item data memebers wrt your needs.  
And I believ you can also simplify your driver code.  
If your interface protocol allows the valid signal to be high during execution, then assert it at the beinning of the data transfer and de-assert it after the tarnsfer has been finished.  
And please remove the mechanism with the process variables. It is not needed.
