异步FIFO的实现

本文介绍了异步FIFO在处理多bit数据流跨时钟域的问题中所起的关键作用。代码示例展示了如何实现一个异步FIFO,包括读写数据、读写指针同步、读空和写满标志的检测。通过格雷码转换确保了指针同步的正确性,从而保证了数据传输的可靠性。
摘要由CSDN通过智能技术生成

多bit的数据流跨时钟域处理常采用异步FIFO
异步FIFO的结构框图如图所示
在这里插入图片描述

异步FIFO的代码如下:

module asyn_fifo#(parameter DSIZE = 8, parameter ASIZE = 4)(
      output [DSIZE-1:0] rdata,   //读数据
      output reg wfull,           //写满
      output reg rempty,          //读空
      input [DSIZE-1:0] wdata,    //写数据
      input winc, 
      input wclk,                 //写时钟 
      input wrst_n, 
      input rinc, 
      input rclk,                 //读时钟
      input rrst_n
    );   
 
  reg [ASIZE:0] wptr, rptr, wp1_rptr, wp2_rptr, rp1_wptr, rp2_wptr;
  reg [ASIZE:0] rbin, wbin;
  wire [ASIZE:0] rgraynext, rbinnext,wgraynext,wbinnext;
  reg [DSIZE-1:0] mem [ASIZE-1:0];
  wire [ASIZE-1:0] waddr, raddr;
 
  //FIFO读写数据
  always@(posedge wclk)begin
    if(winc & ~wfull)  mem[waddr] <= wdata;
  end
  always @(posedge rclk)begin
    if(rinc & ~rempty) rdata <= mem[raddr]; 
  end

  //FIFO读写指针同步
  always@(posedge wclk or negedge wrst_n)begin
   if(~wrst_n)begin
     wp1_rptr <= 'd0;
     wp2_rptr <= 'd0;
   end
   else begin
   	 wp1_rptr <= rptr;
     wp2_rptr <= wp1_rptr;
   end
  end	

  always@(posedge rclk or negedge rrst_n)begin
   if(~rrst_n)begin
     rp1_wptr <= 'd0;
     rp2_wptr <= 'd0;
   end
   else begin
   	 rp1_wptr <= wptr;
     rp2_wptr <= rp1_wptr;
   end
  end

  assign raddr = rbin[ASIZE-1:0];	            //获取读地址
  assign rbinnext = rbin + (rinc & ~rempty);    
  assign rgraynext = (rbinnext>>1)^rbinnext;  //获取读指针格雷码

 always@(posedge rclk or negedge rrst_n)begin
   if(~rrst_n)begin
     {rbin,rptr} <= 0;
   end
   else begin
   	 {rbin,rptr} <= {rbinnext,rgraynext};
   end
 end

 wire rempty_val;
 assign rempty_val = (rgraynext == rp2_wptr);
 always@(posedge rclk or negedge rrst_n)begin
   if(~rrst_n)begin
     rempty <= 0;
   end
   else begin
   	 rempty <= rempty_val;                    //获取读空标志
   end
 end 

  assign waddr = wbin[ASIZE-1:0];	            //获取写地址
  assign wbinnext = wbin + (winc & ~wfull);    
  assign wgraynext = (wbinnext>>1)^wbinnext;  //获取写指针格雷码

 always@(posedge wclk or negedge wrst_n)begin
   if(~wrst_n)begin
     {wbin,wptr} <= 0;
   end
   else begin
   	 {wbin,wptr} <= {wbinnext,wgraynext};
   end
 end

 wire wfull_val;
 assign wfull_val = (wgraynext == {~wp2_rptr[ASIZE:ASIZE-1],wp2_rptr[ASIZE-2:0]});
 always@(posedge wclk or negedge wrst_n)begin
   if(~wrst_n)begin
     wfull <= 0;
   end
   else begin
   	 wfull <= wfull_val;                     //获取写满标志
   end
 end

endmodule
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值