zoukankan      html  css  js  c++  java
  • 异步FIFO的设计

      1 `timescale 1ns / 1ns
      2 module async_fifo #(
      3     parameter   DP = 8,
      4     parameter   DW = 32 )(
      5     input               wr_clk,
      6     input               wr_reset_n,
      7     input               wr_en,
      8     input   [DW-1:0]    wr_data,
      9     output              full,
     10     output              afull,
     11     input               rd_clk,
     12     input               rd_reset_n,
     13     input               rd_en,
     14     output  [DW-1:0]    rd_data,
     15     output              empty,
     16     output              aempty
     17 );
     18 
     19 localparam  AW      = $clog2(DP);
     20 localparam  WR_FAST = 1'b1;
     21 localparam  RD_FAST = 1'b1;
     22 
     23 reg     [DW-1:0]    mem[DP-1:0];
     24 reg     [AW:0]      sync_rd_ptr_0, sync_rd_ptr_1;
     25 wire    [AW:0]      sync_rd_ptr;
     26 reg                 full_q;
     27 reg     [AW:0]      wr_ptr, gray_wr_ptr;
     28 reg     [AW:0]      gray_rd_ptr;
     29 wire    [AW:0]      wr_ptr_inc = wr_ptr + 1'b1;
     30 wire    [AW:0]      wr_cnt = get_cnt(wr_ptr, sync_rd_ptr);
     31 wire                full_c  = (wr_cnt == DP) ? 1'b1 : 1'b0;
     32 reg     [AW:0]      sync_wr_ptr_0, sync_wr_ptr_1;
     33 wire    [AW:0]      sync_wr_ptr;
     34 reg     [AW:0]      rd_ptr;
     35 reg                 empty_q;
     36 wire    [AW:0]      rd_ptr_inc = rd_ptr + 1'b1;
     37 wire    [AW:0]      rd_cnt = get_cnt(sync_wr_ptr, rd_ptr);
     38 wire                empty_c  = (rd_cnt == 0) ? 1'b1 : 1'b0;
     39 reg     [DW-1:0]    rd_data_q;
     40 wire    [DW-1:0]    rd_data_c = mem[rd_ptr[AW-1:0]];
     41 
     42 always @(posedge wr_clk or negedge wr_reset_n)
     43     if (!wr_reset_n) begin
     44         wr_ptr <= 'd0;
     45         gray_wr_ptr <= 'd0;
     46         full_q <= 'b0;
     47     end
     48     else if (wr_en) begin
     49         wr_ptr <= wr_ptr_inc;
     50         gray_wr_ptr <= bin2gray(wr_ptr_inc);
     51         if (wr_cnt == (DP-'d1)) begin
     52             full_q <= 'b1;
     53         end
     54     end
     55     else begin
     56         if (full_q && (wr_cnt<DP)) begin
     57             full_q <= 'b0;
     58         end
     59     end
     60 
     61 assign full  = (WR_FAST == 1) ? full_c : full_q;
     62 assign afull = (wr_cnt >= DP/2 - 1) ? 1'b1 : 1'b0;
     63 
     64 always @(posedge wr_clk)
     65     if (wr_en) begin
     66         mem[wr_ptr[AW-1:0]] <= wr_data;
     67     end
     68 
     69 // read pointer synchronizer
     70 always @(posedge wr_clk or negedge wr_reset_n)
     71     if (!wr_reset_n) begin
     72         sync_rd_ptr_0 <= 'b0;
     73         sync_rd_ptr_1 <= 'b0;
     74     end
     75     else begin
     76         sync_rd_ptr_0 <= gray_rd_ptr;
     77         sync_rd_ptr_1 <= sync_rd_ptr_0;
     78     end
     79 
     80 assign sync_rd_ptr = gray2bin(sync_rd_ptr_1);
     81 
     82 always @(posedge rd_clk or negedge rd_reset_n)
     83     if (!rd_reset_n) begin
     84         rd_ptr <= 'd0;
     85         gray_rd_ptr <= 'd0;
     86         empty_q <= 'b1;
     87     end
     88     else begin
     89         if (rd_en) begin
     90             rd_ptr <= rd_ptr_inc;
     91             gray_rd_ptr <= bin2gray(rd_ptr_inc);
     92             if (rd_cnt=='d1) begin
     93                 empty_q <= 'b1;
     94             end
     95         end
     96         else begin
     97             if (empty_q && (rd_cnt!='d0)) begin
     98                 empty_q <= 'b0;
     99             end
    100         end
    101     end
    102 
    103 assign empty  = (RD_FAST == 1) ? empty_c : empty_q;
    104 assign aempty = (rd_cnt < DP/2 - 'd3) ? 1'b1 : 1'b0;
    105 
    106 always @(posedge rd_clk)
    107     rd_data_q <= rd_data_c;
    108 
    109 assign rd_data  = (RD_FAST == 1) ? rd_data_c : rd_data_q;
    110 
    111 // write pointer synchronizer
    112 always @(posedge rd_clk or negedge rd_reset_n)
    113     if (!rd_reset_n) begin
    114        sync_wr_ptr_0 <= 'b0;
    115        sync_wr_ptr_1 <= 'b0;
    116     end
    117     else begin
    118        sync_wr_ptr_0 <= gray_wr_ptr;
    119        sync_wr_ptr_1 <= sync_wr_ptr_0;
    120     end
    121 
    122 assign sync_wr_ptr = gray2bin(sync_wr_ptr_1);
    123 
    124 function [AW:0] get_cnt;
    125 input [AW:0] wr_ptr, rd_ptr;
    126 begin
    127     if (wr_ptr >= rd_ptr) begin
    128         get_cnt = (wr_ptr - rd_ptr);
    129     end
    130     else begin
    131         get_cnt = DP*2 - (rd_ptr - wr_ptr);
    132     end
    133 end
    134 endfunction
    135 
    136 function [AW:0] bin2gray;
    137 input   [AW:0]  bin;
    138 
    139 bin2gray = (bin >> 1) ^ bin;
    140 
    141 endfunction
    142 
    143 function [AW:0] gray2bin;
    144 input   [AW:0]  gray;
    145 integer         k;
    146 
    147 for (k = 0; k <= AW; k = k + 1)
    148     gray2bin[k] = ^(gray >> k);
    149 
    150 endfunction
    151 
    152 endmodule
  • 相关阅读:
    Bzoj 3654 图样图森波 题解
    1.27号考试记录
    博弈论入门小结
    「考试总结」2020-11-18 爆零
    「补题」考试题泛做
    CSP2020 游记,总结与题解
    Luogu2827 「NOIP2016」 蚯蚓
    【学习笔记】四毛子算法
    「考试反思」2020-11-04 临行
    「考试反思」2020-10-31 警示
  • 原文地址:https://www.cnblogs.com/lyuyangly/p/6816212.html
Copyright © 2011-2022 走看看