1 //////////////////////////////////////////////////////////////////////
3 //// File name "wbw_wbr_fifos.v" ////
5 //// This file is part of the "PCI bridge" project ////
6 //// http://www.opencores.org/cores/pci/ ////
9 //// - Miha Dolenc (mihad@opencores.org) ////
11 //// All additional information is avaliable in the README ////
15 //////////////////////////////////////////////////////////////////////
17 //// Copyright (C) 2001 Miha Dolenc, mihad@opencores.org ////
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. ////
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. ////
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 ////
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 ////
40 //////////////////////////////////////////////////////////////////////
42 // CVS Revision History
44 // $Log: pci_wbw_wbr_fifos.v,v $
45 // Revision 1.1 2007-03-20 17:50:56 sithglan
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.
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.
59 // Revision 1.5 2003/10/17 09:11:52 markom
60 // mbist signals updated according to newest convention
62 // Revision 1.4 2003/08/14 13:06:03 simons
63 // synchronizer_flop replaced with pci_synchronizer_flop, artisan ram instance updated.
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.
70 // Revision 1.2 2003/01/30 22:01:09 mihad
71 // Updated synchronization in top level fifo modules.
73 // Revision 1.1 2003/01/27 16:49:31 mihad
74 // Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed.
76 // Revision 1.9 2002/10/18 03:36:37 tadejm
77 // Changed wrong signal name mbist_sen into mbist_ctrl_i.
79 // Revision 1.8 2002/10/17 22:49:22 tadejm
80 // Changed BIST signals for RAMs.
82 // Revision 1.7 2002/10/11 10:09:01 mihad
83 // Added additional testcase and changed rst name in BIST to trst
85 // Revision 1.6 2002/10/08 17:17:06 mihad
86 // Added BIST signals for RAMs.
88 // Revision 1.5 2002/09/30 16:03:04 mihad
89 // Added meta flop module for easier meta stable FF identification during synthesis
91 // Revision 1.4 2002/09/25 15:53:52 mihad
92 // Removed all logic from asynchronous reset network
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
97 // Revision 1.2 2001/10/05 08:20:12 mihad
98 // Updated all files with inclusion of timescale file for simulation purposes.
100 // Revision 1.1.1.1 2001/10/02 15:33:47 mihad
101 // New project directory structure
105 `include "pci_constants.v"
107 // synopsys translate_off
108 `include "timescale.v"
109 // synopsys translate_on
113 module pci_wbw_wbr_fifos
126 // wbw_flush_in, write fifo flush not used
130 wbw_transaction_ready_out,
131 wbw_half_full_out, ////Robert, burst issue
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
153 /*-----------------------------------------------------------------------------------------------------------
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 ;
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
166 wbw_wenable_in = write enable input for WBW_FIFO - driven by WISHBONE slave interface
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
174 wbw_renable_in = read enable input driven by PCI master interface
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
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 ;
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 ;
201 // input wbw_flush_in ; // not used
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
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,
215 wbr_wenable_in = write enable input for WBR_FIFO - driven by PCI master interface
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
223 wbr_renable_in = read enable input driven by WISHBONE slave interface
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
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 ;
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 ;
250 output wbr_empty_out ;
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
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 ;
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 -----------------------------------------------------------------------------------------------------------*/
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 -----------------------------------------------------------------------------------------------------------*/
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 ;
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 ;
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 ;
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] ;
318 assign wbw_empty_out = wbw_empty ;
319 assign wbr_empty_out = wbr_empty ;
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
325 /*-----------------------------------------------------------------------------------------------------------
326 Definitions of wires for connecting RAM instances
327 -----------------------------------------------------------------------------------------------------------*/
328 wire [39:0] dpram_portA_output ;
329 wire [39:0] dpram_portB_output ;
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} ;
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] ;
340 assign wbw_cbe_out = dpram_portB_output[35:32] ;
341 assign wbr_be_out = dpram_portA_output[35:32] ;
343 assign wbw_addr_data_out = dpram_portB_output[31:0] ;
344 assign wbr_data_out = dpram_portA_output[31:0] ;
346 `ifdef WB_RAM_DONT_SHARE
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 -----------------------------------------------------------------------------------------------------------*/
355 /*-----------------------------------------------------------------------------------------------------------
356 Pad redundant address lines with zeros. This may seem stupid, but it comes in perfect for FPGA impl.
357 -----------------------------------------------------------------------------------------------------------*/
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}} ;
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 ;
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 ;
370 wire wbw_read_enable = 1'b1 ;
371 wire wbr_read_enable = 1'b1 ;
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 ;
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
381 /////////////////Generic synchronous two-port RAM interface
387 .addr_a(wbw_whole_waddr),
388 .di_a(dpram_portA_input),
391 .clk_b(pci_clock_in),
393 .ce_b(wbw_read_enable),
396 .addr_b(wbw_whole_raddr),
397 .di_b(40'h00_0000_0000),
398 .do_b(dpram_portB_output)
402 .mbist_si_i (mbist_si_i),
403 .mbist_so_o (mbist_so_o_internal),
404 .mbist_ctrl_i (mbist_ctrl_i)
408 pci_wb_tpram #(`WB_FIFO_RAM_ADDR_LENGTH, 40) wbr_fifo_storage
410 // Generic synchronous two-port RAM interface
411 .clk_a(pci_clock_in),
416 .addr_a(wbr_whole_waddr),
417 .di_a(dpram_portB_input),
422 .ce_b(wbr_read_enable),
425 .addr_b(wbr_whole_raddr),
426 .di_b(40'h00_0000_0000),
427 .do_b(dpram_portA_output)
431 .mbist_si_i (mbist_si_i_internal),
432 .mbist_so_o (mbist_so_o),
433 .mbist_ctrl_i (mbist_ctrl_i)
438 `else // RAM blocks sharing between two fifos
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}} ;
452 /*-----------------------------------------------------------------------------------------------------------
453 Port A address generation for RAM instance. RAM instance must be full two port RAM - read and write capability
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} ;
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} ;
466 wire portA_enable = 1'b1 ;
468 wire portB_enable = 1'b1 ;
470 // instantiate RAM for these two fifos
471 pci_wb_tpram #(`WB_FIFO_RAM_ADDR_LENGTH, 40) wbu_fifo_storage
473 // Generic synchronous two-port RAM interface
480 .di_a(dpram_portA_input),
481 .do_a(dpram_portA_output),
482 .clk_b(pci_clock_in),
488 .di_b(dpram_portB_input),
489 .do_b(dpram_portB_output)
493 .mbist_si_i (mbist_si_i),
494 .mbist_so_o (mbist_so_o),
495 .mbist_ctrl_i (mbist_ctrl_i)
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
507 .rclock_in(pci_clock_in),
508 .wclock_in(wb_clock_in),
509 .renable_in(wbw_renable_in),
510 .wenable_in(wbw_wenable_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
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),
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)
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]} ;
544 // input transaction counter increment - when last data of transaction is written to fifo
545 wire in_count_en = wbw_wallow && wbw_last_in ;
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 ;
550 // register holding grey coded count of incoming transactions
551 always@(posedge wb_clock_in or posedge wbw_clear)
555 inGreyCount <= #3 0 ;
559 inGreyCount <= #3 inNextGreyCount ;
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
566 .data_in (inGreyCount),
567 .clk_out (pci_clock_in),
568 .sync_data_out (pci_clk_sync_inGreyCount),
569 .async_reset (wbw_clear)
572 always@(posedge pci_clock_in or posedge wbw_clear)
575 pci_clk_inGreyCount <= #`FF_DELAY 0 ;
577 pci_clk_inGreyCount <= # `FF_DELAY pci_clk_sync_inGreyCount ;
580 // register holding grey coded count of outgoing transactions
581 always@(posedge pci_clock_in or posedge wbw_clear)
585 outGreyCount <= #`FF_DELAY 0 ;
589 outGreyCount <= #`FF_DELAY outNextGreyCount ;
592 // incoming transactions counter
593 always@(posedge wb_clock_in or posedge wbw_clear)
596 wbw_inTransactionCount <= #`FF_DELAY 1 ;
599 wbw_inTransactionCount <= #`FF_DELAY wbw_inTransactionCount + 1'b1 ;
602 // outgoing transactions counter
603 always@(posedge pci_clock_in or posedge wbw_clear)
606 wbw_outTransactionCount <= 1 ;
609 wbw_outTransactionCount <= #`FF_DELAY wbw_outTransactionCount + 1'b1 ;
612 assign wbw_transaction_ready_out = pci_clk_inGreyCount != outGreyCount ;