]>
Commit | Line | Data |
---|---|---|
1 | ////////////////////////////////////////////////////////////////////// | |
2 | //// //// | |
3 | //// File name "wbw_wbr_fifos.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_wbr_fifos.v,v $ | |
45 | // Revision 1.1 2007-03-20 17:50:56 sithglan | |
46 | // add shit | |
47 | // | |
48 | // Revision 1.7 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.6 2003/12/19 11:11:30 mihad | |
54 | // Compact PCI Hot Swap support added. | |
55 | // New testcases added. | |
56 | // Specification updated. | |
57 | // Test application changed to support WB B3 cycles. | |
58 | // | |
59 | // Revision 1.5 2003/10/17 09:11:52 markom | |
60 | // mbist signals updated according to newest convention | |
61 | // | |
62 | // Revision 1.4 2003/08/14 13:06:03 simons | |
63 | // synchronizer_flop replaced with pci_synchronizer_flop, artisan ram instance updated. | |
64 | // | |
65 | // Revision 1.3 2003/03/26 13:16:18 mihad | |
66 | // Added the reset value parameter to the synchronizer flop module. | |
67 | // Added resets to all synchronizer flop instances. | |
68 | // Repaired initial sync value in fifos. | |
69 | // | |
70 | // Revision 1.2 2003/01/30 22:01:09 mihad | |
71 | // Updated synchronization in top level fifo modules. | |
72 | // | |
73 | // Revision 1.1 2003/01/27 16:49:31 mihad | |
74 | // Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. | |
75 | // | |
76 | // Revision 1.9 2002/10/18 03:36:37 tadejm | |
77 | // Changed wrong signal name mbist_sen into mbist_ctrl_i. | |
78 | // | |
79 | // Revision 1.8 2002/10/17 22:49:22 tadejm | |
80 | // Changed BIST signals for RAMs. | |
81 | // | |
82 | // Revision 1.7 2002/10/11 10:09:01 mihad | |
83 | // Added additional testcase and changed rst name in BIST to trst | |
84 | // | |
85 | // Revision 1.6 2002/10/08 17:17:06 mihad | |
86 | // Added BIST signals for RAMs. | |
87 | // | |
88 | // Revision 1.5 2002/09/30 16:03:04 mihad | |
89 | // Added meta flop module for easier meta stable FF identification during synthesis | |
90 | // | |
91 | // Revision 1.4 2002/09/25 15:53:52 mihad | |
92 | // Removed all logic from asynchronous reset network | |
93 | // | |
94 | // Revision 1.3 2002/02/01 15:25:14 mihad | |
95 | // Repaired a few bugs, updated specification, added test bench files and design document | |
96 | // | |
97 | // Revision 1.2 2001/10/05 08:20:12 mihad | |
98 | // Updated all files with inclusion of timescale file for simulation purposes. | |
99 | // | |
100 | // Revision 1.1.1.1 2001/10/02 15:33:47 mihad | |
101 | // New project directory structure | |
102 | // | |
103 | // | |
104 | ||
105 | `include "pci_constants.v" | |
106 | ||
107 | // synopsys translate_off | |
108 | `include "timescale.v" | |
109 | // synopsys translate_on | |
110 | ||
111 | ||
112 | ||
113 | module pci_wbw_wbr_fifos | |
114 | ( | |
115 | wb_clock_in, | |
116 | pci_clock_in, | |
117 | reset_in, | |
118 | wbw_wenable_in, | |
119 | wbw_addr_data_in, | |
120 | wbw_cbe_in, | |
121 | wbw_control_in, | |
122 | wbw_renable_in, | |
123 | wbw_addr_data_out, | |
124 | wbw_cbe_out, | |
125 | wbw_control_out, | |
126 | // wbw_flush_in, write fifo flush not used | |
127 | wbw_almost_full_out, | |
128 | wbw_full_out, | |
129 | wbw_empty_out, | |
130 | wbw_transaction_ready_out, | |
131 | wbw_half_full_out, ////Robert, burst issue | |
132 | wbr_wenable_in, | |
133 | wbr_data_in, | |
134 | wbr_be_in, | |
135 | wbr_control_in, | |
136 | wbr_renable_in, | |
137 | wbr_data_out, | |
138 | wbr_be_out, | |
139 | wbr_control_out, | |
140 | wbr_flush_in, | |
141 | wbr_empty_out | |
142 | ||
143 | ||
144 | `ifdef PCI_BIST | |
145 | , | |
146 | // debug chain signals | |
147 | mbist_si_i, // bist scan serial in | |
148 | mbist_so_o, // bist scan serial out | |
149 | mbist_ctrl_i // bist chain shift control | |
150 | `endif | |
151 | ) ; | |
152 | ||
153 | /*----------------------------------------------------------------------------------------------------------- | |
154 | System inputs: | |
155 | wb_clock_in - WISHBONE bus clock | |
156 | pci_clock_in - PCI bus clock | |
157 | reset_in - reset from control logic | |
158 | -------------------------------------------------------------------------------------------------------------*/ | |
159 | input wb_clock_in, pci_clock_in, reset_in ; | |
160 | ||
161 | /*----------------------------------------------------------------------------------------------------------- | |
162 | WISHBONE WRITE FIFO interface signals prefixed with wbw_ - FIFO is used for posted writes initiated by | |
163 | WISHBONE master, traveling through FIFO and are completed on PCI by PCI master interface | |
164 | ||
165 | write enable signal: | |
166 | wbw_wenable_in = write enable input for WBW_FIFO - driven by WISHBONE slave interface | |
167 | ||
168 | data input signals: | |
169 | wbw_addr_data_in = data input - data from WISHBONE bus - first entry of transaction is address others are data entries | |
170 | wbw_cbe_in = bus command/byte enable(~SEL[3:0]) input - first entry of transaction is bus command, other are byte enables | |
171 | wbw_control_in = control input - encoded control bus input | |
172 | ||
173 | read enable signal: | |
174 | wbw_renable_in = read enable input driven by PCI master interface | |
175 | ||
176 | data output signals: | |
177 | wbw_addr_data_out = data output - data from WISHBONE bus - first entry of transaction is address, others are data entries | |
178 | wbw_cbe_out = bus command/byte enable output - first entry of transaction is bus command, others are byte enables | |
179 | wbw_control_out = control input - encoded control bus input | |
180 | ||
181 | status signals - monitored by various resources in the core | |
182 | wbw_flush_in = flush signal input for WBW_FIFO - when asserted, fifo is flushed(emptied) | |
183 | wbw_almost_full_out = almost full output from WBW_FIFO | |
184 | wbw_full_out = full output from WBW_FIFO | |
185 | wbw_empty_out = empty output from WBW_FIFO | |
186 | wbw_transaction_ready_out = output indicating that one complete transaction is waiting in WBW_FIFO | |
187 | -----------------------------------------------------------------------------------------------------------*/ | |
188 | // input control and data | |
189 | input wbw_wenable_in ; | |
190 | input [31:0] wbw_addr_data_in ; | |
191 | input [3:0] wbw_cbe_in ; | |
192 | input [3:0] wbw_control_in ; | |
193 | ||
194 | // output control and data | |
195 | input wbw_renable_in ; | |
196 | output [31:0] wbw_addr_data_out ; | |
197 | output [3:0] wbw_cbe_out ; | |
198 | output [3:0] wbw_control_out ; | |
199 | ||
200 | // flush input | |
201 | // input wbw_flush_in ; // not used | |
202 | ||
203 | // status outputs | |
204 | output wbw_almost_full_out ; | |
205 | output wbw_full_out ; | |
206 | output wbw_empty_out ; | |
207 | output wbw_transaction_ready_out ; | |
208 | output wbw_half_full_out; ////Robert, burst issue | |
209 | ||
210 | /*----------------------------------------------------------------------------------------------------------- | |
211 | WISHBONE READ FIFO interface signals prefixed with wbr_ - FIFO is used for holding delayed read completions | |
212 | initiated by master on WISHBONE bus and completed on PCI bus, | |
213 | ||
214 | write enable signal: | |
215 | wbr_wenable_in = write enable input for WBR_FIFO - driven by PCI master interface | |
216 | ||
217 | data input signals: | |
218 | wbr_data_in = data input - data from PCI bus - there is no address entry here, since address is stored in separate register | |
219 | wbr_be_in = byte enable(~BE#[3:0]) input - byte enables - same through one transaction | |
220 | wbr_control_in = control input - encoded control bus input | |
221 | ||
222 | read enable signal: | |
223 | wbr_renable_in = read enable input driven by WISHBONE slave interface | |
224 | ||
225 | data output signals: | |
226 | wbr_data_out = data output - data from PCI bus | |
227 | wbr_be_out = byte enable output(~#BE) | |
228 | wbr_control_out = control output - encoded control bus output | |
229 | ||
230 | status signals - monitored by various resources in the core | |
231 | wbr_flush_in = flush signal input for WBR_FIFO - when asserted, fifo is flushed(emptied) | |
232 | wbr full_out = full output from WBR_FIFO | |
233 | wbr_empty_out = empty output from WBR_FIFO | |
234 | -----------------------------------------------------------------------------------------------------------*/ | |
235 | // input control and data | |
236 | input wbr_wenable_in ; | |
237 | input [31:0] wbr_data_in ; | |
238 | input [3:0] wbr_be_in ; | |
239 | input [3:0] wbr_control_in ; | |
240 | ||
241 | // output control and data | |
242 | input wbr_renable_in ; | |
243 | output [31:0] wbr_data_out ; | |
244 | output [3:0] wbr_be_out ; | |
245 | output [3:0] wbr_control_out ; | |
246 | ||
247 | // flush input | |
248 | input wbr_flush_in ; | |
249 | ||
250 | output wbr_empty_out ; | |
251 | ||
252 | `ifdef PCI_BIST | |
253 | /*----------------------------------------------------- | |
254 | BIST debug chain port signals | |
255 | -----------------------------------------------------*/ | |
256 | input mbist_si_i; // bist scan serial in | |
257 | output mbist_so_o; // bist scan serial out | |
258 | input [`PCI_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control | |
259 | `endif | |
260 | ||
261 | /*----------------------------------------------------------------------------------------------------------- | |
262 | FIFO depth parameters: | |
263 | WBW_DEPTH = defines WBW_FIFO depth | |
264 | WBR_DEPTH = defines WBR_FIFO depth | |
265 | WBW_ADDR_LENGTH = defines WBW_FIFO's location address length = log2(WBW_DEPTH) | |
266 | WBR_ADDR_LENGTH = defines WBR_FIFO's location address length = log2(WBR_DEPTH) | |
267 | -----------------------------------------------------------------------------------------------------------*/ | |
268 | parameter WBW_DEPTH = `WBW_DEPTH ; | |
269 | parameter WBW_ADDR_LENGTH = `WBW_ADDR_LENGTH ; | |
270 | parameter WBR_DEPTH = `WBR_DEPTH ; | |
271 | parameter WBR_ADDR_LENGTH = `WBR_ADDR_LENGTH ; | |
272 | ||
273 | /*----------------------------------------------------------------------------------------------------------- | |
274 | wbw_wallow = WBW_FIFO write allow wire - writes to FIFO are allowed when FIFO isn't full and write enable is 1 | |
275 | wbw_rallow = WBW_FIFO read allow wire - reads from FIFO are allowed when FIFO isn't empty and read enable is 1 | |
276 | -----------------------------------------------------------------------------------------------------------*/ | |
277 | wire wbw_wallow ; | |
278 | wire wbw_rallow ; | |
279 | ||
280 | /*----------------------------------------------------------------------------------------------------------- | |
281 | wbr_wallow = WBR_FIFO write allow wire - writes to FIFO are allowed when FIFO isn't full and write enable is 1 | |
282 | wbr_rallow = WBR_FIFO read allow wire - reads from FIFO are allowed when FIFO isn't empty and read enable is 1 | |
283 | -----------------------------------------------------------------------------------------------------------*/ | |
284 | wire wbr_wallow ; | |
285 | wire wbr_rallow ; | |
286 | ||
287 | /*----------------------------------------------------------------------------------------------------------- | |
288 | wires for address port conections from WBW_FIFO control logic to RAM blocks used for WBW_FIFO | |
289 | -----------------------------------------------------------------------------------------------------------*/ | |
290 | wire [(WBW_ADDR_LENGTH - 1):0] wbw_raddr ; | |
291 | wire [(WBW_ADDR_LENGTH - 1):0] wbw_waddr ; | |
292 | ||
293 | /*----------------------------------------------------------------------------------------------------------- | |
294 | wires for address port conections from WBR_FIFO control logic to RAM blocks used for WBR_FIFO | |
295 | -----------------------------------------------------------------------------------------------------------*/ | |
296 | wire [(WBR_ADDR_LENGTH - 1):0] wbr_raddr ; | |
297 | wire [(WBR_ADDR_LENGTH - 1):0] wbr_waddr ; | |
298 | ||
299 | /*----------------------------------------------------------------------------------------------------------- | |
300 | WBW_FIFO transaction counters: used to count incoming transactions and outgoing transactions. When number of | |
301 | input transactions is equal to number of output transactions, it means that there isn't any complete transaction | |
302 | currently present in the FIFO. | |
303 | -----------------------------------------------------------------------------------------------------------*/ | |
304 | reg [(WBW_ADDR_LENGTH - 2):0] wbw_inTransactionCount ; | |
305 | reg [(WBW_ADDR_LENGTH - 2):0] wbw_outTransactionCount ; | |
306 | ||
307 | /*----------------------------------------------------------------------------------------------------------- | |
308 | wires monitoring control bus. When control bus on a write transaction has a value of `LAST, it means that | |
309 | complete transaction is in the FIFO. When control bus on a read transaction has a value of `LAST, | |
310 | it means that there was one complete transaction taken out of FIFO. | |
311 | -----------------------------------------------------------------------------------------------------------*/ | |
312 | wire wbw_last_in = wbw_control_in[`LAST_CTRL_BIT] ; | |
313 | wire wbw_last_out = wbw_control_out[`LAST_CTRL_BIT] ; | |
314 | ||
315 | wire wbw_empty ; | |
316 | wire wbr_empty ; | |
317 | ||
318 | assign wbw_empty_out = wbw_empty ; | |
319 | assign wbr_empty_out = wbr_empty ; | |
320 | ||
321 | // clear wires for fifos | |
322 | wire wbw_clear = reset_in /*|| wbw_flush_in*/ ; // WBW_FIFO clear flush not used | |
323 | wire wbr_clear = reset_in /*|| wbr_flush_in*/ ; // WBR_FIFO clear - flush changed from asynchronous to synchronous | |
324 | ||
325 | /*----------------------------------------------------------------------------------------------------------- | |
326 | Definitions of wires for connecting RAM instances | |
327 | -----------------------------------------------------------------------------------------------------------*/ | |
328 | wire [39:0] dpram_portA_output ; | |
329 | wire [39:0] dpram_portB_output ; | |
330 | ||
331 | wire [39:0] dpram_portA_input = {wbw_control_in, wbw_cbe_in, wbw_addr_data_in} ; | |
332 | wire [39:0] dpram_portB_input = {wbr_control_in, wbr_be_in, wbr_data_in} ; | |
333 | ||
334 | /*----------------------------------------------------------------------------------------------------------- | |
335 | Fifo output assignments - each ram port provides data for different fifo | |
336 | -----------------------------------------------------------------------------------------------------------*/ | |
337 | assign wbw_control_out = dpram_portB_output[39:36] ; | |
338 | assign wbr_control_out = dpram_portA_output[39:36] ; | |
339 | ||
340 | assign wbw_cbe_out = dpram_portB_output[35:32] ; | |
341 | assign wbr_be_out = dpram_portA_output[35:32] ; | |
342 | ||
343 | assign wbw_addr_data_out = dpram_portB_output[31:0] ; | |
344 | assign wbr_data_out = dpram_portA_output[31:0] ; | |
345 | ||
346 | `ifdef WB_RAM_DONT_SHARE | |
347 | ||
348 | /*----------------------------------------------------------------------------------------------------------- | |
349 | Piece of code in this ifdef section is used in applications which can provide enough RAM instances to | |
350 | accomodate four fifos - each occupying its own instance of ram. Ports are connected in such a way, | |
351 | that instances of RAMs can be changed from two port to dual port ( async read/write port ). In that case, | |
352 | write port is always port a and read port is port b. | |
353 | -----------------------------------------------------------------------------------------------------------*/ | |
354 | ||
355 | /*----------------------------------------------------------------------------------------------------------- | |
356 | Pad redundant address lines with zeros. This may seem stupid, but it comes in perfect for FPGA impl. | |
357 | -----------------------------------------------------------------------------------------------------------*/ | |
358 | /* | |
359 | wire [(`WBW_FIFO_RAM_ADDR_LENGTH - WBW_ADDR_LENGTH - 1):0] wbw_addr_prefix = {( `WBW_FIFO_RAM_ADDR_LENGTH - WBW_ADDR_LENGTH){1'b0}} ; | |
360 | wire [(`WBR_FIFO_RAM_ADDR_LENGTH - WBR_ADDR_LENGTH - 1):0] wbr_addr_prefix = {( `WBR_FIFO_RAM_ADDR_LENGTH - WBR_ADDR_LENGTH){1'b0}} ; | |
361 | */ | |
362 | ||
363 | // compose complete port addresses | |
364 | wire [(`WB_FIFO_RAM_ADDR_LENGTH-1):0] wbw_whole_waddr = wbw_waddr ; | |
365 | wire [(`WB_FIFO_RAM_ADDR_LENGTH-1):0] wbw_whole_raddr = wbw_raddr ; | |
366 | ||
367 | wire [(`WB_FIFO_RAM_ADDR_LENGTH-1):0] wbr_whole_waddr = wbr_waddr ; | |
368 | wire [(`WB_FIFO_RAM_ADDR_LENGTH-1):0] wbr_whole_raddr = wbr_raddr ; | |
369 | ||
370 | wire wbw_read_enable = 1'b1 ; | |
371 | wire wbr_read_enable = 1'b1 ; | |
372 | ||
373 | `ifdef PCI_BIST | |
374 | wire mbist_so_o_internal ; // wires for connection of debug ports on two rams | |
375 | wire mbist_si_i_internal = mbist_so_o_internal ; | |
376 | `endif | |
377 | ||
378 | // instantiate and connect two generic rams - one for wishbone write fifo and one for wishbone read fifo | |
379 | pci_wb_tpram #(`WB_FIFO_RAM_ADDR_LENGTH, 40) wbw_fifo_storage | |
380 | ( | |
381 | /////////////////Generic synchronous two-port RAM interface | |
382 | .clk_a(wb_clock_in), | |
383 | .rst_a(reset_in), | |
384 | .ce_a(1'b1), | |
385 | .we_a(wbw_wallow), | |
386 | .oe_a(1'b1), | |
387 | .addr_a(wbw_whole_waddr), | |
388 | .di_a(dpram_portA_input), | |
389 | .do_a(), | |
390 | ||
391 | .clk_b(pci_clock_in), | |
392 | .rst_b(reset_in), | |
393 | .ce_b(wbw_read_enable), | |
394 | .we_b(1'b0), | |
395 | .oe_b(1'b1), | |
396 | .addr_b(wbw_whole_raddr), | |
397 | .di_b(40'h00_0000_0000), | |
398 | .do_b(dpram_portB_output) | |
399 | ||
400 | `ifdef PCI_BIST | |
401 | , | |
402 | .mbist_si_i (mbist_si_i), | |
403 | .mbist_so_o (mbist_so_o_internal), | |
404 | .mbist_ctrl_i (mbist_ctrl_i) | |
405 | `endif | |
406 | ); | |
407 | ||
408 | pci_wb_tpram #(`WB_FIFO_RAM_ADDR_LENGTH, 40) wbr_fifo_storage | |
409 | ( | |
410 | // Generic synchronous two-port RAM interface | |
411 | .clk_a(pci_clock_in), | |
412 | .rst_a(reset_in), | |
413 | .ce_a(1'b1), | |
414 | .we_a(wbr_wallow), | |
415 | .oe_a(1'b1), | |
416 | .addr_a(wbr_whole_waddr), | |
417 | .di_a(dpram_portB_input), | |
418 | .do_a(), | |
419 | ||
420 | .clk_b(wb_clock_in), | |
421 | .rst_b(reset_in), | |
422 | .ce_b(wbr_read_enable), | |
423 | .we_b(1'b0), | |
424 | .oe_b(1'b1), | |
425 | .addr_b(wbr_whole_raddr), | |
426 | .di_b(40'h00_0000_0000), | |
427 | .do_b(dpram_portA_output) | |
428 | ||
429 | `ifdef PCI_BIST | |
430 | , | |
431 | .mbist_si_i (mbist_si_i_internal), | |
432 | .mbist_so_o (mbist_so_o), | |
433 | .mbist_ctrl_i (mbist_ctrl_i) | |
434 | `endif | |
435 | ); | |
436 | ||
437 | ||
438 | `else // RAM blocks sharing between two fifos | |
439 | ||
440 | /*----------------------------------------------------------------------------------------------------------- | |
441 | Code section under this ifdef is used for implementation where RAM instances are too expensive. In this | |
442 | case one RAM instance is used for both - WISHBONE read and WISHBONE write fifo. | |
443 | -----------------------------------------------------------------------------------------------------------*/ | |
444 | /*----------------------------------------------------------------------------------------------------------- | |
445 | Address prefix definition - since both FIFOs reside in same RAM instance, storage is separated by MSB | |
446 | addresses. WISHBONE write fifo addresses are padded with zeros on the MSB side ( at least one address line | |
447 | must be used for this ), WISHBONE read fifo addresses are padded with ones on the right ( at least one ). | |
448 | -----------------------------------------------------------------------------------------------------------*/ | |
449 | wire [(`WB_FIFO_RAM_ADDR_LENGTH - WBW_ADDR_LENGTH - 1):0] wbw_addr_prefix = {( `WB_FIFO_RAM_ADDR_LENGTH - WBW_ADDR_LENGTH){1'b0}} ; | |
450 | wire [(`WB_FIFO_RAM_ADDR_LENGTH - WBR_ADDR_LENGTH - 1):0] wbr_addr_prefix = {( `WB_FIFO_RAM_ADDR_LENGTH - WBR_ADDR_LENGTH){1'b1}} ; | |
451 | ||
452 | /*----------------------------------------------------------------------------------------------------------- | |
453 | Port A address generation for RAM instance. RAM instance must be full two port RAM - read and write capability | |
454 | on both sides. | |
455 | Port A is clocked by WISHBONE clock, DIA is input for wbw_fifo, DOA is output for wbr_fifo. | |
456 | Address is multiplexed so operation can be switched between fifos. Default is a read on port. | |
457 | -----------------------------------------------------------------------------------------------------------*/ | |
458 | wire [(`WB_FIFO_RAM_ADDR_LENGTH-1):0] portA_addr = wbw_wallow ? {wbw_addr_prefix, wbw_waddr} : {wbr_addr_prefix, wbr_raddr} ; | |
459 | ||
460 | /*----------------------------------------------------------------------------------------------------------- | |
461 | Port B is clocked by PCI clock, DIB is input for wbr_fifo, DOB is output for wbw_fifo. | |
462 | Address is multiplexed so operation can be switched between fifos. Default is a read on port. | |
463 | -----------------------------------------------------------------------------------------------------------*/ | |
464 | wire [(`WB_FIFO_RAM_ADDR_LENGTH-1):0] portB_addr = wbr_wallow ? {wbr_addr_prefix, wbr_waddr} : {wbw_addr_prefix, wbw_raddr} ; | |
465 | ||
466 | wire portA_enable = 1'b1 ; | |
467 | ||
468 | wire portB_enable = 1'b1 ; | |
469 | ||
470 | // instantiate RAM for these two fifos | |
471 | pci_wb_tpram #(`WB_FIFO_RAM_ADDR_LENGTH, 40) wbu_fifo_storage | |
472 | ( | |
473 | // Generic synchronous two-port RAM interface | |
474 | .clk_a(wb_clock_in), | |
475 | .rst_a(reset_in), | |
476 | .ce_a(portA_enable), | |
477 | .we_a(wbw_wallow), | |
478 | .oe_a(1'b1), | |
479 | .addr_a(portA_addr), | |
480 | .di_a(dpram_portA_input), | |
481 | .do_a(dpram_portA_output), | |
482 | .clk_b(pci_clock_in), | |
483 | .rst_b(reset_in), | |
484 | .ce_b(portB_enable), | |
485 | .we_b(wbr_wallow), | |
486 | .oe_b(1'b1), | |
487 | .addr_b(portB_addr), | |
488 | .di_b(dpram_portB_input), | |
489 | .do_b(dpram_portB_output) | |
490 | ||
491 | `ifdef PCI_BIST | |
492 | , | |
493 | .mbist_si_i (mbist_si_i), | |
494 | .mbist_so_o (mbist_so_o), | |
495 | .mbist_ctrl_i (mbist_ctrl_i) | |
496 | `endif | |
497 | ); | |
498 | ||
499 | `endif | |
500 | ||
501 | ||
502 | /*----------------------------------------------------------------------------------------------------------- | |
503 | Instantiation of two control logic modules - one for WBW_FIFO and one for WBR_FIFO | |
504 | -----------------------------------------------------------------------------------------------------------*/ | |
505 | pci_wbw_fifo_control #(WBW_ADDR_LENGTH) wbw_fifo_ctrl | |
506 | ( | |
507 | .rclock_in(pci_clock_in), | |
508 | .wclock_in(wb_clock_in), | |
509 | .renable_in(wbw_renable_in), | |
510 | .wenable_in(wbw_wenable_in), | |
511 | .reset_in(reset_in), | |
512 | ////////////////////////////// .flush_in(wbw_flush_in), | |
513 | .almost_full_out(wbw_almost_full_out), | |
514 | .full_out(wbw_full_out), | |
515 | .empty_out(wbw_empty), | |
516 | .waddr_out(wbw_waddr), | |
517 | .raddr_out(wbw_raddr), | |
518 | .rallow_out(wbw_rallow), | |
519 | .wallow_out(wbw_wallow), | |
520 | .half_full_out(wbw_half_full_out) ////Robert, burst issue | |
521 | ); | |
522 | ||
523 | pci_wbr_fifo_control #(WBR_ADDR_LENGTH) wbr_fifo_ctrl | |
524 | ( .rclock_in(wb_clock_in), | |
525 | .wclock_in(pci_clock_in), | |
526 | .renable_in(wbr_renable_in), | |
527 | .wenable_in(wbr_wenable_in), | |
528 | .reset_in(reset_in), | |
529 | .flush_in(wbr_flush_in), | |
530 | .empty_out(wbr_empty), | |
531 | .waddr_out(wbr_waddr), | |
532 | .raddr_out(wbr_raddr), | |
533 | .rallow_out(wbr_rallow), | |
534 | .wallow_out(wbr_wallow) | |
535 | ); | |
536 | ||
537 | ||
538 | // in and out transaction counters and grey codes | |
539 | reg [(WBW_ADDR_LENGTH-2):0] inGreyCount ; | |
540 | reg [(WBW_ADDR_LENGTH-2):0] outGreyCount ; | |
541 | wire [(WBW_ADDR_LENGTH-2):0] inNextGreyCount = {wbw_inTransactionCount[(WBW_ADDR_LENGTH-2)], wbw_inTransactionCount[(WBW_ADDR_LENGTH-2):1] ^ wbw_inTransactionCount[(WBW_ADDR_LENGTH-3):0]} ; | |
542 | wire [(WBW_ADDR_LENGTH-2):0] outNextGreyCount = {wbw_outTransactionCount[(WBW_ADDR_LENGTH-2)], wbw_outTransactionCount[(WBW_ADDR_LENGTH-2):1] ^ wbw_outTransactionCount[(WBW_ADDR_LENGTH-3):0]} ; | |
543 | ||
544 | // input transaction counter increment - when last data of transaction is written to fifo | |
545 | wire in_count_en = wbw_wallow && wbw_last_in ; | |
546 | ||
547 | // output transaction counter increment - when last data is on top of fifo and read from it | |
548 | wire out_count_en = wbw_renable_in && wbw_last_out ; | |
549 | ||
550 | // register holding grey coded count of incoming transactions | |
551 | always@(posedge wb_clock_in or posedge wbw_clear) | |
552 | begin | |
553 | if (wbw_clear) | |
554 | begin | |
555 | inGreyCount <= #3 0 ; | |
556 | end | |
557 | else | |
558 | if (in_count_en) | |
559 | inGreyCount <= #3 inNextGreyCount ; | |
560 | end | |
561 | ||
562 | wire [(WBW_ADDR_LENGTH-2):0] pci_clk_sync_inGreyCount ; | |
563 | reg [(WBW_ADDR_LENGTH-2):0] pci_clk_inGreyCount ; | |
564 | pci_synchronizer_flop #((WBW_ADDR_LENGTH - 1), 0) i_synchronizer_reg_inGreyCount | |
565 | ( | |
566 | .data_in (inGreyCount), | |
567 | .clk_out (pci_clock_in), | |
568 | .sync_data_out (pci_clk_sync_inGreyCount), | |
569 | .async_reset (wbw_clear) | |
570 | ) ; | |
571 | ||
572 | always@(posedge pci_clock_in or posedge wbw_clear) | |
573 | begin | |
574 | if (wbw_clear) | |
575 | pci_clk_inGreyCount <= #`FF_DELAY 0 ; | |
576 | else | |
577 | pci_clk_inGreyCount <= # `FF_DELAY pci_clk_sync_inGreyCount ; | |
578 | end | |
579 | ||
580 | // register holding grey coded count of outgoing transactions | |
581 | always@(posedge pci_clock_in or posedge wbw_clear) | |
582 | begin | |
583 | if (wbw_clear) | |
584 | begin | |
585 | outGreyCount <= #`FF_DELAY 0 ; | |
586 | end | |
587 | else | |
588 | if (out_count_en) | |
589 | outGreyCount <= #`FF_DELAY outNextGreyCount ; | |
590 | end | |
591 | ||
592 | // incoming transactions counter | |
593 | always@(posedge wb_clock_in or posedge wbw_clear) | |
594 | begin | |
595 | if (wbw_clear) | |
596 | wbw_inTransactionCount <= #`FF_DELAY 1 ; | |
597 | else | |
598 | if (in_count_en) | |
599 | wbw_inTransactionCount <= #`FF_DELAY wbw_inTransactionCount + 1'b1 ; | |
600 | end | |
601 | ||
602 | // outgoing transactions counter | |
603 | always@(posedge pci_clock_in or posedge wbw_clear) | |
604 | begin | |
605 | if (wbw_clear) | |
606 | wbw_outTransactionCount <= 1 ; | |
607 | else | |
608 | if (out_count_en) | |
609 | wbw_outTransactionCount <= #`FF_DELAY wbw_outTransactionCount + 1'b1 ; | |
610 | end | |
611 | ||
612 | assign wbw_transaction_ready_out = pci_clk_inGreyCount != outGreyCount ; | |
613 | ||
614 | endmodule | |
615 |