1 //////////////////////////////////////////////////////////////////////
3 //// Generic Dual-Port Synchronous RAM ////
5 //// This file is part of memory library available from ////
6 //// http://www.opencores.org/cvsweb.shtml/generic_memories/ ////
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. ////
19 //// Supported ASIC RAMs are: ////
20 //// - Artisan Dual-Port Sync RAM ////
21 //// - Avant! Two-Port Sync RAM (*) ////
22 //// - Virage 2-port Sync RAM ////
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) ////
32 //// - fix Avant! ////
33 //// - add additional RAMs (VS etc) ////
36 //// - Richard Herveille, richard@asics.ws ////
37 //// - Damjan Lampret, lampret@opencores.org ////
39 //////////////////////////////////////////////////////////////////////
41 //// Copyright (C) 2000 Authors and OPENCORES.ORG ////
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. ////
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. ////
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 ////
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 ////
64 //////////////////////////////////////////////////////////////////////
66 // CVS Revision History
68 // $Log: generic_dpram.v,v $
69 // Revision 1.3 2007-02-11 22:18:24 michael
72 // Revision 1.2 2007/02/11 22:15:39 sithglan
73 // define xilinix and fpga
75 // Revision 1.1 2007/02/11 22:05:26 sithglan
78 // Revision 1.4 2002/09/28 08:18:52 rherveille
79 // Changed synthesizeable FPGA memory implementation.
80 // Fixed some issues with Xilinx BlockRAM
82 // Revision 1.3 2001/11/09 00:34:18 samg
83 // minor changes: unified with all common rams
85 // Revision 1.2 2001/11/08 19:11:31 samg
86 // added valid checks to behvioral model
88 // Revision 1.1.1.1 2001/09/14 09:57:10 rherveille
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.
95 // Revision 1.1.1.2 2001/08/21 13:09:27 damjan
96 // *** empty log message ***
98 // Revision 1.1 2001/08/20 18:23:20 damjan
101 // Revision 1.1 2001/08/09 13:39:33 lampret
104 // Revision 1.2 2001/07/30 05:38:02 lampret
105 // Adding empty directories required by HDL coding guidelines
109 //`include "timescale.v"
112 `define VENDOR_XILINX
113 //`define VENDOR_ALTERA
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
122 // Default address and data buses width
124 parameter aw = 12; // number of bits in address-bus
125 parameter dw = 8; // number of bits in data-bus
128 // Generic synchronous double-port RAM interface
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
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
152 // Instantiation synthesizeable FPGA memory
154 // This code has been tested using LeonardoSpectrum and Synplicity.
155 // The code correctly instantiates Altera EABs and Xilinx BlockRAMs.
157 reg [dw-1:0] mem [(1<<aw) -1:0]; // instantiate memory
158 reg [aw-1:0] ra; // register read address
161 always @(posedge rclk)
168 always@(posedge wclk)
176 // Instantiation of FPGA memory:
178 // Virtex/Spartan2 BlockRAMs
180 xilinx_ram_dp xilinx_ram(
201 xilinx_ram.dwidth = dw,
202 xilinx_ram.awidth = aw;
208 // Instantiation of FPGA memory:
210 // Altera FLEX/APEX EABs
212 altera_ram_dp altera_ram(
228 altera_ram.dwidth = dw,
229 altera_ram.awidth = aw;
233 `ifdef VENDOR_ARTISAN
236 // Instantiation of ASIC memory:
238 // Artisan Synchronous Double-Port RAM (ra2sh)
240 art_hsdp #(dw, 1<<aw, aw) artisan_sdp(
265 // Instantiation of ASIC memory:
267 // Avant! Asynchronous Two-Port RAM
286 // Instantiation of ASIC memory:
288 // Virage Synchronous 2-port R/W RAM
290 virage_stp virage_stp(
313 // Generic dual-port synchronous RAM model
317 // Generic RAM's registers and wires
319 reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content
320 reg [dw-1:0] do_reg; // RAM data output register
323 // Data output drivers
325 assign do = (oe & rce) ? do_reg : {dw{1'bz}};
328 always @(posedge rclk)
330 do_reg <= #1 (we && (waddr==raddr)) ? {dw{1'b x}} : mem[raddr];
333 always @(posedge wclk)
338 // Task prints range of memory
339 // *** Remember that tasks are non reentrant, don't call this task in parallel for multiple instantiations.
341 input [aw-1:0] start;
342 input [aw-1:0] finish;
345 for (rnum=start;rnum<=finish;rnum=rnum+1)
346 $display("Addr %h = %h",rnum,mem[rnum]);
350 `endif // !VENDOR_VIRAGE
351 `endif // !VENDOR_AVANT
352 `endif // !VENDOR_ARTISAN
353 `endif // !VENDOR_ALTERA
354 `endif // !VENDOR_XILINX
355 `endif // !VENDOR_FPGA
364 module altera_ram_dp(
373 q) /* synthesis black_box */;
375 parameter awidth = 7;
376 parameter dwidth = 8;
378 input [dwidth -1:0] data;
379 input [awidth -1:0] wraddress;
380 input [awidth -1:0] rdaddress;
386 output [dwidth -1:0] q;
388 // synopsis translate_off
389 // exemplar translate_off
401 .RdAddress(rdaddress),
408 .WrAddress(wraddress),
413 // exemplar translate_on
414 // synopsis translate_on
417 `endif // VENDOR_ALTERA
420 module xilinx_ram_dp (
434 DOB) /* synthesis black_box */ ;
436 parameter awidth = 7;
437 parameter dwidth = 8;
443 input [awidth-1:0] ADDRA;
444 input [dwidth-1:0] DIA;
446 output [dwidth-1:0] DOA;
452 input [awidth-1:0] ADDRB;
453 input [dwidth-1:0] DIB;
455 output [dwidth-1:0] DOB;
457 // insert simulation model
460 // synopsys translate_off
461 // exemplar translate_off
463 C_MEM_DP_BLOCK_V1_0 #(
510 // exemplar translate_on
511 // synopsys translate_on
514 `endif // VENDOR_XILINX