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