同步FIFO和异步FIFO的Verilog实现.docx

上传人:b****7 文档编号:9082477 上传时间:2023-02-03 格式:DOCX 页数:14 大小:20.36KB
下载 相关 举报
同步FIFO和异步FIFO的Verilog实现.docx_第1页
第1页 / 共14页
同步FIFO和异步FIFO的Verilog实现.docx_第2页
第2页 / 共14页
同步FIFO和异步FIFO的Verilog实现.docx_第3页
第3页 / 共14页
同步FIFO和异步FIFO的Verilog实现.docx_第4页
第4页 / 共14页
同步FIFO和异步FIFO的Verilog实现.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

同步FIFO和异步FIFO的Verilog实现.docx

《同步FIFO和异步FIFO的Verilog实现.docx》由会员分享,可在线阅读,更多相关《同步FIFO和异步FIFO的Verilog实现.docx(14页珍藏版)》请在冰豆网上搜索。

同步FIFO和异步FIFO的Verilog实现.docx

同步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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 农学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1