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

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

3天内不再提示

FIFO的原理和设计

CHANBAEK 来源:数字IC与好好生活的两居室 作者:除夕之夜啊 2023-03-26 16:00 次阅读

FIFO(First In First Out)是异步数据传输时经常使用的存储器。该存储器的特点是数据先进先出(后进后出)。其实,多位宽数据的异步传输问题,无论是从快时钟到慢时钟域,还是从慢时钟到快时钟域,都可以使用 FIFO 处理。

FIFO 原理

工作流程

(1) 复位之后,在写时钟和非满状态信号的控制下,数据可以写入 FIFO 中。RAM 的写地址从 0 开始,每写一次数据写地址指针加一,指向下一个存储单元。当 FIFO 写满后,数据将不能再写入,否则数据会因覆盖而丢失。

(2) FIFO 数据为非空、或满状态时,在读时钟和非空状态信号的控制下,数据可以从 FIFO 中读出。RAM 的读地址从 0 开始,每读一次数据读地址指针加一,即指向下一个存储单元。当 FIFO 读空后,就不能再读数据,否则读出的数据将是错误的。

(3) FIFO 的存储结构为双口 RAM,允许读写同时进行。FIFO 的读写指针是循环计数的,即 读写指针对应的 RAM 地址超过 FIFO 深度时,会溢出归零,重新计数。

典型异步 FIFO 结构图如下所示。相关信号及空满状态的原理将在下面一一说明。

图片

读写时刻

(1) 关于写时刻,只要 FIFO 中数据为非满状态,就可以进行写操作;如果 FIFO 为满状态,则禁止再写数据。

(2) 关于读时刻,只要 FIFO 中数据为非空状态,就可以进行读操作;如果 FIFO 为空状态,则禁止再读数据。

(3) 总之,如果一段时间内不间断的对 FIFO 同时进行读写操作,则要求写 FIFO 速率不能大于读 FIFO 速率。

读空状态

(1) 复位时,FIFO 中没有数据,空状态信号拉高。当 FIFO 被写入数据后,空状态信号拉低,表示非空状态。当读数据地址追赶上写地址,即读写地址都相等时,FIFO 为空状态。

(2) 因为 FIFO 是异步的,所以读写地址进行比较时,需要同步打拍逻辑,就需要耗费一定的时间。因此,空状态的指示信号不是实时的,会有一定的延时。如果在这段延迟时间内又有新的数据写入 FIFO,就会出现空状态指示信号有效,但实际上 FIFO 中存在数据的现象。

(3) 严格来讲该空状态指示是错误的。但是产生空状态的意义在于防止读操作对空状态的 FIFO 进行数据读取。产生空状态信号时,实际 FIFO 中有数据,相当于提前判断了空状态信号,此时不再进行读 FIFO 操作也是安全的。所以,该设计从应用上来说是没有问题的。

(4) 牢记,读空状态信号,是在读时钟域产生的。

写满状态

(1) 复位时,FIFO 中没有数据,满信号是拉低的,表示 FIFO 中的数据没有写满 (其实 FIFO 是空的 )。当 FIFO 开始写数据且读操作不进行或读速率相对较慢时,只要写数据地址超过读数据地址的 FIFO 深度时,便会产生满状态信号。此时写地址和读地址也是相等的,但是意义是不一样的。

图片

(2) 此时经常使用多余的 1bit 分别当做读写地址的拓展位,来区分读写地址相同的时候,FIFO 的状态是空还是满状态。当读写地址与拓展位均相同的时候,表明读写数据的数量是一致的,则此时 FIFO 是空状态。如果读写地址相同,拓展位相反,表明写数据的数量已经超过读数据数量的一个 FIFO 深度了,此时 FIFO 是满状态。当然,此条件成立的前提是空状态禁止读操作、满状态禁止写操作。

(3) 同理,由于异步延迟逻辑的存在,满状态信号也不是实时的。但是也相当于提前判断了满状态信号,此时不再进行写 FIFO 操作也不会影响应用的正确性。

(4) 牢记,写满状态信号,是在写时钟域产生的。

格雷码

(1) 当读写时钟都是同一个时钟时,此时 FIFO 是同步的,直接对读写指针进行比对,产生空、满信号即可。

(2) 当读写时钟是异步的时候,因为读时钟域产生读空信号,写时钟域产生写满信号,所以产生空逻辑信号时,需要将写指针同步到读时钟域,再与读指针进行比较;产生满逻辑信号时,需要将读指针同步到写时钟域,再与写指针进行比较。

(3) 因为读写指针的信号宽度一般都是大于 1bit 的,所以同步处理时不能直接对多位宽的读写指针进行延迟打拍,需要借助格雷码对读写指针进行转换,保证每一个周期内地址指针只有 1bit 变化,然后再进行延迟打拍的同步处理。

(4) 4bit 的二进制码与格雷码之间的变化关系如下所示,其中 ⊕ 表示异或操作符。由图可知,二进制码对应的十六进制码递增时,二进制码对应的相邻的两个格雷码之间只有 1bit 数据有变化。当多位宽信号每次只有 1bit 数据变化时,可以使用延迟打拍的方法对其进行同步处理。

图片

(5) 下面对空逻辑的产生进行举例说明:

5.1) 首先需要对写指针 waddr 进行组合逻辑的格雷码变换 waddr_gray。

5.2) 为了保证 waddr_gary 在读时钟域每次被采集时只有 1bit 数据变化,则 waddr_gray 需要在其源时钟域即写时钟域进行一拍缓存 waddr_gray_d。因为 waddr 到 waddr_gray 的组合逻辑变换时,每次两者之间不只是有 1bit 变化的。

5.3) 在读时钟域对 waddr_gray_d 进行打拍同步,得到读时钟域同步后的写指针为 waddr_gray_rclk。

5.4) 根据格雷码变换规则,空信号有效时二进制码相等的读写指针,变为格雷码之后仍然相等。所以直接使用 waddr_gray_rclk 与读指针进行组合逻辑变换后的格雷码进行相等比较,即可产生读空信号逻辑。

5.5) 需要说明的是,满信号有效时,带有拓展位的读写指针高 1bit 相反、低位相同。所以变为格雷码之后,写满信号产生的条件,则是读写指针高 2bit 相反、低位相同 (请读者思考一下为什么?)。

FIFO 设计

设计要求

为设计应用于各种场景的 FIFO,这里对设计提出如下要求:

(1) FIFO 是异步的,即读写控制信号来自不同的时钟域。

(2) FIFO 深度、宽度参数化,输出空、满状态信号,并输出一个可配置的满状态信号。当 FIFO 内部数据达到设置的参数数量时,该信号拉高,此时需要对格雷码进行反解码。

(3) 输入数据和输出数据位宽可以不一致,但要保证写数据、写地址位宽与读数据、读地址位宽的一致性。例如写数据位宽 8bit,写地址位宽为 6bit(64 个数据)。如果输出数据位宽要求 32bit,则输出地址位宽应该为 4bit(16 个数据)。

双口 RAM 设计

RAM 地址位宽、数据位宽等端口参数可配置,读写位宽一致。实际中 RAMDP(Dual Port) 是需要使用 Memory IP 的,这里创建的 RAM 并没有考虑到异步问题。

Verilog 描述如下。

module  ramdp
  #(  parameter       AW     = 5 ,
      parameter       DW     = 16
   )
   (
    input                   CLK_WR , //写时钟
    input [DW-1:0]          D ,      //写数据
    input                   WR_EN ,  //写使能
    input [AW-1:0]          ADDR_WR ,//写地址
    input                   CLK_RD , //读时钟
    input                   RD_EN ,  //读使能
    input [AW-1:0]          ADDR_RD ,//读地址
    output reg [DW-1:0]     Q        //读数据
    );

   reg [DW-1:0]                 mem [(1<

计数器设计

计数器用于产生读写地址信息,位宽可配置,不需要设置结束值,让其溢出后自动重新计数即可。同时该计数器还具有格雷码转换与缓存的功能。

Verilog 描述如下。

module  ccnt_gray
  #(parameter W = 32'd8
    )
   (
    input              rstn ,
    input              clk ,
    input              en ,
    output [W-1:0]     cnt ,
    output [W-1:0]     cnt_gray ,
    output [W-1:0]     cnt_gray_d
    );


   reg [W-1:0]          cnt_r ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         cnt_r        <= 'b0 ;
      end
      else if (en) begin
         cnt_r        <= cnt_r + 1'b1 ;
      end
   end
   assign cnt = cnt_r ;
   assign cnt_gray      = cnt ^ (cnt>>1);


   reg [W-1:0]          cnt_gray_buf ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         cnt_gray_buf   <= 'b0 ;
      end
      else begin
         cnt_gray_buf   <= cnt_gray ;
      end
   end
   assign cnt_gray_d = cnt_gray_buf ;


endmodule

多位宽数据同步设计

读写指针进行格雷码变换并缓存后,每一个计数周期内地址指针只有 1bit 变化,所以可以直接使用延迟打拍的方法进行同步。数据宽度、同步级数均可配置。

Verilog 描述如下。

module  data1c_sync
  #(parameter DW    = 8,
    parameter STAGE = 3
    )
   (
    input              rstn ,
    input              clk ,
    input [DW-1:0]     data_in ,
    output [DW-1:0]    data_out
    );


   reg [DW-1: 0]       data_r [STAGE-1: 0];
   integer             i ;
   always @(posedge clk or negedge rstn) begin
      if (!rstn) begin
         for (i=0; i

格雷码反解码

因为该 FIFO 还存在一个可配置的满状态信号输出,所以需要对格雷码同步后的读指针进行反解码,然后在写时钟域与写指针进行比较,以判读当前 FIFO 中数据的具体个数。

module  gray_decode
  #(parameter W = 32'd8
    )
   (
    input [W-1:0]      gray ,
    output [W-1:0]     gray_decode
    );


   integer             i ;
   reg [W-1:0] gray_decode_r ;
   always @(*) begin
      gray_decode_r[W-1]        = gray[W-1];
      for (i=W-2; i>=0; i=i-1) begin
         gray_decode_r[i]     = gray_decode_r[i+1] ^ gray[i];
      end
   end


   assign gray_decode = gray_decode_r ;
endmodule

FIFO 设计

该模块为 FIFO 的主体部分,产生读写控制逻辑,包括读写指针、读写有效时刻以及空、满、可编程满状态的逻辑。

实际上此模块已经是典型的 FIFO 设计,有需要的读者可以直接使用该层次的 FIFO 代码进行测试,甚至应用到自己的设计之中。

module  fifo
    #(  parameter       DW        = 16 ,
        parameter       DEPTH     = 32 ,
        parameter       PROG_DEPTH = 16) //可设置深度
    (
        input                   rstn,  //读写使用一个复位
        input                   wclk,  //写时钟
        input                   wren,  //写使能
        input [DW-1: 0]         wdata, //写数据
        output                  wfull,    //写满标志
        output                  prog_full, //可编程满标志
        input                   rclk,  //读时钟
        input                   rden,  //读使能
        output [DW-1 : 0]       rdata, //读数据
        output                  rempty   //读空标志
     );


   localparam AW = log2b(DEPTH);
   //==================== push/wr counter ===============
   //wptr/waddr using one more bit to indict new-loop
   wire [AW:0]          waddr ;
   wire [AW:0]          waddr_gray ;
   wire [AW:0]          waddr_gray_d ;
   ccnt_gray        #(.W(AW+1))
   u_push_cnt(
      .rstn             (rstn),
      .clk              (wclk),
      .en               (wren && !wfull), //full 时禁止写
      .cnt              (waddr),
      .cnt_gray         (waddr_gray),
      .cnt_gray_d       (waddr_gray_d)
      );


   // sync: wptr from wclk to rclk
   wire [AW:0]          waddr_gray_rclk ;
   data1c_sync   #(.DW(AW+1), .STAGE(3))
   u_waddr_to_rclk
   (
      .rstn        (rstn),
      .clk         (rclk),
      .data_in     (waddr_gray_d),
      .data_out    (waddr_gray_rclk)
    );
   //============== pop/rd counter ===================
   wire [AW:0]          raddr ;
   wire [AW:0]          raddr_gray ;
   wire [AW:0]          raddr_gray_d ;
   ccnt_gray        #(.W(AW+1))
   u_pop_cnt(
      .rstn             (rstn),
      .clk              (rclk),
      .en               (rden && !rempty), //full 时禁止写
      .cnt              (raddr),
      .cnt_gray         (raddr_gray),
      .cnt_gray_d       (raddr_gray_d)
      );
   // sync: rdtr from rclk to wclk
   wire [AW:0]          raddr_gray_wclk ;
   data1c_sync   #(.DW(AW+1), .STAGE(3) )
   u_raddr_to_wclk
   (
       .rstn        (rstn),
       .clk         (wclk),
       .data_in     (raddr_gray_d),
       .data_out    (raddr_gray_wclk)
    );
   //============== full/empty logic ===================
   //(1) empty logic
   assign rempty = (raddr_gray == waddr_gray_rclk);




   //(2) full logic
   assign wfull  = (waddr_gray[AW:AW-1] == ~raddr_gray_wclk[AW:AW-1]) &&
                   (waddr_gray[AW-2:0] == raddr_gray_wclk[AW-2:0]) ;


   //(3) porgrammable full
   //waddr gray decode
   wire [AW:0]          raddr_degray_wclk ;
   gray_decode  #(.W(AW+1))
   u_waddr_degray_rclk (
       .gray            (raddr_gray_wclk),
       .gray_decode     (raddr_degray_wclk)
     );
   //prog full
   wire [AW:0]  waddr_delta = waddr >= raddr_degray_wclk ?
                              (waddr - raddr_degray_wclk) :
                              ((1<<(AW+1)) + waddr - raddr_degray_wclk) ;
   assign       prog_full   = waddr_delta >= PROG_DEPTH ;


   //双口 ram 例化
   ramdp     #(.AW(AW), .DW (DW))
   u_ramdp
     (
      .CLK_WR          (wclk),
      .WR_EN           (wren & !wfull), //写满时禁止写
      .ADDR_WR         (waddr[AW-1:0]),
      .D               (wdata[DW-1:0]),
      .CLK_RD          (rclk),
      .RD_EN           (rden & !rempty), //读空时禁止读
      .ADDR_RD         (raddr[AW-1:0]),
      .Q               (rdata[DW-1:0])
      );


   function  integer log2b ;
      input     integer depth ;
      for (log2b=0; (1<

FIFO 调用

下面可以调用设计的 FIFO,完成多位宽数据传输的异步处理。

写数据位宽为 4bit,写深度为 32。

读数据位宽为 16bit,读深度为 8,可配置 full 深度为 16。

该模块只是 FIFO 的一个具体应用,用于数据的异步传输、缓存与整合。

//ensure write rate < read rate
module  fifo_buf
  #(  parameter       DWI        = 4 , //width 4
      parameter       AWI        = 5 , //depth 32
      parameter       DWO        = 16 ,
      parameter       AWO        = 3 ,
      parameter       PROG_DEPTH = 16
   )
   (
      input                     rstn,  //读写使用一个复位
      //data in
      input                     din_clk,  //写时钟
      input                     din_en,  //写使能
      input [DWI-1: 0]          din, //写数据
      //data out
      input                     dout_clk,  //读时钟
      output                    dout_valid,  //读使能
      output [DWO-1 : 0]        dout //读数据
    );


   wire                         wfull ;    //写满标志
   wire                         prog_full ; //可编程满标志
   wire                         rempty ;   //读空标志
   wire [DWI-1:0]               rdata_fifo ;
   wire                         rden_fifo ;
   fifo  #(.DW(DWI), .DEPTH(1<

testbench

testbench 描述如下,用于测试空、满逻辑信号,以及读写操作。测试中只列举了输入数据位宽小于输出数据位宽的情景。

`timescale 1ns/1ns
`define SMALL2BIG


module test ;
`ifdef SMALL2BIG
   reg          rstn ;
   reg          clk_slow, clk_fast ;
   reg [3:0]    din ;
   reg          din_en ;
   wire [15:0]  dout ;
   wire         dout_valid ;


   //reset
   initial begin
      clk_slow  = 0 ;
      clk_fast  = 0 ;
      rstn      = 0 ;
      #50 rstn  = 1 ;
   end


   //读时钟 clock_slow 较快于写时钟 clk_fast 的 1/4
   //保证读数据稍快于写数据
   parameter CYCLE_WR = 40 ;
   always #(CYCLE_WR/2/4) clk_fast = ~clk_fast ;
   always #(CYCLE_WR/2-1) clk_slow = ~clk_slow ;


   //data generate
   initial begin
      din       = 16'h4321 ;
      din_en    = 0 ;
      wait (rstn) ;
      //(1) 测试 full、prog_full、empyt 信号
      force test.u_data_buf.u_fifo.rden = 1'b0 ;
      repeat(32) begin
         @(negedge clk_fast) ;
         din_en = 1'b1 ;
         din    = {$random()} % 16;
      end
      @(negedge clk_fast) din_en = 1'b0 ;


      //(2) 测试数据读写
      #500 ;
      rstn = 0 ;
      #10 rstn = 1 ;
      release test.u_data_buf.u_fifo.rden ;
      repeat(60) begin
         @(negedge clk_fast) ;
         if (!test.u_data_buf.u_fifo.wfull) begin
            din_en = 1'b1 ;
            din    = {$random()} % 16;
         end
         else begin
            din_en = 1'b0 ;
         end
      end


      //(3) 停止读取再一次测试 empyt、full、prog_full 信号
      #800 ;
      force test.u_data_buf.u_fifo.rden = 1'b0 ;
      repeat(18) begin
         @(negedge clk_fast) ;
         din_en = 1'b1 ;
         din    = {$random()} % 16;
      end
   end


   fifo_buf #(.DWI(4), .AWI(5), .DWO(16), .AWO(3), .PROG_DEPTH(16))
     u_data_buf(
        .rstn           (rstn),
        .din_clk        (clk_fast),
        .din            (din),
        .din_en         (din_en),
        .dout_clk       (clk_slow),
        .dout           (dout),
        .dout_valid     (dout_valid));


`else // !`ifdef SMALL2BIG
`endif


   //stop sim
   initial begin
      forever begin
         #100;
         if ($time >= 5000)  $finish ;
      end
   end


endmodule

仿真分析

根据 testbench 中的 3 步测试激励,分析如下:

测试 (1) : FIFO 端口及一些内部信号时序结果如下。

由图可知,FIFO 内部开始写数据,空状态信号 rempty 拉低(红色 M1 ) 之前有一段时间延迟,这是写地址同步延时导致的。

由于此时没有进行读 FIFO 操作,所以 prog_full 与 full 拉高 (黄色 M2 与绿色 M3) 几乎没有延迟。

图片

测试 (2) : FIFO 同时进行读写时,fifo 与 fifo_buf 模块的端口信号如下所示。

由图可知,数据开始传输时,fifo 模块的等位宽数据输出、fifo_buf 整合之后的数据输出,均与输入数据对应,没有传输错误。

图片

测试 (3) :整个 FIFO 读写行为及读停止的时序仿真图如下所示。

由图可知,读写操作同时进行时,wfull 信号会不断翻转 (M4 时刻之前),这是因为此时 fifo 的使用方法是非满即写,非空即读。

M4 时刻禁止写操作后(din_en 恒为 0),由于读一致存在,所以 full 信号会拉低并保持,表示 fifo 中数据一直未满。而 prog_full 也会相继拉低 (M5 时刻),表示 FIFO 中的数据已经低于配置的数目。

当恢复写操作后 (din_en 恒为 1,对应 M6 时刻),prog_full 与 full 信号相继拉高。

图片

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 存储器
    +关注

    关注

    38

    文章

    7452

    浏览量

    163598
  • fifo
    +关注

    关注

    3

    文章

    387

    浏览量

    43547
  • 计数器
    +关注

    关注

    32

    文章

    2253

    浏览量

    94351
  • 时钟
    +关注

    关注

    10

    文章

    1720

    浏览量

    131360
  • 指针
    +关注

    关注

    1

    文章

    480

    浏览量

    70509
收藏 人收藏

    评论

    相关推荐

    FIFO队列原理简述

    FIFO是队列机制中最简单的,每个接口上只有一个FIFO队列,表面上看FIFO队列并没有提供什么QoS保证,甚至很多人认为FIFO严格意义上不算做一种队列技术,实则不然,
    发表于 07-10 09:22 1638次阅读

    什么是fifo

    1.什么是FIFOFIFO是英文First In First Out 的缩写,是一种先进先出的数
    发表于 07-22 16:00 0次下载

    FIFO的操作

    系统在上电复位时,SPI工作在标准SPI模式,禁止FIFO功能。FIFO的寄存器SPIFFTX、SPIFFRX和SPIFFCT不起作用。通过将SPIFFTX寄存器中的SPIFFEN的位置为1,使能FIFO模式。SPIRST能在操
    发表于 09-29 10:38 33次下载

    异步FIFO结构

    设计一个FIFO是ASIC设计者遇到的最普遍的问题之一。本文着重介绍怎样设计FIFO——这是一个看似简单却很复杂的任务。一开始,要注意,FIFO通常用于时钟域的过渡,是双时钟设计
    发表于 10-15 08:44 94次下载

    什么是fifo fifo什么意思 GPIF和FIFO的区别

    什么是fifo (First Input First Output,先入先出队列)这是一种传统的按序执行方法,先进入的指令先完成并引退,跟着才执行第二条指令。1.什么是FIFO
    发表于 12-20 13:51 1.2w次阅读

    最经典的FIFO原理

    最经典的FIFO原理,详细讲述了FIFO的原理,适合入门新手,仔细分析阅读,也适合高手查阅。
    发表于 05-03 15:15 0次下载

    fifo存储器是什么_fifo存储器有什么特点

    FIFO( First In First Out)简单说就是指先进先出。由于微电子技术的飞速发展,新一代FIFO芯片容量越来越大,体积越来越小,价格越来越便宜。作为一种新型大规模集成电路,FIFO芯片以其灵活、方便、高效的特性。
    发表于 12-06 14:29 1.1w次阅读
    <b class='flag-5'>fifo</b>存储器是什么_<b class='flag-5'>fifo</b>存储器有什么特点

    如何配置自己需要的FIFOFIFO配置全攻略

    配置FIFO的方法有两种: 一种是通过QUARTUS II 中TOOLS下的MegaWizard Plug-In Manager 中选择FIFO参数编辑器来搭建自己需要的FIFO,这是自动生成
    发表于 07-20 08:00 17次下载
    如何配置自己需要的<b class='flag-5'>FIFO</b>?<b class='flag-5'>FIFO</b>配置全攻略

    同步FIFO之Verilog实现

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

    异步fifo详解

    异步fifo详解 一. 什么是异步FIFO FIFO即First in First out的英文简称,是一种先进先出的数据缓存器,与普通存储器的区别在于没有外部读写的地址线,缺点是只能顺序的读取
    的头像 发表于 12-12 14:17 4081次阅读

    FIFO设计—同步FIFO

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

    FIFO设计—异步FIFO

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

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

    同步FIFO和异步FIFO的区别 同步FIFO和异步FIFO各在什么情况下应用? 1. 同步FIFO和异步
    的头像 发表于 10-18 15:23 1635次阅读

    同步FIFO和异步FIFO区别介绍

    1. FIFO简介 FIFO是一种先进先出数据缓存器,它与普通存储器的区别是没有外部读写地址线,使用起来非常简单,缺点是只能顺序读写,而不能随机读写。 2. 使用场景 数据缓冲:也就是数据写入过快
    的头像 发表于 06-04 14:27 1317次阅读
    同步<b class='flag-5'>FIFO</b>和异步<b class='flag-5'>FIFO</b>区别介绍

    FIFO Generator的Xilinx官方手册

    FIFO作为FPGA岗位求职过程中最常被问到的基础知识点,也是项目中最常被使用到的IP,其意义是非常重要的。本文基于对FIFO Generator的Xilinx官方手册的阅读与总结,汇总主要知识点
    的头像 发表于 11-12 10:46 148次阅读
    <b class='flag-5'>FIFO</b> Generator的Xilinx官方手册