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

Subversion Repositories generic_fifos

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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