]> cvs.zerfleddert.de Git - raggedstone/blob - ethernet/source/pci/pci_wbw_fifo_control.v
watch inta
[raggedstone] / ethernet / source / pci / pci_wbw_fifo_control.v
1 //////////////////////////////////////////////////////////////////////
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: pci_wbw_fifo_control.v,v $
45 // Revision 1.1 2007-03-20 17:50:56 sithglan
46 // add shit
47 //
48 // Revision 1.5 2006/07/04 13:16:19 mihad
49 // Write burst performance patch applied.
50 // Not tested. Everything should be backwards
51 // compatible, since functional code is ifdefed.
52 //
53 // Revision 1.4 2003/08/14 13:06:03 simons
54 // synchronizer_flop replaced with pci_synchronizer_flop, artisan ram instance updated.
55 //
56 // Revision 1.3 2003/07/29 08:20:11 mihad
57 // Found and simulated the problem in the synchronization logic.
58 // Repaired the synchronization logic in the FIFOs.
59 //
60 // Revision 1.2 2003/03/26 13:16:18 mihad
61 // Added the reset value parameter to the synchronizer flop module.
62 // Added resets to all synchronizer flop instances.
63 // Repaired initial sync value in fifos.
64 //
65 // Revision 1.1 2003/01/27 16:49:31 mihad
66 // Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed.
67 //
68 // Revision 1.6 2002/11/27 20:36:13 mihad
69 // Changed the code a bit to make it more readable.
70 // Functionality not changed in any way.
71 // More robust synchronization in fifos is still pending.
72 //
73 // Revision 1.5 2002/09/30 16:03:04 mihad
74 // Added meta flop module for easier meta stable FF identification during synthesis
75 //
76 // Revision 1.4 2002/09/25 15:53:52 mihad
77 // Removed all logic from asynchronous reset network
78 //
79 // Revision 1.3 2002/02/01 15:25:14 mihad
80 // Repaired a few bugs, updated specification, added test bench files and design document
81 //
82 // Revision 1.2 2001/10/05 08:14:30 mihad
83 // Updated all files with inclusion of timescale file for simulation purposes.
84 //
85 // Revision 1.1.1.1 2001/10/02 15:33:47 mihad
86 // New project directory structure
87 //
88 //
89
90 /* FIFO_CONTROL module provides read/write address and status generation for
91 FIFOs implemented with standard dual port SRAM cells in ASIC or FPGA designs */
92 `include "pci_constants.v"
93 // synopsys translate_off
94 `include "timescale.v"
95 // synopsys translate_on
96
97 module pci_wbw_fifo_control
98 (
99 rclock_in,
100 wclock_in,
101 renable_in,
102 wenable_in,
103 reset_in,
104 almost_full_out,
105 full_out,
106 empty_out,
107 waddr_out,
108 raddr_out,
109 rallow_out,
110 wallow_out,
111 half_full_out ////Robert, burst issue
112 );
113
114 parameter ADDR_LENGTH = 7;
115
116 // independent clock inputs - rclock_in = read clock, wclock_in = write clock
117 input rclock_in, wclock_in;
118
119 // enable inputs - read address changes on rising edge of rclock_in when reads are allowed
120 // write address changes on rising edge of wclock_in when writes are allowed
121 input renable_in, wenable_in ;
122
123 // reset input
124 input reset_in;
125
126 // flush input
127 // input flush_in ; // not used
128
129 // almost full and empy status outputs
130 output almost_full_out ;
131
132 // full and empty status outputs
133 output full_out, empty_out;
134
135 // read and write addresses outputs
136 output [(ADDR_LENGTH - 1):0] waddr_out, raddr_out;
137
138 // read and write allow outputs
139 output rallow_out, wallow_out ;
140
141 output half_full_out;
142
143 // read address register
144 reg [(ADDR_LENGTH - 1):0] raddr ;
145
146 // write address register
147 reg [(ADDR_LENGTH - 1):0] waddr;
148 assign waddr_out = waddr ;
149
150 // grey code registers
151 reg [(ADDR_LENGTH - 1):0] wgrey_addr ; // current
152 // grey code register for next write address
153 reg [(ADDR_LENGTH - 1):0] wgrey_next ; // next
154
155 // next write gray address calculation - bitwise xor between address and shifted address
156 wire [(ADDR_LENGTH - 2):0] calc_wgrey_next = waddr[(ADDR_LENGTH - 1):1] ^ waddr[(ADDR_LENGTH - 2):0] ;
157
158 // grey code pipeline for read address
159 reg [(ADDR_LENGTH - 1):0] rgrey_minus1 ; // one before current
160 reg [(ADDR_LENGTH - 1):0] rgrey_addr ; // current
161 reg [(ADDR_LENGTH - 1):0] rgrey_next ; // next
162
163 // next read gray address calculation - bitwise xor between address and shifted address
164 wire [(ADDR_LENGTH - 2):0] calc_rgrey_next = raddr[(ADDR_LENGTH - 1):1] ^ raddr[(ADDR_LENGTH - 2):0] ;
165
166 // write allow wire - writes are allowed when fifo is not full
167 assign wallow_out = wenable_in & ~full_out ;
168
169 // clear generation for FFs and registers
170 wire clear = reset_in ;
171
172 //rallow generation
173 assign rallow_out = renable_in & ~empty_out ; // reads allowed if read enable is high and FIFO is not empty
174
175 // at any clock edge that rallow is high, this register provides next read address, so wait cycles are not necessary
176 // when FIFO is empty, this register provides actual read address, so first location can be read
177 reg [(ADDR_LENGTH - 1):0] raddr_plus_one ;
178
179
180 wire [ADDR_LENGTH :0] fifo_fullness; //Robert, burst issue
181
182 //Robert, burst issue
183 assign fifo_fullness = (waddr > raddr) ? ({1'b0, waddr} - {1'b0, raddr}) : ({1'b1, waddr} - {1'b0, raddr});
184 assign half_full_out = fifo_fullness[(ADDR_LENGTH - 1)] ;
185 //Robert, burst issue
186
187
188 // address output mux - when FIFO is empty, current actual address is driven out, when it is non - empty next address is driven out
189 // done for zero wait state burst
190 assign raddr_out = rallow_out ? raddr_plus_one : raddr ;
191
192 always@(posedge rclock_in or posedge clear)
193 begin
194 if (clear)
195 begin
196 raddr_plus_one <= #`FF_DELAY 4 ;
197 raddr <= #`FF_DELAY 3 ;
198 end
199 else if (rallow_out)
200 begin
201 raddr_plus_one <= #`FF_DELAY raddr_plus_one + 1'b1 ;
202 raddr <= #`FF_DELAY raddr_plus_one ;
203 end
204 end
205
206 /*-----------------------------------------------------------------------------------------------
207 Read address control consists of Read address counter and Grey Address pipeline
208 There are 3 Grey addresses:
209 - rgrey_minus1 is Grey Code of address one before current address
210 - rgrey_addr is Grey Code of current read address
211 - rgrey_next is Grey Code of next read address
212 --------------------------------------------------------------------------------------------------*/
213 // grey coded address pipeline for status generation in read clock domain
214 always@(posedge rclock_in or posedge clear)
215 begin
216 if (clear)
217 begin
218 // initial value is 0
219 rgrey_minus1 <= #1 0 ;
220 rgrey_addr <= #1 1 ;
221 rgrey_next <= #`FF_DELAY 3 ;
222 end
223 else
224 if (rallow_out)
225 begin
226 rgrey_minus1 <= #1 rgrey_addr ;
227 rgrey_addr <= #1 rgrey_next ;
228 rgrey_next <= #`FF_DELAY {raddr[ADDR_LENGTH - 1], calc_rgrey_next} ;
229 end
230 end
231
232 /*--------------------------------------------------------------------------------------------
233 Write address control consists of write address counter and Grey Code Register
234 ----------------------------------------------------------------------------------------------*/
235 // grey coded address pipeline for status generation in write clock domain
236 always@(posedge wclock_in or posedge clear)
237 begin
238 if (clear)
239 begin
240 wgrey_addr <= #`FF_DELAY 1 ;
241 wgrey_next <= #1 3 ;
242 end
243 else
244 if (wallow_out)
245 begin
246 wgrey_addr <= #`FF_DELAY wgrey_next ;
247 wgrey_next <= #1 {waddr[(ADDR_LENGTH - 1)], calc_wgrey_next} ;
248 end
249 end
250
251 // write address counter - nothing special - initial value is important though
252 always@(posedge wclock_in or posedge clear)
253 begin
254 if (clear)
255 // initial value 4
256 waddr <= #`FF_DELAY 3 ;
257 else
258 if (wallow_out)
259 waddr <= #`FF_DELAY waddr + 1'b1 ;
260 end
261
262 /*------------------------------------------------------------------------------------------------------------------------------
263 Gray coded address of read address decremented by 1 is synchronized to write clock domain and compared to:
264
265 - Gray coded write address. If they are equal, fifo is full.
266
267 - Gray coded next write address. If they are equal, fifo is almost full.
268 --------------------------------------------------------------------------------------------------------------------------------*/
269 wire [(ADDR_LENGTH - 1):0] wclk_sync_rgrey_minus1 ;
270 reg [(ADDR_LENGTH - 1):0] wclk_rgrey_minus1 ;
271
272 pci_synchronizer_flop #(ADDR_LENGTH, 0) i_synchronizer_reg_rgrey_minus1
273 (
274 .data_in (rgrey_minus1),
275 .clk_out (wclock_in),
276 .sync_data_out (wclk_sync_rgrey_minus1),
277 .async_reset (clear)
278 ) ;
279
280 always@(posedge wclock_in or posedge clear)
281 begin
282 if (clear)
283 begin
284 wclk_rgrey_minus1 <= #`FF_DELAY 0 ;
285 end
286 else
287 begin
288 wclk_rgrey_minus1 <= #`FF_DELAY wclk_sync_rgrey_minus1 ;
289 end
290 end
291
292 assign full_out = (wgrey_addr == wclk_rgrey_minus1) ;
293 assign almost_full_out = (wgrey_next == wclk_rgrey_minus1) ;
294
295 /*------------------------------------------------------------------------------------------------------------------------------
296 Empty control:
297 Gray coded address of next write address is synchronized to read clock domain and compared to Gray coded next read address.
298 If they are equal, fifo is empty.
299 --------------------------------------------------------------------------------------------------------------------------------*/
300 wire [(ADDR_LENGTH - 1):0] rclk_sync_wgrey_next ;
301 reg [(ADDR_LENGTH - 1):0] rclk_wgrey_next ;
302 pci_synchronizer_flop #(ADDR_LENGTH, 3) i_synchronizer_reg_wgrey_next
303 (
304 .data_in (wgrey_next),
305 .clk_out (rclock_in),
306 .sync_data_out (rclk_sync_wgrey_next),
307 .async_reset (clear)
308 ) ;
309
310 always@(posedge rclock_in or posedge clear)
311 begin
312 if (clear)
313 rclk_wgrey_next <= #`FF_DELAY 3 ;
314 else
315 rclk_wgrey_next <= #`FF_DELAY rclk_sync_wgrey_next ;
316 end
317
318 assign empty_out = (rgrey_next == rclk_wgrey_next) ;
319
320 endmodule
Impressum, Datenschutz