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