0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

跨时钟域类型介绍 同步FIFO和异步FIFO的架构设计

CHANBAEK 来源:奇异白勺书 作者:Kim71 2023-09-19 09:32 次阅读

在《时钟与复位》一文中已经解释了亚稳态的含义以及亚稳态存在的危害。在单时钟系统中,亚稳态出现的概率非常低,采用同步设计基本可以规避风险。但在实际应用中,一个系统往往包含多个时钟,且许多时钟之间没有固定的相位关系,即所谓的异步时钟域,这就给设计带来很大的挑战。

01跨时钟域类型

跨时钟域传输可分为以下几种情况:

  • 同频零相位差时钟
  • 同频恒定相位差时钟
  • 非同频时钟
    • 整数倍频时钟
    • 非整数倍频时钟

同频同相时钟可视为等效的时钟,在不考虑时钟抖动(Jitter)影响的情况下,两个时钟域之间的传输可视作同步的。而同频恒定相位差的时钟由于时钟有效沿之间有一定的相位差,因此对建立/保持时间裕量有一定的影响。设计时需要确保组合逻辑的延时能满足采样处的建立/保持时间要求,一般可通过在发射沿或捕获沿加入适当的偏移来完成时序的调整。

而对于非同频的时钟,二者可以是同步关系,也可以是异步关系,这里再次强调一下同步与异步的界定标准:有固定相位关系的称为同步时钟,没有固定相位关系的称为异步时钟。

那么什么叫固定的相位关系?即两个时钟的有效沿之间的偏移量始终保持恒定,也即所谓的相位差固定。

非同频时钟之间的关系可以分为整数倍频和非整数倍频。整数倍频的时钟往往是同源时钟,相位关系也往往是固定的。但是存在源时钟域和目标时钟域的快慢关系。假设源时钟是20MHz,而目标时钟域只有5MHz,那么就是快时钟域到慢时钟域的传输。

“慢采快”会导致数据丢失的问题,为了避免这个问题,要求源时钟域的数据至少保持一个目标时钟域的周期的稳定状态。对于单比特控制信号的“快→慢”传输,可以采用如图所示的脉冲同步器来检测快时钟域的脉冲信号。

图片

一旦data1有脉冲拉高,经过mux的反馈,第一级DFF的输出就会反转并锁住,直到下一个data1脉冲的到来才会再次反转。中间两级DFF就是用来打两拍消除亚稳态的,最后一级DFF输出的异或用来检测同步过来的信号是否发生反转,由于data1每次脉冲都会导致clk1时钟域的输出发生反转,于是该脉冲信号就在clk2时钟域被记录下来并保持一个周期的稳定状态。

那么假如源时钟比目标时钟要慢呢?在“快采慢”的情况下,需要注意快时钟域触发器不要对慢时钟域的输出信号进行重复采样,在慢时钟域维持一个周期的信号在慢时钟域可能维持好几个周期,这显然会导致逻辑功能的错误。因此需要确保同步过来的信号在快时钟域也只维持一个周期,因此采样如图所示的边沿(上升沿)同步电路,就能将慢时钟域的脉冲同步到快时钟域。

图片

(此法只用于慢时钟域的单周期脉冲信号的同步,若源信号存在维持几个周期的高电平,在快时钟域也只会存在一个周期的脉冲信号,此时用基本的电平同步电路就可以了)

非整数倍频的时钟的之间相位关系总是在变化,这让时序分析变得很复杂,除了亚稳态的问题,还要考虑相位差的变化是否会导致丢数据,即便能满足时序,数据传输不连贯的问题也始终存在。

此时,已经标准化的技术,如FIFO和握手,解决了绝大多数情况下的跨时钟域数据传输。

02FIFO

关于握手机制,笔者在《解剖AXI(一)—— 从握手开始》一文中已有说明,本文不再过多赘述。在实际设计中,使用握手机制来传输单比特信号产生的延迟要远大于使用FIFO进行传输,因此本文重点介绍FIFO传输的机制,以及同步FIFO和异步FIFO的架构。

FIFO,即First In First Out,先进先出的数据缓存器。可类比为排队,先进队伍的先服务,先写入FIFO的数据先读出。所以FIFO没有外部地址线,只能靠回滚递增的内部读写指针来指示下一个要读/写的地址。根据读写控制信号的时钟关系,又可分为同步FIFO和异步FIFO。

2.1 同步FIFO

同步FIFO的写时钟和读时钟为同步时钟,一般情况下为同一个时钟。同步FIFO内的所有逻辑都是同步逻辑。一个最简单的同步FIFO框图如下所示。

图片

产生FIFO空满信号的方法有两种:

一是在FIFO内部设置一个计数器来指示当前FIFO内部缓存了多少个数据,但这会引入新的寄存器造成额外的资源开销;

二是通过拓宽读写指针的位数,然后根据读写指针的关系来判断空满。

当读指针等于写指针时,标明FIFO处于空状态,如图所示,假设FIFO深度为8,那么读写地址的位宽取3,读写指针在此基础上拓宽一位:

图片

当FIFO内有数据写入时,写指针增加,此时读指针的低N-1位不等于写指针的低N-1位(N为指针拓宽一位之后的位宽),如图所示:

图片

如果此时再读出两个数据,FIFO又将回到空状态,此时读指针与写指针又相等:

图片

假如此时,一口气写入8个数据,写指针+8,变成4'b1010,FIFO处于满状态,此时读写指针的最高位不同,但低N-1位相同:

图片

于是可以总结得到FIFO空满信号的生成条件:

  • fifo_empty_o:
assign fifo_empty_o = (wr_ptr == rd_ptr);
  • fifo_full_o:
assign fifo_full_o = ((wr_ptr[$clog2(DEPTH)] != rd_ptr[$clog2(DEPTH)]) && (wr_addr == rd_addr));

2.2 异步FIFO

同步FIFO可用于在同步时钟域传输多比特信号,但若要实现两个异步时钟域之间的数据传输,就要使用异步FIFO。

异步FIFO相较于同步FIFO最大的不同在于读/写时钟域是异步的,也就是说读写控制信号是由不同的时钟驱动的,这就导致读指针需要同步到写时钟域,才能判断FIFO是否满;写指针也需要同步到读时钟域,才能判断FIFO是否空。

异步FIFO的框图如下:

图片

但是对于多比特信号的跨时钟域同步,存在一个严重的问题。如果像同步FIFO那样使用二进制的读写指针,指针每次加一都可能使好几位发生翻转,以三位指针为例,假设当前指针为3'b111下一次操作后指针加1变为3'b000.

我们已经知道,单比特信号打两拍同步之后的结果可能恢复成0或1的其中一个稳态,假如该单比特信号是从0→1,最终哪怕同步结果是0,也不影响整个电路的功能,只当是没有发生这次操作,在后续的运行过程中再把正确信号同步过来也是ok的。

但是对于多比特信号而言,多位发生翻转,其中的每一位都可能同步为不同的结果,也就是说3'b111→3'b000可能变成3'b111→3'b010或者3'b111→3'b110、3'b111→3'b001、3'b111→3'b101之类的任意值,这就明显违背了指针的正常逻辑,破坏了电路的功能。

我们希求的效果是3'b111→3'b000,哪怕同步结果不是3'b000,也得是3’b111保持不变。因此要求指针递增每次只变化一位。

刚好,格雷码的编码方式就是相邻两个数值只有一位不同。因此在异步FIFO设计中,跨时钟域同步读写指针之前,要将二进制指针先转换成格雷码编码的指针,再进行同步。

二进制和格雷码的互相转化逻辑,这里不再赘述,只展示Verilog代码以供参考:

bin2gray:

module bin2gray
#(
    parameter WIDTH = 8
)
(
    input       [WIDTH-1:0] bin,
    output      [WIDTH-1:0] gray
);


    assign gray = bin ^ {1'b0,bin[WIDTH-1:1]};


endmodule

gray2bin:

module gray2bin
#(
    parameter WIDTH = 8
)
(
    input       [WIDTH-1:0] gray,
    output      [WIDTH-1:0] bin
);


    genvar i;
    generate
        for(i=0;i< WIDTH;i=i+1)begin
            assign bin[i] = ^gray[WIDTH-1:i];
        end
    endgenerate


endmodule

相应的,用格雷码编码的指针来判断异步FIFO的空满状态:

  • fifo_empty_o:
assign empty = (rd_ptr_gray == wr_ptr_gray_sync_r2);
  • fifo_full_o:
assign full = ({~wr_ptr_gray[ADDR_WIDTH:ADDR_WIDTH-1],wr_ptr_gray[ADDR_WIDTH-2:0]} == rd_ptr_gray_sync_r2);
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • fifo
    +关注

    关注

    3

    文章

    387

    浏览量

    43533
  • 时钟
    +关注

    关注

    10

    文章

    1720

    浏览量

    131340
  • 时钟域
    +关注

    关注

    0

    文章

    52

    浏览量

    9528
  • 异步FIFO
    +关注

    关注

    0

    文章

    20

    浏览量

    8351
  • 同步FIFO
    +关注

    关注

    0

    文章

    5

    浏览量

    5340
收藏 人收藏

    评论

    相关推荐

    FIFO为什么不能正常工作?

    FIFO的情形。 在FPGA设计中,我们会经常用到异步FIFO进行时钟隔离。作为已经非常成熟
    的头像 发表于 11-02 09:25 1241次阅读
    <b class='flag-5'>FIFO</b>为什么不能正常工作?

    异步FIFO的设计分析及详细代码

    (每个数据的位宽) FIFO同步异步两种,同步即读写时钟相同,异步即读写
    发表于 11-15 12:52 8557次阅读
    <b class='flag-5'>异步</b><b class='flag-5'>FIFO</b>的设计分析及详细代码

    如何解决异步FIFO时钟亚稳态问题?

    时钟的问题:前一篇已经提到要通过比较读写指针来判断产生读空和写满信号,但是读指针是属于读时钟的,写指针是属于写
    的头像 发表于 09-05 14:29 6012次阅读

    同步FIFO之Verilog实现

    FIFO的分类根均FIFO工作的时钟,可以将FIFO分为同步
    的头像 发表于 11-01 09:57 1903次阅读

    异步fifo详解

    和写入数据(对于大型数据存储,在性能上必然缓慢),其数据地址是由内部读写指针自动加一完成的,不能像普通的存储器一样,由地址线决定读取或者写入某个特定地址的数据,按读写是否为相同时钟分为同步
    的头像 发表于 12-12 14:17 4079次阅读

    Verilog电路设计之单bit时钟同步异步FIFO

    FIFO用于为匹配读写速度而设置的数据缓冲buffer,当读写时钟异步时,就是异步FIFO。多bit的数据信号,并不是直接从写
    发表于 01-01 16:48 1258次阅读

    FIFO使用及其各条件仿真介绍

    FIFO(First In First Out )先入先出存储器,在FPG设计中常用于时钟的处理,FIFO可简单分为
    的头像 发表于 04-25 15:55 3872次阅读
    <b class='flag-5'>FIFO</b>使用及其各条件仿真<b class='flag-5'>介绍</b>

    时钟电路设计:多位宽数据通过FIFO时钟

    FIFO是实现多位宽数据的异步时钟操作的常用方法,相比于握手方式,FIFO一方面允许发送端在
    的头像 发表于 05-11 14:01 2927次阅读
    <b class='flag-5'>跨</b><b class='flag-5'>时钟</b><b class='flag-5'>域</b>电路设计:多位宽数据通过<b class='flag-5'>FIFO</b><b class='flag-5'>跨</b><b class='flag-5'>时钟</b><b class='flag-5'>域</b>

    FIFO设计—同步FIFO

    FIFO异步数据传输时常用的存储器,多bit数据异步传输时,无论是从快时钟到慢时钟
    发表于 05-26 16:12 1488次阅读
    <b class='flag-5'>FIFO</b>设计—<b class='flag-5'>同步</b><b class='flag-5'>FIFO</b>

    FIFO设计—异步FIFO

    异步FIFO主要由五部分组成:写控制端、读控制端、FIFO Memory和两个时钟同步
    发表于 05-26 16:17 1511次阅读
    <b class='flag-5'>FIFO</b>设计—<b class='flag-5'>异步</b><b class='flag-5'>FIFO</b>

    时钟设计:异步FIFO设计

    在ASIC设计或者FPGA设计中,我们常常使用异步fifo(first in first out)(下文简称为afifo)进行数据流的时钟,可以说没使用过afifo的Designer
    的头像 发表于 07-31 11:10 2173次阅读
    <b class='flag-5'>跨</b><b class='flag-5'>时钟</b>设计:<b class='flag-5'>异步</b><b class='flag-5'>FIFO</b>设计

    为什么异步fifo中读地址同步在写时钟时序分析不通过?

    为什么异步fifo中读地址同步在写时钟时序分析不通过? 异步
    的头像 发表于 10-18 15:23 680次阅读

    同步FIFO异步FIFO的区别 同步FIFO异步FIFO各在什么情况下应用

    简单的一种,其特点是输入和输出都与时钟信号同步,当时钟到来时,数据总是处于稳定状态,因此容易实现数据的传输和存储。 而异步FIFO则是在波形
    的头像 发表于 10-18 15:23 1630次阅读

    异步FIFO构设

    电子发烧友网站提供《异步FIFO构设计.pdf》资料免费下载
    发表于 02-06 09:06 0次下载

    同步FIFO异步FIFO区别介绍

    ,并且间隔时间长,也就是突发写入。那么通过设置一定深度的FIFO,可以起到数据暂存的功能,且使得后续处理流程平滑。 时钟的隔离:主要用异步FIFO
    的头像 发表于 06-04 14:27 1297次阅读
    <b class='flag-5'>同步</b><b class='flag-5'>FIFO</b>和<b class='flag-5'>异步</b><b class='flag-5'>FIFO</b>区别<b class='flag-5'>介绍</b>