00001
00002
00003
00004
00005
00006
00007 `default_nettype none
00008 `timescale 1ns / 1ps
00009
00010 module wrdata_fifo (clk, reset, din, maskin, rd_en, wr_en, full, almost_full, empty, almost_empty, dout, maskout);
00011 `include "./ddr2_cont_parameters.vh"
00012
00013 input clk;
00014 input reset;
00015 input [INTERFACE_DATA_WIDTH-1 : 0] din;
00016 input [INTERFACE_MASK_WIDTH-1 : 0] maskin;
00017 input rd_en;
00018 input wr_en;
00019 output full;
00020 output almost_full;
00021 output empty;
00022 output almost_empty;
00023 output [INTERFACE_DATA_WIDTH-1 : 0] dout;
00024 output [INTERFACE_MASK_WIDTH-1 : 0] maskout;
00025
00026 wire clk;
00027 wire reset;
00028 wire [INTERFACE_DATA_WIDTH-1 : 0] din;
00029 wire [INTERFACE_MASK_WIDTH-1 : 0] maskin;
00030 wire rd_en;
00031 wire wr_en;
00032 wire full;
00033 wire almost_full;
00034 wire empty;
00035 wire almost_empty;
00036 wire [INTERFACE_DATA_WIDTH-1 : 0] dout;
00037 wire [INTERFACE_MASK_WIDTH-1 : 0] maskout;
00038
00039 reg [3:0] wp, rp;
00040 wire [INTERFACE_DATA_WIDTH-1 : 0] data_node;
00041 reg [INTERFACE_DATA_WIDTH-1 : 0] out_data;
00042 wire [INTERFACE_MASK_WIDTH-1 : 0] mask_node;
00043 reg [INTERFACE_MASK_WIDTH-1 : 0] out_mask;
00044 reg outff_flag;
00045 wire fifo_full, fifo_empty;
00046 wire inner_rd_en;
00047 wire we ;
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=INTERFACE_DATA_WIDTH-1; i>=0; i=i-1) begin: WRDATA_RAM
00059 RAM16X1D #(
00060 .INIT(16'h0000) // Initial contents of RAM
00061 ) RAM16_DATA (
00062 .DPO(data_node[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
00079 generate
00080 genvar j;
00081 for (j=INTERFACE_MASK_WIDTH-1; j>=0; j=j-1) begin: WRMASK_RAM
00082 RAM16X1D #(
00083 .INIT(16'h0000)
00084 ) RAM16_MASK (
00085 .DPO(mask_node[j]),
00086 .SPO(),
00087 .A0(wp[0]),
00088 .A1(wp[1]),
00089 .A2(wp[2]),
00090 .A3(wp[3]),
00091 .D(maskin[j]),
00092 .DPRA0(rp[0]),
00093 .DPRA1(rp[1]),
00094 .DPRA2(rp[2]),
00095 .DPRA3(rp[3]),
00096 .WCLK(clk),
00097 .WE(we)
00098 );
00099 end
00100 endgenerate
00101 assign we = wr_en_node && (~fifo_full);
00102
00103 always @(posedge clk, posedge reset) begin
00104 if (reset==1'b1) begin
00105 wp <= 0;
00106 rp <= 0;
00107 end else begin
00108 if (wr_en_node==1'b1 && fifo_full==1'b0) // wr_enが1で、FIFOがフルでないときに書き込む
00109 wp <= wp + 4'h1;
00110 if (inner_rd_en==1'b1 && fifo_empty==1'b0)
00111 rp <= rp + 4'h1;
00112 end
00113 end
00114 assign fifo_full = (rp-4'h1==wp) ? 1'b1 : 1'b0;
00115 assign full = fifo_full;
00116 assign almost_full = (rp-4'h2==wp) ? 1'b1 : 1'b0;
00117 assign fifo_empty = (rp==wp) ? 1'b1 : 1'b0; // rp = wpの時にAFIFOは空
00118
00119 always @(posedge clk, posedge reset) begin // out_data
00120 if (reset==1'b1) begin
00121 out_data <= 0;
00122 out_mask <= 0;
00123 end else if (fifo_empty==1'b0 && ~(rd_en==1'b0 && outff_flag==1'b1)) begin
00124 // FIFOが空でないか、もしくはoutffが1で読み出しもなかった時以外はoutffにFIFOの内容を読み出し
00125 out_data <= data_node;
00126 out_mask <= mask_node;
00127 end
00128 end
00129 assign inner_rd_en = (fifo_empty==1'b0 && ~(rd_en==1'b0 && outff_flag==1'b1)) ? 1'b1 : 1'b0;
00130
00131 always @(posedge clk, posedge reset) begin
00132 if (reset==1'b1)
00133 outff_flag <= 1'b0;
00134 else if (inner_rd_en==1'b1)
00135 outff_flag <= 1'b1;
00136 else if (rd_en==1'b1)
00137 outff_flag <= 1'b0;
00138 end
00139 assign dout = out_data;
00140 assign maskout = out_mask;
00141 assign empty = ~outff_flag;
00142 assign almost_empty = (outff_flag==1'b0 || (outff_flag==1'b1 && fifo_empty==1'b1)) ? 1'b1 : 1'b0;
00143 // アサーション
00144 // synthesis translate_off
00145 always @ (posedge clk) begin
00146 if (reset)
00147 ;
00148 else
00149 if (rd_en && empty) begin
00150 $display("%m: at time %t ERROR : FIFOが空なのにリードした",$time);
00151 $stop;
00152 end
00153 if (wr_en && full) begin
00154 $display("%m: at time %t ERROR : FIFOがフルなのにライトした",$time);
00155 $stop;
00156 end
00157 end
00158 // synthesis translate_on
00159 endmodule
00160 `default_nettype wire //追加