原创 两个不同的I2C Slave的比较

2009-11-19 17:25 5476 4 13 分类: FPGA/CPLD

                         

两个不同的I2C Slave的比较 (by wind330)


工作过程中总是不断地运用现有的技术和代码,也不断地在丢弃有缺陷的技术。

I2C总线是平时接触比较多的一种低速IC配置总线,网络上也有很多现成的Core可以提供你修改及应用。


概述

本文对两个来自不同开源网站的I2C Slave IPCore进行对比及分析其优劣性,它们分别是OpenCores' I2C SlaveGaisler's I2C Slave。重点说明它们将低速的I2C信号转换到FPGA内部高速处理时钟的过程的区别。


特性区别

OpenCores's I2C Slave

  • 不支持CPU总线
  • 支持256个寄存器配置(8bits地址线)

Gaisler's I2C Slave

  • 支持APB总线
  • 可配置允许Slave挂住时钟线(Master和Slave的速率同步)

从上面的特性可以看出,OpenCores' I2C Slave适合用于支持I2C配置的外部芯片;Gaisler's I2C Slave则适于用做SOC外设,同带I2C Master器件进行交互式通信。


电路中的亚稳态

这里有一段来自网络上的中文解释:

这是跨时钟设计中最基础的一个问题(宏观的问题是FIFO),按照我的观察,上论坛问
问题多的一般不明白这个,请一定要注意了。什么是亚稳态?数字电路中的简单双稳
态电路就是两个反相器首尾相连组成(加一些控制逻辑变成了锁存器,触发器),然
而并不像名字显示的,这种电路其实还有第三种半稳定态——就是当两个反相器都处
于中间值的情况——这称之为亚稳态。我们知道反相器在非逻辑值范围的反馈系数是
相当大的,一旦因为干扰或者噪音离开了这个中心点,就会很快地进入逻辑值范围
(稳态)。数学分析,从亚稳态进入稳态,正如放射元素的衰变,是一个指数的规律
(为什么是指数的规律?你要是想不明白,说明你还没有搞明白亚稳态)。那么,亚
稳态的危害到底是什么呢?消耗功率?其实不是(虽然亚稳态消耗很大的功率),亚
稳态的问题在于其电平并不处于有效逻辑电平范围内,而且在变化。这就导致与其相
连其他数字部件将其作出不同的判断(注意,不同),有的作为'1',有的作为'0',有
的也进入了亚稳态,数字部件就会逻辑混乱。那么究竟如何避免(或者减小)亚稳态
的危险呢?注意到亚稳态的触发器继续停留在亚稳态的几率按照指数减少,那么办法
就是等 ——等足够长的时间,直到这个几率变得小的实际上不会发生。到底需要有多
长呢?有的厂商有一个数据,有的没有,按照普通的做法,至少等一个时钟周期——这
也就是所谓的异步数据要用两个触发器打一下。

参考链接 1 2


I2C信号线的时钟域转换

I2C的常用速率是100kbps或者400kbps,I2C边沿转换的时间可能长达1000ns(Standard-mode),I2C信号允许有50ns宽度的抖动,所以高速对I2C信号直接两级寄存器消除无法亚稳态。假设当前的用50M高速时钟作为I2C Slave的处理时钟,首先我们需要滤除毛刺,代码如下:

// OpenCores' I2C Slave, Verilog
// debounce sda and scl
always @(posedge clk) begin
  if (rstSyncToClk == 1'b1) begin
    sdaPipe <= {`DEB_I2C_LEN{1'b1}};
    sdaDeb <= 1'b1;
    sclPipe <= {`DEB_I2C_LEN{1'b1}};
    sclDeb <= 1'b1;
  end  else begin
    sdaPipe <= {sdaPipe[`DEB_I2C_LEN-2:0], sdaIn};
    sclPipe <= {sclPipe[`DEB_I2C_LEN-2:0], scl};
    if (&sclPipe[`DEB_I2C_LEN-1:1] == 1'b1)
      sclDeb <= 1'b1;
    else if (|sclPipe[`DEB_I2C_LEN-1:1] == 1'b0)
      sclDeb <= 1'b0;
    if (&sdaPipe[`DEB_I2C_LEN-1:1] == 1'b1)
      sdaDeb <= 1'b1;
    else if (|sdaPipe[`DEB_I2C_LEN-1:1] == 1'b0)
      sdaDeb <= 1'b0;
  end
end
// Gaisler's I2C Slave, VHDL
----------------------------------------------------------------------------
-- Bus filtering
----------------------------------------------------------------------------
for i in 0 to 3 loop
  sclfilt(i) := r.i2ci(i+2).scl;
  sdafilt(i) := r.i2ci(i+2).sda;
end loop;  -- i
if sclfilt = "1111" then v.scl := '1'; end if;
if sclfilt = "0000" then v.scl := '0'; end if;
if sdafilt = "1111" then v.sda := '1'; end if;
if sdafilt = "0000" then v.sda := '0'; end if;
从上述代码可以看到,两个I2C Slave都对I2C信号进行过滤消除抖动,不同的是Opencores' I2C Slave可以通过DEB_I2C_LEN可以通过过滤带宽,而Gaisler's I2C Slave,当处理速度达到80M时,将无法滤除50ns宽度的抖动,再加上建立/保持时间冲突引起的亚稳态,FPGA将无法处理I2C信号。在Opencores' I2C Slave中,在48MHz的处理速度下DEB_I2C_LEN为10,这样可以过滤的脉冲宽度是208ns,但是我有一个疑问:处理时钟在采样I2C信号的边沿跳变时,而边沿跳变长度达到最差情况的1000ns,是否会产生错误的I2C信号?例如在边沿的采样值为20'b11111111110000000000,而I2C SCL刚好处在上升沿情况,如此,SCL多产生一个错误的上升沿。

使用情况

wind330使用过Gaisler's I2C Slave,在75M的处理时钟下,该Slave状态机会锁死在Hold状态挂住SCL信号(大概运行一天时间),当时觉得是外部信号太差造成的,所以没有太在意。如今再看OpenCores' I2C Slave才觉得可能是当时处理时钟频率过高,而本身I2C信号轻微毛刺没有被过滤,发生了状态机错误。


总结

通过阅读上述Core的代码,我们可以知道利用高速时钟信号处理低速的通信接口,需要去抖动处理并且根据建立/保持时间再调整滤波处理后的时钟,保证代码的鲁棒性。

 
PARTNER CONTENT

文章评论9条评论)

登录后参与讨论

用户1122702 2016-5-9 09:49

在搜索引擎上搜索关键字“异步复位,同步释放”

用户1749260 2016-4-28 21:32

//给的例程是这样使用rst的完全不知道,这个样做有什么意义? //而且CPLD没有锁相环怎么处理。 pll_48MHz pll_48MHz_inst ( .inclk0 ( clk ), .locked( pll_locked) ); //generate sync reset from pll lock signal always @(posedge clk) begin rstReg[1:0] <= {rstReg[0], ~pll_locked}; end assign rst = rstReg[1];

用户1749260 2016-4-28 21:28

作为菜鸟,我想问一下,我们所知道的i2c不就是一个scl,一个sda吗?OpenCores's I2C Slave怎么还要一个rst和clk,不知道这两个信号怎么配置,我现在不能使用这个模块,我给clk是50mhz,rst不知道怎么处理。

用户1122702 2009-11-30 15:59

组合逻辑的延时和噪声宽度并没有直接联系,与组合逻辑的频率响应相关。我个人觉得组合逻辑滤波目前没有意义,你也不需太关注它。

用户142112 2009-11-29 10:17

那第二个问题呢,边沿会不会变好? 逻辑门存在惯性延时,如果噪声宽度小于惯性延时,那么组合逻辑输出不会有变好这样是否可以了滤掉一部分噪声呢,就是不知道有LUT构成的组合逻辑有什么特性。

用户1122702 2009-11-28 22:56

没有听说过纯逻辑可以起滤波效果的。

用户142112 2009-11-28 19:12

在接到寄存器的D之前,如果加一级冗余的组合逻辑,这样能不能起到滤掉一部分glitch和使边沿变好呢?

用户1122702 2009-11-27 14:52

呵呵,谈不上谢字,平时经常看你的文章,得到很多~~~

ash_riple_768180695 2009-11-23 10:53

分析地真好!感谢!
相关推荐阅读
用户1122702 2015-12-20 21:29
在Emacs中应用Ctags
适宜人群 具备Emacs使用经验的程序员 什么是Tag? Tag,即标记,记录了程序重要信息(如函数、变量、宏定义等)的位置和相应的文件,方便程序浏览器进行跳转。 ...
用户1122702 2015-12-13 22:23
可综合的SystemVerilog:命名空间
关键名词解释: 编译单元(compilation unit):SystemVerilog 源代码的集合 编译单元域(compilation-unit scope):即编...
用户1122702 2015-12-13 22:15
可综合的SystemVerilog:参数化函数/任务
在Verilog中,参数化模块被广泛应用。参数可重新定义保证模块的可配置性及可复用性。但是,函数及任务并无法像模块一样被参数化,减弱了Verilog的描述化能力。 SystemVer...
用户1122702 2010-10-28 11:34
基于SOPC下RapidIO调试方法
RapidIO的一个难点在于地址转换方法,即将远端的Memory映射到当前Avalon-MM总线,所以地址需要一个转换过程——Local Avalon-MM<->RapidIO Addr&...
用户1122702 2010-08-24 14:22
西行重庆
八月初时离开生活并工作四年的深圳,来到求学四年的重庆。已经过去三周时间,对自己的将来也随之变的不可琢磨。重庆的生活水平并不如想象的低,除了房价不像沿海城市高企,其他诸如公共交通,生活日常用品基本都是一...
用户1122702 2010-07-07 18:05
Tcl用后感
                    Tcl用后感 (by Wind330)    Tcl - Tool Command Language近期做了一个Tcl脚本用于Modelsim仿真,完成如下功能...
EE直播间
更多
我要评论
9
4
关闭 站长推荐上一条 /3 下一条