1 /////////////////////////////////////////////////////////////////////
3 //// Universal FIFO Single Clock ////
6 //// Author: Rudolf Usselmann ////
7 //// rudi@asics.ws ////
10 //// D/L from: http://www.opencores.org/cores/generic_fifos/ ////
12 /////////////////////////////////////////////////////////////////////
14 //// Copyright (C) 2000-2002 Rudolf Usselmann ////
15 //// www.asics.ws ////
16 //// rudi@asics.ws ////
18 //// This source file may be used and distributed without ////
19 //// restriction provided that this copyright statement is not ////
20 //// removed from the file and that any derivative work contains ////
21 //// the original copyright notice and the associated disclaimer.////
23 //// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
24 //// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
25 //// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
26 //// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
27 //// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
28 //// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
29 //// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
30 //// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
31 //// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
32 //// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
33 //// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
34 //// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
35 //// POSSIBILITY OF SUCH DAMAGE. ////
37 /////////////////////////////////////////////////////////////////////
41 // $Id: generic_fifo_sc_a.v,v 1.1.1.1 2002-09-25 05:42:06 rudi Exp $
43 // $Date: 2002-09-25 05:42:06 $
44 // $Revision: 1.1.1.1 $
50 // $Log: not supported by cvs2svn $
62 `timescale 1ns / 100ps
63 `include "generic_dpram.v"
72 rst low active, either sync. or async. master reset (see below how to select)
73 clr synchronous clear (just like reset but always synchronous), high active
74 re read enable, synchronous, high active
75 we read enable, synchronous, high active
79 full Indicates the FIFO is full (combinatorial output)
80 full_r same as above, but registered output (see note below)
81 empty Indicates the FIFO is empty
82 empty_r same as above, but registered output (see note below)
84 full_n Indicates if the FIFO has space for N entries (combinatorial output)
85 full_n_r same as above, but registered output (see note below)
86 empty_n Indicates the FIFO has at least N entries (combinatorial output)
87 empty_n_r same as above, but registered output (see note below)
89 level indicates the FIFO level:
95 combinatorial vs. registered status outputs
96 -------------------------------------------
97 Both the combinatorial and registered status outputs have exactly the same
98 synchronous timing. Meaning they are being asserted immediately at the clock
99 edge after the last read or write. The combinatorial outputs however, pass
100 through several levels of logic before they are output. The registered status
101 outputs are direct outputs of a flip-flop. The reason both are provided, is
102 that the registered outputs require quite a bit of additional logic inside
103 the FIFO. If you can meet timing of your device with the combinatorial
104 outputs, use them ! The FIFO will be smaller. If the status signals are
105 in the critical pass, use the registered outputs, they have a much smaller
106 output delay (actually only Tcq).
110 The FIFO takes 3 parameters:
112 aw Address bus width (Determines the FIFO size by evaluating 2^aw)
113 n N is a second status threshold constant for full_n and empty_n
114 If you have no need for the second status threshold, do not
115 connect the outputs and the logic should be removed by your
120 In a Spartan 2e a 8 bit wide, 8 entries deep FIFO, takes 85 LUTs and runs
121 at about 116 MHz (IO insertion disabled). The registered status outputs
122 are valid after 2.1NS, the combinatorial once take out to 6.5 NS to be
128 This design assumes you will do appropriate status checking externally.
130 IMPORTANT ! writing while the FIFO is full or reading while the FIFO is
131 empty will place the FIFO in an undefined state.
136 // Selecting Sync. or Async Reset
137 // ------------------------------
138 // Uncomment one of the two lines below. The first line for
139 // synchronous reset, the second for asynchronous reset
141 `define SC_FIFO_ASYNC_RESET // Uncomment for Syncr. reset
142 //`define SC_FIFO_ASYNC_RESET or negedge rst // Uncomment for Async. reset
145 module generic_fifo_sc_a(clk, rst, clr, din, we, dout, re,
146 full, empty, full_r, empty_r,
147 full_n, empty_n, full_n_r, empty_n_r,
153 parameter max_size = 1<<aw;
158 output [dw-1:0] dout;
161 output empty, empty_r;
162 output full_n, full_n_r;
163 output empty_n, empty_n_r;
166 ////////////////////////////////////////////////////////////////////
172 wire [aw-1:0] wp_pl1;
173 wire [aw-1:0] wp_pl2;
175 wire [aw-1:0] rp_pl1;
181 wire full_n, empty_n;
182 reg full_n_r, empty_n_r;
184 ////////////////////////////////////////////////////////////////////
189 generic_dpram #(aw,dw) u0(
204 ////////////////////////////////////////////////////////////////////
209 always @(posedge clk `SC_FIFO_ASYNC_RESET)
210 if(!rst) wp <= #1 {aw{1'b0}};
212 if(clr) wp <= #1 {aw{1'b0}};
214 if(we) wp <= #1 wp_pl1;
216 assign wp_pl1 = wp + { {aw-1{1'b0}}, 1'b1};
217 assign wp_pl2 = wp + { {aw-2{1'b0}}, 2'b10};
219 always @(posedge clk `SC_FIFO_ASYNC_RESET)
220 if(!rst) rp <= #1 {aw{1'b0}};
222 if(clr) rp <= #1 {aw{1'b0}};
224 if(re) rp <= #1 rp_pl1;
226 assign rp_pl1 = rp + { {aw-1{1'b0}}, 1'b1};
228 ////////////////////////////////////////////////////////////////////
230 // Combinatorial Full & Empty Flags
233 assign empty = ((wp == rp) & !gb);
234 assign full = ((wp == rp) & gb);
237 always @(posedge clk `SC_FIFO_ASYNC_RESET)
238 if(!rst) gb <= #1 1'b0;
240 if(clr) gb <= #1 1'b0;
242 if((wp_pl1 == rp) & we) gb <= #1 1'b1;
244 if(re) gb <= #1 1'b0;
246 ////////////////////////////////////////////////////////////////////
248 // Registered Full & Empty Flags
252 always @(posedge clk `SC_FIFO_ASYNC_RESET)
253 if(!rst) gb2 <= #1 1'b0;
255 if(clr) gb2 <= #1 1'b0;
257 if((wp_pl2 == rp) & we) gb2 <= #1 1'b1;
259 if((wp != rp) & re) gb2 <= #1 1'b0;
261 always @(posedge clk `SC_FIFO_ASYNC_RESET)
262 if(!rst) full_r <= #1 1'b0;
264 if(clr) full_r <= #1 1'b0;
266 if(we & ((wp_pl1 == rp) & gb2) & !re) full_r <= #1 1'b1;
268 if(re & ((wp_pl1 != rp) | !gb2) & !we) full_r <= #1 1'b0;
270 always @(posedge clk `SC_FIFO_ASYNC_RESET)
271 if(!rst) empty_r <= #1 1'b1;
273 if(clr) empty_r <= #1 1'b1;
275 if(we & ((wp != rp_pl1) | gb2) & !re) empty_r <= #1 1'b0;
277 if(re & ((wp == rp_pl1) & !gb2) & !we) empty_r <= #1 1'b1;
279 ////////////////////////////////////////////////////////////////////
281 // Combinatorial Full_n & Empty_n Flags
284 assign empty_n = cnt < n;
285 assign full_n = !(cnt < (max_size-n+1));
286 assign level = {2{cnt[aw]}} | cnt[aw-1:aw-2];
289 always @(posedge clk `SC_FIFO_ASYNC_RESET)
290 if(!rst) cnt <= #1 {aw+1{1'b0}};
292 if(clr) cnt <= #1 {aw+1{1'b0}};
294 if( re & !we) cnt <= #1 cnt + { {aw{1'b1}}, 1'b1};
296 if(!re & we) cnt <= #1 cnt + { {aw{1'b0}}, 1'b1};
298 ////////////////////////////////////////////////////////////////////
300 // Registered Full_n & Empty_n Flags
303 always @(posedge clk `SC_FIFO_ASYNC_RESET)
304 if(!rst) empty_n_r <= #1 1'b1;
306 if(clr) empty_n_r <= #1 1'b1;
308 if(we & (cnt >= (n-1) ) & !re) empty_n_r <= #1 1'b0;
310 if(re & (cnt <= n ) & !we) empty_n_r <= #1 1'b1;
312 always @(posedge clk `SC_FIFO_ASYNC_RESET)
313 if(!rst) full_n_r <= #1 1'b0;
315 if(clr) full_n_r <= #1 1'b0;
317 if(we & (cnt >= (max_size-n) ) & !re) full_n_r <= #1 1'b1;
319 if(re & (cnt <= (max_size-n+1)) & !we) full_n_r <= #1 1'b0;
321 ////////////////////////////////////////////////////////////////////
326 // synopsys translate_off
327 always @(posedge clk)
329 $display("%m WARNING: Writing while fifo is FULL (%t)",$time);
331 always @(posedge clk)
333 $display("%m WARNING: Reading while fifo is EMPTY (%t)",$time);
334 // synopsys translate_on