FPGA——FIFO

这篇具有很好参考价值的文章主要介绍了FPGA——FIFO。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

FIFO
FIFO(First In First Out,即先入先出),是一种数据缓冲器,用来实现数据先入先出的读写方式。FIFO 根据读写时钟是否相同,分为 SCFIFO(single-clock FIFO)和 DCFIFO(duabl-clock FIFO),SCFIFO 的读写为同一时钟,应用在同步时钟系统中;DCFIFO 的读写时钟不同,应用在异步时钟系统中。
SCFIFO
FPGA——FIFO
单时钟FIFO常用于片内数据交互,例如,在FPGA的控制下从外部传感器读取到的一连串传感器数据,首先被写入FIFO中,然后再以UART串口的数据发送速率将数据依次发送出去。由于传感器的单次读取数据可能很快,但并不是时刻都需要采集数据。

**full:**写满标志位,有效表示 FIFO 已经存储满了,此时应该通过该信号控制写请求信号(也称为写使能 信号),禁止再往 FIFO 中写入数据,防止数据溢出丢失。当写入数据量达到 FIFO 设置的最大空间时, 时钟上升沿写入最后一个数据同时 full 拉高;读取数据时随时钟上升沿触发同时拉低。
**empty:**读空标志位,有效表示 FIFO 中已经没有数据了,此时应该通过该信号控制读请求信号(也称为读使能信号),禁止 FIFO 继续再读出数据,否则读出的将是无效数据。与 full 相反,写入数据同时拉低;读到最后一个数据同时拉高。
**usedw:**显示当前 FIFO 中已存数据个数,与写入数据的个数是同步的,即写第一个数据时就置 1,空或满时值为 0(满是因为寄存器溢出)。
**almost full:**几乎满标志信号,我们可以控制 FIFO 快要被写满的时候和 full 信号的作用一样。
almost empty:几乎空标志信号,我们可以控制 FIFO 快要被读空的时候和 empty 信号的作用一样。
Asynchronous clear:异步复位信号,用于清空 FIFO。
**Synchronous clear:**同步复位信号,用于清空 FIFO。
FPGA——FIFO
FIFO读数据两种模式,上图序号1普通同步FIFO模式,当有效的时钟和读请求信号到来时的下一个周期才会从FIFO输出数据。换个说法就是数据滞后读请求一个时钟周期。第2个则是信号先出,也就是数据和读请求信号同时输出。
FPGA——FIFO
FIFO的优化及电路保护。yes是获取最大的速度,但是会占用更多的资源。no是使用更少的资源,但是速度会有所下降。蓝色框选项表示是否禁止上溢检测和下溢检测的保护电路(上溢检测保护电路主要是用于在 FIFO 存储满时禁止继续写数据;下溢检测保护电路主要是用于 FIFO 被读空时,禁止继续读数据)。默认不勾选是使用禁止保护
DCFIFO
双时钟FIFO的一个典型应用就是异步数据的收发。实现跨时钟域数据处理
所谓异步数据是指数据的发送端和接收端分别同步与不同的时钟域,使用双时钟FIFO的独立的读写时钟结构,能够将不同时钟域中的数据同步到所需的时钟域系统中。例如,在一个高速数据采集系统中,实现将高速 ADC采集的数据通过千兆以太网发送到PC机。ADC 的采样时钟(CLK1)由外部专用锁相环芯片产生,则高速ADC采样得到的数据就是同步于该时钟信号的,在 FPGA内部,如果 FPGA工作时钟(CLK2)是由独立的时钟芯片加片上锁相环产生的,则CLK1和 CLK2就是两个不同时钟域的时钟,他们的频率和相位没有必然的联系,假如CLK1为65M,CLK2为125M,那么就不能使用125M的数据来直接采集65M速率的数据,因为两者数据速率不匹配,在采集过程中会出现包括亚稳态问题在内的一系列问题,所以这里就可以使用一个具备双时钟结构的FlIFO来进行异步数据的收发。

FPGA——FIFO
异步FIFO可配置输入输出不同的位宽。满足输入数据位宽乘以FIFO深度等于输出位宽乘以输出数据深度:8256=16128。
FPGA——FIFO
异步FIFO优化选择。
第一个表示生成的IP有最低的延迟,但是需要一个同步时钟,该选项使用一个同步阶段,没有亚稳态保护,适用于同步时钟。面积最小,提供良好的性能。
第二个有两个同步阶段,具有良好的亚稳态保护。面积中等,提供良好的性能。
第三个选项使用三个或更多的同步阶段,具有最好的亚稳态保护。它的面积是最大的,但给出了最好的性能。且为异步时钟。

DCFIFO读写与时序仿真
直接调用厂家的fifo IP



module fifo
(

    input   wire         wrclk     ,   //同步于FIFO写数据的时钟50MHz
    input   wire  [7:0]  pi_data   ,   //输入顶层模块的数据,要写入到FIFO中,的数据同步于wrclk时钟
    input   wire         wrreq     ,   //输入数据有效标志信号,也作为FIFO的,写请求信号,同步于wrclk时钟
    input   wire         rdclk     ,   //同步于FIFO读数据的时钟25MHz
    input   wire         rdreq     ,   //FIFO读请求信号,同步于rdclk时钟

    output  wire         wrempty   ,   //FIFO写端口空标志信号,高有效,同步于wrclk时钟
    output  wire         wrfull    ,   //FIFO写端口满标志信号,高有效,同步于wrclk时钟
    output  wire  [8:0]  wrusedw   ,   //FIFO写端口中存在的数据个数,同步于wrclk时钟
    output  wire  [7:0] po_data   ,   //FIFO读出的数据,同步于rdclk时钟
    output  wire         rdempty   ,   //FIFO读端口空标志信号,高有效,同步于rdclk时钟
    output  wire         rdfull    ,   //FIFO读端口满标志信号,高有效,同步于rdclk时钟
    output  wire  [8:0]  rdusedw       //FIFO读端口中存在的数据个数,同步于rdclk时钟

);

dcfifo_256x8to128x16    dcfifo_256x8to128x16_inst
(
    .data   (pi_data),  
    .rdclk  (rdclk  ),  
    .rdreq  (rdreq  ),  
    .wrclk  (wrclk  ),  
    .wrreq  (wrreq),  	

    .q      (po_data),  
    .rdempty(rdempty),  
    .rdfull (rdfull ),  
    .rdusedw(rdusedw),  
    .wrempty(wrempty),  
    .wrfull (wrfull ),  
    .wrusedw(wrusedw)   
);

endmodule

testbench

`timescale  1ns/1ns
module tb_fifo();


reg          wrclk          ;
reg  [7:0]   pi_data        ;
reg          wrreq        ;
reg          rdclk          ;
reg          rdreq          ;
reg          sys_rst_n      ;



wire            wrempty     ;
wire            wrfull      ;
wire    [8:0]   wrusedw     ;
wire    [7:0]  po_data     ;
wire            rdempty     ;
wire            rdfull      ;
wire    [8:0]   rdusedw     ;


//初始化时钟、复位
initial begin
    wrclk      = 1'b1;
    rdclk      = 1'b1;
    sys_rst_n <= 1'b0;
    #100;
    sys_rst_n <= 1'b1;
end


always #7 wrclk = ~wrclk;
always #20 rdclk = ~rdclk;



always@(posedge wrclk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        wrreq <= 1'b0;
    else    if(wrempty)
        wrreq <= 1'b1;
    else	if(wrfull)
        wrreq <= 1'b0;

//pi_data:输入顶层模块的数据,要写入到FIFO中的数据
always@(posedge wrclk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        pi_data <= 8'b0;
    ////pi_data的值为0~255依次循环
    else    if(pi_data == 8'd255)
        pi_data <= 8'b0;
    else    if(wrreq  == 1'b1)  
        pi_data <= pi_data + 1'b1;



//rdreq:FIFO读请求信号同步于rdclk时钟
always@(posedge rdclk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        rdreq <= 1'b0;
    else    if(rdfull == 1'b1)
        rdreq <= 1'b1;
    else    if(rdempty == 1'b1)
        rdreq <= 1'b0;




fifo    fifo_inst(
    //FIFO写端
    .wrclk  (wrclk  ),  
    .pi_data(pi_data),  
    .wrreq(wrreq)	 ,  
    //FIFO读端
    .rdclk  (rdclk  ),  
    .rdreq  (rdreq  ),  

    //FIFO写端
    .wrempty(wrempty),  
    .wrfull (wrfull ),  
    .wrusedw(wrusedw),  
    //FIFO读端
    .po_data(po_data),  
    .rdempty(rdempty),  
    .rdfull (rdfull ),  
    .rdusedw(rdusedw)   
);

endmodule

FPGA——FIFO

当wrempty有效时拉高wrreq,此时写计数是在写请求有效的下一个周期才开始计数。可以勾选Add an extra MSB to usedw port(s),这样计数就不会计数到255时归零。
FPGA——FIFO
当写满的时,写满信号拉高,注意到写满信号实在wrusedw计数到255就拉高了,而且255还滞后了一个时钟周期,是因为当写入第一数据的,下一个周期wrusedw才开始计数,滞后了一个周期。而且计数从1开始,所以写满整个fifo要计数到256。当写满信号拉高时,在读时钟上升沿检测到写满信号为高时的下一个上升沿到来读满信号也会被拉高。写满信号被拉高,fifo写满,这是从fifo读取数据,如果以写满信号位标志信号,则要把写满信号同步到读时钟下,上诉用读满为标志信号,不用同步。当读空信号被写时钟检测到为高电平的下一个周期写空也会被拉高。当读空时,读请求拉低。
有上两张图可以知道,写请求信号总共占用了257个周期,因为写请求时在写满的时候才被拉低,所以在写入第256个数据写满拉高,但是被检查到占了一个时钟后期,所以写请求的对应的最后一个数据不会被写入fifo。这样子就会引出一个问题,如果想要固定bit的数据完整的写入fifo中,那这样子就得改进fifo。引入fifo最小深度计算。文章来源地址https://www.toymoban.com/news/detail-451482.html

到了这里,关于FPGA——FIFO的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 队列(Queue):先进先出(FIFO)的数据结构

    队列是一种基本的数据结构,用于在计算机科学和编程中管理数据的存储和访问。队列遵循先进先出(First In, First Out,FIFO)原则,即最早入队的元素首先出队。这种数据结构模拟了物理世界中的队列,如排队等待服务的人。 在本篇博客中,我们将详细介绍队列的概念、用途

    2024年02月05日
    浏览(46)
  • 栈:数据结构中的后进先出(LIFO)容器

    栈是一种基本的数据结构,广泛应用于计算机科学和编程中,用于管理数据的存储和访问。栈遵循后进先出(Last In, First Out,LIFO)原则,即最后放入栈的元素首先被取出。这种数据结构模拟了物理世界中的栈,如一堆书或一摞盘子。 栈是一个线性数据结构,具有以下关键特

    2024年02月06日
    浏览(36)
  • FPGA远程更新/远程调试的一种简单方法

    之前介绍过一种远程(无线)更新的方式,详见《起飞!通过无线WIFI下载调试FPGA》,这种方式缺点有两个:一是速度较慢;二是我们的设备中需要增加一个无线设备,增加成本的同时增加了暴露的风险。这两点即无法在调试的时候使用也没办法在实际设备中使用。今天我们

    2024年02月09日
    浏览(44)
  • 一种基于FPGA的雷达综合显示模块技术方案

    一、项目整 这是我们做过的一个项目,若有需求,请联系我。开放PCB和软件技术。 以FPGA为核心,开发设计具有多路图像/视频采集、处理、传输、显示等功能的嵌入式视频模块。可对多路SerDes接口输入的高速串行视频流数据进行解析,将解析出的雷达、红外及可见光图像视频

    2024年02月11日
    浏览(43)
  • 在fpga上开发音视频是一种什么体验?

    今天周末回公司解决了解码播放问题,最近周末也没啥事情,一般周六都会过去公司学习音视频开源项目(过去公司,主要是住的近,所以很方便!),待在家里也是无聊,所以就回去看开源项目,提升自己的视野和水平! 然后这里也分享一些关于音视频开发的一些感悟和日记

    2024年02月08日
    浏览(48)
  • 一种基于FPGA的TCP乱序重排算法,并通过Verilog语言进行了实现

    基于fpga的tcp乱序重排算法实现,通过verilog实现适用于fpga的tcp乱序重排算法,并通过实际数据测试验证。 代码里包含注释,可以明白每个模块的含义。 采用自创的乱序重排算法,易于在硬件中实现。 该算法和工程可用于实际应用、算法设计、研究学习。 提供测试用的抓包文

    2024年02月05日
    浏览(65)
  • 【操作系统】FIFO先进先出页面置换算法(C语言实现)

    FIFO页面置换算法,计算缺页率,文末附代码,及例题解析 1、内容         在地址映射过程中,若在页面中发现所要访问的页面不在内存中,则产生缺页中断。当发生缺页中断时,如果操作系统内存中没有空闲页面,则操作系统必须在内存选择一个页面将其移出内存,以便为

    2024年02月11日
    浏览(37)
  • scanf函数读取数据 & 清空缓冲区

    首先,要清楚的是,scanf在读取数据的时候,不是从键盘上读取,而是从 输入缓冲区读取数据 。 我们从键盘上输入的全部数据,不管是 数字 还是 字母 还是 空格 、 回车 、 Tab键 等,操作系统在接收时,都是将它们当成 字符 来接收的。 比如,我们从键盘输入123,它表示的

    2024年02月14日
    浏览(40)
  • 如何兼顾性能+实时性处理缓冲数据?

    我们经常会遇到这样的数据处理应用场景:我们利用一个组件实时收集外部交付给它的数据,并由它转发给一个外部处理程序进行处理。考虑到性能,它会将数据存储在本地缓冲区,等累积到指定的数量后打包发送;考虑到实时性,数据不能在缓冲区存太长的时间,必须设置

    2024年02月06日
    浏览(47)
  • (六)矢量数据的空间分析——缓冲区分析

    缓冲区是一组或一类地图要素(点、线、面)按设定的距离条件,围绕这组要素而形成具有一定范围的多边形实体,从而实现数据在二维空间扩展的信息分析方法。 从数学的角度来看,缓冲区是给定空间对象或集合后获得的他们的邻域。邻域的大小由邻域的半径或缓冲区建立

    2024年02月09日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包