Quartus Ⅱ调用FIFO IP核方法实现求和(Mega Wizard)

news/2024/11/16 23:58:10/文章来源:https://www.cnblogs.com/handat/p/18295269

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

芯片型号:cyclone Ⅳ EP4CE10F17C8

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

最终框图:

image


【FIFO IP核概述及调用】

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

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

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

image

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

image

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

image

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

image

【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数据后,满信号拉低,持续读取完毕。

image

构建一个异步混合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。这里由于写位宽和读位宽的不同,要区别写计数和读计数的计数方式。

image

【调用FIFO实现求和运算】

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

image

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

image

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

always@(posedge sys_clk or negedge sys_rst)begin	//dispose cnt_row counterif(!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;
endalways@(posedge sys_clk or negedge sys_rst)begin	//dispose cnt_col counterif(!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;
endalways@(posedge sys_clk or negedge sys_rst)begin	//dispose wr_en1 driveif(!sys_rst)	wr_en1  <=  1'b0;else    if((cnt_col == 8'd0) && (pi_flag))	wr_en1  <=  1'b1;else	wr_en1  <=  dout_flag;
endalways@(posedge sys_clk or negedge sys_rst)begin	//dispose data_in1 sequenceif(!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;
endalways@(posedge sys_clk or negedge sys_rst)begin	//dispose wr_en2 driveif(!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;
endalways@(posedge sys_clk or negedge sys_rst)begin	//dispose data_in2 sequenceif(!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;
endalways@(posedge sys_clk or negedge sys_rst)begin	//dispose rd_en driveif(!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;
endalways@(posedge sys_clk or negedge sys_rst)begin	//dispose dout_flag sequenceif(!sys_rst)	dout_flag <=  0;else    if((wr_en2)&&(rd_en))	dout_flag <=  1'b1;else	dout_flag <=  1'b0;
endalways@(posedge sys_clk or negedge sys_rst)begin	//dispose sum_flag sequenceif(!sys_rst)	sum_flag <=  1'b0;else    if(rd_en)	sum_flag <=  1'b1;else    sum_flag <=  1'b0;
endalways@(posedge sys_clk or negedge sys_rst)begin	//dispose po_data resultif(!sys_rst)	po_data  <=  8'b0;else    if(sum_flag)	po_data  <=  data_out1 + data_out2 + pi_data;else	po_data  <=  po_data;
endalways@(posedge sys_clk or negedge sys_rst)begin	//dispose po_flag sequenceif(!sys_rst)	po_flag <=  1'b0;else 	po_flag <=  sum_flag;
end

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

image

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

image

文献参考:

[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/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/742045.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

INFINI Easysearch 尝鲜 Hands on

INFINI Easysearch 是一个分布式的近实时搜索与分析引擎,核心引擎基于开源的 Apache Lucene。Easysearch 的目标是提供一个自主可控的轻量级的 Elasticsearch 可替代版本,并继续完善和支持更多的企业级功能。与 Elasticsearch 相比,Easysearch 更关注在搜索业务场景的优化和…

全网最适合入门的面向对象编程教程:13 类和对象的Python实现-可视化阅读代码神器Sourcetrail的安装使用

本文主要介绍了可视化阅读代码神器Sourcetrail的安装与使用,包括软件简介和特性、下载地址、安装方式、新建工程和如何查看分析源码,同时简单介绍了PyCharm中Sourcetrail插件的使用。全网最适合入门的面向对象编程教程:13 类和对象的 Python 实现-可视化阅读代码神器 Source…

2024年7.4-7.8学习总结/暑假day7-11

2024年7.4-7.8学习总结/暑假day7-11 日记 上班有点小累,每天早上六点二十就得起床,每天偷摸着学java,回家了也学点,打算这段时间快速看完javaweb就开始做项目。 java day02-10~04-08 JS对象 Array,String,JSON,BOM,DOM等 Bom 概念:Browser Object Model 浏览器对象模型,允…

基于极大似然估计方法的diffusion

1、极大似然估计就是求概率的最大值2、VAE (1)q(x|z)是编码器的隐向量,可以是任意分布,通过化简,得到了最低下界,最大化这个最低下界就行:(2)类比出DDPm的目标(3)DDPM的最终下界:(4)红色部分化简一波(5)红色部分化简一波(6)红色部分也是高斯分布,让两个高斯分布均值相近…

六大主流商业模式的对比一览图

六大主流商业模式的对比一览图

算法金 | DL 骚操作扫盲,神经网络设计与选择、参数初始化与优化、学习率调整与正则化、Loss Function、Bad Gradient

大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」今日 216/10000 抱个拳,送个礼神经网络设计与选择 参数初始化与优化 学习率调整与正则化 数据预处理与标准化 训练过程与监控 特定模型技巧 其他训练技巧1. 神经网络设…

k8s安装v1.30.2(contanerd容器运行时)实录

一、主机准备主机名 NAT IP 系统 配置k8s-master 192.168.1.201 ubuntu 18.04.6 2C2Gk8s-node01 192.168.1.202 ubuntu 18.04.6 2C2Gk8s-node02 192.168.1.203 ubuntu 18.04.6 2C2G 二、前提 主机配置好网络、ntp,关闭ufw,swap,安装好containerd,runc服务 三、安装步骤 mas…

Docker入门(三):nodejs后端服务部署

本文主要内容是通过dockerfile创建镜像,并通过kubernets(简称k8s)来启动集群服务。最后你会得到一个简单的nodejs提供的api服务。写在前面 需要安装的有node(如何安装?),kubectl(如何安装?) 一,创建nodejs应用 本文主要是用于实践k8s,所以nodejs项目写的非常简单,除了…

如何不错过手机的重要消息-草稿

你是不是手机里有许多未读消息,许多“小红点”,系统通知里有很多通知,久而久之你已习惯并麻木了?你只在自己需要的时候主动去找,而对于推送的信息一概不理。有时也有朋友向你抱怨发给你的信息你久久不回。或者反过来,你经常去看推送的消息,但大多是不太重要的,是广告,…

pandas agg函数的详细介绍与应用

pandas agg函数的详细介绍与应用 参考:pandas agg Pandas 是一个强大的 Python 数据处理库,提供了广泛的方法来进行数据分析。其中,agg 函数是一个非常有用的工具,它允许用户对数据进行多种聚合操作,可以极大地简化数据处理过程。本文将详细介绍 agg 函数的使用方法,并通…

Ollama完整教程:本地LLM管理、WebUI对话、Python/Java客户端API应用

Ollama可以非常方便的管理和部署我们本地大语言模型,老牛同学希望通过本文对Ollama进行一次详细介绍,包括本地大模型管理和使用、WebUI对话界面部署、通过Python和Java使用Ollama的API接口等……老牛同学在前面有关大模型应用的文章中,多次使用了Ollama来管理和部署本地大模…

Python爬虫(1-4)-基本概念、六个读取方法、下载(源代码、图片、视频 )、user-agent反爬

Python爬虫 一、爬虫相关概念介绍 1.什么是互联网爬虫 如果我们把互联网比作一张大的蜘蛛网,那一台计算机上的数据便是蜘蛛网上的一个猎物,而爬虫程序就是一只小蜘蛛,沿着蜘蛛网抓取自己想要的数据解释1:通过一个程序,根据URL进行爬取网页,获取有用信息 解释2:使用程序模…