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