00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 `default_nettype none
00011 `timescale 1ns / 1ps
00012
00013 module addr_fifo(clk, reset, din, read_write, wr_en, rd_en, dout, rw_out, full, empty, next_dout, next_rw_out, almost_empty, almost_full);
00014 `include "./ddr2_cont_parameters.vh"
00015
00016 input clk, reset;
00017 input [USER_INPUT_ADDRESS_WIDTH-1:0] din;
00018 input read_write;
00019 input wr_en, rd_en;
00020 output [USER_INPUT_ADDRESS_WIDTH-1:0] dout;
00021 output rw_out;
00022 output full, empty;
00023 output [USER_INPUT_ADDRESS_WIDTH-1:0] next_dout;
00024 output next_rw_out, almost_empty, almost_full;
00025
00026 wire clk, reset;
00027 wire [USER_INPUT_ADDRESS_WIDTH-1:0] din;
00028 wire read_write;
00029 wire wr_en, rd_en;
00030
00031 wire [USER_INPUT_ADDRESS_WIDTH-1:0] dout;
00032 wire rw_out;
00033 wire full;
00034 wire empty;
00035 wire [USER_INPUT_ADDRESS_WIDTH-1:0] next_dout;
00036 wire next_rw_out, almost_empty, almost_full;
00037
00038 wire we;
00039 reg [3:0] wp, rp;
00040 reg [USER_INPUT_ADDRESS_WIDTH-1:0] outff1, outff2;
00041 wire [USER_INPUT_ADDRESS_WIDTH-1:0] out_sig;
00042 wire fifo_full;
00043 wire fifo_empty;
00044 reg rwff1, rwff2;
00045 wire out_rw;
00046 wire inner_rd_en;
00047 reg outff1_flag, outff2_flag;
00048 wire wr_en_node;
00049
00050 assign
00051
00052 #1
00053
00054 wr_en_node =wr_en;
00055
00056 generate
00057 genvar i;
00058 for (i=USER_INPUT_ADDRESS_WIDTH-1; i>=0; i=i-1) begin: ADDR_RAM
00059 RAM16X1D #(
00060 .INIT(16'h0000) // Initial contents of RAM
00061 ) RAM16_INST (
00062 .DPO(out_sig[i]),
00063 .SPO(),
00064 .A0(wp[0]),
00065 .A1(wp[1]),
00066 .A2(wp[2]),
00067 .A3(wp[3]),
00068 .D(din[i]),
00069 .DPRA0(rp[0]),
00070 .DPRA1(rp[1]),
00071 .DPRA2(rp[2]),
00072 .DPRA3(rp[3]),
00073 .WCLK(clk),
00074 .WE(we)
00075 );
00076 end
00077 endgenerate
00078 assign we = wr_en_node & ~fifo_full;
00079
00080 RAM16X1D #(
00081 .INIT(16'h0000)
00082 ) Inst_FIFO_WR (
00083 .DPO(out_rw),
00084 .SPO(),
00085 .A0(wp[0]),
00086 .A1(wp[1]),
00087 .A2(wp[2]),
00088 .A3(wp[3]),
00089 .D(read_write),
00090 .DPRA0(rp[0]),
00091 .DPRA1(rp[1]),
00092 .DPRA2(rp[2]),
00093 .DPRA3(rp[3]),
00094 .WCLK(clk),
00095 .WE(we)
00096 );
00097
00098 always @(posedge reset, posedge clk) begin
00099 if (reset==1'b1)
00100 wp <= 0;
00101 else if (wr_en_node==1'b1 && fifo_full==1'b0) // wr_enが1で、FIFOがフルでないときに書き込む
00102 wp <= wp + 4'h1;
00103 end
00104 always @(posedge reset, posedge clk) begin
00105 if (reset==1'b1)
00106 rp <= 0;
00107 else if (inner_rd_en==1'b1 && fifo_empty==1'b0) // rd_enが1で、FIFOがemptyでない時に読み出す
00108 rp <= rp + 4'h1;
00109 end
00110
00111 assign fifo_full = (rp-4'h1==wp) ? 1'b1: 1'b0;
00112 assign full = fifo_full;
00113 assign almost_full = (rp-4'h2==wp) ? 1'b1: 1'b0;
00114 assign fifo_empty = (rp==wp) ? 1'b1: 1'b0;
00115
00116 always @(posedge reset, posedge clk) begin
00117 if (reset==1'b1) begin
00118 outff1 <= 0;
00119 rwff1 <= 1'b0;
00120 end else if (fifo_empty==1'b0 && (~(rd_en==1'b0 && outff1_flag==1'b1 && outff2_flag==1'b1))) begin
00121
00122 outff1 <= out_sig;
00123 rwff1 <= out_rw;
00124 end
00125 end
00126
00127 assign inner_rd_en = (fifo_empty==1'b0 && (~(rd_en==1'b0 && outff1_flag==1'b1 && outff2_flag==1'b1))) ? 1'b1 : 1'b0;
00128
00129 always @(posedge reset, posedge clk) begin
00130 if (reset==1'b1) begin
00131 outff2 <= 0;
00132 rwff2 <= 1'b0;
00133 end else if (outff1_flag==1'b1 && (outff2_flag==1'b0 || (outff2_flag==1'b1 && rd_en==1'b1))) begin
00134
00135 outff2 <= outff1;
00136 rwff2 <= rwff1;
00137 end
00138 end
00139
00140 always @(posedge reset, posedge clk) begin
00141 if (reset==1'b1)
00142 outff1_flag <= 1'b0;
00143 else if (inner_rd_en == 1'b1)
00144 outff1_flag <= 1'b1;
00145 else if (outff2_flag==1'b0 || rd_en==1'b1)
00146 outff1_flag <= 1'b0;
00147 end
00148
00149 always @(posedge reset, posedge clk) begin
00150 if (reset==1'b1)
00151 outff2_flag <= 1'b0;
00152 else if (outff1_flag==1'b1 && (outff2_flag==1'b0 || (outff2_flag==1'b1 && rd_en==1'b1)))
00153
00154 outff2_flag <= 1'b1;
00155 else if (outff1_flag==1'b0 && rd_en==1'b1)
00156 outff2_flag <= 1'b0;
00157 end
00158
00159 assign empty = ~outff2_flag;
00160 assign almost_empty = (outff2_flag==1'b0 || (outff2_flag==1'b1 && outff1_flag==1'b0)) ? 1'b1 : 1'b0;
00161 assign next_dout = outff1;
00162 assign dout = outff2;
00163 assign next_rw_out = rwff1;
00164 assign rw_out = rwff2;
00165
00166
00167
00168 always @ (posedge clk) begin
00169 if (reset)
00170 ;
00171 else
00172 if (rd_en && empty) begin
00173 $display("%m: at time %t ERROR : FIFOが空なのにリードした",$time);
00174 $stop;
00175 end
00176 if (wr_en && full) begin
00177 $display("%m: at time %t ERROR : FIFOがフルなのにライトした",$time);
00178 $stop;
00179 end
00180 end
00181
00182
00183 endmodule