浅谈FPGA的乒乓操作
乒乓操作是FPGA设计中经常用到的设计思想,常用于需要提高数据效率的地方。其主要特点有:
1、 实现数据的无缝缓冲和处理;
2、 可节约缓冲区空间;
3、 可实现低速模块处理高速模块。
典型的乒乓操作原理如下图:
如图所示:
T1时刻,DATA_T1存入buffer 1;
T2时刻,buffer 1已被写满,DATA_T2存入buffer 2, 同时buffer 1将DATA_T1送至运算模块处理;
T3时刻,DATA_T3存入buffer A1,同时buffer 2将DATA_T2送至运算模块处理;
然后重复2、3阶段的操作。
从上图也可以看出乒乓操作的核心就是控制缓冲模块的读写,具体可以细化为输入数据控制模块、缓冲模块1、缓冲模块2以及输出数据控制模块,这里的缓冲模块可以是FIFO、BRAM等。下面举例具体说明:
输入不连续的数据字节,工作时钟要求是50Mhz;
输出要求每次16字节连续输出,并且有一个信号作为数据有效指示;
每次输出之间间隔时间可以是随机的,一般是至少不低于一个时钟周期的间隔;
思考:
1、 数据为8位且16个后输出,所以考虑用16*8的BRAM做缓冲模块。
2、 两个缓冲模块写控制考虑用5位计数器,其中最高位控制不同缓冲模块的写,低4位代表写地址
3、 缓冲模块的读控制需要判断缓冲模块是否写满,利用写计数器最高位的上升沿和下降沿判断:上升沿代表buffer 1写满,下降沿代表buffer 2写满。
4、 注意输出数据流单元数据与数据有效指示同步的关系(不同缓冲模块,数据有效指示做不同的同步处理)
基于上述考虑画出时序图,如下:
其对应的电路图如下:
对应的verilog描述如下:
`timescale 1ns/10ps
module pingpang_operation (rst_n ,clk_50m ,data_in , // 输入数据data_valid , // 输入数据有效信号 data_out , // 输出数据data_out_vld
// 输出数据有效信号);input rst_n ;inputclk_50m ;input
[7:0] data_in ; // 输入数据input data_valid ; // 输入数据有效信号output [7:0] data_out ; // 输出数据outputdata_out_vld ;
// 输出数据有效信号reg [4:0] wr_cnt;// ram A and ram B 的写地址reg wr_cnt4_d; // wr_cnt[4] 寄存一拍wire wr_a_en; // ram A 的写使能 wire wr_b_en; //
ram B 的写使能reg rd_a_en; // ram A 的读使能reg rd_a_en_d1,
rd_a_en_d2; // ram A 的读使能寄存2拍 reg [3:0] rd_a_addr; // ram
A 的读地址reg rd_b_en; // ram B 的读使能reg rd_b_en_d1, rd_b_en_d2; // ram
B 的读使能寄存2拍reg [3:0] rd_b_addr; // ram
B 的读地址wire [7:0] rd_a_data; // ram
A 的读数据wire [7:0] rd_b_data; // ram
B 的读数据wire [7:0] data_out;// 数据输出wire data_out_vld; // 数据输出有效信号//------------------------------------------------------ // ramA和ramB的写电路模块设计 //------------------------------------------------------//设计ramA 和ramB的写地址always
@(posedge clk_50m or negedge rst_n) beginif (!rst_n)wr_cnt <= 5'h00;else if(data_valid) wr_cnt <= wr_cnt + 5'd1; end // 设计ram A 和 ram B的写使能 assign wr_a_en = ~wr_cnt[4] & data_valid;assign wr_b_en = wr_cnt[4]
& data_valid;//------------------------------------------------------ // ramA和ramB的读电路模块设计 //------------------------------------------------------//ram_a或ram_b写完成后才能进行相应的读always @(posedge clk_50m or negedge rst_n) beginif (!rst_n)wr_cnt4_d <= 1'b0;else wr_cnt4_d
<= wr_cnt[4];endwire wr_cnt4_rise,wr_cnt4_down;assign wr_cnt4_rise
= wr_cnt[4] & ~wr_cnt4_d;//ram_a 可读assign wr_cnt4_down
= ~wr_cnt[4] & wr_cnt4_d;//ram_b 可读//reg [3:0] cnt_rd;//always @(posedge clk_50m or negedge
rst_n) // begin// if (!rst_n)// cnt_rd <= 4'd0;// else if(wr_cnt4_rise | wr_cnt4_down)// cnt_rd <= cnt_rd + 4'd1;//
end//ramA的
读使能 always
@(posedge clk_50m or negedge rst_n) beginif (!rst_n)rd_a_en <= 1'b0;else if(wr_cnt4_rise)rd_a_en <= 1'b1;else if(rd_a_addr==4'hf)//else
if(cnt_cnt==4'd15)rd_a_en <= 1'b0;end//ramA的 读地址always
@(posedge clk_50m or negedge rst_n) beginif (!rst_n)rd_a_addr <= 4'h0;else if (rd_a_en)rd_a_addr <= rd_a_addr +4'h1;end//ramB的 读使能 always
@(posedge clk_50m or negedge rst_n) beginif (!rst_n)rd_b_en <= 1'b0;else if(wr_cnt4_down)rd_b_en <= 1'b1;else if(rd_b_addr==4'hf)//else
if(cnt_cnt==4'd15)rd_b_en <= 1'b0;end//ramB的 读地址always
@(posedge clk_50m or negedge rst_n) beginif (!rst_n)rd_b_addr <= 4'h0;else if (rd_b_en)rd_b_addr <= rd_b_addr +4'h1;end//------------------------------------------------------ // ramA和ramB的读数据输出电路//------------------------------------------------------//ramA的 读使能寄存2拍 always
@(posedge clk_50m or negedge rst_n) beginif (!rst_n)beginrd_a_en_d1 <= 1'b0;rd_a_en_d2 <= 1'b0;endelse beginrd_a_en_d1 <= rd_a_en;rd_a_en_d2 <= rd_a_en_d1;endend//ramB的 读使能寄存2拍 always
@(posedge clk_50m or negedge rst_n) beginif (!rst_n)beginrd_b_en_d1 <= 1'b0;rd_b_en_d2 <= 1'b0;endelse beginrd_b_en_d1 <= rd_b_en;rd_b_en_d2 <= rd_b_en_d1;endend//读数据输出assign data_out =
rd_a_en_d2 ? rd_a_data : rd_b_data;//读数据有效信号assign data_out_vld = rd_a_en_d2
| rd_b_en_d2;//------------------------------------------------------ // ramA和ramB//------------------------------------------------------ //
ram A 16 X 8bits ,ram的读数据比读地址和读使能延迟2Tram_lyram_a( .clock (clk_50m), //时钟 .data (data_in), //写数据.rdaddress(
rd_a_addr), //读地址.rden (rd_a_en), //读使能.wraddress(wr_cnt[3:0]
), //写地址.wren (wr_a_en ), //写使能.q (rd_a_data) //读数据);//
ram B 16 X 8bitsram_lyram_b( .clock (clk_50m ), //时钟 .data (data_in), //写数据.rdaddress(rd_b_addr), //读地址.rden (rd_b_en), //读使能.wraddress(wr_cnt[3:0]), //写地址.wren (wr_b_en ), //写使能.q (rd_b_data) //读数据);endmodule
至此完成FPGA乒乓操作的设计。
本设计完整工程下载地址:链接:https://pan.baidu.com/s/19ZjRFEDLXUhPrV6gtn9uEA
提取码:1z44
另外,感谢恩师李煜老师。
浅谈FPGA的乒乓操作相关推荐
- 浅谈区间最值操作与历史最值问题
浅谈树状数组与线段树:https://www.cnblogs.com/AKMer/p/9946944.html 区间最值问题 以Gorgeous Sequence为例: 对于线段树上每个结点,我们维护 ...
- 浅谈FPGA网络PHY芯片RTL8211FD的配置和简单使用
最近迷上了FPGA的网络通信和GTP光通信,个人感觉光通信简单一些,那就从难得网络通信开始吧,先搞个最简单的,使用MDIO配置和读取网络PHY的信息. 板子:米联客的MA703FA(A7-35T板子) ...
- 浅谈FPGA有限状态机
状态机几乎可以实现一切时序电路. 有限状态机(FiniteStateMachine, FSM),根据状态机的输出是否与输入有关,可分为Moore型状态机和Mealy型状态机.Moore型状态机输出仅仅 ...
- 浅谈FPGA与音频处理器的结合
FPGA通常是面向通信行业,尽管其主要开发者仍然专注于通信应用, 但他们越来越关注存储和服务器市场. 但是, 广阔的工业市场又如何呢? 通常, 工业市场的要求并不像存储.服务器或通信应用程序所要求的那 ...
- 浅谈无缓存I/O操作和标准I/O文件操作区别 (转载)
首先,先稍微了解系统调用的概念: 系统调用,英文名system call,每个操作系统都在内核里有一些内建的函数库,这些函数可以用来完成一些系统系统调用把应用程序的请求传给内核,调用相应的的内核函数完 ...
- python中判断列表数据类型_浅谈Python数据类型判断及列表脚本操作
数据类型判断 在python(版本3.0以上)使用变量,并进行值比较时.有时候会出现以下错误: TypeError: unorderable types: NoneType() < int() ...
- (19)FPGA乒乓操作
(19)FPGA乒乓操作 1.1 目录 1)目录 2)FPGA简介 3)Verilog HDL简介 4)FPGA乒乓操作 5)结语 1.2 FPGA简介 FPGA(Field Programmable ...
- python列表使用判断_浅谈Python数据类型判断及列表脚本操作
数据类型判断 在python(版本3.0以上)使用变量,并进行值比较时.有时候会出现以下错误: TypeError: unorderable types: NoneType() < int() ...
- java双层list扁平化,浅谈java8 stream flatMap流的扁平化操作
概念: Steam 是Java8 提出的一个新概念,不是输入输出的 Stream 流,而是一种用函数式编程方式在集合类上进行复杂操作的工具.简而言之,是以内部迭代的方式处理集合数据的操作,内部迭代可以 ...
- 浅谈XILINX FPGA CLB单元 汇总 (CLB、LUT、存储单元、Distributed RAM、移位寄存器、多路复用器、进位逻辑(Carry Logic))
浅谈XILINX FPGA CLB单元 汇总 (CLB.LUT.存储单元.Distributed RAM.移位寄存器.多路复用器.进位逻辑(Carry Logic)) 一.概述 CLB可配置逻辑块是指 ...
最新文章
- ios(iphone/ipad)开发笔记(1)
- MSRA副院长周明博士:四大研究领域揭示自然语言技术的奥秘
- 网站制作基本要素了解一下
- AD RMS保护电子邮件安全
- aptitude命令的使用
- DrJava试用笔记
- widows下nignx的使用
- 接口与抽象类区别和接口jdk8新特性
- 学fpga(在线verilog编程)
- JBOSS 5.0.0GA的集群搭建
- 记录下docker命令
- 5个可以让你事半功倍的Python自动化脚本
- 一些事,只配当回忆.一些人,只能做过客。既不回头 何必不忘 既然无缘 何必誓言 。这个世界.那么脏.谁有资格.说悲伤。...
- 下面哪些不是java的原始数据类型_以下哪个不是Java的原始数据类型()A? – 手机爱问...
- 怎么才能写好技术文档?这是我的全部经验
- ucache灾备云报价_UCache云灾备体系介绍
- 【连载】人类唯一的出路:变成人工智能(一)
- The long goodbye 漫长的告别 | 经济学人中英双语对照精读笔记
- MATLAB2016b遗传算法工具箱安装
- 某大学生写给女朋友的信
热门文章
- 学编程c语言高考能加分吗,编程已列入中高考,孩子升学加分的机会你抓住了么?...
- Kubernetes Secrets
- rn在java中什么意思,RN150中RN是什么意思
- PLSQL连接Oracle 数据库配置详解
- WiFi万能钥匙+小米手机拿到coffee店WiFi密码
- windows2008+IIS7部署智遥工作流
- Problem: 美丽的黄山 (指针)
- Word里输入带框的对号
- RS编译码理论介绍与MATLAB性能仿真
- 家用双千兆路由器推荐_千兆以上(专业级)无线路由器路由器哪款好