项目名称
异步fifo
具体要求
异步fifo:输入输出速率不一样
用100mhz写入0-1023,并用10mhz读出
设计架构
Fifo是一种先进先出的缓存区只能顺序写入数据,顺序 读出数据,其数据地址由内部读写指针自动加 1 完成,不能像普通存储器那样可 以由地址线决定读取或写入某个指定的地址,读请求打开时,数据会自动被读出。
需要注意锁相环为高电平复位.
rdfull:读满信号,fifo满未读出时为真
rdempty:读空信号,fifo全读出时为真
wrfll:写满信号,fifo写满是为真
wrempty:写空信号,fifo没写任何数据时为真
fifo与ram和rom不同,数据读出之后fifo中就不存在数据,但是ram和rom中的数据被读出之后数据依然存在
代码设计
verilog代码设计
创建pll,生成100mhz和10mhz的时钟
创建fifo ipcore
顶层模块设计
module fifo_top(
input clk,
input rst_n,
output [9:0] q
);
//产生100m写时钟和10m的读时钟
wire clk_100m;
wire clk_10m;
wire locked;
my_pll my_pll(
.areset(!rst_n),
.inclk0(clk),
.c0(clk_100m),
.c1(clk_10m),
.locked(locked)
);
//写fifo控制模块
wire wrfull;
wire wrempty;
wire wrrerq;
wire [9:0] wrdata;
wire rdfull;
wire rdempty;
wire rdreq;
wr_fifo wr_fifo(
.wrclk(clk_100m),
.rst_n(locked),
.wrfull(wrfull),
.wrempty(wrempty),
.wrrerq(wrrerq),
.wrdata(wrdata)
);
//fifo模块
my_fifo my_fifo(
.data(wrdata),
.rdclk(clk_10m),
.rdreq(rdreq),
.wrclk(clk_100m),
.wrreq(wrrerq),
.q(q),
.rdempty(rdempty),
.rdfull(rdfull),
.wrempty(wrempty),
.wrfull(wrfull)
);
//读fifo控制模块
rd_fifo rd_fifo(
.rdclk(clk_10m),
.rst_n(locked),
.rdfull(rdfull),
.rdempty(rdempty),
.rdreq(rdreq)
);
endmodule
写fifo控制模块
module wr_fifo(
input wrclk,
input rst_n,
input wrfull,
input wrempty,
output reg wrrerq,
output reg[9:0] wrdata
);
reg state;
always@(posedge wrclk or negedge rst_n)
if(!rst_n)
begin
state<=0;
wrrerq<=0;
wrdata<=10'd0;
end
else begin
case(state)
0: begin
if(wrempty) //fifo中没有写任何数据
begin
wrrerq<=1;
state<=1;
end
else begin
wrrerq<=0;
state<=0;
wrdata<=10'd0;
end
end
1: begin
if(wrfull)
begin
wrrerq<=0;
wrdata<=10'd0;
state<=0;//跳回原来状态,等待下一次写入
end
else begin
wrrerq<=1;
wrdata<=wrdata+1'b1;
end
end
default:;
endcase
end
endmodule
读fifo控制模块
module rd_fifo(
input rdclk,
input rst_n,
input rdfull,
input rdempty,
output reg rdreq
);
reg state;
always@(posedge rdclk or negedge rst_n)
if(!rst_n)
begin
state<=0;
rdreq<=0;
end
else begin
case(state)
0: begin
if(rdfull)
begin
state<=1;
rdreq<=1;
end
else begin
state<=0;
rdreq<=0;
end
end
1: begin
if(rdempty)
begin
state<=0;
rdreq<=0;
end
else begin
state<=1;
rdreq<=1;
end
end
default:;
endcase
end
endmodule
仿真代码
`timescale 1ns/1ns
module fifo_top_tb;
reg clk;
reg rst_n;
wire [9:0] q;
fifo_top fifo_top(
.clk(clk),
.rst_n(rst_n),
. q(q)
);
initial clk=0;
always #10 clk=~clk;
initial begin
rst_n=0;
#200;
rst_n=1;
end
endmodule
仿真结果
出现写空信号时,打开写请求数据在下一个时钟上升沿开始写入,当写入数据之后,fifo中写空信号为低电平
fifo中写满之后,发出写满信号,写请求关闭
fifi中写满之后发出读满信号,读请求打开开始读数据
fifo数据读完之后,发出读空信号,读请求关闭。