VIP Model of i2c project

In my I2C project
am writing data from master driver to slave driver, write part is working properly but am not able read the data from slave driver which i have written in the slave driver

can you please let me know

what is an issue ?

We’d have to see your code to provide an answer.

Hi sir,
about I2C project,
i have attached my i2c code, please have a look at these following codes, sequence class, master driver class and slave driver class.

plz let me know sir, if it is there any issues ?

sequnece class

class mas_sequence extends uvm_sequence #(trans);
`uvm_object_utils(mas_sequence)

trans req;

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

endclass

/****** write_seq*****/

class wr_seq extends mas_sequence;
`uvm_object_utils(wr_seq)

 function new(string name = "wr_seq");
	 super.new(name);
 endfunction
 virtual task body();
 
 	req = trans::type_id::create("req");
	start_item(req);
	assert(req.randomize() with {addr[7:0] == 8'b01101001; data[7:0]==8'b00100101;}); 
	finish_item(req);    // 69 write   // data 25
 endtask

endclass

/******** read_seq*********/
class rd_seq extends mas_sequence;
`uvm_object_utils(rd_seq)
function new(string name = “rd_seq”);
super.new(name);
endfunction
virtual task body();
req = trans::type_id::create(“req”);
start_item(req);
assert(req.randomize() with {addr[7:0] == 8’b01101000;}); // 68 read
finish_item(req);
endtask
endclass

2.master driver class

class mas_driver extends uvm_driver #(trans);
`uvm_component_utils(mas_driver)

// transaction trans1;
virtual intf vif;
trans trans1;
bit ack_a,ack_d;
reg [7:0]read_data,data_md;
//master_config mconfig;

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

function void build_phase(uvm_phase phase);
super.build_phase(phase);
//if(!uvm_config_db#(master_config)::get(this,“”, “master_config”, mconfig))
// $display(“master driver is getting master config”);
//uvm_fatal(get_full_name(),"master driver getting interface or not?") if(!uvm_config_db#(virtual intf)::get(this,"","vif",vif)) uvm_fatal(“NO_VIF”,{“virtual interface must be set for:”,get_full_name(),“.vif”});

endfunction

virtual task run_phase(uvm_phase phase);

forever
begin
seq_item_port.get_next_item(req);
$display(“display the value of data item in master driver”);
req.print();

 sent_to_dut(req);
 seq_item_port.item_done();

end
endtask

task sent_to_dut(trans trans1);
$display(“\n… master driver start…\n”);
begin
/START BIT/

@(posedge vif.scl)
vif.sda=1'b1;
#2500;
vif.sda = 1'b0;

$display($time,“_start bit in master, send to slave=%d”,vif.sda);

/*****ADDRESS/

for(int i = 7; i>=0; i--) 
 begin
   @(negedge vif.scl);
   vif.sda=trans1.addr[i];
   $display($time,"_send_address in master trans1.addr[%0d]=%d\t",i,trans1.addr[i]);

 end     
   
   @(posedge vif.scl);  
   ack_a = vif.sda;  //getting address ack from slave
   $display($time,"_receive ack address in the master, sent from slave = %d",ack_a);
  
   
   //WRITING THE DATA//
   
if(ack_a == 1'b1 && trans1.addr[0] == 1'b1)
  begin     
    data_md = trans1.data;
    
      for(int j =7; j>=0 ; j--)    // writing the data(from msb)
      begin   
        @(negedge vif.scl);         
        vif.sda = data_md[j];            
        $display($time,"_(master)_data is sent from master trans1.data[%0d]=%d\t",j,trans1.data[j]); 
                 
                     
        @(posedge vif.scl);
        ack_d = vif.sda;  
       $display($time,"_ack wr data in the master, sent from slave = %d",ack_d);         
                 
        if(ack_d == 1'b0 || ack_d == 1'b1)   
          begin    
             @(posedge vif.scl);  
             vif.sda = 1'b0;
             #2500;
             vif.sda = 1'b1;  
            $display($time,"_stop bit in master, send to slave vif.sda=%d",vif.sda);        
          end
   end
   
   // READING DATA // 

if( ack_a == 1’b1 && trans1.addr[0] == 1’b0)
begin
for(int i = 7;i>=0;i–)

          begin
             @(posedge vif.scl); 
             read_data[i] = vif.sda; 
             $display($time,"_received read data in master vif.sda= %d",vif.sda);
            $display($time,"_copying read data in master in read_data[%0d]=%d",i,read_data[i]);                                          
             
              
             if(read_data[i] === 1'bx || read_data[i] === 1'bz)          
             ack_a = 1'b0;
                         
                   else
             ack_a= 1'b1;
        
                   end  

        if(ack_a == 1'b0)
             begin
            @(posedge vif.scl);
            vif.sda = 1'b0;
  $display($time,"_read data NACK in the master, sent to slave = %d",vif.sda);
            end
         else 
             begin
             @(posedge vif.scl);
              vif.sda = 1'b1;
 $display($time,"_read data ACK in the master, sent to slave = %d",vif.sda); 
             end
          
          @(posedge vif.scl);
          vif.sda = 1'b0;
          #2500;
          vif.sda = 1'b1;     
 $display($time,"_stop bit in master, send to slave after read vif.sda=%d",vif.sda);  
     end

end
endtask
endclass

  1. slave driver class

class slave_driver extends uvm_driver#(trans);
`uvm_component_utils(slave_driver)

virtual intf vif;
trans trans2;

reg [7:0] addr1;
bit [7:0]mem[127:0];
bit start;
bit stop;
bit ack,ack_rdt;
reg [7:0]data_in,data_out;
reg [6:0]addr;

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

function void build_phase(uvm_phase phase);
super.build_phase(phase);

   if(!uvm_config_db#(virtual intf)::get(this,"","vif",vif))
	  `uvm_fatal("NO_VIF",{"virtual interface must be set for:",get_full_name(),".vif"});  

endfunction

task run_phase(uvm_phase phase);

forever

begin
/* seq_item_port.get_next_item(req);
$display(“addressyyyyyyyyyyyyyy_received”);

 seq_item_port.item_done();*/
 sent_to_dut(trans2);

end

endtask

task sent_to_dut(trans trans2);
begin

 $display($time,"_slave_driver_start");

 @(posedge vif.scl);
 start = vif.sda;
 $display($time,"_receive start bit in slave =%d",start);   

 
 
 // RECEIVING ADDRESS // 
  for(int i = 7; i>=0; i-- )  
    begin
     @(posedge vif.scl);         
      addr1[i] = vif.sda;
     $display($time,"_receiving address addr1[%0d]=%d",i,addr1[i]);      
  
       
     if(addr1[i] === 1'bx || addr1 [i] === 1'bz)
       begin
          ack = 1'b0; // it means addr nack 
       end
       else
         begin
         ack = 1'b1;   // it means addr ack
           end
    end
    
  addr = addr1[7:1];
  $display($time,"_display received addr1 in the slave addr1[7:1]= %h",addr1);
  $display($time,"_copying received address to the slave memory addr7:1 = %b",addr);

     
      if(ack == 1'b0) 
       begin
         @(posedge vif.scl);             
         vif.sda = 1'b0; //sending addr nack to master
         $display($time,"_sending addr NACK IN slave driver = %b",vif.sda);
       end  
      else
       begin
     vif.sda=1'b1;  // sending addr ack to master
    $display($time,"_sending addr ACK IN slave driver = %b",vif.sda);
        end

/*else if(addr1[7:1] == trans2.addr[7:1])
begin
//ack = 1’b1;
@(posedge vif.scl);
vif.sda = 1’b1; // sending ack to master
end */

//WRITE DATA   

  if(addr1[0] == 1'b1) 
   begin              
     for(int j=7;j>=0;j--)     // writing the data
         begin      
           @(posedge vif.scl);                       
           data_in[j] = vif.sda;
       $display($time,"_slave_Receving we data data_in[%0d]= %d",j,data_in[j]);
    
         
           if(data_in[j] === 1'bx || data_in[j] === 1'bz)
           begin
             ack = 1'b0; // data nack
           end   
         else
         ack=1'b1;     // data ack                  
       end
       
        mem[addr] = data_in;
        $display($time,"_received data_in = %h",data_in);
        $display($time,"_copying received data to SLAVE_memory = %h",mem[addr]);
     
        
        if(ack == 1'b0) 
           begin
           @(posedge vif.scl);
           vif.sda=1'b0;    //sending data nack   

$display($time,“_we_data NACK IN slave driver, send to master = %d”,vif.sda);
end
else
begin
@(posedge vif.scl);
vif.sda = 1’b1; // sending data ack
$display($time,“_we_data ACK IN slave driver,send to master = %b”,vif.sda);
end

         @(posedge vif.scl);
          stop = vif.sda;
    $display($time,"_receive stop bit in the slave after write data stop= %d",stop);
       end
    
   
    
       // READING DATA //    
    if(addr1[0] == 1'b0)
      
         begin
            $display("entering in to read part in slave");
            data_out = mem[addr];
            $display($time,"_slave, reading the data DATA IN slave MEMORY mem[addr1]= %h",mem[addr]); 
                 
            
             for(int i=7; i>=0; i--) // reading the data or sending data to master from slave
              begin
                @(negedge vif.scl);
                vif.sda = data_out[i];     
     $display($time,"_slave sending read data to master data_out[%0d]= %d",i,data_out[i]);   
             end 
           end       
              @(posedge vif.scl);
                ack_rdt = vif.sda; // receiving ack from master
               $display($time,"_slave receiving read data ack bit in the slave= %d",ack);
              @(posedge vif.scl);
                stop = vif.sda; // receiving stop bit from master
          $display($time,"_slave receiving stop bit after read in the slave= %d",stop);
        end   

endtask
endclass

In reply to Gireesh:

Could you please show how your transaction trans looks like?

Hi sir
please find the below my transaction class of i2c
please let me know, what is the issue, where i can change the code ??

class trans extends uvm_sequence_item;

bit sda ;
bit scl;
bit stop;
bit start;
bit ack;
rand bit [7:0]addr;
rand bit [7:0]data;

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

uvm_object_utils_begin(trans) uvm_field_int(addr, UVM_ALL_ON)
uvm_field_int(data, UVM_ALL_ON) uvm_object_utils_end

endclass

In reply to Gireesh:

Thanks for sharing the code.
I try to understand what it emans ’ writing data from master driver to slave driver’.
What do you have? A master core? This is my guess.
Because the description of the env is missing I do not know how the master and slave agnets are working together. I need more information to help you.
If you do not want to share your code with the whole community, please use my email
christoph@christoph-suehnel.de