]> cvs.zerfleddert.de Git - raggedstone/blame - ethernet/source/pci/pci_wbw_fifo_control.v
PHY Documentation
[raggedstone] / ethernet / source / pci / pci_wbw_fifo_control.v
CommitLineData
40a1f26c 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
97module 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
114parameter ADDR_LENGTH = 7;
115
116// independent clock inputs - rclock_in = read clock, wclock_in = write clock
117input 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
121input renable_in, wenable_in ;
122
123// reset input
124input reset_in;
125
126// flush input
127// input flush_in ; // not used
128
129// almost full and empy status outputs
130output almost_full_out ;
131
132// full and empty status outputs
133output full_out, empty_out;
134
135// read and write addresses outputs
136output [(ADDR_LENGTH - 1):0] waddr_out, raddr_out;
137
138// read and write allow outputs
139output rallow_out, wallow_out ;
140
141output half_full_out;
142
143// read address register
144reg [(ADDR_LENGTH - 1):0] raddr ;
145
146// write address register
147reg [(ADDR_LENGTH - 1):0] waddr;
148assign waddr_out = waddr ;
149
150// grey code registers
151reg [(ADDR_LENGTH - 1):0] wgrey_addr ; // current
152// grey code register for next write address
153reg [(ADDR_LENGTH - 1):0] wgrey_next ; // next
154
155// next write gray address calculation - bitwise xor between address and shifted address
156wire [(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
159reg [(ADDR_LENGTH - 1):0] rgrey_minus1 ; // one before current
160reg [(ADDR_LENGTH - 1):0] rgrey_addr ; // current
161reg [(ADDR_LENGTH - 1):0] rgrey_next ; // next
162
163// next read gray address calculation - bitwise xor between address and shifted address
164wire [(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
167assign wallow_out = wenable_in & ~full_out ;
168
169// clear generation for FFs and registers
170wire clear = reset_in ;
171
172//rallow generation
173assign 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
177reg [(ADDR_LENGTH - 1):0] raddr_plus_one ;
178
179
180wire [ADDR_LENGTH :0] fifo_fullness; //Robert, burst issue
181
182//Robert, burst issue
183assign fifo_fullness = (waddr > raddr) ? ({1'b0, waddr} - {1'b0, raddr}) : ({1'b1, waddr} - {1'b0, raddr});
184assign 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
190assign raddr_out = rallow_out ? raddr_plus_one : raddr ;
191
192always@(posedge rclock_in or posedge clear)
193begin
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
204end
205
206/*-----------------------------------------------------------------------------------------------
207Read address control consists of Read address counter and Grey Address pipeline
208There 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
214always@(posedge rclock_in or posedge clear)
215begin
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
230end
231
232/*--------------------------------------------------------------------------------------------
233Write address control consists of write address counter and Grey Code Register
234----------------------------------------------------------------------------------------------*/
235// grey coded address pipeline for status generation in write clock domain
236always@(posedge wclock_in or posedge clear)
237begin
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
249end
250
251// write address counter - nothing special - initial value is important though
252always@(posedge wclock_in or posedge clear)
253begin
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 ;
260end
261
262/*------------------------------------------------------------------------------------------------------------------------------
263Gray 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--------------------------------------------------------------------------------------------------------------------------------*/
269wire [(ADDR_LENGTH - 1):0] wclk_sync_rgrey_minus1 ;
270reg [(ADDR_LENGTH - 1):0] wclk_rgrey_minus1 ;
271
272pci_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
280always@(posedge wclock_in or posedge clear)
281begin
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
290end
291
292assign full_out = (wgrey_addr == wclk_rgrey_minus1) ;
293assign almost_full_out = (wgrey_next == wclk_rgrey_minus1) ;
294
295/*------------------------------------------------------------------------------------------------------------------------------
296Empty control:
297Gray coded address of next write address is synchronized to read clock domain and compared to Gray coded next read address.
298If they are equal, fifo is empty.
299--------------------------------------------------------------------------------------------------------------------------------*/
300wire [(ADDR_LENGTH - 1):0] rclk_sync_wgrey_next ;
301reg [(ADDR_LENGTH - 1):0] rclk_wgrey_next ;
302pci_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
310always@(posedge rclock_in or posedge clear)
311begin
312 if (clear)
313 rclk_wgrey_next <= #`FF_DELAY 3 ;
314 else
315 rclk_wgrey_next <= #`FF_DELAY rclk_sync_wgrey_next ;
316end
317
318assign empty_out = (rgrey_next == rclk_wgrey_next) ;
319
320endmodule
Impressum, Datenschutz