NXP / i3c-slave-design

MIPI I3C Basic v1.0 communication Slave source code in Verilog with BSD license to support use in sensors and other devices.
Other
114 stars 35 forks source link

Master ACK not detected during adr arbitration #29

Closed sdolezal closed 4 years ago

sdolezal commented 4 years ago

Hi Paul,

I've been testing IBI requests with your I3C slave IP and a simulation master I wrote from scratch. It seems, I can't get the slave to respond with the mandatory IBI byte after it wrote its address on SDA during address arbitration.

In the screenshot below you can see the master interface + some status signals. Between cursors 1 and 2 (the white ones) the slave address "b4" is written with open drain. After cursor 2 R/W bit '1' follows, which yields the byte "b5". Everything's ok until here. Now the Slave engine goes from state b (=ADR Arbitration) to state 6 (=MACK) and awaits Master ACK.

The code from sdr_slave_engine is the following at line 547:

    ST_MACK:                            // if IBI or MR or HotJoin, this is Master ACK/NACKing us
      next_state = SDA_r ? ST_WAIT_SrP :// not accepted IBI/MR/HJ 
                   (pend_IBI & ibi_has_byte) ? ST_IBI_BYTE : // IBI byte follows
                   ST_WAIT_SrP;         // done our job, in Master's hands now

Master assigns ACK at the magenta cursor, when the engine already jumps to wait state ST_WAIT_SrP=0, since registered SDA_r (which shows clock/2 after SDA) is still '1'. So it seems to me, that I don't have a chance to reach state ST_IBI_BYTE (pend_IBI and ibi_has_byte are true, although not shown in the graph), since SDA is always evaluated half a clock too early and is held '1' the clock before by the slaves R/W bit. Do you agree or am I doing something wrong here? I'm grateful for every hint -

Regards, Stephan

VCS_I3C_IBI

pkimelman-nxp commented 4 years ago

The SDA_r is correctly registering a 0, so that is not a problem. State (or really state_base) only changes on the falling edge, but your state moves to 0 on the rising. This means that state!=state_base at that point, which likely means STOP_r got set. You need to look at your simulation pin equations as the sim likely sees a very short duration change of SDA_in which triggers STOP_r (edge sensitive to SDA rising). This can happen if you are using ?: in your pin_SDA_in equation on the outside as well as due to other factors in how you made that Master ACK work. But, you will see that just after the SCL rising, it detects STOP. So, this is a simulation setup problem (and/or a master model problem).

sdolezal commented 4 years ago

Yes, you're right - I can see the slave detecting "stop" on the rising edge of SCL, which is strange, since I expected it to detect this only on rising edge of SDA. But I've seen glitches on SDA today when using a different simulator, so it's probably my sim model causing this. I will have to tweak the simulator to be sure.

sdolezal commented 4 years ago

Ok, I've seen it clearly in the sim - this problem is definitely on my side, like you described - Many Thanks!