SPI read data

Hi,
In my sequence item , I have address ,write data and read data.

In sequence , I am randomizing the sequence item.

for Write data, SPI Master give the address and data to the Slave.
for Read data, SPI Master give the address and get the Data from Slave.

In my Master driver and Monitor ,I can able to get the read data correctly. But while printing the read data in my sequence I am getting the value read data=0.

Can anyone help me with this.?

Thanks,
Sandeep Gaur

In reply to Sandeep Gaur:

It’s difficult to comment on an issue without seeing the code. Can you share the sequence and driver code ?

In reply to Rahulkumar Patel:

Hi ,
Please find the code below, In the BFM I can get the read data correctly but in sequence the read data = 0.

class spi_sequence extends uvm_sequence#(spi_trans);

`uvm_object_utils(spi_sequence)

function new(string name = “spi_sequence”);
super.new(name);
endfunction

task body();
spi_trans spi_seq_item;

for(int i=0; i<2; i=i+1)
begin //{
spi_seq_item = spi_trans::type_id::create(“spi_seq_item”);
start_item(spi_seq_item);
case(i)
0 : begin //{
void’(spi_seq_item.randomize() with {pkt_type == WRITE; bit_order == MSB; mode == MODE0; address == 'h01F0; write_data == ‘hAAAA_5555; });
end //}
1 : begin //{
void’(spi_seq_item.randomize() with {pkt_type == READ; bit_order == MSB; mode == MODE0; address == 'h01F0; });
end //}
endcase

        `uvm_info(get_type_name(),$sformatf("SEQ_0: Write and read spi_seq_item.write_data : %0h spi_seq_item.read_data : %0h spi_seq_item.address : %0h", spi_seq_item.write_data, spi_seq_item.read_data, spi_seq_item.address),UVM_LOW)

  finish_item(spi_seq_item);

#10000ns;

    `uvm_info(get_type_name(),$sformatf("SEQ_1: Write and read spi_seq_item.write_data : %0h spi_seq_item.read_data : %0h spi_seq_item.address : %0h", spi_seq_item.write_data, spi_seq_item.read_data, spi_seq_item.address),UVM_LOW)
 end //}

endtask : body

endclass : spi_sequence

class spi_bfm extends uvm_driver #(spi_trans);

`uvm_component_utils(spi_bfm)

spi_trans spi_seq_item;

virtual spi_interface spi_intf;
spi_config spi_cfg;
spi_trans spi_wr_rd_req;
spi_trans spi_wr_rd_data_q[$];
spi_trans data_to_mosi;
bit cmd_assert;

bit [SPI_ADDR_WIDTH-1 : 0] addr; bit [SPI_DATA_WIDTH-1 : 0] data_payload;

extern function new(string name = “spi_bfm”, uvm_component parent = null);
extern function void build_phase(uvm_phase phase);
extern task run_phase(uvm_phase phase);
extern task collect_wr_rd_req(spi_trans wr_rd_request);
extern task set_mode(spi_trans mode_sel);
extern task initialisation();
extern task drive(spi_trans spi_seq_item);
extern task send_addr(input bit [SPI_ADDR_WIDTH-1 : 0] addr); extern task send_data(input bit [SPI_DATA_WIDTH-1 : 0] data_payload);
extern task receive_data(spi_trans spi_seq_item);
extern task receive_dummy(spi_trans spi_seq_item);

endclass : spi_bfm

function spi_bfm::new(string name = “spi_bfm”, uvm_component parent = null);
super.new(name,parent);
endfunction : new

function void spi_bfm::build_phase(uvm_phase phase); // {
super.build_phase(phase);

if(!uvm_config_db #(virtual spi_interface)::get(this, “”, “spi_interface”, spi_intf))
`uvm_fatal(“CONFIG FATAL”,“CAN’T GET THE SPI INTERFACE”)

if(!uvm_config_db #(spi_config)::get(this, “”, “spi_cfg”, spi_cfg))
`uvm_fatal(“CONFIG FATAL”,“CAN’T GET THE SPI CONFIG”)

endfunction : build_phase // }

task spi_bfm::run_phase(uvm_phase phase); // {

`uvm_info(“SPI_BFM”, $sformatf("Entering run_phase "),UVM_LOW);

forever
begin //{
spi_trans spi_seq_item;

seq_item_port.get_next_item(spi_seq_item);

if(spi_seq_item.pkt_type == WRITE || spi_seq_item.pkt_type == READ)
begin //{
`uvm_info(get_type_name(),$sformatf("------ ENTERED PACKET TYPE IS : %s ", spi_seq_item.pkt_type.name),UVM_LOW)
if(spi_seq_item != null)
begin //{
set_mode(spi_seq_item);
initialisation();
fork
collect_wr_rd_req(spi_seq_item);
join
end //}
end //}

 seq_item_port.item_done();

`uvm_info(get_type_name(),$sformatf("------ ENTERED ITEM DONE "),UVM_LOW)
end //}

endtask : run_phase // }

task spi_bfm::collect_wr_rd_req (spi_trans wr_rd_request); // {
@(posedge spi_intf.sample_clk)
spi_wr_rd_req = new wr_rd_request;
spi_wr_rd_data_q.push_back(spi_wr_rd_req);
drive(spi_wr_rd_req);
`uvm_info(get_type_name(),$sformatf("------ CHECK RECEIVE DATA : %h %h ",spi_intf.spi_rd_data,spi_wr_rd_req.read_data),UVM_LOW)
endtask : collect_wr_rd_req // }

task spi_bfm::set_mode(spi_trans mode_sel);
if(mode_sel.mode == 2 || mode_sel.mode == 3)
begin //{
spi_intf.clk_pol = 1’b1;
uvm_info(get_type_name(),$sformatf("------ ENTERED MODE SET : %d , clk_pol : %d ",mode_sel.mode,spi_intf.clk_pol),UVM_LOW) end //} else begin //{ spi_intf.clk_pol = 1'b0; uvm_info(get_type_name(),$sformatf("------ ENTERED MODE SET : %d , clk_pol : %d ",mode_sel.mode,spi_intf.clk_pol),UVM_LOW)
end //}
endtask : set_mode

task spi_bfm::initialisation();
spi_intf.ss = 1’b1;
spi_intf.mosi = 1’b0;

if(spi_intf.clk_pol == 0)
spi_intf.spi_clk <= 1’b0;
else
spi_intf.spi_clk <= 1’b1;

endtask : initialisation

task spi_bfm::drive(spi_trans spi_seq_item);
begin //{
int burst_cnt;

 @(posedge spi_intf.sample_clk)
 if(spi_wr_rd_data_q.size() > 0)
  begin //{
   data_to_mosi           =  spi_wr_rd_data_q.pop_front();

   spi_intf.mode          =  data_to_mosi.mode;
   spi_intf.clk_pol       =  data_to_mosi.clk_pol;
   spi_intf.clk_phase     =  data_to_mosi.clk_phase;
   spi_intf.bit_order     =  data_to_mosi.bit_order;
   spi_intf.pkt_type      =  data_to_mosi.pkt_type;

   addr                   =  data_to_mosi.address; 

   spi_intf.ss           <=  1'b0;
  #(spi_cfg.t_ss_h2l - (spi_cfg.t_clk/2));
   send_addr(addr);

   if(data_to_mosi.pkt_type == WRITE)
     begin //{ 

`uvm_info(get_type_name(),$sformatf("------ ENTERED WRITE : %d ",data_to_mosi.pkt_type),UVM_LOW)
send_data(data_to_mosi.write_data);
#(spi_cfg.t_ss_l2h);
spi_intf.ss <= 1’b1;
#(spi_cfg.t_ss_high);
end //}

   if(data_to_mosi.pkt_type == READ)
     begin //{ 
     //  spi_intf.mosi <= 0;

uvm_info(get_type_name(),$sformatf("------ ENTERED READ : %d ",data_to_mosi.pkt_type),UVM_LOW) receive_data(data_to_mosi); uvm_info(get_type_name(),$sformatf(“------ CHECK RECEIVE DATA : %h %h , %h”,spi_intf.spi_rd_data,spi_seq_item.read_data,data_to_mosi.read_data),UVM_LOW)
#(spi_cfg.t_ss_l2h);
spi_intf.ss <= 1’b1;
#(spi_cfg.t_ss_high);
end //}
end //}

end //}
endtask : drive

task spi_bfm::send_addr(input bit [SPI_ADDR_WIDTH-1 : 0] addr); uvm_info(get_type_name(),$sformatf("------ ENTERED SEND ADDR : %h ",addr),UVM_LOW)
spi_intf.addr_start = 1’b1;
cmd_assert = 1’b1;

for(int i=0; i<(`SPI_ADDR_WIDTH/8); i=i+1) 
 begin //{
  repeat(8)
   begin //{
     if(spi_intf.clk_phase == 0)
       begin //{
           if(spi_intf.bit_order == 0)
            begin //{
             spi_intf.mosi <= addr[`SPI_ADDR_WIDTH-1];
             spi_intf.spi_addr <= addr[`SPI_ADDR_WIDTH-1];
  `uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MOSI PHASE 0 spi_intf.mosi : %d ", spi_intf.mosi),UVM_LOW)
            end //}
           else
            begin //{
             spi_intf.mosi <= addr[0];
             spi_intf.spi_addr <= addr[0];
  `uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MOSI PHASE 0 spi_intf.mosi : %d ", spi_intf.mosi),UVM_LOW)
            end //}
       end //} 

     if(spi_intf.clk_phase == 1)
       begin //{
           if(spi_intf.bit_order == 0)
            begin //{
             spi_intf.mosi <= addr[`SPI_ADDR_WIDTH-1];
             spi_intf.spi_addr <= addr[`SPI_ADDR_WIDTH-1];
`uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MOSI PHASE 1 spi_intf.mosi : %d ", spi_intf.mosi),UVM_LOW)
            end //}
           else
            begin //{
             spi_intf.mosi <= addr[0];
             spi_intf.spi_addr <= addr[0];
`uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MOSI PHASE 1 spi_intf.mosi : %d ", spi_intf.mosi),UVM_LOW)
            end //}
       end //}

       if(spi_intf.bit_order == 0)
        begin //{
         addr <<= 1;
        end //}
       else
        begin //{
         if(cmd_assert == 0)
          addr >>= 1;
        end //}
   end //}
 end //}

endtask : send_addr

task spi_bfm::send_data(input bit [SPI_DATA_WIDTH-1 : 0] data_payload); uvm_info(get_type_name(),$sformatf("------ ENTERED SEND DATA : %h “,data_payload),UVM_LOW)
for(int i=0; i<(SPI_DATA_WIDTH/8); i=i+1) begin //{ repeat(8) begin //{ if(spi_intf.clk_phase == 0) begin //{ if(spi_intf.bit_order == 0) begin //{ spi_intf.mosi <= data_payload[SPI_DATA_WIDTH-1];
uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MOSI PHASE 0 spi_intf.mosi : %d ", spi_intf.mosi),UVM_LOW) end //} else begin //{ spi_intf.mosi <= data_payload[0]; uvm_info(get_type_name(),$sformatf(”------ ENTERED SEND TO MOSI PHASE 0 spi_intf.mosi : %d ", spi_intf.mosi),UVM_LOW)
end //}
end //}

      if(spi_intf.clk_phase == 1)
        begin //{
         if(spi_intf.bit_order == 0)
          begin //{
           spi_intf.mosi <= data_payload[`SPI_DATA_WIDTH-1];
 `uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MOSI PHASE 1 spi_intf.mosi : %d ", spi_intf.mosi),UVM_LOW)
          end //}
         else
          begin //{
           spi_intf.mosi <= data_payload[0];
 `uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MOSI PHASE 1 spi_intf.mosi : %d ", spi_intf.mosi),UVM_LOW)
          end //}
        end //}

        if(spi_intf.bit_order == 0)
          data_payload <<= 1;
        else
          data_payload >>= 1;

    end //}
  end //}

endtask : send_data

task spi_bfm::receive_data(spi_trans spi_seq_item);

uvm_info(get_type_name(),$sformatf("------ ENTERED RECEIVE DATA "),UVM_LOW) for(int i=0; i<(SPI_DATA_WIDTH/8); i=i+1)
begin //{
repeat(8)
begin //{
if(spi_intf.clk_phase == 0)
begin //{
if(spi_intf.bit_order == 0)
begin //{
spi_intf.spi_rd_data[0] <= spi_intf.miso;
spi_intf.temp_miso <= spi_intf.miso;
uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MISO PHASE 0 spi_intf.miso : %d ", spi_intf.miso),UVM_LOW) end //} else begin //{ spi_intf.spi_rd_data[31] <= spi_intf.miso; spi_intf.temp_miso <= spi_intf.miso; uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MISO PHASE 0 spi_intf.miso : %d ", spi_intf.miso),UVM_LOW)
end //}

         if(spi_intf.bit_order == 0)
           spi_intf.spi_rd_data <<= 1;
         else
           spi_intf.spi_rd_data >>= 1;

        end //} 
  
      if(spi_intf.clk_phase == 1)
        begin //{
         if(spi_intf.bit_order == 0)
          spi_intf.spi_rd_data <<= 1;
         else
          spi_intf.spi_rd_data >>= 1;

         if(spi_intf.bit_order == 0)
          begin //{
             spi_intf.spi_rd_data[0]   =  spi_intf.miso; 
             spi_intf.temp_miso   =  spi_intf.miso; 
`uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MISO PHASE 1 spi_intf.miso : %d ", spi_intf.miso),UVM_LOW)
          end //}
         else
          begin //{
             spi_intf.spi_rd_data[31]  =  spi_intf.miso; 
             spi_intf.temp_miso   =  spi_intf.miso; 
 `uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MISO PHASE 1 spi_intf.miso : %d ", spi_intf.miso),UVM_LOW)
          end //}
        end //}
    end //}
 end //}
 spi_seq_item.read_data = spi_intf.spi_rd_data;
`uvm_info(get_type_name(),$sformatf("------ ENTERED RECEIVE DATA : %h  %h",spi_intf.spi_rd_data,spi_seq_item.read_data),UVM_LOW)

endtask : receive_data

In reply to Sandeep Gaur:

Few changes are need in your code:

  1. driver : driver need to send the response back
  2. sequence : sequence need to collect the response for each transaction

//Change in driver
forever
begin //{
spi_trans spi_seq_item;

seq_item_port.get_next_item(spi_seq_item);

/*...other code ... */

//Need to send the response back which have read data 
//seq_item_port.item_done();
seq_item_port.item_done(spi_seq_item);

end //}


//change in sequence
class spi_sequence extends uvm_sequence#(spi_trans);

/*...other code ... */

   task body();
        spi_trans spi_seq_item;

        for(int i=0; i<2; i=i+1)
        begin //{
            spi_seq_item = spi_trans::type_id::create("spi_seq_item");
            start_item(spi_seq_item);
            case(i)
              0 : begin //{
              void'(spi_seq_item.randomize() with {pkt_type == WRITE; bit_order == MSB; mode == MODE0; address == 'h01F0; write_data == 'hAAAA_5555; });
              end //}
              1 : begin //{
              void'(spi_seq_item.randomize() with {pkt_type == READ; bit_order == MSB; mode == MODE0; address == 'h01F0; });
              end //}
            endcase

            `uvm_info(get_type_name(),$sformatf("SEQ_0: Write and read spi_seq_item.write_data : %0h spi_seq_item.read_data : %0h spi_seq_item.address : %0h", spi_seq_item.write_data, spi_seq_item.read_data, spi_seq_item.address),UVM_LOW)

            finish_item(spi_seq_item);

            //#10000ns;
            //change : Need to collect the responce back for each transaction
            get_response(rsp);
            
            //This is not require if you use rsp.read_data, rsp.address etc. 
            $cast(spi_seq_item,rsp);


            `uvm_info(get_type_name(),$sformatf("SEQ_1: Write and read spi_seq_item.write_data : %0h spi_seq_item.read_data : %0h spi_seq_item.address : %0h", spi_seq_item.write_data, spi_seq_item.read_data, spi_seq_item.address),UVM_LOW)

        end //}

   endtask : body
endclass : spi_sequence

In reply to Rahulkumar Patel:

Hi Rahul,
I have tried this code , but still it is not working. I dont know what is wrong here everything is fine in the code…but still cannot get the read data

Thanks,
Sandeep Gaur

In reply to Sandeep Gaur:

In reply to Rahulkumar Patel:
Hi Rahul,
I have tried this code , but still it is not working. I dont know what is wrong here everything is fine in the code…but still cannot get the read data
Thanks,
Sandeep Gaur

can you show modified driver, sequence code ? please use code tag.

In reply to Rahulkumar Patel:

class spi_sequence extends uvm_sequence#(spi_trans);

`uvm_object_utils(spi_sequence)

function new(string name = "spi_sequence");
super.new(name);
endfunction

task body();
spi_trans spi_seq_item;

for(int i=0; i<2; i=i+1)
begin //{
spi_seq_item = spi_trans::type_id::create("spi_seq_item");
start_item(spi_seq_item);
case(i)
0 : begin //{
void'(spi_seq_item.randomize() with {pkt_type == WRITE; bit_order == MSB; mode == MODE0; address == 'h01F0; write_data == 'hAAAA_5555; });
end //}
1 : begin //{
void'(spi_seq_item.randomize() with {pkt_type == READ; bit_order == MSB; mode == MODE0; address == 'h01F0; });
end //}
endcase

`uvm_info(get_type_name(),$sformatf("SEQ_0: Write and read spi_seq_item.write_data : %0h spi_seq_item.read_data : %0h spi_seq_item.address : %0h", spi_seq_item.write_data, spi_seq_item.read_data, spi_seq_item.address),UVM_LOW)

finish_item(spi_seq_item);

//#10000ns;

  get_response(rsp);
 
  $cast(spi_seq_item,rsp);

`uvm_info(get_type_name(),$sformatf("SEQ_1: Write and read spi_seq_item.write_data : %0h spi_seq_item.read_data : %0h spi_seq_item.address : %0h", spi_seq_item.write_data, spi_seq_item.read_data, spi_seq_item.address),UVM_LOW)
end //}

endtask : body

endclass : spi_sequence

class spi_bfm extends uvm_driver #(spi_trans);

`uvm_component_utils(spi_bfm)

spi_trans spi_seq_item;

virtual spi_interface spi_intf;
spi_config spi_cfg;
spi_trans spi_wr_rd_req;
spi_trans spi_wr_rd_data_q[$];
spi_trans data_to_mosi;
bit cmd_assert;

bit [`SPI_ADDR_WIDTH-1 : 0] addr;
bit [`SPI_DATA_WIDTH-1 : 0] data_payload;

extern function new(string name = "spi_bfm", uvm_component parent = null);
extern function void build_phase(uvm_phase phase);
extern task run_phase(uvm_phase phase);
extern task collect_wr_rd_req(spi_trans wr_rd_request);
extern task set_mode(spi_trans mode_sel);
extern task initialisation();
extern task drive(spi_trans spi_seq_item);
extern task send_addr(input bit [`SPI_ADDR_WIDTH-1 : 0] addr);
extern task send_data(input bit [`SPI_DATA_WIDTH-1 : 0] data_payload);
extern task receive_data(spi_trans spi_seq_item);
extern task receive_dummy(spi_trans spi_seq_item);

endclass : spi_bfm

function spi_bfm::new(string name = "spi_bfm", uvm_component parent = null);
super.new(name,parent);
endfunction : new

function void spi_bfm::build_phase(uvm_phase phase); // {
super.build_phase(phase);

if(!uvm_config_db #(virtual spi_interface)::get(this, "", "spi_interface", spi_intf))
`uvm_fatal("CONFIG FATAL","CAN'T GET THE SPI INTERFACE")

if(!uvm_config_db #(spi_config)::get(this, "", "spi_cfg", spi_cfg))
`uvm_fatal("CONFIG FATAL","CAN'T GET THE SPI CONFIG")

endfunction : build_phase // }

task spi_bfm::run_phase(uvm_phase phase); // {

`uvm_info("SPI_BFM", $sformatf("Entering run_phase "),UVM_LOW);

forever
begin //{
spi_trans spi_seq_item;

seq_item_port.get_next_item(spi_seq_item);
if(spi_seq_item.pkt_type == WRITE || spi_seq_item.pkt_type == READ)
begin //{
`uvm_info(get_type_name(),$sformatf("------ ENTERED PACKET TYPE IS : %s ", spi_seq_item.pkt_type.name),UVM_LOW)
if(spi_seq_item != null)
begin //{
set_mode(spi_seq_item);
initialisation();
fork
collect_wr_rd_req(spi_seq_item);
join
end //}
end //}

seq_item_port.item_done(spi_seq_item);
`uvm_info(get_type_name(),$sformatf("------ ENTERED ITEM DONE "),UVM_LOW)
end //}

endtask : run_phase // }

task spi_bfm::collect_wr_rd_req (spi_trans wr_rd_request); // {
@(posedge spi_intf.sample_clk)
spi_wr_rd_req = new wr_rd_request;
spi_wr_rd_data_q.push_back(spi_wr_rd_req);
drive(spi_wr_rd_req);
`uvm_info(get_type_name(),$sformatf("------ CHECK RECEIVE DATA : %h %h ",spi_intf.spi_rd_data,spi_wr_rd_req.read_data),UVM_LOW)
endtask : collect_wr_rd_req // }

task spi_bfm::set_mode(spi_trans mode_sel);
if(mode_sel.mode == 2 || mode_sel.mode == 3)
begin //{
spi_intf.clk_pol = 1'b1;
`uvm_info(get_type_name(),$sformatf("------ ENTERED MODE SET : %d , clk_pol : %d ",mode_sel.mode,spi_intf.clk_pol),UVM_LOW)
end //}
else
begin //{
spi_intf.clk_pol = 1'b0;
`uvm_info(get_type_name(),$sformatf("------ ENTERED MODE SET : %d , clk_pol : %d ",mode_sel.mode,spi_intf.clk_pol),UVM_LOW)
end //}
endtask : set_mode

task spi_bfm::initialisation();
spi_intf.ss = 1'b1;
spi_intf.mosi = 1'b0;

if(spi_intf.clk_pol == 0)
spi_intf.spi_clk <= 1'b0;
else
spi_intf.spi_clk <= 1'b1;

endtask : initialisation

task spi_bfm::drive(spi_trans spi_seq_item);
begin //{
int burst_cnt;

@(posedge spi_intf.sample_clk)
if(spi_wr_rd_data_q.size() > 0)
begin //{
data_to_mosi = spi_wr_rd_data_q.pop_front();

spi_intf.mode = data_to_mosi.mode;
spi_intf.clk_pol = data_to_mosi.clk_pol;
spi_intf.clk_phase = data_to_mosi.clk_phase;
spi_intf.bit_order = data_to_mosi.bit_order;
spi_intf.pkt_type = data_to_mosi.pkt_type;

addr = data_to_mosi.address;

spi_intf.ss <= 1'b0;
#(spi_cfg.t_ss_h2l - (spi_cfg.t_clk/2));
send_addr(addr);

if(data_to_mosi.pkt_type == WRITE)
begin //{
`uvm_info(get_type_name(),$sformatf("------ ENTERED WRITE : %d ",data_to_mosi.pkt_type),UVM_LOW)
send_data(data_to_mosi.write_data);
#(spi_cfg.t_ss_l2h);
spi_intf.ss <= 1'b1;
#(spi_cfg.t_ss_high);
end //}

if(data_to_mosi.pkt_type == READ)
begin //{
// spi_intf.mosi <= 0;
`uvm_info(get_type_name(),$sformatf("------ ENTERED READ : %d ",data_to_mosi.pkt_type),UVM_LOW)
receive_data(data_to_mosi);
`uvm_info(get_type_name(),$sformatf("------ CHECK RECEIVE DATA : %h %h , %h",spi_intf.spi_rd_data,spi_seq_item.read_data,data_to_mosi.read_data),UVM_LOW)
#(spi_cfg.t_ss_l2h);
spi_intf.ss <= 1'b1;
#(spi_cfg.t_ss_high);
end //}
end //}

end //}
endtask : drive

task spi_bfm::send_addr(input bit [`SPI_ADDR_WIDTH-1 : 0] addr);
`uvm_info(get_type_name(),$sformatf("------ ENTERED SEND ADDR : %h ",addr),UVM_LOW)
spi_intf.addr_start = 1'b1;
cmd_assert = 1'b1;

for(int i=0; i<(`SPI_ADDR_WIDTH/8); i=i+1)
begin //{
repeat(8)
begin //{
if(spi_intf.clk_phase == 0)
begin //{
if(spi_intf.bit_order == 0)
begin //{
spi_intf.mosi <= addr[`SPI_ADDR_WIDTH-1];
spi_intf.spi_addr <= addr[`SPI_ADDR_WIDTH-1];
`uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MOSI PHASE 0 spi_intf.mosi : %d ", spi_intf.mosi),UVM_LOW)
end //}
else
begin //{
spi_intf.mosi <= addr[0];
spi_intf.spi_addr <= addr[0];
`uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MOSI PHASE 0 spi_intf.mosi : %d ", spi_intf.mosi),UVM_LOW)
end //}
end //}

if(spi_intf.clk_phase == 1)
begin //{
if(spi_intf.bit_order == 0)
begin //{
spi_intf.mosi <= addr[`SPI_ADDR_WIDTH-1];
spi_intf.spi_addr <= addr[`SPI_ADDR_WIDTH-1];
`uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MOSI PHASE 1 spi_intf.mosi : %d ", spi_intf.mosi),UVM_LOW)
end //}
else
begin //{
spi_intf.mosi <= addr[0];
spi_intf.spi_addr <= addr[0];
`uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MOSI PHASE 1 spi_intf.mosi : %d ", spi_intf.mosi),UVM_LOW)
end //}
end //}

if(spi_intf.bit_order == 0)
begin //{
addr <<= 1;
end //}
else
begin //{
if(cmd_assert == 0)
addr >>= 1;
end //}
end //}
end //}
endtask : send_addr

task spi_bfm::send_data(input bit [`SPI_DATA_WIDTH-1 : 0] data_payload);
`uvm_info(get_type_name(),$sformatf("------ ENTERED SEND DATA : %h ",data_payload),UVM_LOW)
for(int i=0; i<(`SPI_DATA_WIDTH/8); i=i+1)
begin //{
repeat(8)
begin //{
if(spi_intf.clk_phase == 0)
begin //{
if(spi_intf.bit_order == 0)
begin //{
spi_intf.mosi <= data_payload[`SPI_DATA_WIDTH-1];
`uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MOSI PHASE 0 spi_intf.mosi : %d ", spi_intf.mosi),UVM_LOW)
end //}
else
begin //{
spi_intf.mosi <= data_payload[0];
`uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MOSI PHASE 0 spi_intf.mosi : %d ", spi_intf.mosi),UVM_LOW)
end //}
end //}

if(spi_intf.clk_phase == 1)
begin //{
if(spi_intf.bit_order == 0)
begin //{
spi_intf.mosi <= data_payload[`SPI_DATA_WIDTH-1];
`uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MOSI PHASE 1 spi_intf.mosi : %d ", spi_intf.mosi),UVM_LOW)
end //}
else
begin //{
spi_intf.mosi <= data_payload[0];
`uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MOSI PHASE 1 spi_intf.mosi : %d ", spi_intf.mosi),UVM_LOW)
end //}
end //}

if(spi_intf.bit_order == 0)
data_payload <<= 1;
else
data_payload >>= 1;

end //}
end //}
endtask : send_data

task spi_bfm::receive_data(spi_trans spi_seq_item);

`uvm_info(get_type_name(),$sformatf("------ ENTERED RECEIVE DATA "),UVM_LOW)
for(int i=0; i<(`SPI_DATA_WIDTH/8); i=i+1)
begin //{
repeat(8)
begin //{
if(spi_intf.clk_phase == 0)
begin //{
if(spi_intf.bit_order == 0)
begin //{
spi_intf.spi_rd_data[0] <= spi_intf.miso;
spi_intf.temp_miso <= spi_intf.miso;
`uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MISO PHASE 0 spi_intf.miso : %d ", spi_intf.miso),UVM_LOW)
end //}
else
begin //{
spi_intf.spi_rd_data[31] <= spi_intf.miso;
spi_intf.temp_miso <= spi_intf.miso;
`uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MISO PHASE 0 spi_intf.miso : %d ", spi_intf.miso),UVM_LOW)
end //}

if(spi_intf.bit_order == 0)
spi_intf.spi_rd_data <<= 1;
else
spi_intf.spi_rd_data >>= 1;

end //}

if(spi_intf.clk_phase == 1)
begin //{
if(spi_intf.bit_order == 0)
spi_intf.spi_rd_data <<= 1;
else
spi_intf.spi_rd_data >>= 1;

if(spi_intf.bit_order == 0)
begin //{
spi_intf.spi_rd_data[0] = spi_intf.miso;
spi_intf.temp_miso = spi_intf.miso;
`uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MISO PHASE 1 spi_intf.miso : %d ", spi_intf.miso),UVM_LOW)
end //}
else
begin //{
spi_intf.spi_rd_data[31] = spi_intf.miso;
spi_intf.temp_miso = spi_intf.miso;
`uvm_info(get_type_name(),$sformatf("------ ENTERED SEND TO MISO PHASE 1 spi_intf.miso : %d ", spi_intf.miso),UVM_LOW)
end //}
end //}
end //}
end //}
spi_seq_item.read_data = spi_intf.spi_rd_data;
`uvm_info(get_type_name(),$sformatf("------ ENTERED RECEIVE DATA : %h %h",spi_intf.spi_rd_data,spi_seq_item.read_data),UVM_LOW)

endtask : receive_data

In reply to Sandeep Gaur:

Just review your code quickly, it seems the issue happened because you created new object handle spi_wr_rd_req (copied from wr_rd_request) in collect_wr_rd_req task.



task spi_bfm::collect_wr_rd_req (spi_trans wr_rd_request); // {
@(posedge spi_intf.sample_clk)
spi_wr_rd_req = new wr_rd_request;

The response read data was stored in spi_wr_rd_req object, instead of wr_rd_request object handler (spi_seq_item object) which was used to send back to your sequence.

To fix, do not create new object, use assignment only:


spi_wr_rd_req = wr_rd_request;

In reply to chris90:

Hi ,

I have changed the same handle name for all the functions and it is working now.I can able to get the read data now. Thanks for your response.

Thanks,
Sandeep Gaur