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.1 2007-02-11 22:05:26 sithglan
72 // Revision 1.4 2002/09/28 08:18:52 rherveille
73 // Changed synthesizeable FPGA memory implementation.
74 // Fixed some issues with Xilinx BlockRAM
76 // Revision 1.3 2001/11/09 00:34:18 samg
77 // minor changes: unified with all common rams
79 // Revision 1.2 2001/11/08 19:11:31 samg
80 // added valid checks to behvioral model
82 // Revision 1.1.1.1 2001/09/14 09:57:10 rherveille
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.
89 // Revision 1.1.1.2 2001/08/21 13:09:27 damjan
90 // *** empty log message ***
92 // Revision 1.1 2001/08/20 18:23:20 damjan
95 // Revision 1.1 2001/08/09 13:39:33 lampret
98 // Revision 1.2 2001/07/30 05:38:02 lampret
99 // Adding empty directories required by HDL coding guidelines
103 //`include "timescale.v"
105 //`define VENDOR_FPGA
106 //`define VENDOR_XILINX
107 //`define VENDOR_ALTERA
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
116 // Default address and data buses width
118 parameter aw = 5; // number of bits in address-bus
119 parameter dw = 16; // number of bits in data-bus
122 // Generic synchronous double-port RAM interface
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
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
146 // Instantiation synthesizeable FPGA memory
148 // This code has been tested using LeonardoSpectrum and Synplicity.
149 // The code correctly instantiates Altera EABs and Xilinx BlockRAMs.
151 reg [dw-1:0] mem [(1<<aw) -1:0]; // instantiate memory
152 reg [aw-1:0] ra; // register read address
155 always @(posedge rclk)
162 always@(posedge wclk)
170 // Instantiation of FPGA memory:
172 // Virtex/Spartan2 BlockRAMs
174 xilinx_ram_dp xilinx_ram(
195 xilinx_ram.dwidth = dw,
196 xilinx_ram.awidth = aw;
202 // Instantiation of FPGA memory:
204 // Altera FLEX/APEX EABs
206 altera_ram_dp altera_ram(
222 altera_ram.dwidth = dw,
223 altera_ram.awidth = aw;
227 `ifdef VENDOR_ARTISAN
230 // Instantiation of ASIC memory:
232 // Artisan Synchronous Double-Port RAM (ra2sh)
234 art_hsdp #(dw, 1<<aw, aw) artisan_sdp(
259 // Instantiation of ASIC memory:
261 // Avant! Asynchronous Two-Port RAM
280 // Instantiation of ASIC memory:
282 // Virage Synchronous 2-port R/W RAM
284 virage_stp virage_stp(
307 // Generic dual-port synchronous RAM model
311 // Generic RAM's registers and wires
313 reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content
314 reg [dw-1:0] do_reg; // RAM data output register
317 // Data output drivers
319 assign do = (oe & rce) ? do_reg : {dw{1'bz}};
322 always @(posedge rclk)
324 do_reg <= #1 (we && (waddr==raddr)) ? {dw{1'b x}} : mem[raddr];
327 always @(posedge wclk)
332 // Task prints range of memory
333 // *** Remember that tasks are non reentrant, don't call this task in parallel for multiple instantiations.
335 input [aw-1:0] start;
336 input [aw-1:0] finish;
339 for (rnum=start;rnum<=finish;rnum=rnum+1)
340 $display("Addr %h = %h",rnum,mem[rnum]);
344 `endif // !VENDOR_VIRAGE
345 `endif // !VENDOR_AVANT
346 `endif // !VENDOR_ARTISAN
347 `endif // !VENDOR_ALTERA
348 `endif // !VENDOR_XILINX
349 `endif // !VENDOR_FPGA
358 module altera_ram_dp(
367 q) /* synthesis black_box */;
369 parameter awidth = 7;
370 parameter dwidth = 8;
372 input [dwidth -1:0] data;
373 input [awidth -1:0] wraddress;
374 input [awidth -1:0] rdaddress;
380 output [dwidth -1:0] q;
382 // synopsis translate_off
383 // exemplar translate_off
395 .RdAddress(rdaddress),
402 .WrAddress(wraddress),
407 // exemplar translate_on
408 // synopsis translate_on
411 `endif // VENDOR_ALTERA
414 module xilinx_ram_dp (
428 DOB) /* synthesis black_box */ ;
430 parameter awidth = 7;
431 parameter dwidth = 8;
437 input [awidth-1:0] ADDRA;
438 input [dwidth-1:0] DIA;
440 output [dwidth-1:0] DOA;
446 input [awidth-1:0] ADDRB;
447 input [dwidth-1:0] DIB;
449 output [dwidth-1:0] DOB;
451 // insert simulation model
454 // synopsys translate_off
455 // exemplar translate_off
457 C_MEM_DP_BLOCK_V1_0 #(
504 // exemplar translate_on
505 // synopsys translate_on
508 `endif // VENDOR_XILINX