当前位置:网站首页>Start from the bottom structure to learn the customization and testing of fpga---- FIFO IP
Start from the bottom structure to learn the customization and testing of fpga---- FIFO IP
2022-07-07 01:25:00 【Lonely single knife】
List of articles
2、FIFO IP Instantiation and testing of
2.1、 Exemplify a FIFO IP nucleus
2.3、 Simulation test and test results
Series catalog and portal
《 Start with the underlying structure FPGA》 Directory and portal
Customizing one FIFO IP Before nuclear , It is strongly recommended that you read : Start with the underlying structure FPGA----FIFO IP Introduction to nuclear and its key parameters
In this article , Have been to FIFO IP The key factors of nuclear are explained in detail .
1、FIFO IP The custom of
- After creating a new project , Click on IP Catalog
- It will appear after clicking IP Catalog page , stay IP Search in the search box of the kernel fifo
- According to the screening , Double click to select fifo nucleus “FIFO Generator”
①、 first page
②、 The second page
③、 The third page
④、 Page four
⑤、 Page 5
2、FIFO IP Instantiation and testing of
2.1、 Exemplify a FIFO IP nucleus
Follow the above steps to generate IP after , Copy IP The instantiation template provided by the core .
2.2、RTL
Let's write a RTL Code to verify this FIFO IP, And learn its temporal logic .
Because it's asynchronous FIFO, So there is also an example PLL The afterlife becomes a writing clock 50M, Read the clock 75M.RTL The code uses a simple state machine , To realize the following logic :
- wait for PLL Stable
- PLL After stabilization, right FIFO Reset , Duration 10 More than one cycle
- FIFO After reset , Write data until it is full , The written data are 0,1,2···14, common 15 Data
- After writing the data , from FIFO Read data from , Observe whether the read data is consistent with the written data
module fifot_test(
(* MARK_DEBUG="true" *) input sys_clk,
(* MARK_DEBUG="true" *) input sys_rst_n
);
(* MARK_DEBUG="true" *)reg fifo_rst ; // Make yourself a FIFO Reset signal of
(* MARK_DEBUG="true" *)reg [3:0] din ;
(* MARK_DEBUG="true" *)reg [3:0] rst_cnt ; // Reset counter
(* 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; // stay locked Reset until pulled high
//PLL After outputting the waveform , Start counting until 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
// Write enable
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
// Writing data
always @(posedge wr_clk or negedge rst_n)begin
if(~rst_n)
din <= 4'd0;
else if(wr_en)
din <= din + 1;
end
// Put state state Sync to read clock field
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
// Reading enable
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 )
);
// Exemplification 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、 Simulation test and test results
Because the test logic is RTL Implemented in the , therefore testbench It's simpler , Just instantiate the tested module and realize clock and reset .
`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; // Stop simulation
end
always #10 sys_clk = ~ sys_clk;
fifot_test fifot_test_inst(
.sys_clk (sys_clk ),
.sys_rst_n (sys_rst_n )
);
endmodule
Use vivado Built in simulation tools simulator Run the simulation , The simulation results are as follows :
(1) whole
(2)PLL From unstable to stable
(3)FIFO It takes some time to operate after reset
(4) Write FIFO operation
(5) read FIFO operation
Write data 0-14 common 15 Data , Reading data is also 0-14 common 15 Data . Write 、 Read consistent , Function verification is correct .
2.4、 Lower plate measurement
Download the code to the development board , use ILA Observe , The observation results are consistent with the simulation results , Don't go into , Just put a few pictures :
(1)PLL Stable and FIFO Reset
(2) Write FIFO operation , Write data 0-14
(3) read FIFO operation , Reading data 0-14
3、 Summary and reference
- FIFO Pay attention to the actual depth when using
- FIFO Reset before use , The reset time should be long enough , And it takes some time to use after reset FIFO
- Sync FIFO It will be simpler to use , Because it is not asynchronous FIFO The delay caused by the required synchronization clock domain
- Implemented by different resources FIFO There will be subtle differences in various functional features , Be sure to test carefully before using , Summarize the sequence
- asynchronous FIFO The counter of is not accurate , It can only be used as a general reference , To achieve, for example, half empty and half full 、1/4 Empty and full wait for judgment
- The implementation of programmable empty full is counter dependent , Its value is also not accurate
Reference material 1:pg057-fifo-generator
- Blog home page :wuzhikai.blog.csdn.net
- This paper is written by Lonely single blade original , First appeared in CSDN platform
- The article is still being updated , Do you have any questions , You can communicate with me in the comment area !
- It's not easy to create , Your support is the biggest driving force for me to continuously update ! If this article helps you , Please give me more praise 、 Reviews and collections !
边栏推荐
- Metauniverse urban legend 02: metaphor of the number one player
- C# 计算农历日期方法 2022
- Taro中添加小程序 “lazyCodeLoading“: “requiredComponents“,
- 黑马笔记---异常处理
- Your cache folder contains root-owned files, due to a bug in npm ERR! previous versions of npm which
- Meet in the middle
- Analysis of mutex principle in golang
- Force buckle 1037 Effective boomerang
- MySQL script batch queries all tables containing specified field types in the database
- JTAG debugging experience of arm bare board debugging
猜你喜欢
移植DAC芯片MCP4725驱动到NUC980
Can the system hibernation file be deleted? How to delete the system hibernation file
第三方跳转网站 出现 405 Method Not Allowed
Installation of gazebo & connection with ROS
Segmenttree
c语言—数组
LeetCode:1175. 质数排列
Body mass index program, entry to write dead applet project
Dynamic planning idea "from getting started to giving up"
Dark horse notes - exception handling
随机推荐
7.6模拟赛总结
Atomic in golang, and cas Operations
2022 Google CTF SEGFAULT LABYRINTH wp
405 method not allowed appears when the third party jumps to the website
力扣1037. 有效的回旋镖
如何管理分布式团队?
Gazebo的安装&与ROS的连接
Typical problems of subnet division and super network construction
Body mass index program, entry to write dead applet project
Do you understand this patch of the interface control devaxpress WinForms skin editor?
云呐-工单管理制度及流程,工单管理规范
AI automatically generates annotation documents from code
C# 计算农历日期方法 2022
【案例分享】网络环路检测基本功能配置
736. Lisp 语法解析 : DFS 模拟题
Go zero micro service practical series (IX. ultimate optimization of seckill performance)
golang中的atomic,以及CAS操作
2022 Google CTF segfault Labyrinth WP
Taro中添加小程序 “lazyCodeLoading“: “requiredComponents“,
[Niuke] [noip2015] jumping stone