module FIFO(Wr_Clk,//write FIFO clock
nWr,
//write FIFO signal
Din,
//write FIFO data
Rd_Clk,//read
FIFO clock
nRd,
//read FIFO signal
Dout,
//read FIFO data
Full,
// 1 = FIFO full
Empty);// 1 = FIFO
empty
input Wr_Clk, nWr, Rd_Clk,
nRd;
input [Bsize-1:0]
Din;
output [Bsize-1:0] Dout;
output Full, Empty;
reg Full, Empty;
reg [Bsize-1:0] Buff [Dsize-1:0];
reg [Asize:0] Wr_Addr_Bin,
Rd_Addr_Bin;
reg [Asize:0] Sync_Wr_Addr0_Gray,
Sync_Wr_Addr1_Gray, Sync_Wr_Addr2_Gray;
reg [Asize:0] Sync_Rd_Addr0_Gray,
Sync_Rd_Addr1_Gray, Sync_Rd_Addr2_Gray;
wire [Asize-1:0] FIFO_Entry_Addr,
FIFO_Exit_Addr;
wire [Asize:0] Wr_NextAddr_Bin,
Rd_NextAddr_Bin;
wire [Asize:0] Wr_NextAddr_Gray,
Rd_NextAddr_Gray;
wire Asyn_Full, Asyn_Empty;
parameter
Dsize = 256, Asize = 8,
Bsize = 8;
initial
begin
Full = 0;
Empty = 1;
Wr_Addr_Bin = 0;
Rd_Addr_Bin = 0;
Sync_Wr_Addr0_Gray = 0;
Sync_Wr_Addr1_Gray = 0;
Sync_Wr_Addr2_Gray = 0;
Sync_Rd_Addr0_Gray = 0;
Sync_Rd_Addr1_Gray = 0;
Sync_Rd_Addr2_Gray = 0;
end
////////////////////FIFO数据的写入与输出//////////////////////////////////////
assign FIFO_Exit_Addr =
Rd_Addr_Bin[Asize-1:0];
assign FIFO_Entry_Addr =
Wr_Addr_Bin[Asize-1:0];
assign Dout = Buff[FIFO_Exit_Addr];
always @ (posedge Wr_Clk)
begin
if (~nWr & ~Full)
Buff[FIFO_Entry_Addr] <= Din;
else
Buff[FIFO_Entry_Addr]
<= Buff[FIFO_Entry_Addr];
end
///////////////////FIFO读写的地址生成器///////////////////////////////////////
assign Wr_NextAddr_Bin =
(~nWr&~Full)
?Wr_Addr_Bin[Asize:0]+1:Wr_Addr_Bin[Asize:0];
assign Rd_NextAddr_Bin =
(~nRd&~Empty)?Rd_Addr_Bin[Asize:0]+1:Rd_Addr_Bin[Asize:0];
assign Wr_NextAddr_Gray = (Wr_NextAddr_Bin
>> 1) ^ Wr_NextAddr_Bin;
assign Rd_NextAddr_Gray = (Rd_NextAddr_Bin
>> 1) ^ Rd_NextAddr_Bin;
always @ (posedge Wr_Clk)
begin
Wr_Addr_Bin
<= Wr_NextAddr_Bin;
Sync_Wr_Addr0_Gray <=
Wr_NextAddr_Gray;
end
always @ (posedge Rd_Clk)
begin
Rd_Addr_Bin
<= Rd_NextAddr_Bin;
Sync_Rd_Addr0_Gray <=
Rd_NextAddr_Gray;
end
///////////////////采用双锁存器把异步信号同步起来/////////////////////////////
always @ (posedge Wr_Clk)
begin
Sync_Rd_Addr2_Gray <=
Sync_Rd_Addr1_Gray;//读信号同步到写时钟
Sync_Rd_Addr1_Gray <=
Sync_Rd_Addr0_Gray;
end
always @ (posedge Rd_Clk)
begin
Sync_Wr_Addr2_Gray <=
Sync_Wr_Addr1_Gray;//写信号同步到读时钟
Sync_Wr_Addr1_Gray <=
Sync_Wr_Addr0_Gray;
end
/////////////////将产生的Full信号和Empty信号同步的各自的时钟域上//////////////
assign Asyn_Empty =
(Rd_NextAddr_Gray==Sync_Wr_Addr2_Gray);
assign Asyn_Full =
(Wr_NextAddr_Gray=={~Sync_Rd_Addr2_Gray[Asize:Asize-1],
Sync_Rd_Addr2_Gray[Asize-2:0]});
always @ (posedge Wr_Clk)
begin
Full <= Asyn_Full;
end
always @ (posedge Rd_Clk)
begin
Empty <= Asyn_Empty;
end
//////////////////////////////////////////////////////////////////////////////
endmodule
加载中,请稍候......