文档视界 最新最全的文档下载
当前位置:文档视界 › 同步FIFO设计代码

同步FIFO设计代码

module fifo_syn(datain,
rd,
wr,
rst,
clk,
dataout,
full,
empty);

input [7:0] datain;
input rd, wr, rst, clk;
output [7:0] dataout;
output full, empty;

reg [7:0] dataout;
reg full_in, empty_in;
reg [7:0] mem [15:0];
reg [3:0] rp, wp;

assign full = full_in;
assign empty = empty_in;
// memory read out 稍作修改
always@(posedge clk) begin
if(rd && ~empty_in) dataout = mem[rp];
end

// memory write in
always@(posedge clk) begin
if(wr && ~full_in) mem[wp]<=datain;
end

// memory write pointer increment
always@(posedge clk or negedge rst)
if(!rst)
wp<=0;
else wp <= (wr && ~full_in) ? (wp + 1'b1) : wp;
// memory read pointer increment
always@(posedge clk or negedge rst)
if(!rst)
rp <= 0;
else rp <= (rd && ~empty_in)? (rp + 1'b1): rp;

// Full signal generate
always@(posedge clk or negedge rst) begin
if(!rst) full_in <= 1'b0;
else begin
if( (~rd && wr)&&((wp==rp-1)||(rp==4'h0&&wp==4'hf)))
full_in <= 1'b1;
else if(full_in && rd) full_in <= 1'b0;
end
end

// Empty signal generate
always@(posedge clk or negedge rst) begin
if(!rst) empty_in <= 1'b1;
else begin
if((rd&&~wr)&&(rp==wp-1 || (rp==4'hf&&wp==4'h0)))
empty_in<=1'b1;
else if(empty_in && wr) empty_in<=1'b0;
end
end
endmodule




另一种风格的同步FIFO

module FIFO_Buffer(
Data_out,
stack_full,
stack_almost_full,
stack_half_full,
stack_almost_empty,
stack_empty,
Data_in,
write_to_stack,
read_from_stack,
clk,rst
);
parameter stack_width=32;
parameter stack_height=8;
parameter stack_ptr_width=3;
parameter AE_level=2;
parameter AF_level=6;
parameter HF_level=4;
output [stack_width-1:0] Data_out;

output stack_full,stack_almost_full,stack_half_full;
output stack_almost_empty,stack_empty;
input[stack_width-1:0] Data_in;
input write_to_stack,read_from_stack;
input clk,rst;

reg[stack_ptr_width-1:0] read_ptr,write_ptr;

reg[stack_ptr_width:0] ptr_gap;
reg[stack_width-1:0] Data_out;
reg[stack_width-1:0] stack[stack_height-1:0];

assign stack_full=(ptr_gap==stack_height);
assign stack_almost_full=(ptr_gap==AF_level);
assign stack_half_full=(ptr_gap==HF_level);
assign stack_almost_empty=(ptr_gap==AE_level);
assign stack_empty=(ptr_gap==0);

always @(posedge clk or posedge rst)
if(rst)begin
Data_out<=0;
read_ptr<=0;
write_ptr<=0;
ptr_gap<=0;
end
else if(write_to_stack &&(!stack_full)&&(!read_from_stack))begin
stack[write_ptr]<=Data_in;
write_ptr<=write_ptr+1;

ptr_gap<=ptr_gap+1;
end
else if((!write_to_stack)&&(!stack_empty)&&read_from_stack)begin
Data_out<=stack[read_ptr];
read_ptr<=read_ptr+1;
ptr_gap<=ptr_gap-1;
end
else if(write_to_stack &&read_from_stack&&stack_empty)begin
stack[write_ptr]<=Data_in;
write_ptr<=write_ptr+1;
ptr_gap<=ptr_gap+1;
end
else if(write_to_stack &&read_from_stack&&stack_full)begin
Data_out<=stack[read_ptr];
read_ptr<=read_ptr+1;
ptr_gap<=ptr_gap-1;
end
else if(write_to_stack&&read_from_stack&&(!stack_full)&&(!stack_empty))
begin
Data_out<=stack[read_ptr];
stack[write_ptr]<=Data_in;
read_ptr<=read_ptr+1;
write_ptr<=write_ptr+1;
end
endmodule


异步

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



相关文档
相关文档 最新文档