1
votes

I've got a problem with i2c master acknowledgment for the slave that the data sent were ok. In my test bench i give a Z on SDA bus so that master could do the acknowledgment, but after the ack from master (it's 0) i sand a nother part of data and when i go from master ack 0 on the SDA bus to '1' as the first bit to be sent form the slave, I get an X state od the first bit. It's like it wouldn't appear if the bus was Z. Is it the simulation problem or am I just doing it wrong that i get that result? Will it appear in reality or the slave will give a Z on the SDA bus for longer? Belowe i give the simulation code and the waveforms.

 sda <='Z', 
    '0' after 3200 ps, 
    'Z' after 3400 ps,
    '0' after 5800 ps, 
    'Z' after 6000 ps,
    '0' after 8600 ps, 
    'Z' after 8800 ps,
    '0' after 11600 ps, 
    '1' after 11850 ps,------ start first byte
    '1' after 12150 ps,
    '0' after 13050 ps,
    '1' after 13350 ps,
    '0' after 13650 ps, ----- end first byte 
    'Z' after 14250 ps,------ Z for master ack
    '1' after 14550 ps,------ start second byte
    '0' after 14850 ps,
    '1' after 16650 ps,------ end second byte
    'Z' after 16950 ps,------ Z for master ack
    '1' after 17250 ps,------ start third byte
    '1' after 17550 ps,
    '0' after 18150 ps,
    '1' after 18750 ps,
    '0' after 19350 ps,------ end third byte
    'Z' after 19650 ps;------ Z for master ack

waveform

3
here's a link to the waveform image s18.postimg.org/y2s770p3t/stackoverflow.pngflanela_man
Are you talking about where the simulation goes blue (High Z) for 1 clock cycle? Or are you referring to the end of the 3-bit pattern where it's red and green for one small unit of time?Russell
i'm referring to the end of the 3-bit pattern where it's red and green, as Yuo know the red means it's X state and this small amount of red makes my first bit read also Xflanela_man
Thanks guys!!!! Your hints helped me a lot!!!!flanela_man

3 Answers

2
votes

That testbench doesn't simulate I2C signalling correctly.

I2C uses open-collector drivers which can never drive the bus strongly high, and a weak pullup resistor. To simulate that you can do:

sda <= 'H'; -- weak pullup always in effect

sda <='Z', 
  '0' after 3200 ps, 
  'Z' after 3400 ps,
  '0' after 5800 ps, 
  'Z' after 6000 ps,
  '0' after 8600 ps, 
  'Z' after 8800 ps,
  '0' after 11600 ps, 
  'Z' after 11850 ps,------ want to send '1', but open-collector cannot drive high!
  'Z' after 12150 ps,

When reading from the signal, you can use e.g.

IF TO_X01(sda) = '1'

to resolve the wire-AND nature of multiple open-collector drivers.

You still will need to resolve the setup and hold timing issues that Russell mentioned.

1
votes

As others have pointed out your issue is due to multiple conflicting drivers that are momentarily active during the same delta cycle. This creates cascade effects in your logic that begins to propagate 'X' values stemming from the conflict.

Even though this is an open-collector/drain system where driver contention can't happen you shouldn't ignore flaws like this. Moreover you shouldn't paper over the problem by making the testbench act differently than a real I2C slave.

When simulating open-collector drivers you should never drive the shared bus signals with a '1'. Instead, when you want a '1' you should simulate the effect of the pull-up resistor by driving SDA/SCL to 'Z' with a third dedicated driver putting a constant 'H' on the signal (or, less accurately, by driving 'H' directly from the master or slave). This creates a weak driver that can be overridden by a strong '0' without conflict. You can use the to_X01() function on your input port signals to prevent 'H' values from propagating through your logic inside the master or slave. It will convert 'H' to '1' internally so you only ever see a logical '1' or '0' on the bus signals.

0
votes

The small red and green part at the end of your 3-bit pattern is caused when there are two places driving the same signal in that delta time. This happens when the simulator is unable to resolve the two drives on the line.

In order to not have this happen, you should write your testbench such that it uses the same clock that your master i2c module uses. Right now, your testbench is using fixed simulator time. There is probably a 1 picosecond time where the simulator sees that the master i2c and the testbench are both driving the line.

The other option is for you to wait some small amount of time after the clock edge to actually look at the data, maybe use the negative edge for the master and the positive edge for the slave, for example.

Either way, this should not actually be a problem after synthesis, so the third option is just to ignore it.