同步FIFO和异步FIFO的Verilog实现.docx
- 文档编号:9082477
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:14
- 大小:20.36KB
同步FIFO和异步FIFO的Verilog实现.docx
《同步FIFO和异步FIFO的Verilog实现.docx》由会员分享,可在线阅读,更多相关《同步FIFO和异步FIFO的Verilog实现.docx(14页珍藏版)》请在冰豆网上搜索。
同步FIFO和异步FIFO的Verilog实现
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的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
..........................................................................................................................
异步FIFO的Verilog代码之一
这个是基于RAM的异步FIFO代码,个人认为代码结构简单易懂,非常适合于考试中填写。
记得10月份参加威盛的笔试的时候,就考过异步FIFO的实现。
想当初要是早点复习,可能就可以通过威盛的笔试了。
与之前的用RAM实现的同步FIFO的程序相比,异步更为复杂。
增加了读写控制信号的跨时钟域的同步。
此外,判空与判满的也稍有不同。
modulefifo1(rdata,wfull,rempty,wdata,winc,wclk,wrst_n,rinc,rclk,rrst_n);
parameterDSIZE=8;parameterASIZE=4;
output[DSIZE-1:
0]rdata;
outputwfull;
outputrempty;
input[DSIZE-1:
0]wdata;
inputwinc,wclk,wrst_n;
inputrinc,rclk,rrst_n;
regwfull,rempty;
reg[ASIZE:
0]wptr,rptr,wq2_rptr,rq2_wptr,wq1_rptr,rq1_wptr;
reg[ASIZE:
0]rbin,wbin;
reg[DSIZE-1:
0]mem[0:
(1< wire[ASIZE-1: 0]waddr,raddr; wire[ASIZE: 0]rgraynext,rbinnext,wgraynext,wbinnext; wirerempty_val,wfull_val; //-----------------双口RAM存储器-------------------- assignrdata=mem[raddr]; always@(posedgewclk) if(winc&&! wfull)mem[waddr]<=wdata; //-------------同步rptr指针------------------------- always@(posedgew
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 同步 FIFO 异步 Verilog 实现