]> cvs.zerfleddert.de Git - raggedstone/blob - dhwk_old/source/generic_dpram.v
+= dpram
[raggedstone] / dhwk_old / source / generic_dpram.v
1 //////////////////////////////////////////////////////////////////////
2 //// ////
3 //// Generic Dual-Port Synchronous RAM ////
4 //// ////
5 //// This file is part of memory library available from ////
6 //// http://www.opencores.org/cvsweb.shtml/generic_memories/ ////
7 //// ////
8 //// Description ////
9 //// This block is a wrapper with common dual-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 //// dual-port synchronous RAM. ////
14 //// It also contains a fully synthesizeable model for FPGAs. ////
15 //// It should be used in all OPENCORES designs that want to be ////
16 //// portable accross different target technologies and ////
17 //// independent of target memory. ////
18 //// ////
19 //// Supported ASIC RAMs are: ////
20 //// - Artisan Dual-Port Sync RAM ////
21 //// - Avant! Two-Port Sync RAM (*) ////
22 //// - Virage 2-port Sync RAM ////
23 //// ////
24 //// Supported FPGA RAMs are: ////
25 //// - Generic FPGA (VENDOR_FPGA) ////
26 //// Tested RAMs: Altera, Xilinx ////
27 //// Synthesis tools: LeonardoSpectrum, Synplicity ////
28 //// - Xilinx (VENDOR_XILINX) ////
29 //// - Altera (VENDOR_ALTERA) ////
30 //// ////
31 //// To Do: ////
32 //// - fix Avant! ////
33 //// - add additional RAMs (VS etc) ////
34 //// ////
35 //// Author(s): ////
36 //// - Richard Herveille, richard@asics.ws ////
37 //// - Damjan Lampret, lampret@opencores.org ////
38 //// ////
39 //////////////////////////////////////////////////////////////////////
40 //// ////
41 //// Copyright (C) 2000 Authors and OPENCORES.ORG ////
42 //// ////
43 //// This source file may be used and distributed without ////
44 //// restriction provided that this copyright statement is not ////
45 //// removed from the file and that any derivative work contains ////
46 //// the original copyright notice and the associated disclaimer. ////
47 //// ////
48 //// This source file is free software; you can redistribute it ////
49 //// and/or modify it under the terms of the GNU Lesser General ////
50 //// Public License as published by the Free Software Foundation; ////
51 //// either version 2.1 of the License, or (at your option) any ////
52 //// later version. ////
53 //// ////
54 //// This source is distributed in the hope that it will be ////
55 //// useful, but WITHOUT ANY WARRANTY; without even the implied ////
56 //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
57 //// PURPOSE. See the GNU Lesser General Public License for more ////
58 //// details. ////
59 //// ////
60 //// You should have received a copy of the GNU Lesser General ////
61 //// Public License along with this source; if not, download it ////
62 //// from http://www.opencores.org/lgpl.shtml ////
63 //// ////
64 //////////////////////////////////////////////////////////////////////
65 //
66 // CVS Revision History
67 //
68 // $Log: generic_dpram.v,v $
69 // Revision 1.1 2007-02-11 22:05:26 sithglan
70 // += dpram
71 //
72 // Revision 1.4 2002/09/28 08:18:52 rherveille
73 // Changed synthesizeable FPGA memory implementation.
74 // Fixed some issues with Xilinx BlockRAM
75 //
76 // Revision 1.3 2001/11/09 00:34:18 samg
77 // minor changes: unified with all common rams
78 //
79 // Revision 1.2 2001/11/08 19:11:31 samg
80 // added valid checks to behvioral model
81 //
82 // Revision 1.1.1.1 2001/09/14 09:57:10 rherveille
83 // Major cleanup.
84 // Files are now compliant to Altera & Xilinx memories.
85 // Memories are now compatible, i.e. drop-in replacements.
86 // Added synthesizeable generic FPGA description.
87 // Created "generic_memories" cvs entry.
88 //
89 // Revision 1.1.1.2 2001/08/21 13:09:27 damjan
90 // *** empty log message ***
91 //
92 // Revision 1.1 2001/08/20 18:23:20 damjan
93 // Initial revision
94 //
95 // Revision 1.1 2001/08/09 13:39:33 lampret
96 // Major clean-up.
97 //
98 // Revision 1.2 2001/07/30 05:38:02 lampret
99 // Adding empty directories required by HDL coding guidelines
100 //
101 //
102
103 //`include "timescale.v"
104
105 //`define VENDOR_FPGA
106 //`define VENDOR_XILINX
107 //`define VENDOR_ALTERA
108
109 module generic_dpram(
110 // Generic synchronous dual-port RAM interface
111 rclk, rrst, rce, oe, raddr, do,
112 wclk, wrst, wce, we, waddr, di
113 );
114
115 //
116 // Default address and data buses width
117 //
118 parameter aw = 5; // number of bits in address-bus
119 parameter dw = 16; // number of bits in data-bus
120
121 //
122 // Generic synchronous double-port RAM interface
123 //
124 // read port
125 input rclk; // read clock, rising edge trigger
126 input rrst; // read port reset, active high
127 input rce; // read port chip enable, active high
128 input oe; // output enable, active high
129 input [aw-1:0] raddr; // read address
130 output [dw-1:0] do; // data output
131
132 // write port
133 input wclk; // write clock, rising edge trigger
134 input wrst; // write port reset, active high
135 input wce; // write port chip enable, active high
136 input we; // write enable, active high
137 input [aw-1:0] waddr; // write address
138 input [dw-1:0] di; // data input
139
140 //
141 // Module body
142 //
143
144 `ifdef VENDOR_FPGA
145 //
146 // Instantiation synthesizeable FPGA memory
147 //
148 // This code has been tested using LeonardoSpectrum and Synplicity.
149 // The code correctly instantiates Altera EABs and Xilinx BlockRAMs.
150 //
151 reg [dw-1:0] mem [(1<<aw) -1:0]; // instantiate memory
152 reg [aw-1:0] ra; // register read address
153
154 // read operation
155 always @(posedge rclk)
156 if (rce)
157 ra <= #1 raddr;
158
159 assign do = mem[ra];
160
161 // write operation
162 always@(posedge wclk)
163 if (we && wce)
164 mem[waddr] <= #1 di;
165
166 `else
167
168 `ifdef VENDOR_XILINX
169 //
170 // Instantiation of FPGA memory:
171 //
172 // Virtex/Spartan2 BlockRAMs
173 //
174 xilinx_ram_dp xilinx_ram(
175 // read port
176 .CLKA(rclk),
177 .RSTA(rrst),
178 .ENA(rce),
179 .ADDRA(raddr),
180 .DIA( {dw{1'b0}} ),
181 .WEA(1'b0),
182 .DOA(do),
183
184 // write port
185 .CLKB(wclk),
186 .RSTB(wrst),
187 .ENB(wce),
188 .ADDRB(waddr),
189 .DIB(di),
190 .WEB(we),
191 .DOB()
192 );
193
194 defparam
195 xilinx_ram.dwidth = dw,
196 xilinx_ram.awidth = aw;
197
198 `else
199
200 `ifdef VENDOR_ALTERA
201 //
202 // Instantiation of FPGA memory:
203 //
204 // Altera FLEX/APEX EABs
205 //
206 altera_ram_dp altera_ram(
207 // read port
208 .rdclock(rclk),
209 .rdclocken(rce),
210 .rdaddress(raddr),
211 .q(do),
212
213 // write port
214 .wrclock(wclk),
215 .wrclocken(wce),
216 .wren(we),
217 .wraddress(waddr),
218 .data(di)
219 );
220
221 defparam
222 altera_ram.dwidth = dw,
223 altera_ram.awidth = aw;
224
225 `else
226
227 `ifdef VENDOR_ARTISAN
228
229 //
230 // Instantiation of ASIC memory:
231 //
232 // Artisan Synchronous Double-Port RAM (ra2sh)
233 //
234 art_hsdp #(dw, 1<<aw, aw) artisan_sdp(
235 // read port
236 .qa(do),
237 .clka(rclk),
238 .cena(~rce),
239 .wena(1'b1),
240 .aa(raddr),
241 .da( {dw{1'b0}} ),
242 .oena(~oe),
243
244 // write port
245 .qb(),
246 .clkb(wclk),
247 .cenb(~wce),
248 .wenb(~we),
249 .ab(waddr),
250 .db(di),
251 .oenb(1'b1)
252 );
253
254 `else
255
256 `ifdef VENDOR_AVANT
257
258 //
259 // Instantiation of ASIC memory:
260 //
261 // Avant! Asynchronous Two-Port RAM
262 //
263 avant_atp avant_atp(
264 .web(~we),
265 .reb(),
266 .oeb(~oe),
267 .rcsb(),
268 .wcsb(),
269 .ra(raddr),
270 .wa(waddr),
271 .di(di),
272 .do(do)
273 );
274
275 `else
276
277 `ifdef VENDOR_VIRAGE
278
279 //
280 // Instantiation of ASIC memory:
281 //
282 // Virage Synchronous 2-port R/W RAM
283 //
284 virage_stp virage_stp(
285 // read port
286 .CLKA(rclk),
287 .MEA(rce_a),
288 .ADRA(raddr),
289 .DA( {dw{1'b0}} ),
290 .WEA(1'b0),
291 .OEA(oe),
292 .QA(do),
293
294 // write port
295 .CLKB(wclk),
296 .MEB(wce),
297 .ADRB(waddr),
298 .DB(di),
299 .WEB(we),
300 .OEB(1'b1),
301 .QB()
302 );
303
304 `else
305
306 //
307 // Generic dual-port synchronous RAM model
308 //
309
310 //
311 // Generic RAM's registers and wires
312 //
313 reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content
314 reg [dw-1:0] do_reg; // RAM data output register
315
316 //
317 // Data output drivers
318 //
319 assign do = (oe & rce) ? do_reg : {dw{1'bz}};
320
321 // read operation
322 always @(posedge rclk)
323 if (rce)
324 do_reg <= #1 (we && (waddr==raddr)) ? {dw{1'b x}} : mem[raddr];
325
326 // write operation
327 always @(posedge wclk)
328 if (wce && we)
329 mem[waddr] <= #1 di;
330
331
332 // Task prints range of memory
333 // *** Remember that tasks are non reentrant, don't call this task in parallel for multiple instantiations.
334 task print_ram;
335 input [aw-1:0] start;
336 input [aw-1:0] finish;
337 integer rnum;
338 begin
339 for (rnum=start;rnum<=finish;rnum=rnum+1)
340 $display("Addr %h = %h",rnum,mem[rnum]);
341 end
342 endtask
343
344 `endif // !VENDOR_VIRAGE
345 `endif // !VENDOR_AVANT
346 `endif // !VENDOR_ARTISAN
347 `endif // !VENDOR_ALTERA
348 `endif // !VENDOR_XILINX
349 `endif // !VENDOR_FPGA
350
351 endmodule
352
353 //
354 // Black-box modules
355 //
356
357 `ifdef VENDOR_ALTERA
358 module altera_ram_dp(
359 data,
360 wraddress,
361 rdaddress,
362 wren,
363 wrclock,
364 wrclocken,
365 rdclock,
366 rdclocken,
367 q) /* synthesis black_box */;
368
369 parameter awidth = 7;
370 parameter dwidth = 8;
371
372 input [dwidth -1:0] data;
373 input [awidth -1:0] wraddress;
374 input [awidth -1:0] rdaddress;
375 input wren;
376 input wrclock;
377 input wrclocken;
378 input rdclock;
379 input rdclocken;
380 output [dwidth -1:0] q;
381
382 // synopsis translate_off
383 // exemplar translate_off
384
385 syn_dpram_rowr #(
386 "UNUSED",
387 dwidth,
388 awidth,
389 1 << awidth
390 )
391 altera_dpram_model (
392 // read port
393 .RdClock(rdclock),
394 .RdClken(rdclocken),
395 .RdAddress(rdaddress),
396 .RdEn(1'b1),
397 .Q(q),
398
399 // write port
400 .WrClock(wrclock),
401 .WrClken(wrclocken),
402 .WrAddress(wraddress),
403 .WrEn(wren),
404 .Data(data)
405 );
406
407 // exemplar translate_on
408 // synopsis translate_on
409
410 endmodule
411 `endif // VENDOR_ALTERA
412
413 `ifdef VENDOR_XILINX
414 module xilinx_ram_dp (
415 ADDRA,
416 CLKA,
417 ADDRB,
418 CLKB,
419 DIA,
420 WEA,
421 DIB,
422 WEB,
423 ENA,
424 ENB,
425 RSTA,
426 RSTB,
427 DOA,
428 DOB) /* synthesis black_box */ ;
429
430 parameter awidth = 7;
431 parameter dwidth = 8;
432
433 // port_a
434 input CLKA;
435 input RSTA;
436 input ENA;
437 input [awidth-1:0] ADDRA;
438 input [dwidth-1:0] DIA;
439 input WEA;
440 output [dwidth-1:0] DOA;
441
442 // port_b
443 input CLKB;
444 input RSTB;
445 input ENB;
446 input [awidth-1:0] ADDRB;
447 input [dwidth-1:0] DIB;
448 input WEB;
449 output [dwidth-1:0] DOB;
450
451 // insert simulation model
452
453
454 // synopsys translate_off
455 // exemplar translate_off
456
457 C_MEM_DP_BLOCK_V1_0 #(
458 awidth,
459 awidth,
460 1,
461 1,
462 "0",
463 1 << awidth,
464 1 << awidth,
465 1,
466 1,
467 1,
468 1,
469 1,
470 1,
471 1,
472 1,
473 1,
474 1,
475 1,
476 1,
477 1,
478 "",
479 16,
480 0,
481 0,
482 1,
483 1,
484 1,
485 1,
486 dwidth,
487 dwidth)
488 xilinx_dpram_model (
489 .ADDRA(ADDRA),
490 .CLKA(CLKA),
491 .ADDRB(ADDRB),
492 .CLKB(CLKB),
493 .DIA(DIA),
494 .WEA(WEA),
495 .DIB(DIB),
496 .WEB(WEB),
497 .ENA(ENA),
498 .ENB(ENB),
499 .RSTA(RSTA),
500 .RSTB(RSTB),
501 .DOA(DOA),
502 .DOB(DOB));
503
504 // exemplar translate_on
505 // synopsys translate_on
506
507 endmodule
508 `endif // VENDOR_XILINX
Impressum, Datenschutz