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 ?
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
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
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