首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

IC设计基础系列之CDC篇10:跨时钟域信号传输(二)——数据信号篇A

IC设计基础系列之CDC篇10:跨时钟域信号传输(二)——数据信号篇A

因为学习了其他方面的知识,耽搁了更新。今天我们就聊聊跨时钟域中的数据信号传输的问题。主要内容预览:
   ·使用握手信号进行跨时钟域的数据传输
  ·FIFO的介绍
  ·在进行FIFO的RTL设计前的问题
  ·FIFO的RTL设计(与仿真测试)
  ·跨时钟域中的数据信号传输总结



一、使用握手信号进行跨时钟域的数据传输
  下面叙述的意义相同:前级时钟=发送时钟; 后级时钟=采样时钟=接收时钟


  使用握手信号传输数据不是我们的重点,重点是FIFO的设计。在使用握手信号进行数据传输之前,我们说说为什么双D触发器链不应该用于数据的传输。
  一般情况下,我们要传输的数据都是多位的,也就是以数据总线的形式传播的。如果我们使用简单的多组D触发器链进行同步数据的话,由于每一种D触发器链第一级触发器都有可能出现亚稳态,稳定下来之后的电平可能出错;由于有多组D触发器链,就有可能发送多个电平出错,因而导致数据出错,如下图所示:
        
可以看到,原来前面的时钟域发送的0111数据变成1000的时候,捕获时钟的时钟采样本来要才到0111的,由于保持时间不足,导致了b[2]、b[1]出现亚稳态,而且b[2]稳定后的电平是错误的电平,由此就传输了错误的数据。因此直接使用触发器链进行同步数据是不建议的。
  于是乎,我们就看看使用握手信号是怎么进行传输数据的。
  ·数据变化速率比采样时钟域低
  当数据的速率比采样时钟域慢时,也就是说,数据速率相对于采样时钟域(接收数据的时钟域)来说是慢时钟,可以使用控制信号进行同步,在采样到慢时钟域的控制信号后,接收采样数据,时序图如下所示:
              


这里只给出了时序图,电路可以按照时序图进行设计。需要注意的是,这个额外的控制信号(wr_en_s)是由前面的逻辑产生的。这与下面的电路不一样:
在下面的这个电路中,控制信号是由上升沿检测电路产生的,而且是接收时钟驱动的上升沿检测电路(也就是说这个控制信号是由后级的逻辑产生的),电路如下所示:
                 


下面我们来分析一下这个电路吧,时序图如下所示:
                 


  从时序图中可以看到,可以用上升沿检测电路,检测发送时钟的上升沿,然后这个沿相当于使能信号。上面中,检测到了第二个发送时钟的上升沿,之后就有了使能信号,采样的数据也是第二时钟发送的数据DB,因此对应起来是没有问题。这里由于没有检测到EN1第一个上升沿,所以没有采样到DA也是正常的,这是因为前面的波形没有画出的缘故。
  ·当数据的速率(或者说发送时钟的频率)略高于接收时钟端
  由于发送时钟比接收时钟快,于是对于接收时钟,发送时钟就相当于窄脉冲信号,这样我们就有思路了。我们还是上面一样,采用上升沿检测信号当做使能信号;但是问题来了,发送时钟是快的,可能会错过上升沿。于是乎,我们就把窄脉冲捕获电路和上升沿检测电路结合起来。先是窄脉冲捕捉电路,把时钟的沿捕捉到,然后进行边沿检测,检测得到的结果作为使能信号,电路图如下所示:
               


具体就不分析了,需要强调的是,这个是发送时钟也不能太快。
  ·数据变化速率比采样时钟快很多

当数据的速率比采样的时钟的速率快很多时,对应到时钟的关系就是——发送时钟和比接收时钟快很多时,这个时候采样时钟就采样不到数据,或者说会采漏部分数据,因此这时候就不能用握手信号了。也许有人说我可以增加使能信号,把数据拉长啊,等后面的采样时钟采样到使能信号、接收到数据之后,我再改变时钟。这种方法的实质就是硬生生地把数据变化率盖满,也就是把发送时钟域的时钟改慢,跟前面的数据变化速率比采样时钟域低的实质是一样的。因此当数据变化率比采样时钟快很多时,就要采样下面介绍的FIFO了。



二、FIFO的介绍
  终于写到FIFO了,FIFO 是first in first out的缩写,也就是“先进先出”;从字面理解,就是说,数据先进来的,就先出去。前面说了当快时钟域传输数据到慢时钟域时,就推荐用FIFO了。FIFO无论是快到慢,还是慢到快,都可以使用它进行数据的缓冲,可谓是“快慢皆宜”啊。
  FIFO的工作流程如下:
  FIFO在写时钟和状态信号的控制下,根据写使能信号往FIFO里面写数据,当写到一定程度后,FIFO存不下新数据的了(或者要以牺牲丢弃旧数据为贷款),这时候就不能往FIFO里面写数据了;在读时钟和状态信号的控制下,根据读使能信号从FIFO里面读出数据,当读到一定程度后,FIFO里面没有数据了,就不能继续读了,不然就会读出错误的数据。根据读写时钟是否一致(同步),FIFO的种类又可以分成同步FIFO和异步FIFO。FIFO能够读写数据,肯定需要数据的存储单元,这里存储数据的单元往往是双口RAM
  FIFO的写过程:在复位的时候,FIFO(双口RAM)里面的数据被清零(也就是不存在数据)。复位之后,只能进行写操作,因为什么都没有,读数据会读出错误的值。这个时候,当外部给FIFO写使能信号了,在时钟的驱动下,数据就会被写入FIFO里面的RAM存储单元(存储单元的地址由写指针寄存器的内容确定,写指针寄存器中的内容称为写地址,复位的时候为0),写完数据之后(或者在允许写数据之后),这个写指针寄存器就会自动加一,指向下一个存储单元。当写到一定程度的时候(写指针寄存器到达一定的数值),旧数据还没有被读出的时候,再写入新数据就会把旧数据给覆盖,这个时候称为写满,需要产生写满的状态信号(full,简称)。在写满的时候,需要禁止继续写数据。


三、在进行FIFO的RTL设计前的问题
  根据FIFO的介绍内容,我们试着来推导一下FIFO大致由哪些部分构成。
  首先,FIFO需要存储数据,因此就需要存储器;由于需要读,也需要写,于是乎就需要一个DPRAM(double  port  RAM,双端口RAM)。
  然后,RAM需要读/写地址,它才知道在哪里读/写数据,因此需要读/写地址产生模块,也就是需要读/写地址寄存器。什么时候进行写,什么时候进行读,因此需要读/写控制逻辑空满状态的信号产生逻辑
  最后,空满信号的产生需要通过对读地址和写地址的比较,由于读写地址在不同的时钟域,因此需要同步电路进行同步。
  通过上面的简单介绍,我们就得到了FIFO的大致框图如下(主要是告诉大家为什么会有这么一个框图):
            
返回列表