当前位置:网站首页>Synchronous FIFO
Synchronous FIFO
2022-06-24 08:00:00 【A restless Sir Zhang】
One article understanding synchronization FIFO
List of articles
1、FIFO brief introduction
FIFO namely First In First Out, It is a first in first out data storage 、 Buffer , We know that the general memory uses the external read-write address to read and write , and FIFO This memory structure does not need external read-write address, but controls read-write through automatic plus one operation , It's up to you FIFO You can only read and write data sequentially . Actually FIFO The process is like running circles , When it is full, it means that the write signal covers the read signal , While reading empty , The read signal catches up with the write signal .
FIFO It is a first in first out data buffer , The difference between it and ordinary memory is that there is no external read-write address line , It's very simple to use , The disadvantage is that you can only read and write sequentially , Instead of random reading and writing .
2、 Use scenarios
- Data buffering : That is, the data is written too fast , And the interval is long , That is, burst writing . So by setting a certain depth of FIFO, Can play a data temporary storage function , And make the subsequent processing process smooth .
- Isolation of clock domain : Mainly asynchronous FIFO. For data transmission in different clock domains , Can pass FIFO In isolation , Avoid the complexity of design and constraints caused by cross clock domain data transmission . such as FIFO At one end of the spectrum is AD, The other end is PCI;AD The acquisition rate of is 16 position 100KSPS, The amount of data per second is 1.6Mbps. and PCI The speed of the bus is 33MHz, The bus width is 32 position
- For data interfaces of different widths . For example, a single chip computer is 8 position ,DSP yes 16.
3、FIFO classification
Sync FIFO, Read and write use the same clock . It is generally used as a buffer for interactive data , In other words, its main function is to buffer.
asynchronous FIFO, Different clocks are used for reading and writing , It has two main functions , One is to realize data transmission in different clock domains , Another function is to implement data interfaces with different data widths .


4、 Sync FIFO
Sync fifo It means that the write clock and the read clock are in the same frequency and phase , That is, synchronization fifo Reading and writing work on the same clock .
4.1 Sync fifo The three parts of :
- fifo Write control logic : Generate write address ( Decide where to write , from 0 Start writing )、 Write valid signal 、 Write full ( Decide if you can still write ) Equal signal ;
- fifo Read control logic : Generate read address ( Decide where to read , from 0 Start reading )、 Read valid signal 、 Read full ( Decide if you can still read ) Equal signal ;
- fifo Storage entity (reg、memory)
4.2 Module diagram

Generate respective read / write addresses through read / write pointers , The write pointer points to the next address to be written , The read pointer points to the next address to be read . Effective write enable is to increment the write pointer , A valid read enable is to increment the read pointer .
Dual port memory (DPRAM) Sure Synchronous read or asynchronous read . You can read 、 Write independently . It's fine too Read and write at the same time
For synchronous read operations : It should be in the data FIFO Provide a clear read signal before the output is valid .
4.3 FIFO Working mode
◆ Workflow
After reset , Under the control of write clock and status signal , Data writing FIFO in .RAM Write address from 0 Start , Each time the data is written, the write address pointer is incremented by one , Point to the next storage unit . When FIFO After full , Data will no longer be written to , Otherwise, the data will be lost due to overwriting .
FIFO The data is not empty 、 Or full , Under the control of reading clock and status signal , Data can be transferred from FIFO Middle readout .RAM Read address from 0 Start , Each time the data is read, the read address pointer is incremented by one , Point to the next storage unit . When FIFO After reading empty , You can't read the data anymore , Otherwise, the data read out will be wrong .
FIFO The storage structure is double port RAM, So it is allowed to read and write at the same time . Typical asynchronous FIFO The structure diagram is shown below . The port and internal signal will be explained during code writing .
◆ Reading and writing time
About writing time , as long as FIFO The data in is not full , You can write ; If FIFO Is full , Then it is forbidden to write data again .
About reading time , as long as FIFO The data in is not empty , You can read ; If FIFO Is empty , Then it is forbidden to read the data again .
No matter what , A normal reading and writing FIFO Time period , If reading and writing are done at the same time , It is required to write FIFO The rate cannot be greater than the read rate .
◆ Read empty state
When starting reset ,FIFO No data , The empty status signal is valid . When FIFO After data is written in , The empty status signal is pulled low and invalid . When the read data address catches up with the write address , That is, when the read and write addresses are equal ,FIFO Is empty .
Because it's asynchronous FIFO, So when comparing read and write addresses , Need synchronous shooting logic , It takes some time . Therefore, the indication signal of empty state is not real-time , There will be a certain delay . If new data is written during this delay time FIFO, There will be an empty status indicating that the signal is valid , however FIFO In fact, there is a phenomenon of data in .
Strictly speaking, the empty status indication is wrong . However, the significance of generating empty state is to prevent the read operation from affecting the empty state FIFO Read the data . When an empty status signal is generated , actual FIFO There's data in , It is equivalent to judging the empty state signal in advance , No more reading at this time FIFO Data manipulation is also safe . therefore , The design has no problem in application .
◆ Write full status
When starting reset ,FIFO No data , The full signal is invalid . When FIFO After data is written in , At this time, the read operation does not proceed or the read rate is relatively slow , As long as the write data address exceeds the read data address by one FIFO At depth , A full status signal will be generated . At this time, the write address and read address are also equal , But the meaning is different .

At this time, often use redundant 1bit As the extended bits of the read-write address , To distinguish when the read and write addresses are the same ,FIFO Is the state empty or full . When the read-write address and the extension bit are the same , Indicates that the number of read and write data is consistent , Now FIFO It's empty . If the read and write addresses are the same , The extension bits are the opposite number , Indicates that the number of written data has exceeded one of the number of read data FIFO Depth , here FIFO It's full . Of course , The premise of this condition is that reading operation is prohibited in empty state 、 Write operation is prohibited in full state .
Empathy , Due to the existence of asynchronous delay logic , The full status signal is not real-time . But it is also equivalent to judging the full state signal in advance , No more writing at this time FIFO The operation will not affect the correctness of the application .
5、 Sync FIFO Of Verilog Realization
surface 1-1 Sync FIFO port
| port | attribute |
|---|---|
| clk | The clock |
| rstn | Reset |
| wr_reg | Write requests |
| data_in | Writing data , This time is 8bit |
| rd_reg | Read request |
| data_out | Reading data , Write data together , by 8bit |
| empty | fifo Empty sign |
| full | fifo Full logo |
| wr_usedw | fifo Current data volume , This use 8words , finger FIFO How much data remains unread in |
| almost_empty | Near space ,usedw Greater than or equal to a certain value |
| almost_full | Nearly full ,usedw Less than a certain value |
Of course fifo There is also an address inside , Read the address , Write enable , Reading enable .
Note the relationship between the request signal and the enable signal , To protect fifo The previous data is correct , The request signal came in but was not satisfied fifo Read and write conditions , Such as fifo Empty or fifo full , The former fifo Reading enablers pull down , The latter write enable will pull down .
as for usedw, stay altera Of IP Representing fifo How many more data are there in , If the data input is 8bit, And fifo It's written in 100 individual 8bit data , be usedw Then for 100, It is also a judgment almost_empty and almost_full The logo of .
5.1 Implementation of storage module
The storage module can be implemented with two ports RAM resources , Use directly in simulation reg Just simulate its behavior ; meanwhile , Need to achieve RAM The depth of is configurable , So add a parameter Control depth .
In the process of implementing this module , Consider the relationship between depth and address bit width , Because different depths correspond to different address bit widths .
| depth | Address range | Address bit width |
|---|---|---|
| 64 | 0-63 | 6 |
| 32 | 0-31 | 5 |
| 16 | 0-15 | 4 |
| 8 | 0-7 | 3 |
| 4 | 0-3 | 2 |
| 2 | 0-1 | 1 |
Here is to use RAM To simulate the
reg [DATA_WIDTH-1:0]mem[DATA_WIDTH-1:0];// depth 8 Data bit width 10
5.2 How to judge read blank / Write full
Remember what I just said ? Actually FIFO Your workflow is like running circles , When it is full, it means that the write signal covers the read signal , While reading empty , The read signal catches up with the write signal .
How to judge read blank : according to FIFO How it works , Obvious , When reading empty , There is no data to read , therefore wr_addr Address and rd_addr Your address should be the same .
How to judge whether it is full : according to FIFO How it works , Because the write signal covers the read signal one circle , Then we can set up Parity bit ( It can also be understood as carry ), The parity check is used to determine whether the “ Ferrule ”, Every jump of parity bit 1 Time , It means that the signal is written or read . Watch out! , Writing a signal is always ahead , It is impossible to lag behind the reading signal . So when it's full at the same time wr_addr Address and rd_addr Your address should be the same .
assign empty = ({wr_flag,wr_addr} == {rd_flag,rd_addr}) ? 1'b1:1'b0;
assign full = ((wr_addr == rd_addr) && (wr_flag != rd_flag)) ? 1'b1:1'b0;
5.3 How to calculate FIFO Current data volume ( How much data is left unread )
Or the ferrule idea , Because whenever . The write signal is ahead of the read signal , therefore FIFO The current amount of data in must be **( Write the address — Read the address )** To get . Then you may ask when the write address is greater than the read address , without doubt , This must be true , But is it still true that the write address is less than the read address ?
without doubt , Of course , Remember the parity bit defined ? By parity bit , You won't have the above problems . The following code is for details .
assign wr_usedw = {wr_flag,wr_addr} - {rd_flag,rd_addr};
5.4 Source code
module synchronize_fifo #(
parameter [3:0] DATA_DEPTH = 4'd8, // depth finger FIFO How many numbers are saved in
parameter [3:0] DATA_WIDTH = 4'd8, // Width The bit width of each number
parameter [1:0] ADDR_WIDTH = 2'd3, //FIFO Address (000——111) 2^ADDR_WIDTH = DATA_DEPTH
parameter [1:0] almost_empty_ref = 2'd2,
parameter [2:0] almost_full_ref = 3'd6
)(
input wire clk,
input wire rstn,
input wire wr_reg, // Write requests
input wire rd_reg, // Read request
input wire [DATA_WIDTH-1:0] data_in,// Data writing
output reg [DATA_WIDTH-1:0] data_out,// data fetch
output wire empty,full,
output wire almost_empty,almost_full, // Nearly full or Reading empty
output wire [ADDR_WIDTH :0] wr_usedw // FIFO How much data remains unread in
);
wire wr_en,rd_en; // Reading enable , Write enable
reg [{ADDR_WIDTH-1}:0] wr_addr,rd_addr; // Read the address , Write the address
reg [DATA_WIDTH-1:0]mem[DATA_WIDTH-1:0];// depth 8 Data bit width 10
reg wr_flag,rd_flag; // Parity bit Judge whether it is full according to the highest address or Write empty
// Write the address
integer i;
assign wr_en = (!full) & wr_reg; // If it's full Then stop writing
assign rd_en = (!empty) & rd_reg; // If read empty Stop the read operation
always @(posedge clk or negedge rstn)
if(!rstn)begin
wr_addr <= 3'd0;
wr_flag <= 1'd0;
end else if(wr_en)
{wr_flag,wr_addr} <= {wr_flag,wr_addr} +1'b1;
else
{wr_flag,wr_addr} <= {wr_flag,wr_addr};
// Writing data
always @(posedge clk or negedge rstn)
if(!rstn)begin
for(i=0;i<8;i=i+1)
mem[i] <= 8'd0;
end else if(wr_en)
mem[wr_addr] <= data_in;
else
mem[wr_addr] <= mem[wr_addr];
// Read the address
always @(posedge clk or negedge rstn)
if(!rstn)begin
rd_addr <= 3'd0;
rd_flag <= 1'd0;
end else if(rd_en)
{rd_flag,rd_addr} <= {rd_flag,rd_addr} + 1'b1;
else
{rd_flag,rd_addr} <= {rd_flag,rd_addr};
// Reading data
always @(posedge clk or negedge rstn)
if(!rstn)
data_out <= 8'd0;
else if(rd_en)
data_out <= mem[rd_addr];
else
data_out <= data_out;
// Judge empty or full
assign wr_usedw = {wr_flag,wr_addr} - {rd_flag,rd_addr};
assign almost_empty = (wr_usedw < almost_empty_ref) ? 1'b1:1'b0;
assign almost_full = (wr_usedw > almost_full_ref ) ? 1'b1:1'b0;
assign empty = ({wr_flag,wr_addr} == {rd_flag,rd_addr}) ? 1'b1:1'b0;
//assign full = ((wr_addr == rd_addr) && (wr_flag != rd_flag)) ? 1'b1:1'b0; //FIFO Full hour wr_addr = 000 rd_addr=000
assign full = ({~wr_flag,wr_addr} == {rd_flag,rd_addr}) ? 1'b1:1'b0; //FIFO Full hour wr_addr = 000 rd_addr=000
endmodule //synchronize_fifo
6、TestBench Simulation

This testbench Go first FIFO Write data in , Then read the data , Finally, write the data . The read data is stored 3-10.
So look wr_usedw First from 0-8, Again from 8-0 , And then from 0-8.
and wr_flag The signal also jumps twice , Write the instructions twice .rd_flag The signal jumps once , Description read empty once .
边栏推荐
- 火线,零线,地线,你知道这三根线的作用是什么吗?
- Los Angeles p1051 who won the most Scholarships
- How to cancel the display of the return button at the uniapp uni app H5 end the autobackbutton does not take effect
- 语料库数据处理个案实例(读取多个文本文件、读取一个文件夹下面指定的多个文件、解码错误、读取多个子文件夹文本、多个文件批量改名)
- Svn actual measurement common operation record operation
- Solution to the error of running NPM run eject
- Any remarks
- Configure your own free Internet domain name with ngrok
- Chapter 3: drawing triangles
- AWTK 最新动态:Grid 控件新用法
猜你喜欢

Chapter 3: drawing triangles

Ad-gcl:advantageous graph augmentation to improve graph contractual learning

How to cancel the display of the return button at the uniapp uni app H5 end the autobackbutton does not take effect

面试中的最常被问到的两种锁

Graphmae ---- quick reading of papers

单片机STM32F103RB,BLDC直流电机控制器设计,原理图、源码和电路方案

Graphmae - - lecture rapide des documents

快速读论文----AD-GCL:Adversarial Graph Augmentation to Improve Graph Contrastive Learning

一文理解同步FIFO

Oracle advanced SQL qualified query
随机推荐
SCM stm32f103rb, BLDC DC motor controller design, schematic diagram, source code and circuit scheme
Domain environment importing Tencent cloud considerations
Vulnhub靶机:BOREDHACKERBLOG: SOCIAL NETWORK
Specify IP when calling feign interface
[run the script framework in Django and store the data in the database]
行内元素、块元素、行内块元素
L1-019 who goes first (15 points)
慕思股份在深交所上市:毛利率持续下滑,2022年一季度营销失利
Vulnhub target: boredhackerblog_ CLOUD AV
Error:Kotlin: Module was compiled with an incompatible version of Kotlin. The binary version of its
火线,零线,地线,你知道这三根线的作用是什么吗?
单片机STM32F103RB,BLDC直流电机控制器设计,原理图、源码和电路方案
语料库数据处理个案实例(句子检索相关个案)
Case examples of corpus data processing (cases related to sentence retrieval)
Live wire, neutral wire and ground wire. Do you know the function of these three wires?
Hongmeng OS development III
How does dating software cut your leeks
auto使用示例
3-list introduction
洛谷 P1051 谁拿了最多奖学金