异步FIFO控制代码

在芯片设计中,遇到跨时钟操作时,经常用的哦啊异步FIFO,下面整理了异步FIFO控制代码。

module async_fifo #(
    parameter  DT_WID =8,
    parameter  ADR_WID =9
)(

//write port
input                  wr_rst_n,
input                  wr_clk,
input                  wr_en,
input  [DT_WID-1:0]    wr_dt,
//read port
input                  rd_rst_n,
input                  rd_clk,
input                  rd_en,
output [DT_WID-1:0]    rd_dt,
output             reg fifo_full,
output             reg fifo_empty

);


reg  [ADR_WID:0]   wptr;
reg  [ADR_WID:0]   wptr1;
reg  [ADR_WID:0]   wptr2;
reg  [ADR_WID:0]   wptr3;
reg  [ADR_WID:0]   rptr;
reg  [ADR_WID:0]   rptr1;
reg  [ADR_WID:0]   rptr2;
reg  [ADR_WID:0]   rptr3;

reg [ADR_WID:0]    raddr_bin;
reg [ADR_WID:0]    raddr_gray;
reg [ADR_WID:0]    raddr_gray_next;
reg [ADR_WID:0]    raddr_bin_next;

reg [ADR_WID:0]    waddr_bin;
reg [ADR_WID:0]    waddr_gray;
reg [ADR_WID:0]    waddr_gray_next;
reg [ADR_WID:0]    waddr_bin_next;


//read addr and empyt flag
always @(posedeg rd_clk or negedge rd_rst_n) begin
    if(!rd_rst_n) begin
        raddr_bin <= 'b0;
        raddr_gray <= 'b0;
    end
    else begin
        raddr_bin <= raddr_bin_next;
        raddr_gray <= raddr_gray_next;
    end
end


always @(posedeg rd_clk or negedge rd_rst_n) begin
    if(!rd_rst_n) begin
        fifo_empty <= 'b1;
    end
    else begin
        fifo_empty <= (raddr_gray_next == wptr2); 
    end
end

assign raddr_bin_next = raddr_bin + (rd_en & ~fifo_empty);
assign raddr_gray_next = (raddr_bin_next>>1) ^ raddr_bin_next;

//write addr and full flag
always @(posedeg wr_clk or negedge wr_rst_n) begin
    if(!wr_rst_n) begin
        waddr_bin <= 'b0;
        waddr_gray <= 'b0;
    end
    else begin
        waddr_bin <= waddr_bin_next;
        waddr_gray <= waddr_gray_next;
    end
end

always @(posedeg wr_clk or negedge wr_rst_n) begin
    if(!wr_rst_n) begin
        fifo_full <= 'b0;
    end
    else begin
        fifo_full <= (waddr_gray_next == {~rptr2[ADR_WID:ADR_WID-1],rptr2[ADR_WID-2:0]}); 
    end
end


assign waddr_bin_next = waddr_bin + (wr_en & ~fifo_full);
assign waddr_gray_next = (waddr_bin_next>>1) ^ waddr_bin_next;

//sync wprt to rclk domain
always @(posedeg rd_clk or negedge rd_rst_n) begin
    if(!rd_rst_n) begin
        wptr1 <= 'b0;
        wptr2 <= 'b0;
    end
    else begin
        wptr1 <= waddr_gray;
        wptr2 <= wptr1 ;
    end
end


always @(posedeg wr_clk or negedge wr_rst_n) begin
    if(!rd_rst_n) begin
        rptr1 <= 'b0;
        rptr2 <= 'b0;
    end
    else begin
        rptr1 <= raddr_gray;
        rptr2 <= rptr1 ;
    end
end

async_ram #(.DT_WID(DT_WID),
            .ADR_WID(ADR_WID))
 async_ram_u(
.wr_dt(wr_dt),
.wr_addr(waddr_bin[ADR_WID-1:0]),
.wr_clk(wr_clk),
.wr_en  (wr_en),

.rd_dt(rd_dt),
.rd_addr(raddr_bin[ADR_WID-1:0]),
.rd_clk(rd_clk),
.rd_en  (rd_en)
);



endmodule

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值