摘要:本次实验学习记录主题为“FIFO_IP核实现算术求和”,主要内容是上位机通过串口向FPGA发送一定规格的数字矩阵,FPGA对矩阵处理,按规定逻辑实现求和运算,将结果返回串口转发至上位机。

芯片型号:cyclone Ⅳ EP4CE10F17C8

平台工具:Quartus II 15.0 (64-bit)、Modelsim SE-64 10.4

最终框图:


【FIFO IP核概述及调用】

FIFO(First In First Out,先入先出) IP核作为数据缓冲区,能临时存储从数据源接收的数据,直到数据被其他处理单元再次读取。FIFO IP核通常用于多比特数据的跨时钟域处理以及前后带宽不同步情况,平衡数据源和处理单元之间的速度差异,同时减少因速率不匹配而导致的等待时间或数据丢失。

FIFO IP核支持同步(SCFIFO)和异步(DCFIFO)操作模式,在同步模式下,读写操作在同一时钟域下进行。其支持可配置的参数(如数据宽度、深度等,调整以适应不同的需求。针对不同模式的选择,需要考虑方面包括时钟源、存取位宽和深度、以及一系列辅助设计的标志信号和操作信号。

下图为Quartus Ⅱ构建IP核能产生的全部接口,同步模式下,除了基本的外接口如数据位、时钟、写标志和读标志、计数位usedw外,还有清零操作(同步sclr/异步aclr)、满/近满/空/近空/校检eccstatus信号。而异步模式下,对于入栈和出栈辅助设计的分为了两批,具体结构如下图。

访问IP Catalog:在Quartus Ⅱ的菜单栏中,点击“Tools”选项,然后选择“IP Catalog”或者“MegaWizard Plug-In Manager”,打开“fifo”选项即可。FIFO配置流程分为三部分:parameter settings、EDA和summary。如下图的配置界面,在其左上可以实时看到配置产生的接口,左下角看到FIFO在FPGA所产生的资源消耗。

在配置完基本参数后,FIFO还支持功能等设置趋向,rdreq读取驱动:信号作为请求,数据滞后一个时钟周期输出;信号作为确认,数据同时输出。存储方式和最大深度选择自动匹配即可。FIFO性能支持最大速度和最小消耗资源空间两种,可根据具体工程需求选定。黄色方框内是上级检测和下级检测保护电路,即存储栈满和栈空情况下的继续操作保护,最小面是存储空间位置选择,这里默认选定内部存储块即可。

异步模式下,还需配置速度和稳定性的优化方式,一是保持最低延迟,但需要同步时钟,没有亚稳态保护,占用资源空间最小,提供良好性能;二是具备两个同步阶段和良好的亚稳态保护,资源空间消耗中等;三是提高最佳的亚稳态保护,具有三个或更多同步阶段。

【IP核的同步、异步调用及仿真验证】

首先,构建一个同步FIFO_IP核,具体配置如下:

almost_empty_value = 20,	//近空阈值
almost_full_value = 220, //近满阈值
intended_device_family = "Cyclone IV E", //FPGA IP核型号
lpm_numwords = 256, //FIFO深度
lpm_showahead = "OFF", //rdreq模式选择
lpm_type = "scfifo", //FIFO工作模式(同步,单时钟模式)
lpm_width = 8, //时钟源同步下,进入FIFO位宽
lpm_widthu = 8, //计数位宽

IP的直接调用inst.v模块文件即可,实例化应用后,通过一个简单的录入核/退出核仿真(如下两图)。可以看到,程序启动,持续向核内写入256个8bit数据,仿真设定,写入周期是读入周期的四倍。

计数到20时,退出近空阈值,近空信号拉低;计数到220,达到近满阈值,近满信号拉高,等到写入完毕(这里计数单元usedw_sig溢出,显示8'h00),满信号拉高。下一周期,读标志拉高,读取一个8bit数据后,满信号拉低,持续读取完毕。

构建一个异步混合FIFO_IP核,具体配置如下:

add_usedw_msb_bit = "ON",	//为计数位扩充一位,避免溢出
intended_device_family = "Cyclone IV E", //FPGA IP核型号
lpm_numwords = 256, //FIFO深度
lpm_showahead = "OFF", //rdreq模式选择
lpm_type = "dcfifo_mixed_widths", //混合异步fifo模式,意思是录入核和退出核位宽不一致
lpm_width = 8, //录入核位宽
lpm_widthu = 9, //计数位宽+1 = 9
lpm_widthu_r = 8, //读取退出核位宽
lpm_width_r = 16, //读取退出核计数位宽

异步模式,需要关注时序上的同步(打了两拍),50MHz的写时钟wrclk,25MHz的读时钟rdclk。这里由于写位宽和读位宽的不同,要区别写计数和读计数的计数方式。

【调用FIFO实现求和运算】

调用Quartus Ⅱ的IP核实现普通求和运算(便于Sobel算法FPGA学习),左边是求和模块的框图,需要复用两个相同位宽及深度的FIFO IP核,以m x n(5x4)矩阵为例,先对上三行求运算后,持续向下降一行运算,形成一个新的矩阵(m-2) x n形式。

FPGA运算:pi_data持续接入数据,先将第一、二行数据分布存入FIFO 1核和2核内,在第三行数据开始,同步读取两核一个数据,并对其作求和运算,通过po_data输出。求和的同时,将FIFO 2核内数据写入1核(1、2核此时为空),即第二行充当原先的第一行。第三行写入2核,第四行持续运算.......

时序图如下,pi_flagpi_data是串口rx模块接收上位机处理后的数据,录入此fifo_disp模块。矩阵的列和行计数器cnt_rowcnt_rol作为的顺序标志,方便确认求和准备。dout_flag条件(wr_en2)&&(rd_en),标志建立用于1核数据再次写入。借入标志信号sum_flag,触发求和po_data=data_out1+data_out2+pi_data

对应的各信号时序条件处理,代码如下:

always@(posedge sys_clk or negedge sys_rst)begin	//dispose cnt_row counter
if(!sys_rst) cnt_row <= 8'd0;
else if((cnt_row == CNT_ROW_MAX)&&(pi_flag)) cnt_row <= 8'd0;
else if(pi_flag) cnt_row <= cnt_row + 1'b1;
end always@(posedge sys_clk or negedge sys_rst)begin //dispose cnt_col counter
if(!sys_rst) cnt_col <= 8'd0;
else if((cnt_col == CNT_COL_MAX)&&(pi_flag)&&(cnt_row == CNT_ROW_MAX))
cnt_col <= 8'd0;
else if((cnt_row == CNT_ROW_MAX)&&(pi_flag))cnt_col <= cnt_col + 1'b1;
end always@(posedge sys_clk or negedge sys_rst)begin //dispose wr_en1 drive
if(!sys_rst) wr_en1 <= 1'b0;
else if((cnt_col == 8'd0) && (pi_flag)) wr_en1 <= 1'b1;
else wr_en1 <= dout_flag;
end always@(posedge sys_clk or negedge sys_rst)begin //dispose data_in1 sequence
if(!sys_rst) data_in1 <= 8'd0;
else if((pi_flag)&&(cnt_col == 8'd0)) data_in1 <= pi_data;
else if(dout_flag == 1'b1) data_in1 <= data_out2;
else data_in1 <= data_in1;
end always@(posedge sys_clk or negedge sys_rst)begin //dispose wr_en2 drive
if(!sys_rst) wr_en2 <= 1'b0;
else if((cnt_col >= 8'd1)&&(cnt_col <= CNT_COL_MAX - 1'b1)&&(pi_flag))
wr_en2 <= 1'b1;
else wr_en2 <= 1'b0;
end always@(posedge sys_clk or negedge sys_rst)begin //dispose data_in2 sequence
if(!sys_rst) data_in2 <= 8'b0;
else if((pi_flag)&&(cnt_col >= 8'd1)&&(cnt_col <= (CNT_COL_MAX - 1'b1)))
data_in2 <= pi_data;
else data_in2 <= data_in2;
end always@(posedge sys_clk or negedge sys_rst)begin //dispose rd_en drive
if(!sys_rst) rd_en <= 1'b0;
else if((pi_flag)&&(cnt_col >= 8'd2)&&(cnt_col <= CNT_COL_MAX)) rd_en <= 1'b1;
else rd_en <= 1'b0;
end always@(posedge sys_clk or negedge sys_rst)begin //dispose dout_flag sequence
if(!sys_rst) dout_flag <= 0;
else if((wr_en2)&&(rd_en)) dout_flag <= 1'b1;
else dout_flag <= 1'b0;
end always@(posedge sys_clk or negedge sys_rst)begin //dispose sum_flag sequence
if(!sys_rst) sum_flag <= 1'b0;
else if(rd_en) sum_flag <= 1'b1;
else sum_flag <= 1'b0;
end always@(posedge sys_clk or negedge sys_rst)begin //dispose po_data result
if(!sys_rst) po_data <= 8'b0;
else if(sum_flag) po_data <= data_out1 + data_out2 + pi_data;
else po_data <= po_data;
end always@(posedge sys_clk or negedge sys_rst)begin //dispose po_flag sequence
if(!sys_rst) po_flag <= 1'b0;
else po_flag <= sum_flag;
end

仿真分析:很明显,仿真图与上面的时序图一致,tx、rx模块在之前的实验经过仿真验证了。

最后,将程序下载至开发板,得到的数据与仿真结果一样,简单做了两次测试,结果都正确。

文献参考:

[1] FIFO求和实验 野火FPGA Verilog开发实战指南——基于Altera EP4CE10 征途Pro开发板 文档 (embedfire.com);

[2] 掰开揉碎讲 FIFO(同步FIFO和异步FIFO) - Doreen的FPGA自留地 - 博客园 (cnblogs.com)


本篇文章中使用的Verilog程序模块,若有需见网页左栏Gitee仓库链接:https://gitee.com/silly-big-head/little-mouse-funnyhouse/tree/FPGA-Verilog/

Quartus Ⅱ调用FIFO IP核方法实现求和(Mega Wizard)的更多相关文章

  1. 调用altera IP核的仿真流程—上

    调用altera IP核的仿真流程—上 在学习本节内容之后,请详细阅读<基于modelsim-SE的简单仿真流程>,因为本节是基于<基于modelsim-SE的简单仿真流程>的 ...

  2. FIFO IP核

    转载: 说白了,IP核就是别人做好了的硬件模块,提供完整的用户接口和说明文档,更复杂的还有示例工程,你只要能用好这个IP核,设计已经完成一半了.说起来容易,从冗长的英文文档和网上各个非标准教程中汲取所 ...

  3. 调用altera IP核的仿真流程—下

    调用altera IP核的仿真流程—下 编译 在 WorkSpace 窗口的 counter_tst.v上点击右键,如果选择Compile selected 则编译选中的文件,Compile All是 ...

  4. FIFO IP核仿真

    FIFO IP核仿真 1.FIFO IP核配置 2.FIFO测试逻辑代码 首先往FIFO里面写入512个数据(FIFO深度的一半),然后再开始同时往FIFO里面写入,读出数据.FIFO读和写的时钟域不 ...

  5. Vivado 调用自定义IP核

    关于Vivado如何创建自定义IP核有大量的参考文章,这里就不多加阐述了,本文目的主要是解决如何在新建工程中引用其它工程已经自定义封装好的IP核,从而实现自定义IP核的灵活复用. 举个例子,我们的目标 ...

  6. FPGA基础学习(2) -- FIFO IP核(Quartus)

    ALTERA在LPM(library of parameterized mudules)库中提供了参数可配置的单时钟FIFO(SCFIFO)和双时钟FIFO(DCFIFO).FIFO主要应用在需要数据 ...

  7. Altera FIFO IP核时序说明

    ALTERA在LPM(library of parameterized mudules)库中提供了参数可配置的单时钟FIFO(SCFIFO)和双时钟FIFO(DCFIFO).FIFO主要应用在需要数据 ...

  8. FPGA分频与倍频的简单总结(涉及自己设计,调用时钟IP核,调用MMCM原语模块)

    原理介绍 1.分频 FPGA设计中时钟分频是重要的基础知识,对于分频通常是利用计数器来实现想要的时钟频率,由此可知分频后的频率周期更大.一般而言实现偶数系数的分频在程序设计上较为容易,而奇数分频则相对 ...

  9. quartus ip核破解

    在证书文件中添加一段: FEATURE 6AF7_0012 alterad 2035.12 permanent uncounted E75BE809707E VENDOR_STRING="i ...

  10. IP核之初——FIFO添加以太网MAC头部

    本文设计思路源自明德扬至简设计法.在之前的几篇博文中,由于设计比较简单,所有的功能都是用verilogHDL代码编写实现的.我们要学会站在巨人的肩膀上,这时候就该IP核登场了! 说白了,IP核就是别人 ...

随机推荐

  1. C++ 资源大全:标准库、Web框架、人工智能等 | 最全整理

    C++ 资源列表,内容包括: 标准库.Web应用框架.人工智能.数据库.图片处理.机器学习.日志.代码分析等 目录 进程间通信 Json 日志 机器学习 数学 内存分配 多媒体 网络 PDF 物理学 ...

  2. vscode开发uniapp

    VS Code 对 TS 类型支持友好,前端开发者主流的编辑器 HbuilderX 对 TS 类型支持暂不完善,期待官方完善 工作区禁用 Vetur 插件(Vue2 插件和 Vue3 插件冲突) 工作 ...

  3. 圣诞快乐 - Splashtop 2020 年回顾及未来展望

    ​ 我们很高兴 Splashtop 的远程访问解决方案能够在这个充满挑战的时期为全球的组织和教育机构提供帮助. 实际上,2020 年 Splashtop 的每日使用量增加了400%!不仅如此,我们还增 ...

  4. Linux使用宝塔面板发布.NetCore3.1

    1,安装宝塔面板 yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0 ...

  5. 【OpenVINO™】在C#中使用 OpenVINO™ 部署 YOLOv10 模型实现目标

      最近YOLO家族又添新成员:YOLOv10,YOLOv10 提出了一种一致的双任务方法,用于无nms训练的YOLOs,它同时带来了具有竞争力的性能和较低的推理延迟.此外,还介绍了整体效率-精度驱动 ...

  6. 010. Jenkins安装与插件管理

    jenkins安装 要求安装环境: 内存: 1G以上 cpu: 1核以上 1. 环境准备: 10.0.0.65 jenkins 10.0.0.66 gitlab 官方安装文档: https://jen ...

  7. Dump Rtmp Audio Stream To AAC Formate File (从Rtmp流提取并保存AAC音频文件)

    一.准备工作 参考:https://www.cnblogs.com/doudouyoutang/p/10220599.html 搭建本地rtmp服务: https://www.cnblogs.com/ ...

  8. Vue3简单项目流程分享——工作室主页

    Vue3简单项目流程分享--工作室主页 零.写在最前 以下是项目相关的一些链接: 源代码GitHub仓库(需要魔法上网):仓库 网页示例(需要魔法上网):网页示例 UI图(来源@设计师杨贺):Mast ...

  9. Docker部署深度学习模型

    Docker部署深度学习模型 基础概念 Docker Docker是一个打包.分发和运行应用程序的平台,允许将你的应用程序和应用程序所依赖的整个环境打包在一起.比如我有一个目标检测的项目,我想分享给朋 ...

  10. php分组查询和聚合函数 数据显示的顺序

      // 分组查询和聚合函数         // 分组查询 : 将指定字段中的数据,按照不同的具体数值,进行分组         //           数据相同的分在一个分组中          ...