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

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

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

·FIFO的空满信号产生空状态信号:
  一开始复位的时候,空信号是有效的,当写了数据之后,空信号就无效了。然后当数据被读取完之后,空信号就有效了。那么什么时候数据被读取完了呢,也就是数据被读取完的时候有什么特征呢?特征就是读地址和写地址相等,如下所示:
                 


  由于读地址要追赶写地址,在赶上的时候,地址全等就证明了读空了。
  也许有人会问:写地址由于要同步到读时钟域去,会存在同步延时的,比如 说t=0s的时候同步过去,此时写地址为A;在t=2s的时候A同步过来了,但是这个 时候写地址已经变为A+2,而你同步过来的这个写地址为A。如果在t=2s这个时候读地址=A,即读地址=写地址,读赶上了写,按照上面的设计想法就会产生读空信号,但是实际上是不相等的,也就是实际上读并没有赶上写,即没有读空的,这不就是产生错误的读空信号了吗?
  首先,是存在这样的情况,但是这种情况不是设计错误。一方面由于我们要产生读空信号,目的是也就是防止继续读从而读出错误的数据;实际上没有读空,即使产生了读空信号,也是没有影响,相当于提前判断产生读空信号而已。另一方面由于是读时钟域采样的读的地址,这个读地址是实时的;写地址是延时的,当这个两者相等时,我们这个实时的地址在比实际的写地址小的时候就产生读空信号,防止了读空。因此即使产生读空信号,也不会因为读空而产生错误的数据。因此是没有设计错误的。
写满状态:
  一开始复位之后,进行写数据;由于地址(假设地址是4位,也就是深度是4位)是可以回卷的,也就是说,写指针从3写到15后,继续写又会返回到3那里;假如复位后读操作只读到地址3那里就不读了,那么这个时候就写满了。也就是说,写满的时候,写地址和读地址是相等的,如下所示:
            


于是乎,我们该怎么区分在读地址写地址相同的时候是读空还是写满呢?下面来介绍一种常用的方法:
  将地址深度拓宽1位当做标志位,回卷一次标志位取反。比如上面的例子中,4bit地址拓宽为5bit,那么读地址就是3(由于读地址没有回卷,所以是(0)0011)那里,当写地址回卷之后与读地址相同(由于写地址回卷了,最高位取反,所以是(1)0011),因此这就是写满了。当读地址回卷之后,变成10011,这个时候,就读空了。也就说,虽然DPRAM的深度还是4bit,但是我们在进行设计地址寄存器的时候,增多一位当做状态。然后读写地址全相等的时候,表示是读空;除了标志位外,剩余的地址为全部相等,那么就表示是写满
  这里还是会产生与前面的空信号一样的问题,也就是同步过来的读信号是延时的值,与前面一样,是不会影响写满信号的,不属于设计错误。


  除了上面这种方法之外,在同步FIFO中,还可以使用计数器的方法。设置一个状态计数器,复位的时候为0。的时候,计数器加1的时候,计数器减1。那么很容易得出,计数器为0的时候,就是读空就有效了;当计数器等于FIFO的深度(2^n  -  1)时,就说明写满了。这种方法如果FIFO深度很大的话,就需要很大的计数器了,所以有局限性。
  从上面的分析中,由此也可以知道,空信号的产生需要把写地址同步到读时钟域,然后进行比较(比较之后产生);满的信号需要把读地址同步到写时钟域,然后进行比较(比较之后产生)。


  ·为什么要选择格雷码作为同步地址的编码
  首先,我们知道,读地址需要跟写地址比较来产生空和满信号,然后对于异步FIFO,读写为不同时钟,如果直接采样,就会有:类似前面数据产生多位亚稳态的问题,(时序图就不画了)比如写地址从00111改变从01000的时候,读时钟恰好采样,那么除了最高位外,其它的4位都有可能产生亚稳态,有可能同步得错误的地址。这是引入格雷码的一个原因。另外一个原因就是:无论是读地址还是写地址,在(允许)进行读和写之后,地址都是加1,而不是加2或者加3等其他的值。为什么会这样呢?我们来看看格雷码的编码:
               
  从上图中我们可以知道,从地址0变成地址1,格雷码和二进制码都是0000变成0001;地址从1变成地址2,格雷码是0001变成0011,而二进制是0010......我们很容易得到,在相邻地址变化中,格雷码只有一位发生变化,如地址从7变为8时,格雷码是0100变成1100,也就是只有最高位发送变化;我们再来看看二进制编码,二进制编码则有可能全部都改变,地址从7变为8时,二进制码是0111变成1000,4位都发生了变化。假如采样的时候地址恰好从7变为8时,那么二进制编码就有多位发生亚稳态,稳定后的值什么都有可能;而格雷码由于只有最高位跳变,第三位由于没有跳变,不会产生亚稳态可以稳定正确采样,稳定后的值只有0100和1100,地址只差数值1,是不会影响判断的结果的(因为是同步过来的,是个延时的值,不打紧)。
  知道了格雷码的优点之后,我们就要使用各格雷码了。由于RAM的读写地址都是(传统)二进制编码,这里使用格雷码有两种使用方法,第一种使用方式是,将二进制编码转换成格雷码,然后把格雷码同步过去,再把同步过来的格雷码反转换成二进制码,进行二进制地址和二进制地址的比较;另外一种使用方式是,将二进制编码转换成格雷码,然后把格雷码同步过去,然后使用格雷码进行比较。这里使用第一种方式,虽然这种方式比较需要多两块格雷码转二进制的电路,但是我们可以实时比较,能将寻址的二进制马上与同步过来的“延时”二进制进行比较;使用格雷码比较的话,实际值会慢一拍(因为实时方的格雷码需要寄存输出,会慢一拍,如果不寄存输出,就有可能产生毛刺)。
然后格雷码的与二进制的互相转换如上图,下面是转换讲解(左边为格雷转二进制,右边为二进制转格雷):
                 
在布尔代数里面有A^B=C →A=B^C
返回列表