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_gray.v] - Blame information for rev 94

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 94 JonasDC
/////////////////////////////////////////////////////////////////////
2
////                                                             ////
3
////  Universal FIFO Dual Clock, gray encoded                    ////
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_gray.v,v 1.2 2004-01-13 09:11:55 rudi Exp $
51
//
52
//  $Date: 2004-01-13 09:11:55 $
53
//  $Revision: 1.2 $
54
//  $Author: rudi $
55
//  $Locker:  $
56
//  $State: Exp $
57
//
58
// Change History:
59
//               $Log: not supported by cvs2svn $
60
//               Revision 1.1  2003/10/14 09:34:41  rudi
61
//               Dual clock FIFO Gray Code encoded version.
62
//
63
//
64
//
65
//
66
//
67
 
68
 
69
//`include "timescale.v"
70
 
71
/*
72
 
73
Description
74
===========
75
 
76
I/Os
77
----
78
rd_clk  Read Port Clock
79
wr_clk  Write Port Clock
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
84
din     Data Input
85
dout    Data Output
86
 
87
full    Indicates the FIFO is full (driven at the rising edge of wr_clk)
88
empty   Indicates the FIFO is empty (driven at the rising edge of rd_clk)
89
 
90
wr_level        indicates the FIFO level:
91
                2'b00   0-25%    full
92
                2'b01   25-50%   full
93
                2'b10   50-75%   full
94
                2'b11   %75-100% full
95
 
96
rd_level        indicates the FIFO level:
97
                2'b00   0-25%    empty
98
                2'b01   25-50%   empty
99
                2'b10   50-75%   empty
100
                2'b11   %75-100% empty
101
 
102
Status Timing
103
-------------
104
All status outputs are registered. They are asserted immediately
105
as the full/empty condition occurs, however, there is a 2 cycle
106
delay before they are de-asserted once the condition is not true
107
anymore.
108
 
109
Parameters
110
----------
111
The FIFO takes 2 parameters:
112
dw      Data bus width
113
aw      Address bus width (Determines the FIFO size by evaluating 2^aw)
114
 
115
Synthesis Results
116
-----------------
117
In a Spartan 2e a 8 bit wide, 8 entries deep FIFO, takes 97 LUTs and runs
118
at about 113 MHz (IO insertion disabled).
119
 
120
Misc
121
----
122
This design assumes you will do appropriate status checking externally.
123
 
124
IMPORTANT ! writing while the FIFO is full or reading while the FIFO is
125
empty will place the FIFO in an undefined state.
126
 
127
*/
128
 
129
 
130
module generic_fifo_dc_gray(    rd_clk, wr_clk, clr, din, we,
131
                dout, re, full, empty, wr_level, rd_level, nopop, nopush  );
132
 
133
parameter dw=32;
134
parameter aw=7;
135
 
136
input                   rd_clk, wr_clk, clr;
137
input   [dw-1:0] din;
138
input                   we;
139
output  [dw-1:0] dout;
140
input                   re;
141
output                  full;
142
output                  empty;
143
output  [1:0]            wr_level;
144
output  [1:0]            rd_level;
145
output        nopop;
146
output        nopush;
147
 
148
////////////////////////////////////////////////////////////////////
149
//
150
// Local Wires
151
//
152
 
153
reg     [aw:0]           wp_bin, wp_gray;
154
reg     [aw:0]           rp_bin, rp_gray;
155
reg     [aw:0]           wp_s, rp_s;
156
reg                     full, empty;
157
 
158
wire    [aw:0]           wp_bin_next, wp_gray_next;
159
wire    [aw:0]           rp_bin_next, rp_gray_next;
160
 
161
wire    [aw:0]           wp_bin_x, rp_bin_x;
162
reg     [aw-1:0] d1, d2;
163
 
164
reg                     rd_clr, wr_clr;
165
reg                     rd_clr_r, wr_clr_r;
166
wire [dw-1:0]    dout_ram;
167
reg [dw-1:0]    dout;
168
reg       nopop, nopush;
169
 
170
////////////////////////////////////////////////////////////////////
171
//
172
// Reset Logic
173
//
174
 
175
always @(posedge rd_clk or posedge clr)
176
        if(clr)         rd_clr <= 1'b1;
177
        else
178
        if(!rd_clr_r)   rd_clr <= 1'b0;         // Release Clear
179
 
180
always @(posedge rd_clk or posedge clr)
181
        if(clr)         rd_clr_r <= 1'b1;
182
        else            rd_clr_r <= 1'b0;
183
 
184
always @(posedge wr_clk or posedge clr)
185
        if(clr)         wr_clr <= 1'b1;
186
        else
187
        if(!wr_clr_r)   wr_clr <= 1'b0;         // Release Clear
188
 
189
always @(posedge wr_clk or posedge clr)
190
        if(clr)         wr_clr_r <= 1'b1;
191
        else            wr_clr_r <= 1'b0;
192
 
193
////////////////////////////////////////////////////////////////////
194
//
195
// Memory Block
196
//
197
 
198
 
199
dpram_generic #(2**aw) u0(
200
  .clkA(wr_clk),
201
  .waddrA(wp_bin[aw-1:0]),
202
  .weA(we & !full),
203
  .dinA(din),
204
  .clkB(rd_clk),
205
  .raddrB(rp_bin[aw-1:0]),
206
  .doutB(dout_ram)
207
);
208
 
209
//generic_dpram  #(aw,dw) u0(
210
//  .rclk(      rd_clk      ),
211
//  .rrst(      !rd_rst     ),
212
//  .rce(       1'b1        ),
213
//  .oe(        1'b1        ),
214
//  .raddr(     rp_bin[aw-1:0]  ),
215
//  .do(        dout        ),
216
//  .wclk(      wr_clk      ),
217
//  .wrst(      !wr_rst     ),
218
//  .wce(       1'b1        ),
219
//  .we(        we      ),
220
//  .waddr(     wp_bin[aw-1:0]  ),
221
//  .di(        din     )
222
//  );
223
 
224
always @(posedge rd_clk)
225
    if(re & !empty)     dout <= #1 dout_ram;
226
 
227
////////////////////////////////////////////////////////////////////
228
//
229
// Read/Write Pointers Logic
230
//
231
 
232
always @(posedge wr_clk)
233
        if(wr_clr)      wp_bin <= {aw+1{1'b0}};
234
        else
235
        if(we & !full)          wp_bin <= wp_bin_next;
236
 
237
always @(posedge wr_clk)
238
        if(wr_clr)      wp_gray <= {aw+1{1'b0}};
239
        else
240
        if(we & !full)          wp_gray <= wp_gray_next;
241
 
242
assign wp_bin_next  = wp_bin + {{aw{1'b0}},1'b1};
243
assign wp_gray_next = wp_bin_next ^ {1'b0, wp_bin_next[aw:1]};
244
 
245
always @(posedge rd_clk)
246
        if(rd_clr)      rp_bin <= {aw+1{1'b0}};
247
        else
248
        if(re & !empty)         rp_bin <= rp_bin_next;
249
 
250
always @(posedge rd_clk)
251
        if(rd_clr)      rp_gray <= {aw+1{1'b0}};
252
        else
253
        if(re & !empty)         rp_gray <= rp_gray_next;
254
 
255
assign rp_bin_next  = rp_bin + {{aw{1'b0}},1'b1};
256
assign rp_gray_next = rp_bin_next ^ {1'b0, rp_bin_next[aw:1]};
257
 
258
////////////////////////////////////////////////////////////////////
259
//
260
// Synchronization Logic
261
//
262
 
263
// write pointer
264
always @(posedge rd_clk)        wp_s <= wp_gray;
265
 
266
// read pointer
267
always @(posedge wr_clk)        rp_s <= rp_gray;
268
 
269
////////////////////////////////////////////////////////////////////
270
//
271
// Registered Full & Empty Flags
272
//
273
 
274
assign wp_bin_x = wp_s ^ {1'b0, wp_bin_x[aw:1]};        // convert gray to binary
275
assign rp_bin_x = rp_s ^ {1'b0, rp_bin_x[aw:1]};        // convert gray to binary
276
 
277
always @(posedge rd_clk)
278
        empty <= (wp_s == rp_gray) | (re & (wp_s == rp_gray_next));
279
 
280
always @(posedge wr_clk)
281
        full <= ((wp_bin[aw-1:0] == rp_bin_x[aw-1:0]) & (wp_bin[aw] != rp_bin_x[aw])) |
282
        (we & (wp_bin_next[aw-1:0] == rp_bin_x[aw-1:0]) & (wp_bin_next[aw] != rp_bin_x[aw]));
283
 
284
////////////////////////////////////////////////////////////////////
285
//
286
// nopop & nopush Flags
287
//
288
 
289
always @(posedge rd_clk)
290
  nopop <= #1 ((re & empty) | (re & clr));
291
 
292
always @(posedge wr_clk)
293
  nopush <= #1 ((we & full) | (we & clr));
294
 
295
////////////////////////////////////////////////////////////////////
296
//
297
// Registered Level Indicators
298
//
299
reg     [1:0]            wr_level;
300
reg     [1:0]            rd_level;
301
reg     [aw-1:0] wp_bin_xr, rp_bin_xr;
302
reg                     full_rc;
303
reg                     full_wc;
304
 
305
always @(posedge wr_clk)        full_wc <= full;
306
always @(posedge wr_clk)        rp_bin_xr <=  ~rp_bin_x[aw-1:0] + {{aw-1{1'b0}}, 1'b1};
307
always @(posedge wr_clk)        d1 <= wp_bin[aw-1:0] + rp_bin_xr[aw-1:0];
308
 
309
always @(posedge wr_clk)        wr_level <= {d1[aw-1] | full | full_wc, d1[aw-2] | full | full_wc};
310
 
311
always @(posedge rd_clk)        wp_bin_xr <=  ~wp_bin_x[aw-1:0];
312
always @(posedge rd_clk)        d2 <= rp_bin[aw-1:0] + wp_bin_xr[aw-1:0];
313
 
314
always @(posedge rd_clk)        full_rc <= full;
315
always @(posedge rd_clk)        rd_level <= full_rc ? 2'h0 : {d2[aw-1] | empty, d2[aw-2] | empty};
316
 
317
////////////////////////////////////////////////////////////////////
318
//
319
// Sanity Check
320
//
321
 
322
// synopsys translate_off
323
always @(posedge wr_clk)
324
        if(we && full)
325
                $display("%m WARNING: Writing while fifo is FULL (%t)",$time);
326
 
327
always @(posedge rd_clk)
328
        if(re && empty)
329
                $display("%m WARNING: Reading while fifo is EMPTY (%t)",$time);
330
// synopsys translate_on
331
 
332
endmodule
333
 

powered by: WebSVN 2.1.0

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