FPGA教程系列-乒乓操作

FPGA教程系列-乒乓操作

概述

摘抄了两段,品一品。

乒乓操作是一个经常用于数据流控制的处理技术,具有节约缓冲空间、对数据流无缝处理等特点。
乒乓操作(Ping-Pong Buffering)是一种常见的设计模式。它通过双缓冲技术,使得一个缓冲区在进行数据传输或处理时,另一个缓冲区可以同时接受或准备新的数据。这样就可以在多个时钟周期内实现数据的无缝交替,最大化利用FPGA资源和提高数据处理效率。

操作过程

通俗的总结一下就是:乒乓操作(Ping-Pong Buffer)的核心思想就是"为了不让干活的人停下来等,准备两个盘子轮流装菜" 。其实与流水线思想类似,也是拿空间去换取时间。

空间换时间:

  • 流水线: 用更多的寄存器(空间),换取了更高的吞吐率(时间)。
  • 乒乓: 用双倍的存储器(空间),换取了连续不断的读写能力(时间)。

并行处理 (Parallelism):

  • 流水线: 是"工序"的并行。第1个数据在做第3步时,第3个数据正在做第1步。
  • 乒乓: 是"读写"的并行。你在"写"这块地的时候,我在"读"那块地。

分别有两个缓冲区(两个RAM,buffer A和buffer B),都处于空闲状态,等待数据传输的开始。控制逻辑会指定一个缓冲区(例如buffer A)作为当前的写入缓冲区,另一个缓冲区(buffer B)则作为读取缓冲区。

  • 数据写入:数据从外部设备或数据源传输到当前的写入缓冲区(例如Buffer A)。当buffer A在接收新数据时,系统会按照时序或控制逻辑将数据逐步写入该缓冲区。
  • 数据读取:与此同时,处理器或其他模块从另一个缓冲区(例如Buffer B)读取并处理数据。此时,Buffer B存储的是之前已经接收完毕的数据,供系统进行处理或输出。

外部输入数据流通过输入数据流选择单元将数据流输入到数据缓存模块,比较常用的存储单元有双口RAM,FIFO,SDRAM等。在第一个缓冲周期,数据流通过"输入数据流选择单元"将数据写入"数据缓冲模块1"。写完之后进入第二个缓冲周期,在第二个缓冲周期数据流通过"输入数 据流选择单元"将数据写入到"数据缓冲模块2"的同时"输出数据流选择单元"将"数据缓冲模块1"的数据流读出,此时进入第三个缓冲周期。在第三个缓冲周期数据流通过"输入数据流选择单元"将数据写入到"数据缓存模块1"的同时将"数据缓冲模块2"的数据读出。如此反复循环地操作,即为乒乓操作。

应用场景

对于乒乓操作的应用,定义是:乒乓操作主要适用于block级流水线且对数据完整性有较高要求的场景。

具体的参考:https://mp.weixin.qq.com/s/ntgKDi6y9_cNiiqRx--MpA

如果要处理从高速数据到低速据的传输,FIFO可以在很多情况下发挥作用。然而,当高速数据流向低速数据处理的,并且对数据完整性有严格要求时,FIFO可能不适用。这是因为在这种情况下,你需要确保每一份数据的完整性,而FIFO的有限容量可能会导致数据溢出,从而无法保证数据的完整性。使用乒乓操作相当于使用双FIFO。在带宽较大的情况下,这种方式能够将数据流视作一次性突发数据(burst),从而有效缓解FIFO的压力。

例如,每0.5s写入1次,每1s读出1次,如果使用单FIFO缓存的话,每1s就会积累1次数据的余量,这种情况下无论FIFO设计的多大,都会溢出。但是,使用乒乓操作,相当于FIFO A/B写入,FIFO B/A休息,因此可以视为1s内FIFO A/B突发写入2次,在下一秒FIFO B/A突发写入2次。

实战

程序基于野火的教程,https://doc.embedfire.com/fpga/altera/ep4ce10_mini/zh/latest/fpga/pingpong.html

比较早了,目前用的是vivado的平台,还需要进行一个适配,很简单,就是需要vivado的IP核clk_wizard和ram核,可以自行进行一个适配。

时钟是50MHz和25MHz,数据以50MHz的速率进行写入,然后分两个25MHz的ram进行存储以及读取。

仿真可以考到数据的交替写入和读取。

仿真的时候发现数据会写入0000,这里应该是6362,检查一下逻辑

不知道是本身就存在逻辑错误还是移植的时候的错误,应该是判断的时候有一个打拍的延时,更新一下ctrl程序:

verilog 复制代码
//RAM1读使能,使用读时钟赋值
always@(negedge clk_25m or  negedge rst_n)
    if(rst_n == 1'b0)
        ram1_rd_en  <=  1'b0;
    else    if(ram1_wr_addr == 7'd99)
        ram1_rd_en  <=  1'b1;
    else   if(state == WRAM2_RRAM1)
        ram1_rd_en  <=  1'b1;
    else
        ram1_rd_en  <=  1'b0;

//RAM2读使能,使用读时钟赋值
always@(negedge clk_25m or  negedge rst_n)
    if(rst_n == 1'b0)
        ram2_rd_en  <=  1'b0;
    else    if(ram2_wr_addr == 7'd99)
        ram2_rd_en  <=  1'b1;
    else   if(state == WRAM1_RRAM2)
        ram2_rd_en  <=  1'b1;
    else
        ram2_rd_en  <=  1'b0;

重新仿真,发现按照预期的结果。

这个是简单的乒乓操作,主要是学习下思想。

相关推荐
Wishell20151 天前
FPGA教程系列-Vivado AXI串口仿真测试
仿真
Terasic友晶科技1 天前
6-DE10-Nano的HDMI方块移动案例——使用Modelsim仿真I2C控制器
fpga开发·仿真·modelsim·hdmi·i2c_controller
Wishell20153 天前
FPGA教程系列-Vivado AXI串口程序解析
仿真
云雾J视界7 天前
SPICE仿真进阶:AI芯片低功耗设计中的瞬态/AC分析实战
低功耗·仿真·spice·ai芯片·ac·均值估算
FPGA小迷弟8 天前
京微齐力FPGA联合modelsim仿真操作
fpga开发·ic·verilog·fpga·仿真
Wishell20159 天前
FPGA教程系列-Vivado Aurora 8B/10B 例程修改
仿真
Wishell201510 天前
FPGA教程系列-Vivado AXI4-Full 仿真测试
仿真
Wishell201511 天前
日拱一卒之FPGA学习计划
仿真
Wishell201512 天前
日拱一卒之quartus芯片移植查看
仿真