·一、什么是FIFO?
FIFO分为同步FIFO和异步FIFO。
同步 FIFO 的写时钟和读时钟为同一个时钟,FIFO 内部所有逻辑都是同步逻辑,常常用于交
互数据缓冲。异步 FIFO 的写时钟和读时钟为异步时钟,FIFO 内部的写逻辑和读逻辑的交互
需要异步处理,异步 FIFO 常用于跨时钟域交互。
异步 FIFO中数据流的传输与指示信号不同在于:数据流大多具有连续性,及背靠背传输;数据流要求信 号具有较快的传输速度。主要的方案是利用 FIFO 进行传输。
二、vivado的FIFO IP核
打开vivado软件中的IP Catalog,在搜索框中输入FIFO,找到FIFO Generator并双击打开FIFO IP核。
根据需求可选择同步FIFO和异步FIFO,此处选择同步FIFO。
FIFO生成好以后打开IP Sources的.veo文件找到例化。
三、uart头文件中引入FIFO
`timescale 1ns / 1ps
module uart(
input clk,
input rx,
output tx
);
// ================pll================//
wire clk_50m;
wire rst;
wire locked;
assign rst = locked;
pll pll_inst
(
.clk_out1(clk_50m), // output clk_out1
.reset(1'b0), // input reset
.locked(locked), // output locked
.clk_in1(clk)); // input clk_in1
//==============串口使能模块==========//
wire tx_en;
wire rx_en;
uart_en
#(
.BPS (115200 ) ,
.sysclk (50_000_000)
)
uart_en_inst
(
.clk (clk_50m),
.rst (locked),
.rx_en (rx_en),
.tx_en (tx_en)
);
//=============串口接收模块===========//
wire rx;
wire rx_data_vld;
wire [7:0] rx_data;
wire rx_end;
uart_rx
#(
.PARITY ("NONE"),
.STOP (1 )
)
uart_rx_inst
(
.clk (clk_50m),
.rst (locked),
.rx_en (rx_en),
.tx_en (tx_en),
.rx (rx),
.rx_data (rx_data),
.rx_end (rx_end),
.rx_data_vld (rx_data_vld)
);
//=============串口发送模块===========//
wire tx_ack;
wire tx;
uart_tx
#(
.PARITY ("NONE"),
.STOP (1 )
)
uart_tx_inst
(
.clk (clk_50m),
.rst (locked),
.tx_data_vld (tx_data_vld),
.tx_data (tx_data),
.tx_en (tx_en),
.tx_ack (tx_ack),
.tx (tx)
);
//===========fifo=====================//
wire wr_en;
reg rd_en;
reg [7:0] tx_data;
wire [7:0] fifo_out;
reg tx_data_vld;
reg [2:0]state;
always@(posedge clk or negedge rst)
if(!rst)
begin
rd_en<=0;
tx_data<=0;
tx_data_vld<=0;
state<=0;
end
else
begin
case(state)
0: begin
rd_en<=0;
tx_data<=0;
tx_data_vld<=0;
if(!empty)
state<=1;
end
1: begin
rd_en<=1;
state<=2;
end
2: begin //等待状态
rd_en<=0;
state<=3;
end
3: begin
tx_data<=fifo_out;
tx_data_vld<=1;
state<=4;
end
4: begin
if(tx_ack)
begin
tx_data_vld<=0;
state<=5;
end
end
5: begin
if(!tx_ack)
state<=0;
end
default:state<=0;
endcase
end
wire [6:0] data_count;
wire empty;
fifo fifo_inst (
.clk(clk_50m), // input wire clk
.din(rx_data), // input wire [7 : 0] din
.wr_en(rx_data_vld), // input wire wr_en
.rd_en(rd_en), // input wire rd_en
.dout(fifo_out), // output wire [7 : 0] dout
.full(full), // output wire full
.empty(empty), // output wire empty
.data_count(data_count), // output wire [6 : 0] data_count
.prog_full(prog_full) // output wire prog_full
);
endmodule