摘要:本次实验学习记录主题为“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. 在 ThinkPad E470 上安装 Ubuntu 16.04 无线网卡驱动

    目录 文章目录 目录 安装 安装 # 查看无线网卡驱动类型,E470 一般为 RTL8821CE lspci # 安装必要工具 sudo apt-get install build-essential ...

  2. nginx 常见配置案例参考(优化)

    在NGINX中,可以通过配置文件和特定的指令来实现权限控制.以下是一些常见的权限控制方法: 使用deny指令: 在NGINX配置文件中,可以使用deny指令来拒绝特定IP地址或IP地址范围的访问.可以 ...

  3. iis worker process w3wp 进程 占用率100%

    今天电脑特别的卡,我没当回事,但是实在是卡得不行了,我打开任务管理器,发现 iis worker process 进程已经快100%了,我之前在iis上发布了一个webservice,我就把这个网站给 ...

  4. Angular等了三年,那个她已经来了

    Angular生态丰富,功能强大,支撑了许多大型项目的开发.而且一直在前方等待着其他框架跟上.但是不得不直面的一个问题就是:"在等待其他框架跟上的这三年",Angular在陆陆续续 ...

  5. [吐槽]困扰了1周的API调用失败问题的原因是使用了加密DNS

    参考API的官方文档使用postman测试了一下,导入了百度提供的postman环境配置文件,粘贴提供的预处理代码后直接发起请求,响应里提示 "signature is empty" ...

  6. vue3 elementui plus Select 选择器不选择下拉框里面的数据得到的value值

    我们先来看 我点击弹框出现什么都不做 直接点击确定 看传参 tableId,timeColumnId,userColumnId直接是名称而没有获取value值 看下下拉框里面的数据 而我想直接点击获取 ...

  7. 讲课 PPT 公开啦

    目前限于时间原因,只在 Github Pages 上托管了. 之后有时间会托管到 pythonanywhere 上,因为 Github Pages 是在太慢了.

  8. EF EntityFramework 强制从数据库中取数据,而不是上下文

    场景:插入了一条数据到数据库,这条数据会有其它程序修改,接着程序想获取最新数据.此时不加额外处理,取的仍是旧的. t_task ta = new t_task(); ta.item_id = item ...

  9. Spring扩展——Aware接口

    Aware接口 在Spring中有许多的Aware接口,提供给应用开发者使用,通过Aware接口,我们可以通过set的方式拿到我们需要的bean对象(包括容器中提供的一些对象,ApplicationC ...

  10. 如何去掉安装IDEA生成的鼠标右键

    IDEA去掉右键 在安装IDEA或其它Intellij软件时,因为整个安装流程都是英文的环境,有童鞋稍不注意,就会把Intellij系列软件自动生成鼠标右键给选上 但问题来了,Intellij系列软件 ...