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 5

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

powered by: WebSVN 2.1.0

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