OpenCores
URL https://opencores.org/ocsvn/generic_fifos/generic_fifos/trunk

Subversion Repositories generic_fifos

[/] [generic_fifos/] [trunk/] [rtl/] [verilog/] [generic_fifo_sc_a.v] - Blame information for rev 7

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.