在vhdl中进行i2c通信,从形成主ack到第一位读取vhdl时为X位

时间:2015-02-17 12:35:26

标签: vhdl fpga i2c

我遇到了i2c主设备确认问题,因为发送的数据没问题。在我的测试平台上,我在SDA总线上给出一个Z,这样主人就可以做出确认,但是在主人的ack(它为0)之后,我将另外一部分数据打磨,当我从SDA总线上的主ack 0转到' 1'作为从器件发送的第一个位,我得到第一位的X状态。如果总线是Z,它就不会出现。是模拟问题还是我做错了我得到了结果?它会出现在现实中还是奴隶会在SDA总线上提供更长时间的Z?下面我给出模拟代码和波形。

 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 个答案:

答案 0 :(得分:2)

该测试平台无法正确模拟I2C信号。

I2C使用开路集电极驱动器,它永远不会强烈驱动总线,以及弱上拉电阻。要模拟你可以做到:

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,

从信号中读取时,您可以使用例如

IF TO_X01(sda) = '1'

解决多个开放式收集器驱动程序的线与属性。

你仍然需要解决Russell提到的设置和保持时间问题。

答案 1 :(得分:1)

正如其他人指出的那样,您的问题是由于多个冲突的驱动程序在同一个增量循环期间暂时处于活动状态。这会在你的逻辑中产生级联效应,开始传播源于冲突的“X”值。

即使这是一个开放式收集器/排水系统,驱动器争用不会发生,你也不应该忽视这样的缺陷。此外,您不应该通过使测试平台的行为与真正的I2C从设备不同来解决问题。

在模拟集电极开路驱动器时,不应该使用“1”驱动共享总线信号。相反,当你想要一个'1'时,你应该通过驱动SDA / SCL到'Z'来模拟上拉电阻的效果,第三个专用驱动器在信号上放置一个恒定的'H'(或者,不太准确,直接从主人或奴隶驾驶'H')。这会产生一个弱驱动程序,可以被强大的'0'覆盖而不会发生冲突。您可以在输入端口信号上使用to_X01()函数,以防止“H”值通过主站或从站内的逻辑传播。它会在内部将“H”转换为“1”,因此您只能在总线信号上看到逻辑“1”或“0”。

答案 2 :(得分:0)

当在该增量时间内有两个位置驱动相同信号时,会导致3位模式末尾的红色和绿色部分变小。当模拟器无法解析线路上的两个驱动器时,会发生这种情况。

为了不发生这种情况,您应该编写测试平台,使其使用与主i2c模块使用的时钟相同的时钟。现在,您的测试平台正在使用固定的模拟器时间。可能有1皮秒的时间,模拟器看到主i2c和测试台都在驱动线路。

另一个选项是让您在时钟边沿后等待一小段时间来实际查看数据,例如,可以使用主机的下降沿和从机的上升沿。

无论哪种方式,这在合成后实际上不应该是一个问题,所以第三种选择就是忽略它。