如何在Vivado创建一个FIFO的IP核并使用ILA工具验证
文章目录
- 一、FIFO实验背景知识
- FIFO的定义
- FIFO的分类
- 一般FIFO的结构(在这里对引脚进行说明,下面实验过程中直接引用这里的说明)
- FIFO的使用框图
- 实验目的
- 二、创建一个新的工程
- 三、创建FIFO IP核
- 四、编写程序
- fifo_rd.v
- fifo_wr.v
- ip_fifo.v
- xdc文件
- 五、创建ILA IP核
- 六、生成比特流文件
- 七、将文件下载到芯片并用ILA观察波形
一、FIFO实验背景知识
FIFO的定义
FIFO的英文全称是First In First Out,即先进先出。FPGA使用的FIFO一般指的是对数据的存储具有先进先出特性的一个缓存器,常被用于数据的缓存,或者高速异步数据的交互也即所谓的跨时钟域信号传递。它与FPGA内部的RAM和ROM的区别是没有外部读写地址线,采取顺序写入数据,顺序读出数据的方式,使用起来简单方便,由此带来的缺点就是不能像RAM和ROM那样可以由地址线决定读取或写入某个指定的地址。(先进先出,不能像RAM一样对选定的地址进行存取)
FIFO的分类
- 同步FIFO:指读时钟和写时钟为同一个时钟,在时钟沿来临时同时发生读写操作。
- 异步FIFO:指读写时钟不一致,读写时钟是互相独立的。
- (说明:FIFO可用两种RAM资源实现,一种是BRAM,一种是DRAM,BRAM支持读写位宽不相同,DRAM不支持)
一般FIFO的结构(在这里对引脚进行说明,下面实验过程中直接引用这里的说明)
对图上引脚进行说明
- wr_clk:写时钟
- rd_clk:读时钟,1和2可以相同也可以不同
- wr_rst:写复位
- rd_rst:读复位
- rst:整体复位
- wr_en:写使能
- rd_en:读使能。使能打开就是对应开启读和写
- full:写满标志,full拉高代表FIFO已经写到最大容量,不能再写数据了
- empty:读空标志,empty拉高代表FIFO里面所有可读数据都被读完了,不能继续读数据了
- almost_full: 比full提前一个时钟拉高,防止检测到满了的时候已经 把下一个数据发出去了
- almost_empty:比empty提前一个时钟拉高,功能类比10
- prog_full:可编程的写满,就是自己设定一个值,写到这个容量就拉高
- prog_empty:写编程的读空,功能类比12
- din:数据输入,自己设计的位宽
- dout:数据输出,自己设定的位宽
- wr_ack:写反馈,给写使能的时候,FIFO成功处理了,会给一个写反馈
- overflow:满溢出,写满之后会给一个标志(上溢出)
- valid:当FIFO出来的数据有效,给一个标志
- underflow:读空,下溢出
- wr_data_cout:指示FIFO里面写了多少个数据
- rd_data_cout:指示FIFO里面还有多少个可以读的数据(如果异步时钟,异步位宽,20和21不相等)
- prog_full_thresh_assert:动态修改可编程满(确认信号,配合26)
- prog_empty_thresh_assert:动态修改可编程空(确认信号,配合27)
- prog_full_thresh_negate:可编程满失效
- prog_empty_thresh_negate:可编程空失效
- prog_full_thresh:动态修改可编程满(输入值)
- prog_empty_thresh:动态修改可编程空(输入值)
- 最下面两行是注入一个单比特或双比特的错误,FIFO的译码器可以自动检测修正,但是不是所有都支持(不用太多关注)
FIFO的使用框图
实验目的
本次实验实现快满了之后延迟一小会开始读,快空了延迟一小会开始写
二、创建一个新的工程
新建工程不熟悉的可以看我之前的文章
工程创建完成
三、创建FIFO IP核
看到IP Source里面刷新好了,证明IP核创建成功了
四、编写程序
创建fifo_rd.v(读模块),fifo_wr.v(写模块),ip_fifo.v(上层)(FIFO IP核的例化可以复制.veo然后粘到ip_fifo.v),ip_fifo_xdc.xdc(时序约束文件),代码如下(下面粘的都是加完ila之后的完整代码!!!!):
fifo_rd.v
`timescale 1ns / 1psmodule fifo_rd(input clk,input rst_n,input almost_full,input almost_empty,output reg fifo_rd_en);reg almost_full_d0;reg almost_full_d1;wire almost_full_syn;reg [1 : 0] state;reg [3 : 0] dly_cnt;assign almost_full_syn = (~almost_full_d1)&almost_full_d0;//检测上升沿always@(posedge clk or negedge rst_n) beginif(!rst_n) beginalmost_full_d0 <= 1'b0;almost_full_d1 <= 1'b0;endelse beginalmost_full_d0 <= almost_full;almost_full_d1 <= almost_full_d0;endendalways@(posedge clk or negedge rst_n) beginif(!rst_n) beginfifo_rd_en <= 1'b0;state <= 2'b0;dly_cnt <= 4'b0;endelse begincase(state)//状态机2'd0 : beginif(almost_full_syn) state <= 2'd1;else state <= state;end2'd1 :beginif(dly_cnt == 4'd10) begindly_cnt <= 4'd0;state <= 2'd2;fifo_rd_en <= 1'b1;endelse dly_cnt <= dly_cnt + 1'b1;end2'd2 :beginif(almost_empty) beginfifo_rd_en <= 1'b0;state <= 2'd0;endelse fifo_rd_en <= 1'b1;enddefault : state <= 2'd0;endcaseendend endmodule
fifo_wr.v
`timescale 1ns / 1psmodule fifo_wr(input clk,input rst_n,input almost_full,input almost_empty,output reg fifo_wr_en,output reg [7 : 0] fifo_wr_data);reg almost_empty_d0;reg almost_empty_d1;wire almost_empty_syn;reg [1 : 0] state;reg [3 : 0] dly_cnt;assign almost_empty_syn = (~almost_empty_d1)&almost_empty_d0;always@(posedge clk or negedge rst_n) beginif(!rst_n) beginalmost_empty_d0 <= 1'b0;almost_empty_d1 <= 1'b0;endelse beginalmost_empty_d0 <= almost_empty;almost_empty_d1 <= almost_empty_d0;endendalways@(posedge clk or negedge rst_n) beginif(!rst_n) beginfifo_wr_en <= 1'b0;fifo_wr_data <= 8'd0;state <= 2'b0;dly_cnt <= 4'b0;endelse begincase(state)2'd0 : beginif(almost_empty_syn) state <= 2'd1;else state <= state;end2'd1 :beginif(dly_cnt == 4'd10) begindly_cnt <= 4'd0;state <= 2'd2;fifo_wr_en <= 1'b1;endelse dly_cnt <= dly_cnt + 1'b1;end2'd2 :beginif(almost_full) beginfifo_wr_en <= 1'b0;fifo_wr_data <= 8'd0;state <= 2'd0;endelse beginfifo_wr_en <= 1'b1;fifo_wr_data <= fifo_wr_data + 1'b1;endenddefault : state <= 2'd0;endcaseendend endmodule
ip_fifo.v
`timescale 1ns / 1psmodule ip_fifo(input sys_clk,input sys_rst_n);wire almost_full;
wire almost_empty;
wire fifo_wr_en;
wire [7 : 0] fifo_wr_data;
wire fifo_rd_en;
wire [7 : 0] dout;
wire full;
wire empty;
wire [7 : 0] rd_data_count;
wire [7 : 0] wr_data_count;fifo_generator_0 fifo_generator_0_u (.wr_clk(sys_clk), // input wire wr_clk.rd_clk(sys_clk), // input wire rd_clk.din(fifo_wr_data), // input wire [7 : 0] din.wr_en(fifo_wr_en), // input wire wr_en.rd_en(fifo_rd_en), // input wire rd_en.dout(dout), // output wire [7 : 0] dout.full(full), // output wire full.almost_full(almost_full), // output wire almost_full.empty(empty), // output wire empty.almost_empty(almost_empty), // output wire almost_empty.rd_data_count(rd_data_count), // output wire [7 : 0] rd_data_count.wr_data_count(wr_data_count) // output wire [7 : 0] wr_data_count
);fifo_wr fifo_wr_u(.clk (sys_clk) , .rst_n (sys_rst_n) , .almost_full (almost_full) ,.almost_empty (almost_empty) , .fifo_wr_en (wr_en) , .fifo_wr_data (rd_en)
);fifo_rd fifo_rd_u(.clk (sys_clk) , .rst_n (sys_rst_n) , .almost_full (almost_full) , .almost_empty (almost_empty) , .fifo_rd_en (wr_en)
);ila_0 your_instance_name (.clk(sys_clk), // input wire clk.probe0(fifo_wr_en), // input wire [0:0] probe0 .probe1(fifo_rd_en), // input wire [0:0] probe1 .probe2(full), // input wire [0:0] probe2 .probe3(almost_full), // input wire [0:0] probe3 .probe4(fifo_wr_data), // input wire [7:0] probe4 .probe5(dout), // input wire [7:0] probe5 .probe6(rd_data_count), // input wire [7:0] probe6 .probe7(wr_data_count), // input wire [7:0] probe7 .probe8(empty), // input wire [0:0] probe8 .probe9(almost_empty) // input wire [0:0] probe9
); endmodule
xdc文件
create_clock -period 20.000 -name sys_clk [get_ports sys_clk]
set_property -dict {PACKAGE_PIN R4 IOSTANDARD LVCMOS15} [get_ports sys_clk]
set_property -dict {PACKAGE_PIN U7 IOSTANDARD LVCMOS15} [get_ports sys_rst_n]
五、创建ILA IP核
采集的有四个是八位的位宽,修改一下
ILA创建完成
这里需要修改代码,把ILA添加到代码里,完整代码已经放在前面了
六、生成比特流文件
点击生成bit流文件
出现下面这个界面代表bit流生成成功,点击取消就可以
七、将文件下载到芯片并用ILA观察波形
下载到芯片
观察ILA,波形正确,实验成功
如何在Vivado创建一个FIFO的IP核并使用ILA工具验证相关推荐
- 手把手教你在Vivado创建一个RAM的IP核并使用ILA工具验证
文章目录 一.RAM实验背景知识 RAM的定义 RAM的分类 实验设计 二.创建一个新的工程 三.创建RAM IP核 四.编写代码 五.创建ILA IP核并生成比特流文件 六.将程序下入芯片,并通过I ...
- [react] 举例说明如何在React创建一个事件
[react] 举例说明如何在React创建一个事件 import React, { Component } from 'react'; import ReactDOM from 'react-dom ...
- vivado使用自带IP核和创建自己定义的IP核
任务:使用vivado自带IP和创建IP 目的:学会使用Vivadao相关的IP组件 步骤: 1.使用自带IP 工程创建好之后,选择IP Catalog.软件就会列出自带的,自带的IP核有很多种,选择 ...
- 如何在 GitHub 创建一个“有人用”的项目
2019独角兽企业重金招聘Python工程师标准>>> 转载自:http://www.infoq.com/cn/news/2014/10/github-bulid-project 近 ...
- vivado中复数乘法器的ip核调用及其仿真的详细介绍
复数乘法器的ip核可在下图的中找到 ip核的输入配置和输出配置如下图所示 当我们在选择multplier construction的Use LUTs选项时,选择的是三次乘法的算法,相比于四次 ...
- Xilinx Vivado复数乘法器Complex Multiplier IP核调用及其仿真
Complex Multiplier IP核的使用,尤其是输出数据的截位到底怎么弄,我感觉官方文档PG104写的不清楚.我个人在网上也没找到好的讲解文章,就自己琢磨了下,然后写成文档记录在此,方便将来 ...
- 如何在windows创建一个ftp站点
在虚拟机中点击win+r输入control打开控制面板 点击程序,点击用或关闭windows功能 找到Internet Information Service选项,勾选FTP服务器以及web管理工具, ...
- 如何在OpenAI创建一个api key(chatgpt)?
要创建OpenAI API Key,请按照以下步骤进行: 访问OpenAI的官方网站(https://openai.com/)并注册一个账户.如果你已经有了账户,请直接登录. 登录后,转到OpenAI ...
- 异步fifo_正点原子开拓者FPGA开发板资料连载第十五章 IP核之FIFO实验
1)实验平台:正点原子开拓者FPGA 开发板 2)摘自<开拓者FPGA开发指南>关注官方微信号公众号,获取更多资料:正点原子 3)全套实验源码+手册+视频下载地址:http://www.o ...
最新文章
- linux命令注入,Linux kernel本地命令注入漏洞
- alsa声音编程介绍
- mysql初体验学习笔记_【MySQL】mycli初体验
- [转载] python打包程序在win10不能运行、点击无反应_Windows10平台用PyInstaller打成exe程序后不能运行请高手指点...
- 每日打卡 22 11 16 CF 1694B Paranoid String
- u盘数据恢复的原理_U盘数据恢复其实很简单
- 经常看到RS485和MODBUS写在一起,它们的区别和联系?
- 一步一步教你网站采集规则
- USB设备无法识别也无法读取怎么办?
- ZZULIoj-1088: 手机短号 (多实例)
- 微信健身房小程序开发源码设计方案
- 扫雷html5简单初级,纯原生JS用面向对象class方法实现简易扫雷小游戏
- PyTorch搭建卷积神经网络(CNN)进行视频行为识别(附源码和数据集)
- 4、Python基本数据类型之字典,集合
- OC中的^怎么理解?
- php微信访问,PHP开发之判断微信浏览器访问
- pic单片机使用printf函数
- 最新百度 阿里 华为 腾讯 谷歌面试笔试题及解析
- 【C语言】用函数实现求两个自然数的最大公约数
- 【720科技SpringMVC】智慧养老商业画布分析-0408-v1.0小白
热门文章
- c#操作word文档之简历导出
- 程序员,你的薪资和劳动价值成正比吗?
- EDA技术 一:EDA技术概况及大规模可编程逻辑器件
- php behaviors,详解在PHP的Yii框架中使用行为Behaviors的方法
- 调度里的猫腻| 那么多AGV为什么不撞在一起?
- MDK-Keil记录
- seurat提取表达矩阵_Hemberg-lab单细胞转录组数据分析
- 永磁同步电机矢量控制中的双闭环是什么意思_伺服系统组成、概述与控制原理(三环控制)...
- 关于 iOS开发者账号提示必须更新绑定手机号的解决方法
- java tm已被阻止_win7系统不能运行java提示“应用程序已被安全设置被阻止”的解决方法...