在进修跨时钟域处理的时候,有一种方法是用异步FIFO来处理跨时钟域处理的
在进修跨时钟域处理的时候,有一种方法是用异步FIFO来处理跨时钟域处理的。那么在这之前先看看同步FIFO实现。
所谓同步FIFO,就是读写时钟是同一个时钟频次。本次实现是通过计数器的形式来实现满空标志。详细实现如下:
module fifo_sync(
input clk,
inputrst_n,
input[7:0]datain, //输写数据inputwr, //写请求inputrd, //读请求
outputreg[7:0] dataout, //输出数据outputempt, //空标志outputfull //满标志);
//定义寄存器reg [3:0]cnt; //计数器用于计算FIFO中寄存了多少数据,方便提供满空标志reg [3:0]wr_ptr, rd_ptr; //读写指针reg[7:0]fifo_mem[15:0]; //定义16个8位的寄存器用于寄存数据,FIFO管道//定义状态parameter S0 = 2'b00, S1 = 2'b01, S2 = 2'b10, S3 = 2'b11;
//用一段式状态机简略实现FIFOalways @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
cnt
wr_ptr
rd_ptr
dataout
end
else begin
case ({rd,wr})
S0 : begin //空闲cnt
wr_ptr
rd_ptr
dataout0;
end
S1:begin//写FIOFif(!full)begin
fifo_mem[wr_ptr]datain;
wr_ptrwr_ptr+1'b1;
rd_ptrrd_ptr;
cntcnt+1'b1;
dataout0;
end
end
S2:begin//读FIFOif(!empt)begin
dataoutfifo_mem[rd_ptr];
rd_ptrrd_ptr+1'b1;
wr_ptrwr_ptr;
cntcnt-1'b1;
end
end
S3:begin//同时读写FIFOif(!full)begin
fifo_mem[wr_ptr]datain;
wr_ptrwr_ptr+1'b1;
end
if(!empt)begin
dataoutfifo_mem[rd_ptr];
rd_ptrrd_ptr+1'b1;
end
end
default:;
endcase
endend
//满空标志信号产生assignfull=(cnt==4'd15);assignempt=(cnt==4'd0);
endmodule
简单的测试:
`timescale1ns/1nsmodulefifo_sync_tb();
regclk;regrst_n;reg[7:0]datain;regwr,rd;
wire[7:0]dataout;wireempt;wirefull;
initialbeginclk=1'b1;rst_n=1'b0;datain=0;wr=1'b0;rd=1'b0;#50rst_n=1'b1;#40wr=1'b1;#20rd=1'b1;#20rd=1'b0;#170wr=1'b0;#200rd=1'b1;#40rd=1'b0;#500$stop;end
always#5clk=~clk;
always@(posedgeclk)begin
dataindatain+1'b1;end
fifo_syncfifo(
.clk(clk),
.rst_n(rst_n),
.datain(datain),//输入数据.wr(wr),//写请求.rd(rd),//读请求
.dataout(dataout),//输出数据.empt(empt),//空标志.full(full)//