]>
Commit | Line | Data |
---|---|---|
1 | ////////////////////////////////////////////////////////////////////// | |
2 | //// //// | |
3 | //// Generic Two-Port Synchronous RAM //// | |
4 | //// //// | |
5 | //// This file is part of pci bridge project //// | |
6 | //// http://www.opencores.org/cvsweb.shtml/pci/ //// | |
7 | //// //// | |
8 | //// Description //// | |
9 | //// This block is a wrapper with common two-port //// | |
10 | //// synchronous memory interface for different //// | |
11 | //// types of ASIC and FPGA RAMs. Beside universal memory //// | |
12 | //// interface it also provides behavioral model of generic //// | |
13 | //// two-port synchronous RAM. //// | |
14 | //// It should be used in all OPENCORES designs that want to be //// | |
15 | //// portable accross different target technologies and //// | |
16 | //// independent of target memory. //// | |
17 | //// //// | |
18 | //// Supported ASIC RAMs are: //// | |
19 | //// - Artisan Double-Port Sync RAM //// | |
20 | //// - Avant! Two-Port Sync RAM (*) //// | |
21 | //// - Virage 2-port Sync RAM //// | |
22 | //// //// | |
23 | //// Supported FPGA RAMs are: //// | |
24 | //// - Xilinx Virtex RAMB4_S16_S16 //// | |
25 | //// //// | |
26 | //// To Do: //// | |
27 | //// - fix Avant! //// | |
28 | //// - xilinx rams need external tri-state logic //// | |
29 | //// - add additional RAMs (Altera, VS etc) //// | |
30 | //// //// | |
31 | //// Author(s): //// | |
32 | //// - Damjan Lampret, lampret@opencores.org //// | |
33 | //// - Miha Dolenc, mihad@opencores.org //// | |
34 | //// //// | |
35 | ////////////////////////////////////////////////////////////////////// | |
36 | //// //// | |
37 | //// Copyright (C) 2000 Authors and OPENCORES.ORG //// | |
38 | //// //// | |
39 | //// This source file may be used and distributed without //// | |
40 | //// restriction provided that this copyright statement is not //// | |
41 | //// removed from the file and that any derivative work contains //// | |
42 | //// the original copyright notice and the associated disclaimer. //// | |
43 | //// //// | |
44 | //// This source file is free software; you can redistribute it //// | |
45 | //// and/or modify it under the terms of the GNU Lesser General //// | |
46 | //// Public License as published by the Free Software Foundation; //// | |
47 | //// either version 2.1 of the License, or (at your option) any //// | |
48 | //// later version. //// | |
49 | //// //// | |
50 | //// This source is distributed in the hope that it will be //// | |
51 | //// useful, but WITHOUT ANY WARRANTY; without even the implied //// | |
52 | //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// | |
53 | //// PURPOSE. See the GNU Lesser General Public License for more //// | |
54 | //// details. //// | |
55 | //// //// | |
56 | //// You should have received a copy of the GNU Lesser General //// | |
57 | //// Public License along with this source; if not, download it //// | |
58 | //// from http://www.opencores.org/lgpl.shtml //// | |
59 | //// //// | |
60 | ////////////////////////////////////////////////////////////////////// | |
61 | // | |
62 | // CVS Revision History | |
63 | // | |
64 | // $Log: pci_wb_tpram.v,v $ | |
65 | // Revision 1.1 2007-03-20 17:50:56 sithglan | |
66 | // add shit | |
67 | // | |
68 | // Revision 1.4 2004/08/19 15:27:34 mihad | |
69 | // Changed minimum pci image size to 256 bytes because | |
70 | // of some PC system problems with size of IO images. | |
71 | // | |
72 | // Revision 1.3 2003/10/17 09:11:52 markom | |
73 | // mbist signals updated according to newest convention | |
74 | // | |
75 | // Revision 1.2 2003/08/14 13:06:03 simons | |
76 | // synchronizer_flop replaced with pci_synchronizer_flop, artisan ram instance updated. | |
77 | // | |
78 | // Revision 1.1 2003/01/27 16:49:31 mihad | |
79 | // Changed module and file names. Updated scripts accordingly. FIFO synchronizations changed. | |
80 | // | |
81 | // Revision 1.7 2002/10/18 03:36:37 tadejm | |
82 | // Changed wrong signal name mbist_sen into mbist_ctrl_i. | |
83 | // | |
84 | // Revision 1.6 2002/10/17 22:49:22 tadejm | |
85 | // Changed BIST signals for RAMs. | |
86 | // | |
87 | // Revision 1.5 2002/10/11 10:09:01 mihad | |
88 | // Added additional testcase and changed rst name in BIST to trst | |
89 | // | |
90 | // Revision 1.4 2002/10/08 17:17:06 mihad | |
91 | // Added BIST signals for RAMs. | |
92 | // | |
93 | // Revision 1.3 2002/09/30 17:22:27 mihad | |
94 | // Added support for Virtual Silicon two port RAM. Didn't run regression on it yet! | |
95 | // | |
96 | // Revision 1.2 2002/08/19 16:51:36 mihad | |
97 | // Extracted distributed RAM module from wb/pci_tpram.v to its own file, got rid of undef directives | |
98 | // | |
99 | // Revision 1.1 2002/02/01 14:43:31 mihad | |
100 | // *** empty log message *** | |
101 | // | |
102 | // | |
103 | ||
104 | // synopsys translate_off | |
105 | `include "timescale.v" | |
106 | // synopsys translate_on | |
107 | `include "pci_constants.v" | |
108 | ||
109 | module pci_wb_tpram | |
110 | ( | |
111 | // Generic synchronous two-port RAM interface | |
112 | clk_a, | |
113 | rst_a, | |
114 | ce_a, | |
115 | we_a, | |
116 | oe_a, | |
117 | addr_a, | |
118 | di_a, | |
119 | do_a, | |
120 | clk_b, | |
121 | rst_b, | |
122 | ce_b, | |
123 | we_b, | |
124 | oe_b, | |
125 | addr_b, | |
126 | di_b, | |
127 | do_b | |
128 | `ifdef PCI_BIST | |
129 | , | |
130 | // debug chain signals | |
131 | mbist_si_i, // bist scan serial in | |
132 | mbist_so_o, // bist scan serial out | |
133 | mbist_ctrl_i // bist chain shift control | |
134 | `endif | |
135 | ); | |
136 | ||
137 | // | |
138 | // Default address and data buses width | |
139 | // | |
140 | parameter aw = 8; | |
141 | parameter dw = 40; | |
142 | ||
143 | // | |
144 | // Generic synchronous two-port RAM interface | |
145 | // | |
146 | input clk_a; // Clock | |
147 | input rst_a; // Reset | |
148 | input ce_a; // Chip enable input | |
149 | input we_a; // Write enable input | |
150 | input oe_a; // Output enable input | |
151 | input [aw-1:0] addr_a; // address bus inputs | |
152 | input [dw-1:0] di_a; // input data bus | |
153 | output [dw-1:0] do_a; // output data bus | |
154 | input clk_b; // Clock | |
155 | input rst_b; // Reset | |
156 | input ce_b; // Chip enable input | |
157 | input we_b; // Write enable input | |
158 | input oe_b; // Output enable input | |
159 | input [aw-1:0] addr_b; // address bus inputs | |
160 | input [dw-1:0] di_b; // input data bus | |
161 | output [dw-1:0] do_b; // output data bus | |
162 | ||
163 | `ifdef PCI_BIST | |
164 | // debug chain signals | |
165 | input mbist_si_i; // bist scan serial in | |
166 | output mbist_so_o; // bist scan serial out | |
167 | input [`PCI_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control | |
168 | `endif | |
169 | ||
170 | // | |
171 | // Internal wires and registers | |
172 | // | |
173 | ||
174 | `ifdef WB_VS_STP | |
175 | `define PCI_WB_RAM_SELECTED | |
176 | `ifdef PCI_BIST | |
177 | vs_hdtp_64x40_bist i_vs_hdtp_64x40_bist | |
178 | `else | |
179 | vs_hdtp_64x40 i_vs_hdtp_64x40 | |
180 | `endif | |
181 | ( | |
182 | .RCK (clk_b), | |
183 | .WCK (clk_a), | |
184 | .RADR (addr_b), | |
185 | .WADR (addr_a), | |
186 | .DI (di_a), | |
187 | .DOUT (do_b), | |
188 | .REN (1'b0), | |
189 | .WEN (!we_a) | |
190 | `ifdef PCI_BIST | |
191 | , | |
192 | // debug chain signals | |
193 | .mbist_si_i (mbist_si_i), | |
194 | .mbist_so_o (mbist_so_o), | |
195 | .mbist_ctrl_i (mbist_ctrl_i) | |
196 | `endif | |
197 | ); | |
198 | ||
199 | assign do_a = 0 ; | |
200 | `endif | |
201 | ||
202 | `ifdef WB_ARTISAN_SDP | |
203 | `define PCI_WB_RAM_SELECTED | |
204 | // | |
205 | // Instantiation of ASIC memory: | |
206 | // | |
207 | // Artisan Synchronous Double-Port RAM (ra2sh) | |
208 | // | |
209 | `ifdef PCI_BIST | |
210 | art_hsdp_64x40_bist /*#(dw, 1<<aw, aw) */ artisan_sdp | |
211 | ( | |
212 | .QA(do_a), | |
213 | .CLKA(clk_a), | |
214 | .CENA(~ce_a), | |
215 | .WENA(~we_a), | |
216 | .AA(addr_a), | |
217 | .DA(di_a), | |
218 | .OENA(~oe_a), | |
219 | .QB(do_b), | |
220 | .CLKB(clk_b), | |
221 | .CENB(~ce_b), | |
222 | .WENB(~we_b), | |
223 | .AB(addr_b), | |
224 | .DB(di_b), | |
225 | .OENB(~oe_b), | |
226 | .mbist_si_i (mbist_si_i), | |
227 | .mbist_so_o (mbist_so_o), | |
228 | .mbist_ctrl_i (mbist_ctrl_i) | |
229 | ); | |
230 | `else | |
231 | art_hsdp_64x40 /*#(dw, 1<<aw, aw) */ artisan_sdp | |
232 | ( | |
233 | .QA(do_a), | |
234 | .CLKA(clk_a), | |
235 | .CENA(~ce_a), | |
236 | .WENA(~we_a), | |
237 | .AA(addr_a), | |
238 | .DA(di_a), | |
239 | .OENA(~oe_a), | |
240 | .QB(do_b), | |
241 | .CLKB(clk_b), | |
242 | .CENB(~ce_b), | |
243 | .WENB(~we_b), | |
244 | .AB(addr_b), | |
245 | .DB(di_b), | |
246 | .OENB(~oe_b) | |
247 | ); | |
248 | `endif | |
249 | `endif | |
250 | ||
251 | `ifdef AVANT_ATP | |
252 | `define PCI_WB_RAM_SELECTED | |
253 | // | |
254 | // Instantiation of ASIC memory: | |
255 | // | |
256 | // Avant! Asynchronous Two-Port RAM | |
257 | // | |
258 | avant_atp avant_atp( | |
259 | .web(~we), | |
260 | .reb(), | |
261 | .oeb(~oe), | |
262 | .rcsb(), | |
263 | .wcsb(), | |
264 | .ra(addr), | |
265 | .wa(addr), | |
266 | .di(di), | |
267 | .do(do) | |
268 | ); | |
269 | ||
270 | `endif | |
271 | ||
272 | `ifdef VIRAGE_STP | |
273 | `define PCI_WB_RAM_SELECTED | |
274 | // | |
275 | // Instantiation of ASIC memory: | |
276 | // | |
277 | // Virage Synchronous 2-port R/W RAM | |
278 | // | |
279 | virage_stp virage_stp( | |
280 | .QA(do_a), | |
281 | .QB(do_b), | |
282 | ||
283 | .ADRA(addr_a), | |
284 | .DA(di_a), | |
285 | .WEA(we_a), | |
286 | .OEA(oe_a), | |
287 | .MEA(ce_a), | |
288 | .CLKA(clk_a), | |
289 | ||
290 | .ADRB(adr_b), | |
291 | .DB(di_b), | |
292 | .WEB(we_b), | |
293 | .OEB(oe_b), | |
294 | .MEB(ce_b), | |
295 | .CLKB(clk_b) | |
296 | ); | |
297 | ||
298 | `endif | |
299 | ||
300 | `ifdef WB_XILINX_DIST_RAM | |
301 | `define PCI_WB_RAM_SELECTED | |
302 | ||
303 | reg [(aw-1):0] out_address ; | |
304 | always@(posedge clk_b or posedge rst_b) | |
305 | begin | |
306 | if ( rst_b ) | |
307 | out_address <= #1 0 ; | |
308 | else if (ce_b) | |
309 | out_address <= #1 addr_b ; | |
310 | end | |
311 | ||
312 | pci_ram_16x40d #(aw) wb_distributed_ram | |
313 | ( | |
314 | .data_out (do_b), | |
315 | .we (we_a), | |
316 | .data_in (di_a), | |
317 | .read_address (out_address), | |
318 | .write_address (addr_a), | |
319 | .wclk (clk_a) | |
320 | ); | |
321 | assign do_a = 0 ; | |
322 | `endif | |
323 | `ifdef WB_XILINX_RAMB4 | |
324 | `define PCI_WB_RAM_SELECTED | |
325 | // | |
326 | // Instantiation of FPGA memory: | |
327 | // | |
328 | // Virtex/Spartan2 | |
329 | // | |
330 | ||
331 | // | |
332 | // Block 0 | |
333 | // | |
334 | ||
335 | RAMB4_S16_S16 ramb4_s16_s16_0( | |
336 | .CLKA(clk_a), | |
337 | .RSTA(rst_a), | |
338 | .ADDRA(addr_a), | |
339 | .DIA(di_a[15:0]), | |
340 | .ENA(ce_a), | |
341 | .WEA(we_a), | |
342 | .DOA(do_a[15:0]), | |
343 | ||
344 | .CLKB(clk_b), | |
345 | .RSTB(rst_b), | |
346 | .ADDRB(addr_b), | |
347 | .DIB(di_b[15:0]), | |
348 | .ENB(ce_b), | |
349 | .WEB(we_b), | |
350 | .DOB(do_b[15:0]) | |
351 | ); | |
352 | ||
353 | // | |
354 | // Block 1 | |
355 | // | |
356 | ||
357 | RAMB4_S16_S16 ramb4_s16_s16_1( | |
358 | .CLKA(clk_a), | |
359 | .RSTA(rst_a), | |
360 | .ADDRA(addr_a), | |
361 | .DIA(di_a[31:16]), | |
362 | .ENA(ce_a), | |
363 | .WEA(we_a), | |
364 | .DOA(do_a[31:16]), | |
365 | ||
366 | .CLKB(clk_b), | |
367 | .RSTB(rst_b), | |
368 | .ADDRB(addr_b), | |
369 | .DIB(di_b[31:16]), | |
370 | .ENB(ce_b), | |
371 | .WEB(we_b), | |
372 | .DOB(do_b[31:16]) | |
373 | ); | |
374 | ||
375 | // | |
376 | // Block 2 | |
377 | // | |
378 | // block ram2 wires - non generic width of block rams | |
379 | wire [15:0] blk2_di_a = {8'h00, di_a[39:32]} ; | |
380 | wire [15:0] blk2_di_b = {8'h00, di_b[39:32]} ; | |
381 | ||
382 | wire [15:0] blk2_do_a ; | |
383 | wire [15:0] blk2_do_b ; | |
384 | ||
385 | assign do_a[39:32] = blk2_do_a[7:0] ; | |
386 | assign do_b[39:32] = blk2_do_b[7:0] ; | |
387 | ||
388 | RAMB4_S16_S16 ramb4_s16_s16_2( | |
389 | .CLKA(clk_a), | |
390 | .RSTA(rst_a), | |
391 | .ADDRA(addr_a), | |
392 | .DIA(blk2_di_a), | |
393 | .ENA(ce_a), | |
394 | .WEA(we_a), | |
395 | .DOA(blk2_do_a), | |
396 | ||
397 | .CLKB(clk_b), | |
398 | .RSTB(rst_b), | |
399 | .ADDRB(addr_b), | |
400 | .DIB(blk2_di_b), | |
401 | .ENB(ce_b), | |
402 | .WEB(we_b), | |
403 | .DOB(blk2_do_b) | |
404 | ); | |
405 | ||
406 | `endif | |
407 | ||
408 | `ifdef PCI_WB_RAM_SELECTED | |
409 | `else | |
410 | // | |
411 | // Generic two-port synchronous RAM model | |
412 | // | |
413 | ||
414 | // | |
415 | // Generic RAM's registers and wires | |
416 | // | |
417 | reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content | |
418 | reg [dw-1:0] do_reg_b; // RAM data output register | |
419 | ||
420 | // | |
421 | // Data output drivers | |
422 | // | |
423 | assign do_a = {dw{1'b0}} ; | |
424 | assign do_b = do_reg_b ; | |
425 | ||
426 | // | |
427 | // RAM read and write | |
428 | // | |
429 | always @(posedge clk_a) | |
430 | if (ce_a && we_a) | |
431 | mem[addr_a] <= #1 di_a; | |
432 | ||
433 | // | |
434 | // RAM read and write | |
435 | // | |
436 | always @(posedge clk_b) | |
437 | if (ce_b) | |
438 | do_reg_b <= #1 mem[addr_b]; | |
439 | `endif | |
440 | ||
441 | // synopsys translate_off | |
442 | initial | |
443 | begin | |
444 | if (dw !== 40) | |
445 | begin | |
446 | $display("RAM instantiation error! Expected RAM width %d, actual %h!", 40, dw) ; | |
447 | $finish ; | |
448 | end | |
449 | `ifdef XILINX_RAMB4 | |
450 | if (aw !== 8) | |
451 | begin | |
452 | $display("RAM instantiation error! Expected RAM address width %d, actual %h!", 40, aw) ; | |
453 | $finish ; | |
454 | end | |
455 | `endif | |
456 | // currenlty only artisan ram of depth 256 is supported - they don't provide generic ram models | |
457 | `ifdef ARTISAN_SDP | |
458 | if (aw !== 8) | |
459 | begin | |
460 | $display("RAM instantiation error! Expected RAM address width %d, actual %h!", 40, aw) ; | |
461 | $finish ; | |
462 | end | |
463 | `endif | |
464 | end | |
465 | // synopsys translate_on | |
466 | ||
467 | endmodule | |
468 |