tag 标签: soc,cdc,异步fifo

相关博文
  • 热度 16
    2016-1-24 21:42
    1284 次阅读|
    0 个评论
    2.2 )数据 mux 一笔 Data 及 data_vld 可以利用上面的方式将数据同步到另一个时钟域,也就是 data_vld 经过同步处理以后作为 mux 的选择端去选择 data ,这样也可以作为一种同步数据的方式。 另外也可以将数据分开进行上图的同步,但是这时要求数据在同一时刻只能有一个 bit 在变化,否则也会出问题,通常的格雷码满足这种条件。格雷码也经常被用在跨时钟域处理中。 2.3 )异步 fifo 事实上所有的同步问题都可以用异步 fifo 来处理,以一个时钟域将数据写入 fifo ,另一个时钟域将数据读出来,但是为什么不这样做呢,而是只有大批量的数据要处理时才这样做呢。原因有一下几点,异步 fifo 的 latency 比较大;异步 fifo 一般需要配上对应的 ram 作为存储体, ram 又需要对应的 bist 电路,所以面积也会比较大;异步 fifo 控制部分的逻辑设计起来有些难度,尤其是空满信号的判断,如果处理不好也会带来很大的麻烦。 上图是一般异步 fifo 的设计架构,下面我将对经典异步 fifo 的设计,使用,注意事项进行解读。 将要讲解的两种经典的异步 FIFO 的设计方案来自一篇文章《 simulation and synthesis techniques for asynchronous FIFO design 》,大家可自行下载,设计思路这篇文章里面介绍的很详细,解释的也很出色,我更多的是谈谈我的部分理解。 2.3.1 )异步 FIFO 设计的难点在哪里 2.3.1.1 )写地址和读地址处于不同的时钟域,如何比对写地址和读地址才能正确的产生空满信号; 2.3.1.2 )当读写地址相同时,究竟是读空了还是写满了(因为存在你追我赶的情况,类似于一个圆环)。 2.3.2 )处理思路     2.3.2.1 )对于难点 1 大家自然想到采用同步处理的方式,具体为将写地址或者读地址同步(例如利用两级触发器)到对方的时钟域中,在相同的时钟域中进行地址的比对,但是由于写地址和读地址很多时候并不止 1bit ,同时进行同步处理会增大错误的概率(如地址按 0111-1000 跳变,此时 4bit 都在变化, DFF 进行同步时就很容易出错),因而可以先将地址(二进制的)转换为格雷码(相邻数据之间只有一个 bit 在变化),然后再进行同步,最后进行对比,这样会大大减少错误的概率。 2.3.2.2 )对于难点 2 可以在地址前面添加 1bit 用于标志位进行区分,例如复位时,读写地址的标志位都是 0 ,如果写完 1 轮而开始新的一轮时就将写地址的标志位换为 1 (读也同样道理变换),这样可以通过判断标志位加上对比地址判断是空还是满,具体为当读写地址的标志位相同读写地址相同时为读空,具体为当读写地址的标志位不同读写地址相同时为写满;另外也可以利用格雷码的最高两位 00-01-10-11 进行相位的区分,具体参考我给出的文章或者网络资料,其实本质上和上面的是一个道理。 2.3.3) 经典 FIFO 设计方案的解读 2.3.3.1 )同步读写地址(经格雷码转换后)到对方的时钟域 相比于直接同步二信号进制地址(先用握手,然后同步二进制地址)好处是格雷码相邻数据之间只有一个 bit 在变化,而二进制由于写地址和读地址很多时候并不止 1bit ,同时进行同步处理会增大错误的概率(如地址按 0111-1000 跳变,此时 4bit 都在变化, DFF 进行同步时就很容易出错);利用格雷码进行同步,即使发生同步的时出错也不会造成 overrun 和 underrun 的情况(因为同步后的数据必定小于等于同步前的数据,即只可能 1 被同步为 0 ,而不可能 0 被同步为 1 ),例如当前的读地址到了 6 ,写地址到了 8 ,地址 8 经过同步后出错而变成了 6 ,这时会出现地址相同而判断为读空,不过没关系,读空则不读,至少不会出现 underrun 的情况,随着时间的推移地址 8 总会被采样到;然而格雷码也有缺点,只能连续变化递增或者递减(如果间隔变化就不符合格雷码的特点了),所以设计的深度必须是 2 ^n ,如果不是的话,需要重新产生编码格雷码,否则也会出现间隔变化不符合相邻之间只有 1bit 变化的特点。 2.3.3.2 )将读写地址(经格雷码转换后)同步到一个组合逻辑电路中(异步比较)直接比较空满,然后将空满信号同步到各自对应的模块中 虽然这种电路会给 fifo 带来不好的状态,例如已经满了 wfull==1 ,但是这个时候读走一个数据,由于同步的延时性,导致这一段时间内 wfull==1 一直不变(如果没有同步带来的延时应该变为 0 的), rempty 也会遇到同样的问题,但是这种电路不会出现 underrun 和 overrun 的情况。 2.3.3.2 )相比 2.3.3.1 )可能会节省面积,因为 2.3.3.1 )同步 wptr 和 rptr , 2.3.3.2 )只需要同步 afull_n , aempty_n; 2.3.3.1 )的速率可能较 2.3.3.2 )会快些, 2.3.3.2 )中存在异步且组合逻辑比较,不利于时序的优化。