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

Subversion Repositories mod_sim_exp

[/] [mod_sim_exp/] [trunk/] [rtl/] [verilog/] [generic_fifo_dc.v] - Blame information for rev 98

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 94 JonasDC
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3
////  Universal FIFO Dual 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
//// Some minor modifactions are done by Jonas De Craene, JonasDC@opencores.org
40
//// in this version. The FIFO output is now registered and push and pop
41
//// only works if not full or empty.
42
//// The rst signal is removed, now clr is the only reset.
43
//// nopush and nopop signal are added to indicate if a push or pop operation 
44
//// is not executed.
45
//// and the memory used in the FIFO is now the same from the mod_sim_exp 
46
//// opencores project
47
 
48
//  CVS Log
49
//
50
//  $Id: generic_fifo_dc.v,v 1.1.1.1 2002-09-25 05:42:02 rudi Exp $
51
//
52
//  $Date: 2002-09-25 05:42:02 $
53
//  $Revision: 1.1.1.1 $
54
//  $Author: rudi $
55
//  $Locker:  $
56
//  $State: Exp $
57
//
58
// Change History:
59
//               $Log: not supported by cvs2svn $
60
//
61
//
62
//
63
//
64
//
65
//
66
//
67
//
68
//
69
//
70
 
71
//`include "timescale.v"
72
 
73
/*
74
 
75
Description
76
===========
77
 
78
I/Os
79
----
80
rd_clk  Read Port Clock
81
wr_clk  Write Port Clock
82
rst     low active, either sync. or async. master reset (see below how to select)
83
clr     synchronous clear (just like reset but always synchronous), high active
84
re      read enable, synchronous, high active
85
we      read enable, synchronous, high active
86
din     Data Input
87
dout    Data Output
88
 
89
full    Indicates the FIFO is full (driven at the rising edge of wr_clk)
90
empty   Indicates the FIFO is empty (driven at the rising edge of rd_clk)
91
 
92
full_n  Indicates if the FIFO has space for N entries (driven of wr_clk)
93
empty_n Indicates the FIFO has at least N entries (driven of rd_clk)
94
 
95
level           indicates the FIFO level:
96
                2'b00   0-25%    full
97
                2'b01   25-50%   full
98
                2'b10   50-75%   full
99
                2'b11   %75-100% full
100
 
101
Status Timing
102
-------------
103
All status outputs are registered. They are asserted immediately
104
as the full/empty condition occurs, however, there is a 2 cycle
105
delay before they are de-asserted once the condition is not true
106
anymore.
107
 
108
Parameters
109
----------
110
The FIFO takes 3 parameters:
111
dw      Data bus width
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
116
        synthesis tool.
117
 
118
Synthesis Results
119
-----------------
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
123
available.
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
module generic_fifo_dc(rd_clk, wr_clk, clr, din, we, dout, re,
135
                        full, empty, full_n, empty_n, level, nopop, nopush );
136
 
137
parameter dw=32;
138
parameter aw=7;
139
parameter n=32;
140
parameter max_size = 1<<aw;
141
 
142
input                   rd_clk, wr_clk, clr;
143
input   [dw-1:0] din;
144
input                   we;
145
output  [dw-1:0] dout;
146
input                   re;
147
output                  full;
148
output                  empty;
149
output                  full_n;
150
output                  empty_n;
151
output  [1:0]            level;
152
output        nopop;
153
output        nopush;
154
 
155
////////////////////////////////////////////////////////////////////
156
//
157
// Local Wires
158
//
159
 
160
reg     [aw:0]           wp;
161
wire    [aw:0]           wp_pl1;
162
reg     [aw:0]           rp;
163
wire    [aw:0]           rp_pl1;
164
reg     [aw:0]           wp_s, rp_s;
165
wire    [aw:0]           diff;
166
reg     [aw:0]           diff_r1, diff_r2;
167
reg                     re_r, we_r;
168
reg                     full, empty, full_n, empty_n;
169
reg     [1:0]            level;
170
wire [dw-1:0]    dout_ram;
171
reg [dw-1:0]    dout;
172
reg       nopop, nopush;
173
 
174
////////////////////////////////////////////////////////////////////
175
//
176
// Memory Block
177
//
178
 
179
dpram_generic #(2**aw) u0(
180
  .clkA(wr_clk),
181
  .waddrA(wp[aw-1:0]),
182
  .weA(we & !full),
183
  .dinA(din),
184
  .clkB(rd_clk),
185
  .raddrB(rp[aw-1:0]),
186
  .doutB(dout_ram)
187
);
188
 
189
always @(posedge rd_clk)
190
    if(re & !empty)     dout <= #1 dout_ram;
191
 
192
//generic_dpram  #(aw, dw)u0(
193
//  .rclk(rd_clk),
194
//  .rrst( !rst),
195
//  .rce(1'b1),
196
//  .oe(1'b1),
197
//  .raddr(rp[aw-1:0]),
198
//  .do(dout),
199
//  .wclk(wr_clk),
200
//  .wrst( !rst),
201
//  .wce(1'b1),
202
//  .we(we),
203
//  .waddr(wp[aw-1:0]),
204
//  .di(din)
205
//  );
206
 
207
////////////////////////////////////////////////////////////////////
208
//
209
// Read/Write Pointers Logic
210
//
211
 
212
always @(posedge wr_clk)
213
        if(clr)         wp <= #1 {aw+1{1'b0}};
214
        else
215
        if(we & !full)          wp <= #1 wp_pl1;
216
 
217
assign wp_pl1 = wp + { {aw{1'b0}}, 1'b1};
218
 
219
always @(posedge rd_clk)
220
        if(clr)         rp <= #1 {aw+1{1'b0}};
221
        else
222
        if(re & !empty)         rp <= #1 rp_pl1;
223
 
224
assign rp_pl1 = rp + { {aw{1'b0}}, 1'b1};
225
 
226
////////////////////////////////////////////////////////////////////
227
//
228
// Synchronization Logic
229
//
230
 
231
// write pointer
232
always @(posedge rd_clk)        wp_s <= #1 wp;
233
 
234
// read pointer
235
always @(posedge wr_clk)        rp_s <= #1 rp;
236
 
237
////////////////////////////////////////////////////////////////////
238
//
239
// Registered Full & Empty Flags
240
//
241
 
242
always @(posedge rd_clk)
243
        empty <= #1 (wp_s == rp) | (re & (wp_s == rp_pl1));
244
 
245
always @(posedge wr_clk)
246
        full <= #1 ((wp[aw-1:0] == rp_s[aw-1:0]) & (wp[aw] != rp_s[aw])) |
247
        (we & (wp_pl1[aw-1:0] == rp_s[aw-1:0]) & (wp_pl1[aw] != rp_s[aw]));
248
 
249
////////////////////////////////////////////////////////////////////
250
//
251
// Registered Full_n & Empty_n Flags
252
//
253
 
254
assign diff = wp-rp;
255
 
256
always @(posedge rd_clk)
257
        re_r <= #1 re;
258
 
259
always @(posedge rd_clk)
260
        diff_r1 <= #1 diff;
261
 
262
always @(posedge rd_clk)
263
        empty_n <= #1 (diff_r1 < n) | ((diff_r1==n) & (re | re_r));
264
 
265
always @(posedge wr_clk)
266
        we_r <= #1 we;
267
 
268
always @(posedge wr_clk)
269
        diff_r2 <= #1 diff;
270
 
271
always @(posedge wr_clk)
272
        full_n <= #1 (diff_r2 > max_size-n) | ((diff_r2==max_size-n) & (we | we_r));
273
 
274
always @(posedge wr_clk)
275
        level <= #1 {2{diff[aw]}} | diff[aw-1:aw-2];
276
 
277
////////////////////////////////////////////////////////////////////
278
//
279
// nopop & nopush Flags
280
//
281
 
282
always @(posedge rd_clk)
283
  nopop <= #1 ((re & empty) | (re & clr));
284
 
285
always @(posedge wr_clk)
286
  nopush <= #1 ((we & full) | (we & clr));
287
 
288
////////////////////////////////////////////////////////////////////
289
//
290
// Sanity Check
291
//
292
 
293
// synopsys translate_off
294
always @(posedge wr_clk)
295
        if(we & full)
296
                $display("%m WARNING: Writing while fifo is FULL (%t)",$time);
297
 
298
always @(posedge rd_clk)
299
        if(re & empty)
300
                $display("%m WARNING: Reading while fifo is EMPTY (%t)",$time);
301
// synopsys translate_on
302
 
303
endmodule
304
 

powered by: WebSVN 2.1.0

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