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

Subversion Repositories pci

[/] [pci/] [tags/] [rel_7/] [rtl/] [verilog/] [pci_wbw_fifo_control.v] - Blame information for rev 88

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

Line No. Rev Author Line
1 77 mihad
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  File name "wbw_fifo_control.v"                              ////
4
////                                                              ////
5
////  This file is part of the "PCI bridge" project               ////
6
////  http://www.opencores.org/cores/pci/                         ////
7
////                                                              ////
8
////  Author(s):                                                  ////
9
////      - Miha Dolenc (mihad@opencores.org)                     ////
10
////                                                              ////
11
////  All additional information is avaliable in the README       ////
12
////  file.                                                       ////
13
////                                                              ////
14
////                                                              ////
15
//////////////////////////////////////////////////////////////////////
16
////                                                              ////
17
//// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org          ////
18
////                                                              ////
19
//// This source file may be used and distributed without         ////
20
//// restriction provided that this copyright statement is not    ////
21
//// removed from the file and that any derivative work contains  ////
22
//// the original copyright notice and the associated disclaimer. ////
23
////                                                              ////
24
//// This source file is free software; you can redistribute it   ////
25
//// and/or modify it under the terms of the GNU Lesser General   ////
26
//// Public License as published by the Free Software Foundation; ////
27
//// either version 2.1 of the License, or (at your option) any   ////
28
//// later version.                                               ////
29
////                                                              ////
30
//// This source is distributed in the hope that it will be       ////
31
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
32
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
33
//// PURPOSE.  See the GNU Lesser General Public License for more ////
34
//// details.                                                     ////
35
////                                                              ////
36
//// You should have received a copy of the GNU Lesser General    ////
37
//// Public License along with this source; if not, download it   ////
38
//// from http://www.opencores.org/lgpl.shtml                     ////
39
////                                                              ////
40
//////////////////////////////////////////////////////////////////////
41
//
42
// CVS Revision History
43
//
44
// $Log: not supported by cvs2svn $
45 88 mihad
// Revision 1.1  2003/01/27 16:49:31  mihad
46
// Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed.
47
//
48 77 mihad
// Revision 1.6  2002/11/27 20:36:13  mihad
49
// Changed the code a bit to make it more readable.
50
// Functionality not changed in any way.
51
// More robust synchronization in fifos is still pending.
52
//
53
// Revision 1.5  2002/09/30 16:03:04  mihad
54
// Added meta flop module for easier meta stable FF identification during synthesis
55
//
56
// Revision 1.4  2002/09/25 15:53:52  mihad
57
// Removed all logic from asynchronous reset network
58
//
59
// Revision 1.3  2002/02/01 15:25:14  mihad
60
// Repaired a few bugs, updated specification, added test bench files and design document
61
//
62
// Revision 1.2  2001/10/05 08:14:30  mihad
63
// Updated all files with inclusion of timescale file for simulation purposes.
64
//
65
// Revision 1.1.1.1  2001/10/02 15:33:47  mihad
66
// New project directory structure
67
//
68
//
69
 
70
/* FIFO_CONTROL module provides read/write address and status generation for
71
   FIFOs implemented with standard dual port SRAM cells in ASIC or FPGA designs */
72
`include "pci_constants.v"
73
// synopsys translate_off
74
`include "timescale.v"
75
// synopsys translate_on
76
 
77
module pci_wbw_fifo_control
78
(
79
    rclock_in,
80
    wclock_in,
81
    renable_in,
82
    wenable_in,
83
    reset_in,
84
//    flush_in, // not used
85
    almost_full_out,
86
    full_out,
87
    empty_out,
88
    waddr_out,
89
    raddr_out,
90
    rallow_out,
91
    wallow_out
92
);
93
 
94
parameter ADDR_LENGTH = 7 ;
95
 
96
// independent clock inputs - rclock_in = read clock, wclock_in = write clock
97
input  rclock_in, wclock_in;
98
 
99
// enable inputs - read address changes on rising edge of rclock_in when reads are allowed
100
//                 write address changes on rising edge of wclock_in when writes are allowed
101
input  renable_in, wenable_in ;
102
 
103
// reset input
104
input  reset_in;
105
 
106
// flush input
107
// input flush_in ; // not used
108
 
109
// almost full and empy status outputs
110
output almost_full_out ;
111
 
112
// full and empty status outputs
113
output full_out, empty_out;
114
 
115
// read and write addresses outputs
116
output [(ADDR_LENGTH - 1):0] waddr_out, raddr_out;
117
 
118
// read and write allow outputs
119
output rallow_out, wallow_out ;
120
 
121
// read address register
122
reg [(ADDR_LENGTH - 1):0] raddr ;
123
 
124
// write address register
125
reg [(ADDR_LENGTH - 1):0] waddr;
126
assign waddr_out = waddr ;
127
 
128
// grey code registers
129
// grey code register for next write address
130
reg [(ADDR_LENGTH - 1):0] wgrey_next ; // next
131
 
132
// next write gray address calculation - bitwise xor between address and shifted address
133
wire [(ADDR_LENGTH - 2):0] calc_wgrey_next  = waddr[(ADDR_LENGTH - 1):1] ^ waddr[(ADDR_LENGTH - 2):0] ;
134
 
135
// grey code pipeline for read address
136
reg [(ADDR_LENGTH - 1):0] rgrey_minus1 ; // one before current
137
reg [(ADDR_LENGTH - 1):0] rgrey_addr ; // current
138
reg [(ADDR_LENGTH - 1):0] rgrey_next ; // next
139
 
140
// next read gray address calculation - bitwise xor between address and shifted address
141
wire [(ADDR_LENGTH - 2):0] calc_rgrey_next  = raddr[(ADDR_LENGTH - 1):1] ^ raddr[(ADDR_LENGTH - 2):0] ;
142
 
143
// FFs for registered empty and full flags
144
wire empty ;
145
wire full ;
146
 
147
// almost_full tag
148
wire almost_full ;
149
 
150
// write allow wire - writes are allowed when fifo is not full
151
wire wallow = wenable_in && !full ;
152
 
153
// write allow output assignment
154
assign wallow_out = wallow && !full ;
155
 
156
// read allow wire
157
wire rallow ;
158
 
159
// full output assignment
160
assign full_out  = full ;
161
 
162
// almost full output assignment
163
assign almost_full_out  = almost_full && !full ;
164
 
165
// clear generation for FFs and registers
166
wire clear = reset_in /*|| flush_in*/ ;     // flush not used
167
 
168
assign empty_out = empty ;
169
 
170
//rallow generation
171
assign rallow = renable_in && !empty ; // reads allowed if read enable is high and FIFO is not empty
172
 
173
// rallow output assignment
174
assign rallow_out = rallow ;
175
 
176
// at any clock edge that rallow is high, this register provides next read address, so wait cycles are not necessary
177
// when FIFO is empty, this register provides actual read address, so first location can be read
178
reg [(ADDR_LENGTH - 1):0] raddr_plus_one ;
179
 
180
// address output mux - when FIFO is empty, current actual address is driven out, when it is non - empty next address is driven out
181
// done for zero wait state burst
182
assign raddr_out = rallow ? raddr_plus_one : raddr ;
183
 
184
always@(posedge rclock_in or posedge clear)
185
begin
186
    if (clear)
187
    begin
188
        raddr_plus_one <= #`FF_DELAY 4 ;
189
        raddr          <= #`FF_DELAY 3 ;
190
    end
191
    else if (rallow)
192
    begin
193
        raddr_plus_one <= #`FF_DELAY raddr_plus_one + 1'b1 ;
194
        raddr          <= #`FF_DELAY raddr_plus_one ;
195
    end
196
end
197
 
198
/*-----------------------------------------------------------------------------------------------
199
Read address control consists of Read address counter and Grey Address pipeline
200
There are 3 Grey addresses:
201
    - rgrey_minus1 is Grey Code of address one before current address
202
    - rgrey_addr is Grey Code of current read address
203
    - rgrey_next is Grey Code of next read address
204
--------------------------------------------------------------------------------------------------*/
205
// grey coded address pipeline for status generation in read clock domain
206
always@(posedge rclock_in or posedge clear)
207
begin
208
        if (clear)
209
    begin
210
        // initial value is 0
211
        rgrey_minus1 <= #`FF_DELAY 0 ;
212
        rgrey_addr   <= #`FF_DELAY 1 ;
213
        rgrey_next   <= #`FF_DELAY 3 ;
214
    end
215
    else
216
    if (rallow)
217
    begin
218
        rgrey_minus1 <= #`FF_DELAY rgrey_addr ;
219
        rgrey_addr   <= #`FF_DELAY rgrey_next ;
220
        rgrey_next   <= #`FF_DELAY {raddr[ADDR_LENGTH - 1], calc_rgrey_next} ;
221
    end
222
end
223
 
224
/*--------------------------------------------------------------------------------------------
225
Write address control consists of write address counter and Grey Code Register
226
----------------------------------------------------------------------------------------------*/
227
// grey coded address pipeline for status generation in write clock domain
228
always@(posedge wclock_in or posedge clear)
229
begin
230
    if (clear)
231
    begin
232
        wgrey_next <= #`FF_DELAY 3 ;
233
    end
234
    else
235
    if (wallow)
236
    begin
237
        wgrey_next <= #`FF_DELAY {waddr[(ADDR_LENGTH - 1)], calc_wgrey_next} ;
238
    end
239
end
240
 
241
// write address counter - nothing special - initial value is important though
242
always@(posedge wclock_in or posedge clear)
243
begin
244
    if (clear)
245
        // initial value 4
246
            waddr <= #`FF_DELAY 3 ;
247
    else
248
    if (wallow)
249
        waddr <= #`FF_DELAY waddr + 1'b1 ;
250
end
251
 
252
/*------------------------------------------------------------------------------------------------------------------------------
253
Full control:
254
Gray coded read address pointer is synchronized to write clock domain and compared to Gray coded next write address.
255
If they are equal, fifo is full.
256
 
257
Almost full control:
258
Gray coded address of read address decremented by 1 is synchronized to write clock domain and compared to Gray coded next write
259
address. If they are equal, fifo is almost full.
260
--------------------------------------------------------------------------------------------------------------------------------*/
261
wire [(ADDR_LENGTH - 1):0] wclk_sync_rgrey_addr ;
262
reg  [(ADDR_LENGTH - 1):0] wclk_rgrey_addr ;
263
wire [(ADDR_LENGTH - 1):0] wclk_sync_rgrey_minus1 ;
264
reg  [(ADDR_LENGTH - 1):0] wclk_rgrey_minus1 ;
265
 
266 88 mihad
synchronizer_flop #(ADDR_LENGTH, 1) i_synchronizer_reg_rgrey_addr
267 77 mihad
(
268 88 mihad
    .data_in        (rgrey_addr),
269 77 mihad
    .clk_out        (wclock_in),
270 88 mihad
    .sync_data_out  (wclk_sync_rgrey_addr),
271
    .async_reset    (clear)
272 77 mihad
) ;
273
 
274 88 mihad
synchronizer_flop #(ADDR_LENGTH, 0) i_synchronizer_reg_rgrey_minus1
275
(
276
    .data_in        (rgrey_minus1),
277
    .clk_out        (wclock_in),
278
    .sync_data_out  (wclk_sync_rgrey_minus1),
279
    .async_reset    (clear)
280
) ;
281
 
282
always@(posedge wclock_in or posedge clear)
283 77 mihad
begin
284 88 mihad
    if (clear)
285
    begin
286
        wclk_rgrey_addr   <= #`FF_DELAY 1 ;
287
        wclk_rgrey_minus1 <= #`FF_DELAY 0 ;
288
    end
289
    else
290
    begin
291
        wclk_rgrey_addr   <= #`FF_DELAY wclk_sync_rgrey_addr ;
292
        wclk_rgrey_minus1 <= #`FF_DELAY wclk_sync_rgrey_minus1 ;
293
    end
294 77 mihad
end
295
 
296
assign full         = (wgrey_next == wclk_rgrey_addr) ;
297
assign almost_full  = (wgrey_next == wclk_rgrey_minus1) ;
298
 
299
/*------------------------------------------------------------------------------------------------------------------------------
300
Empty control:
301
Gray coded address of next write address is synchronized to read clock domain and compared to Gray coded next read address.
302
If they are equal, fifo is empty.
303
--------------------------------------------------------------------------------------------------------------------------------*/
304
wire [(ADDR_LENGTH - 1):0] rclk_sync_wgrey_next ;
305
reg  [(ADDR_LENGTH - 1):0] rclk_wgrey_next ;
306 88 mihad
synchronizer_flop #(ADDR_LENGTH, 3) i_synchronizer_reg_wgrey_next
307 77 mihad
(
308
    .data_in        (wgrey_next),
309
    .clk_out        (rclock_in),
310
    .sync_data_out  (rclk_sync_wgrey_next),
311 88 mihad
    .async_reset    (clear)
312 77 mihad
) ;
313
 
314 88 mihad
always@(posedge rclock_in or posedge clear)
315 77 mihad
begin
316 88 mihad
    if (clear)
317
        rclk_wgrey_next <= #`FF_DELAY 3 ;
318
    else
319
        rclk_wgrey_next <= #`FF_DELAY rclk_sync_wgrey_next ;
320 77 mihad
end
321
 
322
assign empty = (rgrey_next == rclk_wgrey_next) ;
323
 
324
endmodule

powered by: WebSVN 2.1.0

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