Add diagrams and pictures
[clump.git] / generic_dpram.v
CommitLineData
a051754e
MG
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: not supported by cvs2svn $
69// Revision 1.2 2001/11/08 19:11:31 samg
70// added valid checks to behvioral model
71//
72// Revision 1.1.1.1 2001/09/14 09:57:10 rherveille
73// Major cleanup.
74// Files are now compliant to Altera & Xilinx memories.
75// Memories are now compatible, i.e. drop-in replacements.
76// Added synthesizeable generic FPGA description.
77// Created "generic_memories" cvs entry.
78//
79// Revision 1.1.1.2 2001/08/21 13:09:27 damjan
80// *** empty log message ***
81//
82// Revision 1.1 2001/08/20 18:23:20 damjan
83// Initial revision
84//
85// Revision 1.1 2001/08/09 13:39:33 lampret
86// Major clean-up.
87//
88// Revision 1.2 2001/07/30 05:38:02 lampret
89// Adding empty directories required by HDL coding guidelines
90//
91//
92
93//`include "timescale.v"
94
95`define VENDOR_FPGA
96//`define VENDOR_XILINX
97//`define VENDOR_ALTERA
98
99module generic_dpram(
100 // Generic synchronous dual-port RAM interface
101 rclk, rrst, rce, oe, raddr, do,
102 wclk, wrst, wce, we, waddr, di
103);
104
105 //
106 // Default address and data buses width
107 //
108 parameter aw = 5; // number of bits in address-bus
109 parameter dw = 16; // number of bits in data-bus
110
111 //
112 // Generic synchronous double-port RAM interface
113 //
114 // read port
115 input rclk; // read clock, rising edge trigger
116 input rrst; // read port reset, active high
117 input rce; // read port chip enable, active high
118 input oe; // output enable, active high
119 input [aw-1:0] raddr; // read address
120 output [dw-1:0] do; // data output
121
122 // write port
123 input wclk; // write clock, rising edge trigger
124 input wrst; // write port reset, active high
125 input wce; // write port chip enable, active high
126 input we; // write enable, active high
127 input [aw-1:0] waddr; // write address
128 input [dw-1:0] di; // data input
129
130 //
131 // Module body
132 //
133
134`ifdef VENDOR_FPGA
135 //
136 // Instantiation synthesizeable FPGA memory
137 //
138 // This code has been tested using LeonardoSpectrum and Synplicity.
139 // The code correctly instantiates Altera EABs and Xilinx BlockRAMs.
140 //
141
142 reg [dw-1 :0] mem [(1<<aw) -1:0]; // instantiate memory
143 reg [dw-1:0] do; // data output registers
144
145 // read operation
146
147 /*
148 always@(posedge rclk)
149 if (rce) // clock enable instructs Xilinx tools to use SelectRAM (LUTS) instead of BlockRAM
150 do <= #1 mem[raddr];
151 */
152
153 always@(posedge rclk)
154 do <= #1 mem[raddr];
155
156 // write operation
157 always@(posedge wclk)
158 if (we && wce)
159 mem[waddr] <= #1 di;
160
161`else
162
163`ifdef VENDOR_XILINX
164 //
165 // Instantiation of FPGA memory:
166 //
167 // Virtex/Spartan2 BlockRAMs
168 //
169 xilinx_ram_dp xilinx_ram(
170 // read port
171 .CLKA(rclk),
172 .RSTA(rrst),
173 .ENA(rce),
174 .ADDRA(raddr),
175 .DIA( {dw{1'b0}} ),
176 .WEA(1'b0),
177 .DOA(do),
178
179 // write port
180 .CLKB(wclk),
181 .RSTB(wrst),
182 .ENB(wce),
183 .ADDRB(waddr),
184 .DIB(di),
185 .WEB(we),
186 .DOB()
187 );
188
189 defparam
190 xilinx_ram.dwidth = dw,
191 xilinx_ram.awidth = aw;
192
193`else
194
195`ifdef VENDOR_ALTERA
196 //
197 // Instantiation of FPGA memory:
198 //
199 // Altera FLEX/APEX EABs
200 //
201 altera_ram_dp altera_ram(
202 // read port
203 .rdclock(rclk),
204 .rdclocken(rce),
205 .rdaddress(raddr),
206 .q(do),
207
208 // write port
209 .wrclock(wclk),
210 .wrclocken(wce),
211 .wren(we),
212 .wraddress(waddr),
213 .data(di)
214 );
215
216 defparam
217 altera_ram.dwidth = dw,
218 altera_ram.awidth = aw;
219
220`else
221
222`ifdef VENDOR_ARTISAN
223
224 //
225 // Instantiation of ASIC memory:
226 //
227 // Artisan Synchronous Double-Port RAM (ra2sh)
228 //
229 art_hsdp #(dw, 1<<aw, aw) artisan_sdp(
230 // read port
231 .qa(do),
232 .clka(rclk),
233 .cena(~rce),
234 .wena(1'b1),
235 .aa(raddr),
236 .da( {dw{1'b0}} ),
237 .oena(~oe),
238
239 // write port
240 .qb(),
241 .clkb(wclk),
242 .cenb(~wce),
243 .wenb(~we),
244 .ab(waddr),
245 .db(di),
246 .oenb(1'b1)
247 );
248
249`else
250
251`ifdef VENDOR_AVANT
252
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(raddr),
265 .wa(waddr),
266 .di(di),
267 .do(do)
268 );
269
270`else
271
272`ifdef VENDOR_VIRAGE
273
274 //
275 // Instantiation of ASIC memory:
276 //
277 // Virage Synchronous 2-port R/W RAM
278 //
279 virage_stp virage_stp(
280 // read port
281 .CLKA(rclk),
282 .MEA(rce_a),
283 .ADRA(raddr),
284 .DA( {dw{1'b0}} ),
285 .WEA(1'b0),
286 .OEA(oe),
287 .QA(do),
288
289 // write port
290 .CLKB(wclk),
291 .MEB(wce),
292 .ADRB(waddr),
293 .DB(di),
294 .WEB(we),
295 .OEB(1'b1),
296 .QB()
297 );
298
299`else
300
301 //
302 // Generic dual-port synchronous RAM model
303 //
304
305 //
306 // Generic RAM's registers and wires
307 //
308 reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content
309 reg [dw-1:0] do_reg; // RAM data output register
310
311 //
312 // Data output drivers
313 //
314 assign do = (oe & rce) ? do_reg : {dw{1'bz}};
315
316 // read operation
317 always @(posedge rclk)
318 if (rce)
319 do_reg <= #1 (we && (waddr==raddr)) ? {dw{1'b x}} : mem[raddr];
320
321 // write operation
322 always @(posedge wclk)
323 if (wce && we)
324 mem[waddr] <= #1 di;
325
326
327 // Task prints range of memory
328 // *** Remember that tasks are non reentrant, don't call this task in parallel for multiple instantiations.
329 task print_ram;
330 input [aw-1:0] start;
331 input [aw-1:0] finish;
332 integer rnum;
333 begin
334 for (rnum=start;rnum<=finish;rnum=rnum+1)
335 $display("Addr %h = %h",rnum,mem[rnum]);
336 end
337 endtask
338
339`endif // !VENDOR_VIRAGE
340`endif // !VENDOR_AVANT
341`endif // !VENDOR_ARTISAN
342`endif // !VENDOR_ALTERA
343`endif // !VENDOR_XILINX
344`endif // !VENDOR_FPGA
345
346endmodule
347
348//
349// Black-box modules
350//
351
352`ifdef VENDOR_ALTERA
353 module altera_ram_dp(
354 data,
355 wraddress,
356 rdaddress,
357 wren,
358 wrclock,
359 wrclocken,
360 rdclock,
361 rdclocken,
362 q) /* synthesis black_box */;
363
364 parameter awidth = 7;
365 parameter dwidth = 8;
366
367 input [dwidth -1:0] data;
368 input [awidth -1:0] wraddress;
369 input [awidth -1:0] rdaddress;
370 input wren;
371 input wrclock;
372 input wrclocken;
373 input rdclock;
374 input rdclocken;
375 output [dwidth -1:0] q;
376
377 // synopsis translate_off
378 // exemplar translate_off
379
380 syn_dpram_rowr #(
381 "UNUSED",
382 dwidth,
383 awidth,
384 1 << awidth
385 )
386 altera_dpram_model (
387 // read port
388 .RdClock(rdclock),
389 .RdClken(rdclocken),
390 .RdAddress(rdaddress),
391 .RdEn(1'b1),
392 .Q(q),
393
394 // write port
395 .WrClock(wrclock),
396 .WrClken(wrclocken),
397 .WrAddress(wraddress),
398 .WrEn(wren),
399 .Data(data)
400 );
401
402 // exemplar translate_on
403 // synopsis translate_on
404
405 endmodule
406`endif // VENDOR_ALTERA
407
408`ifdef VENDOR_XILINX
409 module xilinx_ram_dp (
410 ADDRA,
411 CLKA,
412 ADDRB,
413 CLKB,
414 DIA,
415 WEA,
416 DIB,
417 WEB,
418 ENA,
419 ENB,
420 RSTA,
421 RSTB,
422 DOA,
423 DOB) /* synthesis black_box */ ;
424
425 parameter awidth = 7;
426 parameter dwidth = 8;
427
428 // port_a
429 input CLKA;
430 input RSTA;
431 input ENA;
432 input [awidth-1:0] ADDRA;
433 input [dwidth-1:0] DIA;
434 input WEA;
435 output [dwidth-1:0] DOA;
436
437 // port_b
438 input CLKB;
439 input RSTB;
440 input ENB;
441 input [awidth-1:0] ADDRB;
442 input [dwidth-1:0] DIB;
443 input WEB;
444 output [dwidth-1:0] DOB;
445
446 // insert simulation model
447
448
449 // synopsys translate_off
450 // exemplar translate_off
451
452 C_MEM_DP_BLOCK_V1_0 #(
453 awidth,
454 awidth,
455 1,
456 1,
457 "0",
458 1 << awidth,
459 1 << awidth,
460 1,
461 1,
462 1,
463 1,
464 1,
465 1,
466 1,
467 1,
468 1,
469 1,
470 1,
471 1,
472 1,
473 "",
474 16,
475 0,
476 0,
477 1,
478 1,
479 1,
480 1,
481 dwidth,
482 dwidth)
483 xilinx_dpram_model (
484 .ADDRA(ADDRA),
485 .CLKA(CLKA),
486 .ADDRB(ADDRB),
487 .CLKB(CLKB),
488 .DIA(DIA),
489 .WEA(WEA),
490 .DIB(DIB),
491 .WEB(WEB),
492 .ENA(ENA),
493 .ENB(ENB),
494 .RSTA(RSTA),
495 .RSTB(RSTB),
496 .DOA(DOA),
497 .DOB(DOB));
498
499 // exemplar translate_on
500 // synopsys translate_on
501
502 endmodule
503`endif // VENDOR_XILINX
This page took 0.035686 seconds and 4 git commands to generate.