Always getting a zero output from the DUT

I have written an UVM environment for Round robin arbiter. But when I am displaying a output, which is coming in the monitor from the DUT, it always shows as zero. I am giving my code below:

`include "uvm_macros.svh"

package my_pkg;

  import uvm_pkg::*;
////////////Transaction Class///////////////////////////////
  class my_transaction extends uvm_sequence_item;
  
    `uvm_object_utils(my_transaction)
     
    
    rand  bit[3:0] requ; //Request Signal
    
    logic [3:0] grant;  //Grant Signal
  
    constraint c_requ { requ > 0; requ < 10; }
    //constraint c_data { data >= 0; data < 256; }
   
    
    function new (string name = "");
      super.new(name);
    endfunction
    
    function string convert2string;
      return $sformatf("requ=%b",requ);
    endfunction
    
     function string output2string;      
       $sformatf("grant=%b", grant);     
     endfunction

endclass: my_transaction

///////////////////////Sequencer//////////////////////////////////
  typedef uvm_sequencer #(my_transaction) my_sequencer;


////////////////////////Sequence/////////////////////////////////////
  class my_sequence extends uvm_sequence #(my_transaction);
  
    `uvm_object_utils(my_sequence)
    
    function new (string name = "");
      super.new(name);
    endfunction

    task body;
      if (starting_phase != null)
        starting_phase.raise_objection(this);

      repeat(8)
      begin
        req = my_transaction::type_id::create("req");
        start_item(req);
        if( !req.randomize() )
          `uvm_error("", "Randomize failed")
        finish_item(req);
      end
      
      if (starting_phase != null)
        starting_phase.drop_objection(this);
    endtask: body
   
  endclass: my_sequence
  
///////////////////////Driver//////////////////////////////////////
  class my_driver extends uvm_driver #(my_transaction);
  
    `uvm_component_utils(my_driver)

    virtual dut_if dut_vi; //Interface Handle

   
    function new(string name, uvm_component parent);
      super.new(name, parent);
     
    endfunction
    
    function void build_phase(uvm_phase phase);
      // Get interface reference from config database
      `uvm_info("Driver Build",$sformatf("Driver Build Phase Started"),UVM_MEDIUM);
    if( !uvm_config_db #(virtual dut_if)::get(this, "", "dut_if", dut_vi))
        `uvm_error("", "uvm_config_db::get failed")
        `uvm_info("Driver Build",$sformatf("Driver Build Phase Ended"),UVM_MEDIUM);
    endfunction 
        
      
    task run_phase(uvm_phase phase);
       my_transaction tr;
      forever 
      begin
         @(posedge dut_vi.clk);
       
        seq_item_port.get_next_item(tr);
        
        // Wiggle pins of DUT
       
        dut_vi.requ <= tr.requ;//Assigning transaction to the DUT Port
        `uvm_info("Driver to DUT",$sformatf("requ=%b",dut_vi.requ),UVM_LOW)
        
        seq_item_port.item_done();
       
        
       
      end
      
    endtask
  endclass: my_driver
//////////////////////Monitor/////////////////////////////////////
class my_monitor extends uvm_monitor;
 	`uvm_component_utils(my_monitor)
 	function new(string name, uvm_component parent);
 		super.new(name, parent);
 	endfunction
 	virtual dut_if tb_vif; // virtual interface
        uvm_analysis_port #(my_transaction) dut_inputs_port; // analysis port for DUT inputs
        uvm_analysis_port #(my_transaction) dut_outputs_port; // analysis port for DUT outputs
 	function void build_phase(uvm_phase phase);
 		dut_inputs_port = new("dut_inputs_port", this); // construct the analysis port
 		dut_outputs_port = new("dut_outputs_port", this); // construct the analysis port
                if (!uvm_config_db #(virtual dut_if)::get(this, "", "dut_if", tb_vif))
               `uvm_error("", "uvm_config_db::get failed")
 	endfunction: build_phase
 	task run_phase(uvm_phase phase);
 		my_transaction tx_in; 
                my_transaction tx_out;
                my_transaction tx_copy;
 		fork
 		// monitor DUT inputs synchronous to the interface clock
                    forever @(tb_vif.clk) 
                    begin
 		// create a new tx_write object for this cycle
 		       tx_in = my_transaction::type_id::create("tx_in");
 		       tx_in.requ = tb_vif.requ; 
                       `uvm_info("Inputs to DUT",$sformatf("request=%b",tx_in.requ),UVM_LOW)
                       dut_inputs_port.write(tx_in);
 		   end
 		
 		// create a tx_tmp object to reuse each pass of the loop
 		      tx_out = my_transaction::type_id::create("tx_out"); // tx_out is reused each loop pass
                   forever @(tb_vif.clk) 
                   begin
 			tx_out.grant = tb_vif.grant;
                       `uvm_info("Output from DUT",$sformatf("Output=%b",tx_out.grant),UVM_LOW)
 		// create a copy of tx_out to send to the scoreboard
 			$cast(tx_copy, tx_out.clone());
 			dut_outputs_port.write(tx_copy);
 		   end
 		join
 	endtask: run_phase
endclass: my_monitor 
/////////////////////////////Agent///////////////////////////////////
 class my_agent extends uvm_agent;
        `uvm_component_utils(my_agent)
         uvm_analysis_port #(my_transaction) dut_inputs_port;
         uvm_analysis_port #(my_transaction) dut_outputs_port;        
         my_driver drv;
         my_sequencer seqr;
         my_monitor mon;
       
         function new(string name, uvm_component parent);
             super.new(name, parent);
             dut_inputs_port=new("dut_inputs_port",this);
             dut_outputs_port=new("dut_outputs_port",this);
         endfunction
        
        function void build_phase(uvm_phase phase);
            super.build_phase(phase);
           `uvm_info("Agent Build",$sformatf("Agent Build Phase Started"),UVM_LOW); 
            if(get_is_active() == UVM_ACTIVE) begin
              drv = my_driver::type_id::create("drv", this);
              seqr = my_sequencer::type_id::create("seqr", this);
             end
 
              mon = my_monitor::type_id::create("mon", this);
         
          `uvm_info("Agent Build",$sformatf("Agent Build Phase Ended"),UVM_LOW); 
      
     endfunction : build_phase
 
        
  // connect_phase
 	function void connect_phase(uvm_phase phase);
 		// set agent's analysis ports to point to the monitor's ports
 		dut_inputs_port = mon.dut_inputs_port;
 		dut_outputs_port = mon.dut_outputs_port;
 		if (is_active == UVM_ACTIVE) begin
                 drv.seq_item_port.connect(seqr.seq_item_export); // connect driver to sequencer
 		end 
    endfunction: connect_phase 
endclass 
      
////////////////////////////Scoreboard/////////////////////////////
 `uvm_analysis_imp_decl(_verify_outputs)
 `uvm_analysis_imp_decl(_inputs)
       class my_scoreboard extends uvm_scoreboard;
 			`uvm_component_utils(my_scoreboard)
 			function new(string name, uvm_component parent );
 				super.new(name, parent);
 			endfunction: new
         uvm_analysis_imp_verify_outputs #(my_transaction, my_scoreboard) dut_out_imp_export;
         uvm_analysis_imp_inputs #(my_transaction, my_scoreboard) dut_in_imp_export;
         mailbox #(my_transaction) expected_fifo=new(); // SystemVerilog mailbox for my_tx handles
         int num_passed, num_failed; // score cards
 		function void build_phase(uvm_phase phase);
 			dut_out_imp_export = new("dut_out_imp_export", this);
                        dut_in_imp_export = new("dut_in_imp_export", this);
                endfunction 
         function void write_inputs(my_transaction t);
 			my_transaction expected_tx;
 			$cast(expected_tx, t.clone()); // create new my_tx object and preserve input vals
 			// calculate expected results and store in FIFO
 			if(t.requ[0])
          		expected_tx.grant=4'b0001;
        	        else if(t.requ[1])
          		expected_tx.grant=4'b0010;
                         expected_fifo.try_put(expected_tx); // save transaction handle
            endfunction: write_inputs 
              
           
         	function void write_verify_outputs(my_transaction t);
                       my_transaction expected_tx=new();
              
                       expected_fifo.try_get(expected_tx); // blocks if FIFO is empty
                       if (t.grant !== expected_tx.grant)
 				begin: mismatch
 						  `uvm_error("SCBD_ERR:", "DUT outputs did not match expected results")
                                                  `uvm_info("DUT OUT:",$sformatf("Grant=%b",t.grant), UVM_LOW)
                                                  `uvm_info("EXPECTED:", $sformatf("Grant=%b",expected_tx.grant), UVM_LOW)
 			 			   num_failed++;
 				end: mismatch
 			  else 
                begin:match
                  `uvm_info("DUT OUT:",$sformatf("Grant=%b",t.grant), UVM_LOW)
                  `uvm_info("EXPECTED:",$sformatf ("Grant=%b",expected_tx.grant), UVM_LOW)
                   num_passed++;
                end:match
                
             endfunction: write_verify_outputs 
 		
        function void report_phase(uvm_phase phase);
 			`uvm_info("Scoreboard:", $sformatf("\n passed=%0d failed=%0d\n",num_passed, num_failed),UVM_NONE)
        endfunction: report_phase 

	
endclass
////////////////////////////Environment/////////////////////////////  
  class my_env extends uvm_env;
 		`uvm_component_utils(my_env)
		 function new(string name, uvm_component parent);
 			super.new(name, parent);
 		 endfunction: new
 		 my_agent agent;
 		 my_scoreboard scoreboard;
 		 function void build_phase(uvm_phase phase);
 			agent = my_agent::type_id::create("agent", this);
 			scoreboard = my_scoreboard::type_id::create("scoreboard", this);
 		 endfunction: build_phase
 		 function void connect_phase(uvm_phase phase);
 			agent.dut_inputs_port.connect(scoreboard.dut_in_imp_export);
 			agent.dut_outputs_port.connect(scoreboard.dut_out_imp_export);
 		 endfunction: connect_phase
endclass: my_env 
//////////////////////////////Test/////////////////////////////////////  
  class my_test extends uvm_test;
 
    `uvm_component_utils(my_test)
 
  my_env env;
  
 
    function new(string name = "my_test",uvm_component parent=null);
    super.new(name,parent);
  endfunction : new
 
  virtual function void build_phase(uvm_phase phase);
    super.build_phase(phase);
 
    env = my_env::type_id::create("env", this);
   
  endfunction : build_phase
 
  task run_phase(uvm_phase phase);
			my_sequence seq;
            phase.raise_objection(.obj(this));
		    seq = my_sequence::type_id::create("seq");
				assert(seq.randomize());
				seq.start(env.agent.seqr);
			phase.drop_objection(.obj(this));
  endtask: run_phase 
 
endclass
  
endpackage

///////////////////////////Top module////////////////////////////
module top;

  import uvm_pkg::*;
  import my_pkg::*;
  
  dut_if dut_if1 ();
  
  dut    dut1 (dut_if1.clk,dut_if1.rst_an,dut_if1.requ,dut_if1.grant);

  // Clock generator
  initial
  begin
    dut_if1.clk = 0;
    forever #5 dut_if1.clk = ~dut_if1.clk;
  end

 
 initial
   begin
    dut_if1.rst_an = 1'b0;
    #10;
    dut_if1.rst_an = 1'b1; 
  end
 

  
  
  initial
  begin
    uvm_config_db #(virtual dut_if)::set(null, "*", "dut_if", dut_if1);
    
    uvm_top.finish_on_completion = 1;
    
    run_test("my_test");
  end

endmodule: top
      
     


///////////////////////////////END///////////////////////////////////



///////////////////////////Interface//////////////////////////////////////////////////////////////
interface dut_if;
  logic clk,rst_an;
  logic [3:0] requ;
  //logic [7:0] data;
  logic [3:0]grant;

endinterface

In reply to Prathamesh Govardhane:

Did you check what comes out of your DUT?
Are the port Signals are really changing on each clock?

In reply to chr_sue:

Yes. I have checked the output of the DUT. DUT is working.

In reply to Prathamesh Govardhane:
Please insert anothe uvm_info like this:

 		       tx_in = my_transaction::type_id::create("tx_in");
                       `uvm_info("Inputs to DUT",$sformatf("request=%b",tb_vif.requ),UVM_LOW)
 		       tx_in.requ = tb_vif.requ; 
                       `uvm_info("Inputs to DUT",$sformatf("request=%b",tx_in.requ),UVM_LOW)
                       dut_inputs_port.write(tx_in);

In reply to Prathamesh Govardhane:

You need to implement do_copy() and do_clone() in my_transaction.

In reply to cgales:

I have added wait statement in the driver for grant is coming or not. If grant comes then only the next request will be sent. It is giving me the output.

I will also try the way you have told.

Thank you for your response.

In reply to chr_sue:

Thank you for your response