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