FIFO
基础知识
FIFO(First In First Out,即先入先出),是一种数据缓存器,用来实现数据先入先出
的读写方式。在 FPGA 或者 ASIC 中使用到的 FIFO 一般指的是对数据的存储具有先入先出
特性的缓存器,常被用于多比特 数据跨时钟域的转换、读写数据带宽不同步等场合。
FIFO 本质上是由 RAM 加读写控制逻辑构成的一种先进先出的数据缓冲器,其与普通
存储器 RAM 的 区别在于 FIFO 没有外部读写地址线,使用起来非常简单,但 FIFO 只能顺
序写入数据,并按顺序读出数 据,其数据地址由内部读写指针自动加 1 完成,不能像普通
存储器那样可以由地址线决定读取或写入某个指定的地址,不过也正是因为这个特性,使得
FIFO 在使用时并不存在像 RAM 那样的读写冲突问题。
根据 FIFO 工作的时钟域,可以将 FIFO 分为同步 FIFO 和异步 FIFO。
同步 FIFO 是指读时钟和写时钟 为同一个时钟,在时钟沿来临时同时发生读写操作,常
用于两边数据处理带宽不一致的临时缓冲。
异步 FIFO 是指读写时钟不一致,读写时钟是互相独立的,一般用于数据信号跨时钟阈
处理。
`timescale 1ns / 1ps
module top_fifo(
input wire clk ,
input wire rst_n,
output wire tx
);
reg [7:0] cunt ;
wire wr_en;
wire [7:0]dout ;
wire full ;
wire empyt;
wire tx ;
wire busy ;
reg [3:0]cunt_t;
wire vled ;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
cunt<=0;
else if(cunt==11)
cunt<=cunt; //只写入一次
else
cunt<=cunt+1;
end
assign wr_en=(cunt<11)?1:0; //只写入一次
always @(posedge clk) begin
if(!rst_n)
cunt_t<=0;
else if(busy==0&&wr_en==0)begin //tx中state是空闲状态并且wr_en已经写入
if(cunt_t==3) //每次只读出一位所以每次读取只记一次
cunt_t<=cunt_t;
else
cunt_t<=cunt_t+1;
end
else
cunt_t<=0;
end
assign rd_en=(cunt_t==1)?1:0; //因为要想一位一位读出就需要rd_en每次读一位只制高1个时钟周期
assign vled =(cunt_t==2&dout<10)?1:0;
fifo_generator_0 u_fifo (
.clk (clk ), // input wire clk
.srst (~rst_n ), // input wire srst 复位信号 高电平复位
.din (cunt ), // input wire [7 : 0] din 输入数据
.wr_en(wr_en ), // input wire wr_en 写使能
.rd_en(rd_en ), // input wire rd_en 读使能
.dout (dout ), // output wire [7 : 0] dout 读数据
.full (full ), // output wire full 满标志
.empty(empty ) // output wire empty 空标志
);
tx#(
/*parameter*/ .CLK_DIV (50_000_000) ,
/*parameter*/ .BIT ( 115200 )
)u_tx(
/*input */ . clk (clk ),
/*input */ . rst_n(rst_n),
/*input [7:0]*/ . data (dout ),
/*input */ . vled (vled ),
/*output reg */ . tx (tx ),
. busy (busy )
);
endmodule