当前位置:网站首页>从底层结构开始学习FPGA----FIFO IP的定制与测试
从底层结构开始学习FPGA----FIFO IP的定制与测试
2022-07-06 17:39:00 【孤独的单刀】
文章目录
系列目录与传送门
在定制一个FIFO IP核之前,强烈建议您先阅读:从底层结构开始学习FPGA----FIFO IP核及其关键参数介绍
在这篇文章中,已经对FIFO IP核的各个关键因素做了详细的讲解。
1、FIFO IP的定制
- 在新建一个工程后, 点击IP Catalog
- 点击后会出现 IP Catalog 页面,在 IP 核的搜索框中搜索 fifo
- 根据筛选,双击选择fifo核“FIFO Generator”
①、第一页
②、第二页
③、第三页
④、第四页
⑤、第五页
2、FIFO IP的例化与测试
2.1、例化一个FIFO IP核
按上述步骤生成IP后,复制 IP核自带的例化模板。
2.2、RTL
我们编写一个RTL代码来验证一下这个FIFO IP,并学习一下它的时序逻辑。
由于是异步FIFO,所以还例化了一个PLL来生成写时钟50M,读时钟75M。RTL代码使用了一个简单的状态机,以实现如下逻辑:
- 等待PLL稳定
- PLL稳定后对FIFO进行复位,时长10个周期以上
- FIFO复位完成后,写入数据直到写满,写入数据分别为0,1,2···14,共15个数据
- 写完数据后,从FIFO中读取数据,观察读取数据是否与写入数据一致
module fifot_test(
(* MARK_DEBUG="true" *) input sys_clk,
(* MARK_DEBUG="true" *) input sys_rst_n
);
(* MARK_DEBUG="true" *)reg fifo_rst ; //自己生成一个FIFO的复位信号
(* MARK_DEBUG="true" *)reg [3:0] din ;
(* MARK_DEBUG="true" *)reg [3:0] rst_cnt ; //复位计数器
(* MARK_DEBUG="true" *)reg wr_en ;
(* MARK_DEBUG="true" *)reg rd_en ;
(* MARK_DEBUG="true" *)reg [2:0] state ;
reg [2:0] state_rd1 ;
reg [2:0] state_rd2 ;
(* MARK_DEBUG="true" *)wire locked ;
(* MARK_DEBUG="true" *)wire rst_n ;
(* MARK_DEBUG="true" *)wire rd_clk ;
(* MARK_DEBUG="true" *)wire wr_clk ;
(* MARK_DEBUG="true" *)wire [3 : 0] dout ;
(* MARK_DEBUG="true" *)wire full ;
(* MARK_DEBUG="true" *)wire almost_full ;
(* MARK_DEBUG="true" *)wire wr_ack ;
(* MARK_DEBUG="true" *)wire overflow ;
(* MARK_DEBUG="true" *)wire empty ;
(* MARK_DEBUG="true" *)wire almost_empty ;
(* MARK_DEBUG="true" *)wire valid ;
(* MARK_DEBUG="true" *)wire underflow ;
(* MARK_DEBUG="true" *)wire [3 : 0] rd_data_count ;
(* MARK_DEBUG="true" *)wire [3 : 0] wr_data_count ;
(* MARK_DEBUG="true" *)wire prog_full ;
(* MARK_DEBUG="true" *)wire prog_empty ;
(* MARK_DEBUG="true" *)wire wr_rst_busy ;
(* MARK_DEBUG="true" *)wire rd_rst_busy ;
assign rst_n = sys_rst_n && locked; //在locked拉高之前一直复位
//PLL输出波形后,开始计数直到1111
always @(posedge sys_clk or negedge rst_n)begin
if(~rst_n)
rst_cnt <= 1'b0;
else if(&rst_cnt) //rst_cnt == 1111
rst_cnt <= rst_cnt;
else
rst_cnt <= rst_cnt + 1;
end
always @(posedge sys_clk or negedge rst_n)begin
if(~rst_n)
fifo_rst <= 1'b1;
else if(&rst_cnt)
fifo_rst <= 1'b0;
else
fifo_rst <= 1'b1;
end
always @(posedge sys_clk or negedge rst_n)begin
if(~rst_n)
state <= 3'd0;
else begin
case(state)
3'd0:begin
if(~fifo_rst)
state <= 3'd1;
else
state <= state;
end
3'd1:begin
if(~wr_rst_busy && ~full)
state <= 3'd2;
else
state <= state;
end
3'd2:begin
if(almost_full)
state <= 3'd3;
else
state <= state;
end
3'd3:begin
if(~rd_rst_busy && ~empty)
state <= 3'd4;
else
state <= state;
end
3'd4:begin
if(almost_empty)
state <= 3'd5;
else
state <= state;
end
3'd5:begin
state <= state;
end
default:state <= 3'd0;
endcase
end
end
//写使能
always @(posedge wr_clk or negedge rst_n)begin
if(~rst_n)
wr_en <= 1'b0;
else if(state == 3'd2)
wr_en <= 1'b1;
else
wr_en <= 1'b0;
end
//写数据
always @(posedge wr_clk or negedge rst_n)begin
if(~rst_n)
din <= 4'd0;
else if(wr_en)
din <= din + 1;
end
//把状态state同步到读时钟域
always @(posedge rd_clk or negedge rst_n)begin
if(~rst_n)begin
state_rd1 <= 3'd0;
state_rd2 <= 3'd0;
end
else begin
state_rd1 <= state;
state_rd2 <= state_rd1;
end
end
//读使能
always @(posedge rd_clk or negedge rst_n)begin
if(~rst_n)
rd_en <= 1'b0;
else if(state_rd2 == 3'd4)
rd_en <= 1'b1;
else
rd_en <= 1'b0;
end
clk_wiz_0 clk_wiz_0_inst
(
.clk_in1 (sys_clk ),
.clk_out1 (wr_clk ), //50M
.clk_out2 (rd_clk ), //75M
.resetn (sys_rst_n ),
.locked (locked )
);
//例化FIFO
fifo_w4_d16 fifo_w4_d16_inst(
.rst (fifo_rst),
.wr_clk (wr_clk),
.din (din),
.wr_en (wr_en),
.wr_rst_busy (wr_rst_busy),
.wr_data_count (wr_data_count),
.prog_full (prog_full),
.full (full),
.almost_full (almost_full),
.wr_ack (wr_ack),
.overflow (overflow),
.rd_clk (rd_clk),
.rd_en (rd_en),
.empty (empty),
.almost_empty (almost_empty),
.valid (valid),
.rd_data_count (rd_data_count),
.dout (dout),
.underflow (underflow),
.prog_empty (prog_empty),
.rd_rst_busy (rd_rst_busy)
);
endmodule
2.3、仿真测试与测试结果
由于测试逻辑都在RTL中实现了,所以testbench就比较简单了,只需要例化被测模块和实现时钟和复位即可。
`timescale 1 ns / 1 ns
module tb_fifo_test();
reg sys_clk;
reg sys_rst_n;
initial begin
sys_clk = 0;
sys_rst_n = 0;
#60
sys_rst_n = 1;
#6000
$finish; //停止仿真
end
always #10 sys_clk = ~ sys_clk;
fifot_test fifot_test_inst(
.sys_clk (sys_clk ),
.sys_rst_n (sys_rst_n )
);
endmodule
使用vivado自带的仿真工具simulator运行仿真,仿真结果如下:
(1)整体
(2)PLL从不稳定到稳定
(3)FIFO复位完成后需要一定的时间才可以操作
(4)写FIFO操作
(5)读FIFO操作
写入数据0-14共15个数据,读出数据也是0-14共15个数据。写、读一致,功能验证无误。
2.4、下板实测
把代码下载到开发板,用ILA观察一下,观察结果和仿真结果是一致的,不赘述,只放几张图:
(1)PLL稳定及FIFO复位
(2)写FIFO操作,写入数据0-14
(3)读FIFO操作,读取数据0-14
3、总结与参考
- FIFO的使用要注意实际深度
- FIFO使用需要先复位,复位时间要足够长,且复位后需要一定的时间才能使用FIFO
- 同步FIFO的使用会比较简单,因为其没有异步FIFO所需要的同步时钟域导致的延迟问题
- 不同资源实现的FIFO在各个功能特性上会有细微的区别,使用之前一定要认真测试,总结时序
- 异步FIFO的计数器不是精确的,只能作为大致的参考,以实现例如半空半满、1/4空满等判断
- 可编程空满的实现是依赖计数器的,其值同样不够精确
参考资料1:pg057-fifo-generator
- 博客主页:wuzhikai.blog.csdn.net
- 本文由 孤独的单刀 原创,首发于CSDN平台
- 文章还在持续更新,您有任何问题,都可以在评论区和我交流!
- 创作不易,您的支持是我持续更新的最大动力!如果本文对您有帮助,还请多多点赞、评论和收藏!
边栏推荐
- Gnet: notes on the use of a lightweight and high-performance go network framework
- Send template message via wechat official account
- Installation of gazebo & connection with ROS
- Part VI, STM32 pulse width modulation (PWM) programming
- UI control telerik UI for WinForms new theme - vs2022 heuristic theme
- 黑马笔记---异常处理
- go-zero微服务实战系列(九、极致优化秒杀性能)
- 1123. 最深叶节点的最近公共祖先
- golang中的atomic,以及CAS操作
- 接收用户输入,身高BMI体重指数检测小业务入门案例
猜你喜欢
ClickHouse字段分组聚合、按照任意时间段粒度查询SQL
Can the system hibernation file be deleted? How to delete the system hibernation file
Byte P7 professional level explanation: common tools and test methods for interface testing, Freeman
Niuke cold training camp 6B (Freund has no green name level)
【JVM调优实战100例】04——方法区调优实战(上)
移植DAC芯片MCP4725驱动到NUC980
How to manage distributed teams?
2022 Google CTF segfault Labyrinth WP
c语言—数组
身体质量指数程序,入门写死的小程序项目
随机推荐
[batch dos-cmd command - summary and summary] - string search, search, and filter commands (find, findstr), and the difference and discrimination between find and findstr
云呐|工单管理软件,工单管理软件APP
Rainstorm effect in levels - ue5
HMM notes
Docker method to install MySQL
Make a simple graphical interface with Tkinter
Byte P7 professional level explanation: common tools and test methods for interface testing, Freeman
Metauniverse urban legend 02: metaphor of the number one player
UI控件Telerik UI for WinForms新主题——VS2022启发式主题
Force buckle 1037 Effective boomerang
[batch dos-cmd command - summary and summary] - view or modify file attributes (attrib), view and modify file association types (Assoc, ftype)
Installation of torch and torch vision in pytorch
免费白嫖的图床对比
table表格设置圆角
Neon Optimization: summary of performance optimization experience
[case sharing] basic function configuration of network loop detection
Can the system hibernation file be deleted? How to delete the system hibernation file
boot - prometheus-push gateway 使用
Gazebo的安装&与ROS的连接
黑马笔记---创建不可变集合与Stream流