00001
00002
00003
00004
00005
00006 `default_nettype none
00007 `timescale 1ns / 1ps
00008
00009 (* KEEP_HIERARCHY = "TRUE" *)module async_fifo_rise (
00010 din,
00011 rd_clk,
00012 rd_en,
00013 rst,
00014 wr_clk,
00015 wr_en,
00016 almost_empty,
00017 almost_full,
00018 dout,
00019 empty,
00020 full);
00021
00022 input wire [15 : 0] din;
00023 input wire rd_clk;
00024 input wire rd_en;
00025 input wire rst;
00026 input wire wr_clk;
00027 input wire wr_en;
00028 output wire almost_empty;
00029 output wire almost_full;
00030 output wire [15 : 0] dout;
00031 output wire empty;
00032 output wire full;
00033
00034 reg [3:0] wp, rp;
00035 wire [3:0] inc_wp, inc_rp;
00036 reg [3:0] wgray, rgray;
00037 reg [3:0] rgrayd1, rgrayd2;
00038 reg [3:0] wgrayd1, wgrayd2;
00039 reg [3:0] rdbinary, wrbinary;
00040
00041 generate
00042 genvar i;
00043 for (i=15; i>=0; i=i-1) begin : DPRAM_GEN
00044 RAM16X1D #(
00045 .INIT(16'h000)
00046 ) RAM16X1D_inst (
00047 .WCLK(wr_clk),
00048 .WE(wr_en),
00049 .A0(wp[0]),
00050 .A1(wp[1]),
00051 .A2(wp[2]),
00052 .A3(wp[3]),
00053 .D(din[i]),
00054 .SPO(),
00055 .DPRA0(rp[0]),
00056 .DPRA1(rp[1]),
00057 .DPRA2(rp[2]),
00058 .DPRA3(rp[3]),
00059 .DPO(dout[i])
00060 );
00061 end
00062 endgenerate
00063
00064 // Write Clock Domain
00065 assign inc_wp = wp + 1;
00066 always @(posedge wr_clk, posedge rst) begin : WRITE_COUNTERS
00067 integer j;
00068
00069 if (rst) begin
00070 wp <= 4'h0;
00071 wgray <= 4'h0;
00072 end else begin
00073 if (wr_en) begin
00074 wp <= wp + 4'h1;
00075 wgray <= {inc_wp[3], inc_wp[2:0] ^ inc_wp[3:1]};
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 end
00086 end
00087 end
00088
00089
00090 always @(posedge wr_clk, posedge rst) begin
00091 if (rst) begin
00092 rgrayd1 <= 4'h0;
00093 rgrayd2 <= 4'h0;
00094 end else begin
00095 rgrayd1 <= rgray;
00096 rgrayd2 <= rgrayd1;
00097 end
00098 end
00099
00100
00101 always @* begin : READ_GRAY2BINARY
00102 integer j;
00103
00104 for(j=3; j>=0; j=j-1) begin
00105 if (j==3)
00106 rdbinary[j] <= rgrayd2[j];
00107 else
00108 rdbinary[j] <= rgrayd2[j] ^ rdbinary[j+1];
00109 end
00110 end
00111
00112
00113 assign full = (wp == rdbinary-4'h1) ? 1'b1 : 1'b0;
00114 assign almost_full = (wp==rdbinary-4'h2) ? 1'b1 : 1'b0;
00115
00116
00117
00118 assign inc_rp = rp + 1;
00119 always @(posedge rd_clk, posedge rst) begin : READ_COUNTERS
00120 integer j;
00121
00122 if (rst) begin
00123 rp <= 4'h0;
00124 rgray <= 4'h0;
00125 end else begin
00126 if (rd_en) begin
00127 rp <= rp + 4'h1;
00128 rgray <= {inc_rp[3], inc_rp[2:0] ^ inc_rp[3:1]};
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 end
00139 end
00140 end
00141
00142
00143 always @(posedge rd_clk, posedge rst) begin
00144 if (rst) begin
00145 wgrayd1 <= 4'h0;
00146 wgrayd2 <= 4'h0;
00147 end else begin
00148 wgrayd1 <= wgray;
00149 wgrayd2 <= wgrayd1;
00150 end
00151 end
00152
00153
00154 always @* begin : WRITE_GRAY2BINARY
00155 integer j;
00156
00157 for(j=3; j>=0; j=j-1) begin
00158 if (j==3)
00159 wrbinary[j] <= wgrayd2[j];
00160 else
00161 wrbinary[j] <= wgrayd2[j] ^ wrbinary[j+1];
00162 end
00163 end
00164
00165
00166 assign empty = (wrbinary == rp) ? 1'b1 : 1'b0;
00167 assign almost_empty = (wrbinary-4'h1==rp) ? 1'b1 : 1'b0;
00168 endmodule
00169
00170