2
votes

When I am implementing a I2C slave, here shows a problem. My sda is an inout port. At time 164ns, which is is area circled by red in the picture, the the slave writes ack=1 to sda. After that, the testbench writes data to sda, and the slave SRAM reads from sda. However, seems that the area circled by red is also read by SRAM, which makes SRAM show 1 in MSB in blue denoted area. In practice, SRAM should read from the area after the red circled area. What might it be that causes this error?

enter image description here

part of the code shows below

READ_DATA:begin
    addr_x<=addr_x;
    ROM<=DATA_IN_ROM;      
    SRAM[SRAM_LEN-cnt]<=sda;  
end

READ_ADDR: begin // rw<=rw; 
    SRAM<=SRAM; 
    ROM<=DATA_IN_ROM; 
    addr_x[REG_LEN-cnt-1]<=sda; 
    cnt<=cnt+1; 
    sda_reg<=sda_reg; 
    sda_vid<=sda_vid; 
    freeze_cnt<= freeze_cnt; 
    freeze<=freeze; 
    rwcnt<=rwcnt; 
end
1
please press 'enter image description here' to see the pictureYongcong Luo
What is meaning of ROM<=DATA_IN_ROM;? Seems that you are filling SRAM bit-by-bit based on cnt value, so where is cnt value increment? Can you post some more code?sharvil111
READ_ADDR: begin // rw<=rw; SRAM<=SRAM; ROM<=DATA_IN_ROM; addr_x[REG_LEN-cnt-1]<=sda; cnt<=cnt+1; sda_reg<=sda_reg; sda_vid<=sda_vid; freeze_cnt<= freeze_cnt; freeze<=freeze; rwcnt<=rwcnt; endYongcong Luo
Assuming you're inferring registers (based on you using <=, since there's not enough code to know), you don't need any signal<=signal; statements.wilcroft

1 Answers

0
votes

Based on your duplicate post I believe that you are entering the READ_DATA state too early. Add another state (ACK_R) that go between RW and READ_DATA.

ACK_R: begin
  sda_reg <= 0;
  sda_vin <= 1;
  bus_state_next = READ_DATA; 
end

This will create a clock cycle where your ACK is performed without the SRAM reading the data. If you have set the ACK signal somewhere else, you should remove it. Your counter should now not count to 9, but to 8 instead. This should also be done for ACK_W.