OpenCores
URL https://opencores.org/ocsvn/pci/pci/trunk

Subversion Repositories pci

[/] [pci/] [tags/] [working_demo/] [rtl/] [verilog/] [pciw_pcir_fifos.v] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 mihad
//////////////////////////////////////////////////////////////////////
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: not supported by cvs2svn $
45
//
46
 
47
`include "constants.v"
48
 
49
module PCIW_PCIR_FIFOS
50
(
51
    wb_clock_in,
52
    pci_clock_in,
53
    reset_in,
54
    pciw_wenable_in,
55
    pciw_addr_data_in,
56
    pciw_cbe_in,
57
    pciw_control_in,
58
    pciw_renable_in,
59
    pciw_addr_data_out,
60
    pciw_cbe_out,
61
    pciw_control_out,
62
    pciw_flush_in,
63
    pciw_two_left_out,
64
    pciw_almost_full_out,
65
    pciw_full_out,
66
    pciw_almost_empty_out,
67
    pciw_empty_out,
68
    pciw_transaction_ready_out,
69
    pcir_wenable_in,
70
    pcir_data_in,
71
    pcir_be_in,
72
    pcir_control_in,
73
    pcir_renable_in,
74
    pcir_data_out,
75
    pcir_be_out,
76
    pcir_control_out,
77
    pcir_flush_in,
78
    pcir_almost_full_out,
79
    pcir_full_out,
80
    pcir_almost_empty_out,
81
    pcir_empty_out,
82
    pcir_transaction_ready_out
83
) ;
84
 
85
/*-----------------------------------------------------------------------------------------------------------
86
System inputs:
87
wb_clock_in - WISHBONE bus clock
88
pci_clock_in - PCI bus clock
89
reset_in - reset from control logic
90
-------------------------------------------------------------------------------------------------------------*/
91
input wb_clock_in, pci_clock_in, reset_in ;
92
 
93
/*-----------------------------------------------------------------------------------------------------------
94
PCI WRITE FIFO interface signals prefixed with pciw_ - FIFO is used for posted writes initiated by external
95
PCI master through PCI target interface, traveling through FIFO and are completed on WISHBONE by
96
WISHBONE master interface
97
 
98
write enable signal:
99
pciw_wenable_in = write enable input for PCIW_FIFO - driven by PCI TARGET interface
100
 
101
data input signals:
102
pciw_addr_data_in = data input - data from PCI bus - first entry of transaction is address others are data entries
103
pciw_cbe_in       = bus command/byte enable(~#BE[3:0]) input - first entry of transaction is bus command, other are byte enables
104
pciw_control_in   = control input - encoded control bus input
105
 
106
read enable signal:
107
pciw_renable_in = read enable input driven by WISHBONE master interface
108
 
109
data output signals:
110
pciw_addr_data_out = data output - data from PCI bus - first entry of transaction is address, others are data entries
111
pciw_cbe_out      = bus command/byte enable output - first entry of transaction is bus command, others are byte enables
112
pciw_control_out = control input - encoded control bus input
113
 
114
status signals - monitored by various resources in the core
115
pciw_flush_in = flush signal input for PCIW_FIFO - when asserted, fifo is flushed(emptied)
116
pciw_almost_full_out = almost full output from PCIW_FIFO
117
pciw_full_out = full output from PCIW_FIFO
118
pciw_almost_empty_out = almost empty output from PCIW_FIFO
119
pciw_empty_out = empty output from PCIW_FIFO
120
pciw_transaction_ready_out = output indicating that one complete transaction is waiting in PCIW_FIFO
121
-----------------------------------------------------------------------------------------------------------*/
122
// input control and data
123
input        pciw_wenable_in ;
124
input [31:0] pciw_addr_data_in ;
125
input [3:0]  pciw_cbe_in ;
126
input [3:0]  pciw_control_in ;
127
 
128
// output control and data
129
input         pciw_renable_in ;
130
output [31:0] pciw_addr_data_out ;
131
output [3:0]  pciw_cbe_out ;
132
output [3:0]  pciw_control_out ;
133
 
134
// flush input
135
input pciw_flush_in ;
136
 
137
// status outputs
138
output pciw_two_left_out ;
139
output pciw_almost_full_out ;
140
output pciw_full_out ;
141
output pciw_almost_empty_out ;
142
output pciw_empty_out ;
143
output pciw_transaction_ready_out ;
144
 
145
/*-----------------------------------------------------------------------------------------------------------
146
PCI READ FIFO interface signals prefixed with pcir_ - FIFO is used for holding delayed read completions
147
initiated by master on PCI bus and completed on WISHBONE bus,
148
 
149
write enable signal:
150
pcir_wenable_in = write enable input for PCIR_FIFO - driven by WISHBONE master interface
151
 
152
data input signals:
153
pcir_data_in      = data input - data from WISHBONE bus - there is no address entry here, since address is stored in separate register
154
pcir_be_in        = byte enable(~SEL[3:0]) input - byte enables - same through one transaction
155
pcir_control_in   = control input - encoded control bus input
156
 
157
read enable signal:
158
pcir_renable_in = read enable input driven by PCI target interface
159
 
160
data output signals:
161
pcir_data_out = data output - data from WISHBONE bus
162
pcir_be_out      = byte enable output(~SEL)
163
pcir_control_out = control output - encoded control bus output
164
 
165
status signals - monitored by various resources in the core
166
pcir_flush_in = flush signal input for PCIR_FIFO - when asserted, fifo is flushed(emptied)
167
pcir_almost_full_out = almost full output from PCIR_FIFO
168
pcir full_out = full output from PCIR_FIFO
169
pcir_almost_empty_out = almost empty output from PCIR_FIFO
170
pcir_empty_out = empty output from PCIR_FIFO
171
pcir_transaction_ready_out = output indicating that one complete transaction is waiting in PCIR_FIFO
172
-----------------------------------------------------------------------------------------------------------*/
173
// input control and data
174
input        pcir_wenable_in ;
175
input [31:0] pcir_data_in ;
176
input [3:0]  pcir_be_in ;
177
input [3:0]  pcir_control_in ;
178
 
179
// output control and data
180
input         pcir_renable_in ;
181
output [31:0] pcir_data_out ;
182
output [3:0]  pcir_be_out ;
183
output [3:0]  pcir_control_out ;
184
 
185
// flush input
186
input pcir_flush_in ;
187
 
188
// status outputs
189
output pcir_almost_full_out ;
190
output pcir_full_out ;
191
output pcir_almost_empty_out ;
192
output pcir_empty_out ;
193
output pcir_transaction_ready_out ;
194
 
195
/*-----------------------------------------------------------------------------------------------------------
196
Address length parameters:
197
PCIW_DEPTH = defines PCIW_FIFO depth
198
PCIR_DEPTH = defines PCIR_FIFO depth
199
PCIW_ADDR_LENGTH = defines PCIW_FIFO's location address length - log2(PCIW_DEPTH)
200
PCIR_ADDR_LENGTH = defines PCIR_FIFO's location address length - log2(PCIR_DEPTH)
201
-----------------------------------------------------------------------------------------------------------*/
202
parameter PCIW_DEPTH = `PCIW_DEPTH ;
203
parameter PCIW_ADDR_LENGTH = `PCIW_ADDR_LENGTH ;
204
parameter PCIR_DEPTH = `PCIR_DEPTH ;
205
parameter PCIR_ADDR_LENGTH = `PCIR_ADDR_LENGTH ;
206
 
207
// obvious
208
wire vcc = 1'b1 ;
209
wire gnd = 1'b0 ;
210
 
211
/*-----------------------------------------------------------------------------------------------------------
212
pciw_wallow = PCIW_FIFO write allow wire - writes to FIFO are allowed when FIFO isn't full and write enable is 1
213
pciw_rallow = PCIW_FIFO read allow wire - reads from FIFO are allowed when FIFO isn't empty and read enable is 1
214
-----------------------------------------------------------------------------------------------------------*/
215
wire pciw_wallow ;
216
wire pciw_rallow ;
217
 
218
/*-----------------------------------------------------------------------------------------------------------
219
pcir_wallow = PCIR_FIFO write allow wire - writes to FIFO are allowed when FIFO isn't full and write enable is 1
220
pcir_rallow = PCIR_FIFO read allow wire - reads from FIFO are allowed when FIFO isn't empty and read enable is 1
221
-----------------------------------------------------------------------------------------------------------*/
222
wire pcir_wallow ;
223
wire pcir_rallow ;
224
 
225
/*-----------------------------------------------------------------------------------------------------------
226
wires for address port conections from PCIW_FIFO control logic to RAM blocks used for PCIW_FIFO
227
-----------------------------------------------------------------------------------------------------------*/
228
wire [(PCIW_ADDR_LENGTH - 1):0] pciw_raddr ;
229
wire [(PCIW_ADDR_LENGTH - 1):0] pciw_waddr ;
230
 
231
/*-----------------------------------------------------------------------------------------------------------
232
wires for address port conections from PCIR_FIFO control logic to RAM blocks used for PCIR_FIFO
233
-----------------------------------------------------------------------------------------------------------*/
234
wire [(PCIR_ADDR_LENGTH - 1):0] pcir_raddr ;
235
wire [(PCIR_ADDR_LENGTH - 1):0] pcir_waddr ;
236
 
237
/*-----------------------------------------------------------------------------------------------------------
238
PCIW_FIFO transaction counters: used to count incoming transactions and outgoing transactions. When number of
239
input transactions is equal to number of output transactions, it means that there isn't any complete transaction
240
currently present in the FIFO.
241
-----------------------------------------------------------------------------------------------------------*/
242
reg [(PCIW_ADDR_LENGTH - 1):0] pciw_inTransactionCount ;
243
reg [(PCIW_ADDR_LENGTH - 1):0] pciw_outTransactionCount ;
244
 
245
/*-----------------------------------------------------------------------------------------------------------
246
FlipFlops for indicating if complete delayed read completion is present in the FIFO
247
-----------------------------------------------------------------------------------------------------------*/
248
/*reg pcir_inTransactionCount ;
249
reg pcir_outTransactionCount ;*/
250
/*-----------------------------------------------------------------------------------------------------------
251
wires monitoring control bus. When control bus on a write transaction has a value of `LAST, it means that
252
complete transaction is in the FIFO. When control bus on a read transaction has a value of `LAST,
253
it means that there was one complete transaction taken out of FIFO.
254
-----------------------------------------------------------------------------------------------------------*/
255
wire pciw_last_in  = pciw_control_in[`LAST_CTRL_BIT] ;
256
wire pciw_last_out = pciw_control_out[`LAST_CTRL_BIT] ;
257
 
258
/*wire pcir_last_in  = pcir_wallow && (pcir_control_in == `LAST) ;
259
wire pcir_last_out = pcir_rallow && (pcir_control_out == `LAST) ;*/
260
 
261
wire pciw_empty ;
262
wire pcir_empty ;
263
 
264
assign pciw_empty_out = pciw_empty ;
265
assign pcir_empty_out = pcir_empty ;
266
 
267
// clear wires for clearing FFs and registers
268
wire pciw_clear = reset_in || pciw_flush_in ; // PCIW_FIFO's clear signal
269
wire pcir_clear = reset_in || pcir_flush_in ; // PCIR_FIFO's clear signal
270
 
271
`ifdef FPGA
272
/*-----------------------------------------------------------------------------------------------------------
273
this code is included only for FPGA core usage - somewhat different logic because of sharing
274
one block selectRAM+ between two FIFOs
275
-----------------------------------------------------------------------------------------------------------*/
276
    `ifdef BIG
277
        /*-----------------------------------------------------------------------------------------------------------
278
        Big FPGAs
279
        PCIW_FIFO and PCIR_FIFO address prefixes - used for extending read and write addresses because of varible
280
        FIFO depth and fixed SelectRAM+ size. Addresses are zero paded on the left to form long enough address
281
        -----------------------------------------------------------------------------------------------------------*/
282
        wire [(7 - PCIW_ADDR_LENGTH):0] pciw_addr_prefix = {( 8 - PCIW_ADDR_LENGTH){1'b0}} ;
283
        wire [(7 - PCIR_ADDR_LENGTH):0] pcir_addr_prefix = {( 8 - PCIR_ADDR_LENGTH){1'b0}} ;
284
 
285
        // compose addresses
286
        wire [7:0] pciw_whole_waddr = {pciw_addr_prefix, pciw_waddr} ;
287
        wire [7:0] pciw_whole_raddr = {pciw_addr_prefix, pciw_raddr} ;
288
 
289
        wire [7:0] pcir_whole_waddr = {pcir_addr_prefix, pcir_waddr} ;
290
        wire [7:0] pcir_whole_raddr = {pcir_addr_prefix, pcir_raddr} ;
291
 
292
        /*-----------------------------------------------------------------------------------------------------------
293
        Only 8 bits out of 16 are used in ram3 and ram6 - wires for referencing them
294
        -----------------------------------------------------------------------------------------------------------*/
295
        wire [15:0] dpram3_portB_output ;
296
        wire [15:0] dpram6_portA_output ;
297
 
298
        /*-----------------------------------------------------------------------------------------------------------
299
        Control out assignements from ram3 output
300
        -----------------------------------------------------------------------------------------------------------*/
301
        assign pciw_control_out = dpram3_portB_output[15:12] ;
302
        assign pcir_control_out = dpram6_portA_output[15:12] ;
303
 
304
        assign pciw_cbe_out = dpram3_portB_output[3:0] ;
305
        assign pcir_be_out  = dpram6_portA_output[3:0] ;
306
 
307
        wire pciw_read_enable = pciw_rallow || pciw_empty ;
308
        wire pcir_read_enable = pcir_rallow || pcir_empty ;
309
 
310
        // Block SelectRAM+ cells instantiation
311
        RAMB4_S16_S16 dpram16_1 (.ADDRA(pciw_whole_waddr), .DIA(pciw_addr_data_in[15:0]),
312
                                 .ENA(vcc), .RSTA(reset_in),
313
                                 .CLKA(pci_clock_in), .WEA(pciw_wallow),
314
                                 .DOA(),
315
                                 .ADDRB(pciw_whole_raddr), .DIB(16'h0000),
316
                                 .ENB(pciw_read_enable), .RSTB(reset_in),
317
                                 .CLKB(wb_clock_in), .WEB(gnd),
318
                                 .DOB(pciw_addr_data_out[15:0])) ;
319
 
320
        RAMB4_S16_S16 dpram16_2 (.ADDRA(pciw_whole_waddr), .DIA(pciw_addr_data_in[31:16]),
321
                                 .ENA(vcc), .RSTA(reset_in),
322
                                 .CLKA(pci_clock_in), .WEA(pciw_wallow),
323
                                 .DOA(),
324
                                 .ADDRB(pciw_whole_raddr), .DIB(16'h0000),
325
                                 .ENB(pciw_read_enable), .RSTB(reset_in),
326
                                 .CLKB(wb_clock_in), .WEB(gnd),
327
                                 .DOB(pciw_addr_data_out[31:16])) ;
328
 
329
        RAMB4_S16_S16 dpram16_3 (.ADDRA(pciw_whole_waddr), .DIA({pciw_control_in, 8'h00, pciw_cbe_in}),
330
                                 .ENA(vcc), .RSTA(reset_in),
331
                                 .CLKA(pci_clock_in), .WEA(pciw_wallow),
332
                                 .DOA(),
333
                                 .ADDRB(pciw_whole_raddr), .DIB(16'h0000),
334
                                 .ENB(pciw_read_enable), .RSTB(reset_in),
335
                                 .CLKB(wb_clock_in), .WEB(gnd),
336
                                 .DOB(dpram3_portB_output)) ;
337
 
338
        RAMB4_S16_S16 dpram16_4 (.ADDRA(pcir_whole_raddr), .DIA(16'h0000),
339
                                 .ENA(pcir_read_enable), .RSTA(reset_in),
340
                                 .CLKA(pci_clock_in), .WEA(gnd),
341
                                 .DOA(pcir_data_out[15:0]),
342
                                 .ADDRB(pcir_whole_waddr), .DIB(pcir_data_in[15:0]),
343
                                 .ENB(vcc), .RSTB(reset_in),
344
                                 .CLKB(wb_clock_in), .WEB(pcir_wallow),
345
                                 .DOB()) ;
346
 
347
        RAMB4_S16_S16 dpram16_5 (.ADDRA(pcir_whole_raddr), .DIA(16'h0000),
348
                                 .ENA(pcir_read_enable), .RSTA(reset_in),
349
                                 .CLKA(pci_clock_in), .WEA(gnd),
350
                                 .DOA(pcir_data_out[31:16]),
351
                                 .ADDRB(pcir_whole_waddr), .DIB(pcir_data_in[31:16]),
352
                                 .ENB(vcc), .RSTB(reset_in),
353
                                 .CLKB(wb_clock_in), .WEB(pcir_wallow),
354
                                 .DOB()) ;
355
 
356
        RAMB4_S16_S16 dpram16_6 (.ADDRA(pcir_whole_raddr), .DIA(16'h0000),
357
                                 .ENA(pcir_read_enable), .RSTA(reset_in),
358
                                 .CLKA(pci_clock_in), .WEA(gnd),
359
                                 .DOA(dpram6_portA_output),
360
                                 .ADDRB(pcir_whole_waddr), .DIB({pcir_control_in, 8'h00, pcir_be_in}),
361
                                 .ENB(vcc), .RSTB(reset_in),
362
                                 .CLKB(wb_clock_in), .WEB(pcir_wallow),
363
                                 .DOB()) ;
364
 
365
    `else // SMALL FPGAs
366
 
367
        /*-----------------------------------------------------------------------------------------------------------
368
        Small FPGAs
369
        PCIW_FIFO and PCIR_FIFO address prefixes - used for extending read and write addresses because of varible
370
        FIFO depth and fixed SelectRAM+ size. Addresses are always paded, because of RAM sharing between FIFOs
371
        PCIW addresses are zero padded on the left, PCIR addresses are padded
372
        with ones on the left
373
        -----------------------------------------------------------------------------------------------------------*/
374
        wire [(7 - PCIW_ADDR_LENGTH):0] pciw_addr_prefix = {( 8 - PCIW_ADDR_LENGTH){1'b0}} ;
375
        wire [(7 - PCIR_ADDR_LENGTH):0] pcir_addr_prefix = {( 8 - PCIR_ADDR_LENGTH){1'b1}} ;
376
 
377
        /*-----------------------------------------------------------------------------------------------------------
378
        Only 8 bits out of 16 are used in ram3 - wires for referencing them
379
        -----------------------------------------------------------------------------------------------------------*/
380
        wire [15:0] dpram3_portA_output ;
381
        wire [15:0] dpram3_portB_output ;
382
 
383
        /*-----------------------------------------------------------------------------------------------------------
384
        Control out assignements from ram3 output
385
        -----------------------------------------------------------------------------------------------------------*/
386
        assign pciw_control_out = dpram3_portB_output[15:12] ;
387
        assign pcir_control_out = dpram3_portA_output[15:12] ;
388
 
389
        assign pciw_cbe_out = dpram3_portB_output[3:0] ;
390
        assign pcir_be_out  = dpram3_portA_output[3:0] ;
391
 
392
        /*-----------------------------------------------------------------------------------------------------------
393
        Logic used for extending port's enable input for one clock cycle to allow address and date change from
394
        PCI write fifo's write address and data back to PCI read fifo's address and data ( turnaround cycle )
395
        -----------------------------------------------------------------------------------------------------------*/
396
        reg pciw_write_performed ;
397
        always@(posedge pci_clock_in or posedge reset_in)
398
        begin
399
            if (reset_in)
400
                pciw_write_performed <= #`FF_DELAY 1'b0 ;
401
            else
402
                pciw_write_performed <= #`FF_DELAY pciw_wallow ;
403
        end
404
 
405
        /*-----------------------------------------------------------------------------------------------------------
406
        Logic used for extending port's enable input for one clock cycle to allow address and date change from
407
        PCI read fifo's write address and data back to PCI write fifo's address and data ( turnaround cycle )
408
        -----------------------------------------------------------------------------------------------------------*/
409
        reg pcir_write_performed ;
410
        always@(posedge wb_clock_in or posedge reset_in)
411
        begin
412
            if (reset_in)
413
                pcir_write_performed <= #`FF_DELAY 1'b0 ;
414
            else
415
                pcir_write_performed <= #`FF_DELAY pcir_wallow ;
416
        end
417
 
418
        /*-----------------------------------------------------------------------------------------------------------
419
        Additional register storing actual PCIW read address. It must be applied to port B during turnaround cycle
420
        -----------------------------------------------------------------------------------------------------------*/
421
        reg [(PCIW_ADDR_LENGTH - 1):0] pciw_raddr_0 ;
422
 
423
        always@(posedge wb_clock_in or posedge pciw_clear)
424
        begin
425
            if (pciw_clear)
426
                pciw_raddr_0 <= #`FF_DELAY {PCIW_ADDR_LENGTH{1'b0}} ;
427
            else
428
                if(pciw_rallow)
429
                    pciw_raddr_0 <= #`FF_DELAY pciw_raddr ;
430
        end
431
 
432
        wire [(PCIW_ADDR_LENGTH - 1):0] pciw_raddr_calc = pcir_write_performed ? pciw_raddr_0 : pciw_raddr ;
433
 
434
        /*-----------------------------------------------------------------------------------------------------------
435
        Additional register storing actual PCIR read address. It must be applied to port A during turnaround cycle
436
        -----------------------------------------------------------------------------------------------------------*/
437
        reg [(PCIR_ADDR_LENGTH - 1):0] pcir_raddr_0 ;
438
 
439
        always@(posedge pci_clock_in or posedge pcir_clear)
440
        begin
441
            if(pcir_clear)
442
                pcir_raddr_0 <= #`FF_DELAY {PCIR_ADDR_LENGTH{1'b0}} ;
443
            else
444
                if(pcir_rallow)
445
                    pcir_raddr_0 <= #`FF_DELAY pcir_raddr ;
446
        end
447
 
448
        wire [(PCIR_ADDR_LENGTH - 1):0] pcir_raddr_calc = pciw_write_performed ? pcir_raddr_0 : pcir_raddr ;
449
 
450
        /*-----------------------------------------------------------------------------------------------------------
451
        Port A and B enables
452
        -----------------------------------------------------------------------------------------------------------*/
453
        wire portA_enable = pciw_wallow || pcir_rallow || pcir_empty || pciw_write_performed ;
454
        wire portB_enable = pcir_wallow || pciw_rallow || pciw_empty || pcir_write_performed ;
455
 
456
        /*-----------------------------------------------------------------------------------------------------------
457
        Port A address generation for block SelectRam+ in SpartanII or Virtex
458
        Port A is clocked by PCI clock, DIA is input for pciw_fifo, DOA is output for pcir_fifo. Address is multiplexed
459
        between two values.
460
        Address multiplexing:
461
        pciw_wenable == 1 => ADDRA = pciw_waddr (write pointer of PCIW_FIFO)
462
        else                ADDRA = pcir_raddr (read pointer of PCIR_FIFO)
463
        -----------------------------------------------------------------------------------------------------------*/
464
        wire [7:0] portA_addr = pciw_wallow ? {pciw_addr_prefix, pciw_waddr} : {pcir_addr_prefix, pcir_raddr_calc} ;
465
 
466
        /*-----------------------------------------------------------------------------------------------------------
467
        Port B address generation for block SelectRam+ in SpartanII or Virtex
468
        Port B is clocked by PCI clock, DIB is input for pcir_fifo, DOB is output for pciw_fifo. Address is multiplexed
469
        between two values.
470
        Address multiplexing:
471
        pcir_wenable == 1 => ADDRB = pcir_waddr (write pointer of PCIR_FIFO)
472
        else                ADDRB = pciw_raddr (read pointer of PCIW_FIFO)
473
        -----------------------------------------------------------------------------------------------------------*/
474
        wire [7:0] portB_addr = pcir_wallow ? {pcir_addr_prefix, pcir_waddr} : {pciw_addr_prefix, pciw_raddr_calc} ;
475
 
476
        // Block SelectRAM+ cells instantiation
477
        RAMB4_S16_S16 dpram16_1 (.ADDRA(portA_addr), .DIA(pciw_addr_data_in[15:0]),
478
                                 .ENA(portA_enable), .RSTA(reset_in),
479
                                 .CLKA(pci_clock_in), .WEA(pciw_wallow),
480
                                 .DOA(pcir_data_out[15:0]),
481
                                 .ADDRB(portB_addr), .DIB(pcir_data_in[15:0]),
482
                                 .ENB(portB_enable), .RSTB(reset_in),
483
                                 .CLKB(wb_clock_in), .WEB(pcir_wallow),
484
                                 .DOB(pciw_addr_data_out[15:0])) ;
485
 
486
        RAMB4_S16_S16 dpram16_2 (.ADDRA(portA_addr), .DIA(pciw_addr_data_in[31:16]),
487
                                 .ENA(portA_enable), .RSTA(reset_in),
488
                                 .CLKA(pci_clock_in), .WEA(pciw_wallow),
489
                                 .DOA(pcir_data_out[31:16]),
490
                                 .ADDRB(portB_addr), .DIB(pcir_data_in[31:16]),
491
                                 .ENB(portB_enable), .RSTB(reset_in),
492
                                 .CLKB(wb_clock_in), .WEB(pcir_wallow),
493
                                 .DOB(pciw_addr_data_out[31:16])) ;
494
 
495
        RAMB4_S16_S16 dpram16_3 (.ADDRA(portA_addr), .DIA({pciw_control_in, 8'h00, pciw_cbe_in}),
496
                                 .ENA(portA_enable), .RSTA(reset_in),
497
                                 .CLKA(pci_clock_in), .WEA(pciw_wallow),
498
                                 .DOA(dpram3_portA_output),
499
                                 .ADDRB(portB_addr), .DIB({pcir_control_in, 8'h00, pcir_be_in}),
500
                                 .ENB(portB_enable), .RSTB(reset_in),
501
                                 .CLKB(wb_clock_in), .WEB(pcir_wallow),
502
                                 .DOB(dpram3_portB_output)) ;
503
    `endif
504
 
505
 
506
 
507
 
508
 
509
`else
510
    wire [39:0] pciw_ram_data_out ;
511
    wire [39:0] pciw_ram_data_in = {pciw_control_in, pciw_cbe_in, pciw_addr_data_in} ;
512
    wire [39:0] pcir_ram_data_in = {pcir_control_in, pcir_be_in, pcir_data_in} ;
513
    wire [39:0] pcir_ram_data_out ;
514
    assign pciw_control_out   = pciw_ram_data_out[39:36] ;
515
    assign pciw_cbe_out       = pciw_ram_data_out[35:32] ;
516
    assign pciw_addr_data_out = pciw_ram_data_out [31:0] ;
517
 
518
    assign pcir_control_out   = pcir_ram_data_out[39:36] ;
519
    assign pcir_be_out        = pcir_ram_data_out[35:32] ;
520
    assign pcir_data_out      = pcir_ram_data_out [31:0] ;
521
 
522
    `ifdef SYNCHRONOUS
523
    /*-----------------------------------------------------------------------------------------------------------
524
    ASIC memory primitives will be added here in the near future - currently there is only some generic,
525
    behavioral dual port ram here
526
    -----------------------------------------------------------------------------------------------------------*/
527
 
528
    wire pciw_read_enable = pciw_rallow || pciw_empty ;
529
    wire pcir_read_enable = pcir_rallow || pcir_empty ;
530
 
531
    DP_SRAM #(PCIW_ADDR_LENGTH, PCIW_DEPTH) pciw_ram (.reset_in(reset_in), .wclock_in(pci_clock_in), .rclock_in(wb_clock_in), .data_in(pciw_ram_data_in),
532
                    .raddr_in(pciw_raddr), .waddr_in(pciw_waddr), .data_out(pciw_ram_data_out), .renable_in(pciw_read_enable), .wenable_in(pciw_wallow));
533
 
534
    DP_SRAM #(PCIR_ADDR_LENGTH, PCIR_DEPTH) pcir_ram (.reset_in(reset_in), .wclock_in(wb_clock_in), .rclock_in(pci_clock_in), .data_in(pcir_ram_data_in),
535
                    .raddr_in(pcir_raddr), .waddr_in(pcir_waddr), .data_out(pcir_ram_data_out), .renable_in(pcir_read_enable), .wenable_in(pcir_wallow));
536
 
537
    `else //ASYNCHRONOUS RAM
538
        DP_ASYNC_RAM #(PCIW_ADDR_LENGTH, PCIW_DEPTH) pciw_ram (.reset_in(reset_in), .wclock_in(pci_clock_in), .data_in(pciw_ram_data_in),
539
                    .raddr_in(pciw_raddr), .waddr_in(pciw_waddr), .data_out(pciw_ram_data_out), .wenable_in(pciw_wallow));
540
 
541
        DP_ASYNC_RAM #(PCIR_ADDR_LENGTH, PCIR_DEPTH) pcir_ram (.reset_in(reset_in), .wclock_in(wb_clock_in), .data_in(pcir_ram_data_in),
542
                    .raddr_in(pcir_raddr), .waddr_in(pcir_waddr), .data_out(pcir_ram_data_out), .wenable_in(pcir_wallow));
543
    `endif
544
`endif
545
 
546
/*-----------------------------------------------------------------------------------------------------------
547
Instantiation of two control logic modules - one for PCIW_FIFO and one for PCIR_FIFO
548
-----------------------------------------------------------------------------------------------------------*/
549
PCIW_FIFO_CONTROL #(PCIW_ADDR_LENGTH) pciw_fifo_ctrl
550
(
551
    .rclock_in(wb_clock_in),
552
    .wclock_in(pci_clock_in),
553
    .renable_in(pciw_renable_in),
554
    .wenable_in(pciw_wenable_in),
555
    .reset_in(reset_in),
556
    .flush_in(pciw_flush_in),
557
    .two_left_out(pciw_two_left_out),
558
    .almost_full_out(pciw_almost_full_out),
559
    .full_out(pciw_full_out),
560
    .almost_empty_out(pciw_almost_empty_out),
561
    .empty_out(pciw_empty),
562
    .waddr_out(pciw_waddr),
563
    .raddr_out(pciw_raddr),
564
    .rallow_out(pciw_rallow),
565
    .wallow_out(pciw_wallow)
566
);
567
 
568
FIFO_CONTROL #(PCIR_ADDR_LENGTH) pcir_fifo_ctrl
569
(
570
    .rclock_in(pci_clock_in),
571
    .wclock_in(wb_clock_in),
572
    .renable_in(pcir_renable_in),
573
    .wenable_in(pcir_wenable_in),
574
    .reset_in(reset_in),
575
    .flush_in(pcir_flush_in),
576
    .almost_full_out(pcir_almost_full_out),
577
    .full_out(pcir_full_out),
578
    .almost_empty_out(pcir_almost_empty_out),
579
    .empty_out(pcir_empty),
580
    .waddr_out(pcir_waddr),
581
    .raddr_out(pcir_raddr),
582
    .rallow_out(pcir_rallow),
583
    .wallow_out(pcir_wallow)
584
);
585
 
586
 
587
// in and out transaction counters and grey codes
588
reg  [(PCIW_ADDR_LENGTH-2):0] inGreyCount ;
589
reg  [(PCIW_ADDR_LENGTH-2):0] outGreyCount ;
590
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]} ;
591
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]} ;
592
 
593
wire in_count_en  = pciw_wallow     && pciw_last_in ;
594
wire out_count_en = pciw_renable_in && pciw_last_out ;
595
 
596
always@(posedge pci_clock_in or posedge pciw_clear)
597
begin
598
    if (pciw_clear)
599
    begin
600
        inGreyCount[(PCIW_ADDR_LENGTH-2)] <= #`FF_DELAY 1'b1 ;
601
        inGreyCount[(PCIW_ADDR_LENGTH-3):0] <= #`FF_DELAY {(PCIW_ADDR_LENGTH-2),1'b0} ;
602
    end
603
    else
604
    if (in_count_en)
605
        inGreyCount <= #`FF_DELAY inNextGreyCount ;
606
end
607
 
608
always@(posedge wb_clock_in or posedge pciw_clear)
609
begin
610
    if (pciw_clear)
611
    begin
612
        outGreyCount[(PCIW_ADDR_LENGTH-2)]   <= #`FF_DELAY 1'b1 ;
613
        outGreyCount[(PCIW_ADDR_LENGTH-3):0] <= #`FF_DELAY {(PCIW_ADDR_LENGTH-2),1'b0} ;
614
    end
615
    else
616
    if (out_count_en)
617
        outGreyCount <= #`FF_DELAY outNextGreyCount ;
618
end
619
 
620
always@(posedge pci_clock_in or posedge pciw_clear)
621
begin
622
    if (pciw_clear)
623
        pciw_inTransactionCount <= #`FF_DELAY {(PCIW_ADDR_LENGTH-1){1'b0}} ;
624
    else
625
    if (in_count_en)
626
        pciw_inTransactionCount <= #`FF_DELAY pciw_inTransactionCount + 1'b1 ;
627
end
628
 
629
always@(posedge wb_clock_in or posedge pciw_clear)
630
begin
631
    if (pciw_clear)
632
        pciw_outTransactionCount <= #`FF_DELAY {(PCIW_ADDR_LENGTH-1){1'b0}} ;
633
    else
634
    if (out_count_en)
635
        pciw_outTransactionCount <= #`FF_DELAY pciw_outTransactionCount + 1'b1 ;
636
end
637
 
638
/*always@(posedge wb_clock_in or posedge pcir_clear)
639
begin
640
    if (pcir_clear)
641
        pcir_inTransactionCount <= #`FF_DELAY 1'b0 ;
642
    else
643
        if (pcir_last_in && pcir_wallow)
644
            pcir_inTransactionCount <= #`FF_DELAY ~pcir_inTransactionCount ;
645
end
646
 
647
always@(posedge pci_clock_in or posedge pcir_clear)
648
begin
649
    if (pcir_clear)
650
        pcir_outTransactionCount <= #`FF_DELAY 1'b0 ;
651
    else
652
        if (pcir_last_out)
653
            pcir_outTransactionCount <= #`FF_DELAY ~pcir_outTransactionCount ;
654
end
655
*/
656
 
657
reg pciw_transaction_ready_out ;
658
always@(posedge wb_clock_in or posedge pciw_clear)
659
begin
660
    if (pciw_clear)
661
        pciw_transaction_ready_out <= #`FF_DELAY 1'b0 ;
662
    else
663
    if ( out_count_en )
664
        pciw_transaction_ready_out <= #`FF_DELAY 1'b0 ;
665
    else
666
        pciw_transaction_ready_out <= #`FF_DELAY inGreyCount != outGreyCount ;
667
end
668
 
669
assign pcir_transaction_ready_out  = 1'b0 ;
670
 
671
endmodule
672
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.