FPGA fifo读写实验
FIFO: first-in-first-out
FIFO一般用于不同时钟域之间的数据传输,也常用来实现不同位宽的接口数据的匹配。
FIFO是先进先出的存储器,实现数据的同步与缓存,当数据传输速率不一致的时候,利用FIFO进行数据的缓存。
系统框图
点击Yes表示读写使用同一个clk,NO代表读写不是使用一个clk,使用不同clk;
> module ip_fifo(clk,rst_n);
> input clk,rst_n;
> //wire define
> wire wrreq; //写请求信号
> wire wrempty; //写空信号
> wire wrfull; //写满信号
> wire [7:0] data; //写数据
> wire wrusedw;
> wire rdreq; //读请求信号
> wire rdempty; //读空信号
> wire rdfull; //读满信号
> wire [7:0] q; //读出数据
> wire rdusedw;
> fifo_wr u_fifo_wr(
> .clk(clk),
> .rst_n(rst_n),
> .wrreq(wrreq),
> .data(data),
> .wrfull(wrfull),
> .wrempty(wrempty)
> );
> fifo_rd u_fifo_rd(
> .clk(clk),
> .rst_n(rst_n),
> .rdreq(rdreq),
> .q(q),
> .rdempty(rdempty),
> .rdfull(rdfull)
> );
> fifo fifo_inst ( .data ( data),
> .rdclk ( clk ),
> .rdreq ( rdreq ),
> .wrclk ( clk),
> .wrreq ( wrreq ),
> .q ( q),
> .rdempty ( rdempty ),
> .rdfull ( rdfull ),
> .rdusedw ( rdusedw ),
> .wrempty ( wrempty),
> .wrfull ( wrfull ),
> .wrusedw ( wrusedw ) );
> endmodule
>
>
FIFO写程序
>
> module fifo_wr(clk,rst_n,wrempty,wrfull,data,wrreq);
> input clk,rst_n;
> input wrempty;
> input wrfull;
> output reg [7:0] data;
> output reg wrreq;
> // reg [1:0] flow_cnt;
>
> //向fifo里写入数据
> always @(posedge clk or negedge rst_n)
> begin if(!rst_n)
> begin
> flow_cnt <= 0;
> data <= 8'd0;
> wrreq <= 0;
> end
> else
> case(flow_cnt)
> 2'd0:
> begin
> if(wrempty)
> begin
> wrreq <= 1;
> flow_cnt <= flow_cnt+1;
> end
> else
> flow_cnt <= flow_cnt;
> end
> 2'd1:
> begin
> if(wrfull)
> begin
> wrreq <= 0;
> data <= 8'd0;
> flow_cnt <= 2'd0;
> end
> else begin
> wrreq <= 1;
> data <= data+1;
> end
> end
> default:
> flow_cnt <= 2'd0;
> endcase
> end
>
> endmodule
>
>
>
>
FIFO 读程序
> module fifo_rd(clk,rst_n,rdfull,rdempty,rdreq,q);
> input clk,rst_n;
> input [7:0] q;
> input rdfull;
> input rdempty;
> output reg rdreq;
> reg [7:0] data_fifo; //读取的fifo数据
> reg [1:0] flow_cnt;
> always @(posedge clk or negedge rst_n) begin
> if(!rst_n)
> begin
> data_fifo <= 8'd0;
> rdreq <= 0;
> flow_cnt <= 0;
> end
> else begin
> case(flow_cnt)
> 2'd0: begin //正在写数据
> if(rdfull)
> begin
> flow_cnt <= flow_cnt+1;
> rdreq <= 1;
> end
> else
> flow_cnt <= flow_cnt;
> end
> 2'd1: begin //正在读数据
> if(rdempty)
> begin
> flow_cnt <= 0;
> rdreq <= 0;
> data_fifo <= 8'd0;
> end
> else begin
> rdreq <= 1;
> data_fifo <= q;
> end
> end
> default: flow_cnt <= 2'd0;
> endcase
> end
> end
> endmodule