fifo.docx
《fifo.docx》由会员分享,可在线阅读,更多相关《fifo.docx(12页珍藏版)》请在冰豆网上搜索。
fifo
FIFO很重要,之前参加的各类电子公司的逻辑设计的笔试几乎都会考到。
FIFO是英文FirstInFirstOut的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据,其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。
FIFO一般用于不同时钟域之间的数据传输,比如FIFO的一端是AD数据采集,另一端是计算机的PCI总线,假设其AD采集的速率为16位100KSPS,那么每秒的数据量为100K×16bit=1.6Mbps,而PCI总线的速度为33MHz,总线宽度32bit,其最大传输速率为1056Mbps,在两个不同的时钟域间就可以采用FIFO来作为数据缓冲。
另外对于不同宽度的数据接口也可以用FIFO,例如单片机位8位数据输出,而DSP可能是16位数据输入,在单片机与DSP连接时就可以使用FIFO来达到数据匹配的目的。
FIFO的分类根均FIFO工作的时钟域,可以将FIFO分为同步FIFO和异步FIFO。
同步FIFO是指读时钟和写时钟为同一个时钟。
在时钟沿来临时同时发生读写操作。
异步FIFO是指读写时钟不一致,读写时钟是互相独立的。
FIFO设计的难点FIFO设计的难点在于怎样判断FIFO的空/满状态。
为了保证数据正确的写入或读出,而不发生益处或读空的状态出现,必须保证FIFO在满的情况下,不能进行写操作。
在空的状态下不能进行读操作。
怎样判断FIFO的满/空就成了FIFO设计的核心问题。
.........................................................................................................................................
同步FIFO的Verilog代码之一
在modlesim中验证过。
/******************************************************
Afifocontrollerverilogdescription.
******************************************************/
modulefifo(datain,rd,wr,rst,clk,dataout,full,empty);
input[7:
0]datain;
inputrd,wr,rst,clk;
output[7:
0]dataout;
outputfull,empty;
wire[7:
0]dataout;
regfull_in,empty_in;
reg[7:
0]mem[15:
0];
reg[3:
0]rp,wp;
assignfull=full_in;
assignempty=empty_in;
//memoryreadout
assigndataout=mem[rp];
//memorywritein
always@(posedgeclk)begin
if(wr&&~full_in)mem[wp]<=datain;
end
//memorywritepointerincrement
always@(posedgeclkornegedgerst)begin
if(!
rst)wp<=0;
elsebegin
if(wr&&~full_in)wp<=wp+1'b1;
end
end
//memoryreadpointerincrement
always@(posedgeclkornegedgerst)begin
if(!
rst)rp<=0;
elsebegin
if(rd&&~empty_in)rp<=rp+1'b1;
end
end
//Fullsignalgenerate
always@(posedgeclkornegedgerst)begin
if(!
rst)full_in<=1'b0;
elsebegin
if((~rd&&wr)&&((wp==rp-1)||(rp==4'h0&&wp==4'hf)))
full_in<=1'b1;
elseif(full_in&&rd)full_in<=1'b0;
end
end
//Emptysignalgenerate
always@(posedgeclkornegedgerst)begin
if(!
rst)empty_in<=1'b1;
elsebegin
if((rd&&~wr)&&(rp==wp-1||(rp==4'hf&&wp==4'h0)))
empty_in<=1'b1;
elseif(empty_in&&wr)empty_in<=1'b0;
end
end
endmodule
...........................................................................................................................
同步FIFO的Verilog代码之二
这一种设计的FIFO,是基于触发器的。
宽度,深度的扩展更加方便,结构化跟强。
以下代码在modelsim中验证过。
modulefifo_cell(sys_clk,sys_rst_n,read_fifo,write_fifo,fifo_input_data,
next_cell_data,next_cell_full,last_cell_full,cell_data_out,cell_full);
parameterWIDTH=8;
parameterD=2;
inputsys_clk;
inputsys_rst_n;
inputread_fifo,write_fifo;
input[WIDTH-1:
0]fifo_input_data;
input[WIDTH-1:
0]next_cell_data;
inputnext_cell_full,last_cell_full;
output[WIDTH-1:
0]cell_data_out;
outputcell_full;
reg[WIDTH-1:
0]cell_data_reg_array;
reg[WIDTH-1:
0]cell_data_ld;
regcell_data_ld_en;
regcell_full;
regcell_full_next;
assigncell_data_out=cell_data_reg_array;
always@(posedgesys_clkornegedgesys_rst_n)
if(!
sys_rst_n)
cell_full<=#D0;
elseif(read_fifo||write_fifo)
cell_full<=#Dcell_full_next;
always@(write_fifoorread_fifoornext_cell_fullorlast_cell_fullorcell_full)
casex({read_fifo,write_fifo})
2'b00:
cell_full_next=cell_full;
2'b01:
cell_full_next=next_cell_full;
2'b10:
cell_full_next=last_cell_full;
2'b11:
cell_full_next=cell_full;
endcase
always@(posedgesys_clkornegedgesys_rst_n)
if(!
sys_rst_n)
cell_data_reg_array[WIDTH-1:
0]<=#D0;
elseif(cell_data_ld_en)
cell_data_reg_array[WIDTH-1:
0]<=#Dcell_data_ld[WIDTH-1:
0];
always@(write_fifoorread_fifoorcell_fullorlast_cell_full)
casex({write_fifo,read_fifo,cell_full,last_cell_full})
4'bx1_xx:
cell_data_ld_en=1'b1;
4'b10_01:
cell_data_ld_en=1'b1;
default:
cell_data_ld_en=1'b0;
endcase
always@(write_fifoorread_fifoornext_cell_fullorcell_fullorlast_cell_fullorfifo_input_dataornext_cell_data)
casex({write_fifo,read_fifo,next_cell_full,cell_full,last_cell_full})
5'b10_x01:
cell_data_ld[WIDTH-1:
0]=fifo_input_data[WIDTH-1:
0];
5'b11_01x:
cell_data_ld[WIDTH-1:
0]=fifo_input_data[WIDTH-1:
0];
default:
cell_data_ld[WIDTH-1:
0]=next_cell_data[WIDTH-1:
0];
endcase
endmodule
modulefifo_4cell(sys_clk,sys_rst_n,fifo_input_data,write_fifo,fifo_out_data,
read_fifo,full_cell0,full_cell1,full_cell2,full_cell3);
parameterWIDTH=8;
parameterD=2;
inputsys_clk;
inputsys_rst_n;
input[WIDTH-1:
0]fifo_input_data;
output[WIDTH-1:
0]fifo_out_data;
inputread_fifo,write_fifo;
outputfull_cell0,full_cell1,full_cell2,full_cell3;
wire[WIDTH-1:
0]dara_out_cell0,data_out_cell1,data_out_cell2,
data_out_cell3,data_out_cell4;
wirefull_cell4;
fifo_cell#(WIDTH,D)cell0
(.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.fifo_input_data(fifo_input_data[WIDTH-1:
0]),
.write_fifo(write_fifo),
.next_cell_data(data_out_cell1[WIDTH-1:
0]),
.next_cell_full(full_cell1),
.last_cell_full(1'b1),
.cell_data_out(fifo_out_data[WIDTH-1:
0]),
.read_fifo(read_fifo),
.cell_full(full_cell0)
);
fifo_cell#(WIDTH,D)cell1
(.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.fifo_input_data(fifo_input_data[WIDTH-1:
0]),
.write_fifo(write_fifo),
.next_cell_data(data_out_cell2[WIDTH-1:
0]),
.next_cell_full(full_cell2),
.last_cell_full(full_cell0),
.cell_data_out(data_out_cell1[WIDTH-1:
0]),
.read_fifo(read_fifo),
.cell_full(full_cell1)
);
fifo_cell#(WIDTH,D)cell2
(.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.fifo_input_data(fifo_input_data[WIDTH-1:
0]),
.write_fifo(write_fifo),
.next_cell_data(data_out_cell3[WIDTH-1:
0]),
.next_cell_full(full_cell3),
.last_cell_full(full_cell1),
.cell_data_out(data_out_cell2[WIDTH-1:
0]),
.read_fifo(read_fifo),
.cell_full(full_cell2)
);
fifo_cell#(WIDTH,D)cell3
(.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.fifo_input_data(fifo_input_data[WIDTH-1:
0]),
.write_fifo(write_fifo),
.next_cell_data(data_out_cell4[WIDTH-1:
0]),
.next_cell_full(full_cell4),
.last_cell_full(full_cell2),
.cell_data_out(data_out_cell3[WIDTH-1:
0]),
.read_fifo(read_fifo),
.cell_full(full_cell3)
);
assigndata_out_cell4[WIDTH-1:
0]={WIDTH{1'B0}};
assignfull_cell4=1'b0;
endmodule