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.2 2007-02-11 22:21:28 michael Exp $
43 // $Date: 2007-02-11 22:21:28 $
50 // $Log: generic_fifo_sc_a.v,v $
51 // Revision 1.2 2007-02-11 22:21:28 michael
54 // Revision 1.1 2007/02/11 21:58:30 sithglan
57 // Revision 1.1.1.1 2002/09/25 05:42:06 rudi
71 `include "timescale.v"
80 rst low active, either sync. or async. master reset (see below how to select)
81 clr synchronous clear (just like reset but always synchronous), high active
82 re read enable, synchronous, high active
83 we read enable, synchronous, high active
87 full Indicates the FIFO is full (combinatorial output)
88 full_r same as above, but registered output (see note below)
89 empty Indicates the FIFO is empty
90 empty_r same as above, but registered output (see note below)
92 full_n Indicates if the FIFO has space for N entries (combinatorial output)
93 full_n_r same as above, but registered output (see note below)
94 empty_n Indicates the FIFO has at least N entries (combinatorial output)
95 empty_n_r same as above, but registered output (see note below)
97 level indicates the FIFO level:
103 combinatorial vs. registered status outputs
104 -------------------------------------------
105 Both the combinatorial and registered status outputs have exactly the same
106 synchronous timing. Meaning they are being asserted immediately at the clock
107 edge after the last read or write. The combinatorial outputs however, pass
108 through several levels of logic before they are output. The registered status
109 outputs are direct outputs of a flip-flop. The reason both are provided, is
110 that the registered outputs require quite a bit of additional logic inside
111 the FIFO. If you can meet timing of your device with the combinatorial
112 outputs, use them ! The FIFO will be smaller. If the status signals are
113 in the critical pass, use the registered outputs, they have a much smaller
114 output delay (actually only Tcq).
118 The FIFO takes 3 parameters:
120 aw Address bus width (Determines the FIFO size by evaluating 2^aw)
121 n N is a second status threshold constant for full_n and empty_n
122 If you have no need for the second status threshold, do not
123 connect the outputs and the logic should be removed by your
128 In a Spartan 2e a 8 bit wide, 8 entries deep FIFO, takes 85 LUTs and runs
129 at about 116 MHz (IO insertion disabled). The registered status outputs
130 are valid after 2.1NS, the combinatorial once take out to 6.5 NS to be
136 This design assumes you will do appropriate status checking externally.
138 IMPORTANT ! writing while the FIFO is full or reading while the FIFO is
139 empty will place the FIFO in an undefined state.
144 // Selecting Sync. or Async Reset
145 // ------------------------------
146 // Uncomment one of the two lines below. The first line for
147 // synchronous reset, the second for asynchronous reset
149 `define SC_FIFO_ASYNC_RESET // Uncomment for Syncr. reset
150 //`define SC_FIFO_ASYNC_RESET or negedge rst // Uncomment for Async. reset
153 module generic_fifo_sc_a(clk, rst, clr, din, we, dout, re,
154 full, empty, full_r, empty_r,
155 full_n, empty_n, full_n_r, empty_n_r,
161 parameter max_size = 1<<aw;
166 output [dw-1:0] dout;
169 output empty, empty_r;
170 output full_n, full_n_r;
171 output empty_n, empty_n_r;
174 ////////////////////////////////////////////////////////////////////
180 wire [aw-1:0] wp_pl1;
181 wire [aw-1:0] wp_pl2;
183 wire [aw-1:0] rp_pl1;
189 wire full_n, empty_n;
190 reg full_n_r, empty_n_r;
192 ////////////////////////////////////////////////////////////////////
197 generic_dpram #(aw,dw) u0(
212 ////////////////////////////////////////////////////////////////////
217 always @(posedge clk `SC_FIFO_ASYNC_RESET)
218 if(!rst) wp <= #1 {aw{1'b0}};
220 if(clr) wp <= #1 {aw{1'b0}};
222 if(we) wp <= #1 wp_pl1;
224 assign wp_pl1 = wp + { {aw-1{1'b0}}, 1'b1};
225 assign wp_pl2 = wp + { {aw-2{1'b0}}, 2'b10};
227 always @(posedge clk `SC_FIFO_ASYNC_RESET)
228 if(!rst) rp <= #1 {aw{1'b0}};
230 if(clr) rp <= #1 {aw{1'b0}};
232 if(re) rp <= #1 rp_pl1;
234 assign rp_pl1 = rp + { {aw-1{1'b0}}, 1'b1};
236 ////////////////////////////////////////////////////////////////////
238 // Combinatorial Full & Empty Flags
241 assign empty = ((wp == rp) & !gb);
242 assign full = ((wp == rp) & gb);
245 always @(posedge clk `SC_FIFO_ASYNC_RESET)
246 if(!rst) gb <= #1 1'b0;
248 if(clr) gb <= #1 1'b0;
250 if((wp_pl1 == rp) & we) gb <= #1 1'b1;
252 if(re) gb <= #1 1'b0;
254 ////////////////////////////////////////////////////////////////////
256 // Registered Full & Empty Flags
260 always @(posedge clk `SC_FIFO_ASYNC_RESET)
261 if(!rst) gb2 <= #1 1'b0;
263 if(clr) gb2 <= #1 1'b0;
265 if((wp_pl2 == rp) & we) gb2 <= #1 1'b1;
267 if((wp != rp) & re) gb2 <= #1 1'b0;
269 always @(posedge clk `SC_FIFO_ASYNC_RESET)
270 if(!rst) full_r <= #1 1'b0;
272 if(clr) full_r <= #1 1'b0;
274 if(we & ((wp_pl1 == rp) & gb2) & !re) full_r <= #1 1'b1;
276 if(re & ((wp_pl1 != rp) | !gb2) & !we) full_r <= #1 1'b0;
278 always @(posedge clk `SC_FIFO_ASYNC_RESET)
279 if(!rst) empty_r <= #1 1'b1;
281 if(clr) empty_r <= #1 1'b1;
283 if(we & ((wp != rp_pl1) | gb2) & !re) empty_r <= #1 1'b0;
285 if(re & ((wp == rp_pl1) & !gb2) & !we) empty_r <= #1 1'b1;
287 ////////////////////////////////////////////////////////////////////
289 // Combinatorial Full_n & Empty_n Flags
292 assign empty_n = cnt < n;
293 assign full_n = !(cnt < (max_size-n+1));
294 assign level = {2{cnt[aw]}} | cnt[aw-1:aw-2];
297 always @(posedge clk `SC_FIFO_ASYNC_RESET)
298 if(!rst) cnt <= #1 {aw+1{1'b0}};
300 if(clr) cnt <= #1 {aw+1{1'b0}};
302 if( re & !we) cnt <= #1 cnt + { {aw{1'b1}}, 1'b1};
304 if(!re & we) cnt <= #1 cnt + { {aw{1'b0}}, 1'b1};
306 ////////////////////////////////////////////////////////////////////
308 // Registered Full_n & Empty_n Flags
311 always @(posedge clk `SC_FIFO_ASYNC_RESET)
312 if(!rst) empty_n_r <= #1 1'b1;
314 if(clr) empty_n_r <= #1 1'b1;
316 if(we & (cnt >= (n-1) ) & !re) empty_n_r <= #1 1'b0;
318 if(re & (cnt <= n ) & !we) empty_n_r <= #1 1'b1;
320 always @(posedge clk `SC_FIFO_ASYNC_RESET)
321 if(!rst) full_n_r <= #1 1'b0;
323 if(clr) full_n_r <= #1 1'b0;
325 if(we & (cnt >= (max_size-n) ) & !re) full_n_r <= #1 1'b1;
327 if(re & (cnt <= (max_size-n+1)) & !we) full_n_r <= #1 1'b0;
329 ////////////////////////////////////////////////////////////////////
334 // synopsys translate_off
335 always @(posedge clk)
337 $display("%m WARNING: Writing while fifo is FULL (%t)",$time);
339 always @(posedge clk)
341 $display("%m WARNING: Reading while fifo is EMPTY (%t)",$time);
342 // synopsys translate_on