Creating Transaction in UVM_Driver

Hi Team.,

I have doubt that why we need not to create an transaction type handle which we will pass in get_next_item in driver.

Ex:-

class my_driver extends uvm_driver#(my_txn);
  
  `uvm_component_utils(my_driver);
  function new(string name = "my_driver", uvm_component parent = null);
    super.new(name, parent);
  endfunction: new
  
  my_txn txn; 
  virtual my_interface vif;
  
  extern virtual function void build_phase(uvm_phase phase);
  extern virtual task run_phase(uvm_phase phase);
    
endclass: my_driver
 
function void my_driver::build_phase(uvm_phase phase);
  	super.build_phase(phase);
   // txn = my_txn::type_id::create("txn");            //**Need not to create transaction.**
  if(!uvm_config_db#(virtual my_interface)::get(this,"","my_intrf", vif))
     	begin
       		`uvm_fatal("my_driver001","Can not get vif in my_driver");
     	end
endfunction:build_phase    
    
task my_driver::run_phase(uvm_phase phase);
  	forever 
    begin
      seq_item_port.get_next_item(txn);         //**But we are passing the txn handle without creating txn.**
      @(vif.driver_cb)
   	  begin
      	if(vif.reset ==1)
      	begin
        	@(vif.driver_cb);
      	end
      	else
      	begin
      		if(txn.sel == 0)
      		begin
        		`uvm_info(get_full_name(),$sformatf("Do not have any read transaction"),UVM_NONE);
      		end
      		else
      		begin 
        		vif.driver_mp.driver_cb.addr  <= txn.addr;
        		vif.driver_mp.driver_cb.wdata <= txn.data;
        		vif.driver_mp.driver_cb.sel   <= txn.sel;
    		end
      	end
       end
      seq_item_port.item_done();
    end
endtask: run_phase

In reply to Yash_wanth12345:

The get_next_item gives you a complete transaction object. But your code will not work. You do not declare the transaction. You should do the following

task my_driver::run_phase(uvm_phase phase);
   my_txn txn;
   forever begin
      seq_item_port.get_next_item(txn);
      @(vif.driver_cb)
  ......
   end // forever
endtask

.
Or you can use instead of txn req.
req is declared in the uvm_driver base class. Then you do not need to declare it in your driver class.
Please not you have another problem in your code. You are using a clocking block. Then the line

if(vif.reset ==1)

is not correct.
It should be

if (vif.driver_mp.driver_cb.reset == 1)

In reply to chr_sue:

Hi chr_sue,

Thanks for your clarification. I understood why creating txn is not required in driver.
But, I using

if(vif.reset ==1)

after using clocking block because, i am not declaring reset in any clocking blocks inspite i am declaring in interface port itself. Attaching interface for your reference.


interface my_interface (input logic clk, reset);
  logic [3:0] addr;
  logic [31:0] wdata;
  logic [31:0] rdata;
  bit sel;
  
  clocking driver_cb@(posedge clk);
    default input #1 output #0;
    input rdata;
    output addr, wdata, sel;
  endclocking 
  
  clocking monitor_Cb@(posedge clk);
    input posedge rdata, addr, wdata, sel;
  endclocking 
  
  modport driver_mp(clocking driver_cb, input reset);
  modport monitor_mp(clocking monitor_Cb, input reset);
  
endinterface

In reply to Yash_wanth12345:

I believe it is not a good coding style to use a clocking block for a selected group of signals. I think it is legal, but not a good solution.