Add diagrams and pictures
[clump.git] / generic_fifo_sc_a.v
CommitLineData
a051754e
MG
1/////////////////////////////////////////////////////////////////////
2//// ////
3//// Universal FIFO Single Clock ////
4//// ////
5//// ////
6//// Author: Rudolf Usselmann ////
7//// rudi@asics.ws ////
8//// ////
9//// ////
10//// D/L from: http://www.opencores.org/cores/generic_fifos/ ////
11//// ////
12/////////////////////////////////////////////////////////////////////
13//// ////
14//// Copyright (C) 2000-2002 Rudolf Usselmann ////
15//// www.asics.ws ////
16//// rudi@asics.ws ////
17//// ////
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.////
22//// ////
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. ////
36//// ////
37/////////////////////////////////////////////////////////////////////
38
39// CVS Log
40//
41// $Id: generic_fifo_sc_a.v,v 1.1.1.1 2002-09-25 05:42:06 rudi Exp $
42//
43// $Date: 2002-09-25 05:42:06 $
44// $Revision: 1.1.1.1 $
45// $Author: rudi $
46// $Locker: $
47// $State: Exp $
48//
49// Change History:
50// $Log: not supported by cvs2svn $
51//
52//
53//
54//
55//
56//
57//
58//
59//
60//
61
62`timescale 1ns / 100ps
63`include "generic_dpram.v"
64
65/*
66
67Description
68===========
69
70I/Os
71----
72rst low active, either sync. or async. master reset (see below how to select)
73clr synchronous clear (just like reset but always synchronous), high active
74re read enable, synchronous, high active
75we read enable, synchronous, high active
76din Data Input
77dout Data Output
78
79full Indicates the FIFO is full (combinatorial output)
80full_r same as above, but registered output (see note below)
81empty Indicates the FIFO is empty
82empty_r same as above, but registered output (see note below)
83
84full_n Indicates if the FIFO has space for N entries (combinatorial output)
85full_n_r same as above, but registered output (see note below)
86empty_n Indicates the FIFO has at least N entries (combinatorial output)
87empty_n_r same as above, but registered output (see note below)
88
89level indicates the FIFO level:
90 2'b00 0-25% full
91 2'b01 25-50% full
92 2'b10 50-75% full
93 2'b11 %75-100% full
94
95combinatorial vs. registered status outputs
96-------------------------------------------
97Both the combinatorial and registered status outputs have exactly the same
98synchronous timing. Meaning they are being asserted immediately at the clock
99edge after the last read or write. The combinatorial outputs however, pass
100through several levels of logic before they are output. The registered status
101outputs are direct outputs of a flip-flop. The reason both are provided, is
102that the registered outputs require quite a bit of additional logic inside
103the FIFO. If you can meet timing of your device with the combinatorial
104outputs, use them ! The FIFO will be smaller. If the status signals are
105in the critical pass, use the registered outputs, they have a much smaller
106output delay (actually only Tcq).
107
108Parameters
109----------
110The FIFO takes 3 parameters:
111dw Data bus width
112aw Address bus width (Determines the FIFO size by evaluating 2^aw)
113n 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
116 synthesis tool.
117
118Synthesis Results
119-----------------
120In a Spartan 2e a 8 bit wide, 8 entries deep FIFO, takes 85 LUTs and runs
121at about 116 MHz (IO insertion disabled). The registered status outputs
122are valid after 2.1NS, the combinatorial once take out to 6.5 NS to be
123available.
124
125
126Misc
127----
128This design assumes you will do appropriate status checking externally.
129
130IMPORTANT ! writing while the FIFO is full or reading while the FIFO is
131empty will place the FIFO in an undefined state.
132
133*/
134
135
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
140
141`define SC_FIFO_ASYNC_RESET // Uncomment for Syncr. reset
142//`define SC_FIFO_ASYNC_RESET or negedge rst // Uncomment for Async. reset
143
144
145module 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,
148 level);
149
150parameter dw=8;
151parameter aw=8;
152parameter n=32;
153parameter max_size = 1<<aw;
154
155input clk, rst, clr;
156input [dw-1:0] din;
157input we;
158output [dw-1:0] dout;
159input re;
160output full, full_r;
161output empty, empty_r;
162output full_n, full_n_r;
163output empty_n, empty_n_r;
164output [1:0] level;
165
166////////////////////////////////////////////////////////////////////
167//
168// Local Wires
169//
170
171reg [aw-1:0] wp;
172wire [aw-1:0] wp_pl1;
173wire [aw-1:0] wp_pl2;
174reg [aw-1:0] rp;
175wire [aw-1:0] rp_pl1;
176reg full_r;
177reg empty_r;
178reg gb;
179reg gb2;
180reg [aw:0] cnt;
181wire full_n, empty_n;
182reg full_n_r, empty_n_r;
183
184////////////////////////////////////////////////////////////////////
185//
186// Memory Block
187//
188
189generic_dpram #(aw,dw) u0(
190 .rclk( clk ),
191 .rrst( !rst ),
192 .rce( 1'b1 ),
193 .oe( 1'b1 ),
194 .raddr( rp ),
195 .do( dout ),
196 .wclk( clk ),
197 .wrst( !rst ),
198 .wce( 1'b1 ),
199 .we( we ),
200 .waddr( wp ),
201 .di( din )
202 );
203
204////////////////////////////////////////////////////////////////////
205//
206// Misc Logic
207//
208
209always @(posedge clk `SC_FIFO_ASYNC_RESET)
210 if(!rst) wp <= #1 {aw{1'b0}};
211 else
212 if(clr) wp <= #1 {aw{1'b0}};
213 else
214 if(we) wp <= #1 wp_pl1;
215
216assign wp_pl1 = wp + { {aw-1{1'b0}}, 1'b1};
217assign wp_pl2 = wp + { {aw-2{1'b0}}, 2'b10};
218
219always @(posedge clk `SC_FIFO_ASYNC_RESET)
220 if(!rst) rp <= #1 {aw{1'b0}};
221 else
222 if(clr) rp <= #1 {aw{1'b0}};
223 else
224 if(re) rp <= #1 rp_pl1;
225
226assign rp_pl1 = rp + { {aw-1{1'b0}}, 1'b1};
227
228////////////////////////////////////////////////////////////////////
229//
230// Combinatorial Full & Empty Flags
231//
232
233assign empty = ((wp == rp) & !gb);
234assign full = ((wp == rp) & gb);
235
236// Guard Bit ...
237always @(posedge clk `SC_FIFO_ASYNC_RESET)
238 if(!rst) gb <= #1 1'b0;
239 else
240 if(clr) gb <= #1 1'b0;
241 else
242 if((wp_pl1 == rp) & we) gb <= #1 1'b1;
243 else
244 if(re) gb <= #1 1'b0;
245
246////////////////////////////////////////////////////////////////////
247//
248// Registered Full & Empty Flags
249//
250
251// Guard Bit ...
252always @(posedge clk `SC_FIFO_ASYNC_RESET)
253 if(!rst) gb2 <= #1 1'b0;
254 else
255 if(clr) gb2 <= #1 1'b0;
256 else
257 if((wp_pl2 == rp) & we) gb2 <= #1 1'b1;
258 else
259 if((wp != rp) & re) gb2 <= #1 1'b0;
260
261always @(posedge clk `SC_FIFO_ASYNC_RESET)
262 if(!rst) full_r <= #1 1'b0;
263 else
264 if(clr) full_r <= #1 1'b0;
265 else
266 if(we & ((wp_pl1 == rp) & gb2) & !re) full_r <= #1 1'b1;
267 else
268 if(re & ((wp_pl1 != rp) | !gb2) & !we) full_r <= #1 1'b0;
269
270always @(posedge clk `SC_FIFO_ASYNC_RESET)
271 if(!rst) empty_r <= #1 1'b1;
272 else
273 if(clr) empty_r <= #1 1'b1;
274 else
275 if(we & ((wp != rp_pl1) | gb2) & !re) empty_r <= #1 1'b0;
276 else
277 if(re & ((wp == rp_pl1) & !gb2) & !we) empty_r <= #1 1'b1;
278
279////////////////////////////////////////////////////////////////////
280//
281// Combinatorial Full_n & Empty_n Flags
282//
283
284assign empty_n = cnt < n;
285assign full_n = !(cnt < (max_size-n+1));
286assign level = {2{cnt[aw]}} | cnt[aw-1:aw-2];
287
288// N entries status
289always @(posedge clk `SC_FIFO_ASYNC_RESET)
290 if(!rst) cnt <= #1 {aw+1{1'b0}};
291 else
292 if(clr) cnt <= #1 {aw+1{1'b0}};
293 else
294 if( re & !we) cnt <= #1 cnt + { {aw{1'b1}}, 1'b1};
295 else
296 if(!re & we) cnt <= #1 cnt + { {aw{1'b0}}, 1'b1};
297
298////////////////////////////////////////////////////////////////////
299//
300// Registered Full_n & Empty_n Flags
301//
302
303always @(posedge clk `SC_FIFO_ASYNC_RESET)
304 if(!rst) empty_n_r <= #1 1'b1;
305 else
306 if(clr) empty_n_r <= #1 1'b1;
307 else
308 if(we & (cnt >= (n-1) ) & !re) empty_n_r <= #1 1'b0;
309 else
310 if(re & (cnt <= n ) & !we) empty_n_r <= #1 1'b1;
311
312always @(posedge clk `SC_FIFO_ASYNC_RESET)
313 if(!rst) full_n_r <= #1 1'b0;
314 else
315 if(clr) full_n_r <= #1 1'b0;
316 else
317 if(we & (cnt >= (max_size-n) ) & !re) full_n_r <= #1 1'b1;
318 else
319 if(re & (cnt <= (max_size-n+1)) & !we) full_n_r <= #1 1'b0;
320
321////////////////////////////////////////////////////////////////////
322//
323// Sanity Check
324//
325
326// synopsys translate_off
327always @(posedge clk)
328 if(we & full)
329 $display("%m WARNING: Writing while fifo is FULL (%t)",$time);
330
331always @(posedge clk)
332 if(re & empty)
333 $display("%m WARNING: Reading while fifo is EMPTY (%t)",$time);
334// synopsys translate_on
335endmodule
This page took 0.026991 seconds and 4 git commands to generate.