URL
https://opencores.org/ocsvn/common/common/trunk
Subversion Repositories common
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 42 to Rev 43
- ↔ Reverse comparison
Rev 42 → Rev 43
/tags/rel_19/generic_memories/rtl/verilog/generic_dpram.v
0,0 → 1,501
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Generic Dual-Port Synchronous RAM //// |
//// //// |
//// This file is part of memory library available from //// |
//// http://www.opencores.org/cvsweb.shtml/generic_memories/ //// |
//// //// |
//// Description //// |
//// This block is a wrapper with common dual-port //// |
//// synchronous memory interface for different //// |
//// types of ASIC and FPGA RAMs. Beside universal memory //// |
//// interface it also provides behavioral model of generic //// |
//// dual-port synchronous RAM. //// |
//// It also contains a fully synthesizeable model for FPGAs. //// |
//// It should be used in all OPENCORES designs that want to be //// |
//// portable accross different target technologies and //// |
//// independent of target memory. //// |
//// //// |
//// Supported ASIC RAMs are: //// |
//// - Artisan Dual-Port Sync RAM //// |
//// - Avant! Two-Port Sync RAM (*) //// |
//// - Virage 2-port Sync RAM //// |
//// //// |
//// Supported FPGA RAMs are: //// |
//// - Generic FPGA (VENDOR_FPGA) //// |
//// Tested RAMs: Altera, Xilinx //// |
//// Synthesis tools: LeonardoSpectrum, Synplicity //// |
//// - Xilinx (VENDOR_XILINX) //// |
//// - Altera (VENDOR_ALTERA) //// |
//// //// |
//// To Do: //// |
//// - fix Avant! //// |
//// - add additional RAMs (VS etc) //// |
//// //// |
//// Author(s): //// |
//// - Richard Herveille, richard@asics.ws //// |
//// - Damjan Lampret, lampret@opencores.org //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Copyright (C) 2000 Authors and OPENCORES.ORG //// |
//// //// |
//// This source file may be used and distributed without //// |
//// restriction provided that this copyright statement is not //// |
//// removed from the file and that any derivative work contains //// |
//// the original copyright notice and the associated disclaimer. //// |
//// //// |
//// This source file is free software; you can redistribute it //// |
//// and/or modify it under the terms of the GNU Lesser General //// |
//// Public License as published by the Free Software Foundation; //// |
//// either version 2.1 of the License, or (at your option) any //// |
//// later version. //// |
//// //// |
//// This source is distributed in the hope that it will be //// |
//// useful, but WITHOUT ANY WARRANTY; without even the implied //// |
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// |
//// PURPOSE. See the GNU Lesser General Public License for more //// |
//// details. //// |
//// //// |
//// You should have received a copy of the GNU Lesser General //// |
//// Public License along with this source; if not, download it //// |
//// from http://www.opencores.org/lgpl.shtml //// |
//// //// |
////////////////////////////////////////////////////////////////////// |
// |
// CVS Revision History |
// |
// $Log: not supported by cvs2svn $ |
// Revision 1.3 2001/11/09 00:34:18 samg |
// minor changes: unified with all common rams |
// |
// Revision 1.2 2001/11/08 19:11:31 samg |
// added valid checks to behvioral model |
// |
// Revision 1.1.1.1 2001/09/14 09:57:10 rherveille |
// Major cleanup. |
// Files are now compliant to Altera & Xilinx memories. |
// Memories are now compatible, i.e. drop-in replacements. |
// Added synthesizeable generic FPGA description. |
// Created "generic_memories" cvs entry. |
// |
// Revision 1.1.1.2 2001/08/21 13:09:27 damjan |
// *** empty log message *** |
// |
// Revision 1.1 2001/08/20 18:23:20 damjan |
// Initial revision |
// |
// Revision 1.1 2001/08/09 13:39:33 lampret |
// Major clean-up. |
// |
// Revision 1.2 2001/07/30 05:38:02 lampret |
// Adding empty directories required by HDL coding guidelines |
// |
// |
|
//`include "timescale.v" |
|
//`define VENDOR_FPGA |
//`define VENDOR_XILINX |
//`define VENDOR_ALTERA |
|
module generic_dpram( |
// Generic synchronous dual-port RAM interface |
rclk, rrst, rce, oe, raddr, do, |
wclk, wrst, wce, we, waddr, di |
); |
|
// |
// Default address and data buses width |
// |
parameter aw = 5; // number of bits in address-bus |
parameter dw = 16; // number of bits in data-bus |
|
// |
// Generic synchronous double-port RAM interface |
// |
// read port |
input rclk; // read clock, rising edge trigger |
input rrst; // read port reset, active high |
input rce; // read port chip enable, active high |
input oe; // output enable, active high |
input [aw-1:0] raddr; // read address |
output [dw-1:0] do; // data output |
|
// write port |
input wclk; // write clock, rising edge trigger |
input wrst; // write port reset, active high |
input wce; // write port chip enable, active high |
input we; // write enable, active high |
input [aw-1:0] waddr; // write address |
input [dw-1:0] di; // data input |
|
// |
// Module body |
// |
|
`ifdef VENDOR_FPGA |
// |
// Instantiation synthesizeable FPGA memory |
// |
// This code has been tested using LeonardoSpectrum and Synplicity. |
// The code correctly instantiates Altera EABs and Xilinx BlockRAMs. |
// |
reg [dw-1:0] mem [(1<<aw) -1:0]; // instantiate memory |
reg [aw-1:0] ra; // register read address |
|
// read operation |
always @(posedge rclk) |
if (rce) |
ra <= #1 raddr; |
|
assign do = mem[ra]; |
|
// write operation |
always@(posedge wclk) |
if (we && wce) |
mem[waddr] <= #1 di; |
|
`else |
|
`ifdef VENDOR_XILINX |
// |
// Instantiation of FPGA memory: |
// |
// Virtex/Spartan2 BlockRAMs |
// |
xilinx_ram_dp xilinx_ram( |
// read port |
.CLKA(rclk), |
.RSTA(rrst), |
.ENA(rce), |
.ADDRA(raddr), |
.DIA( {dw{1'b0}} ), |
.WEA(1'b0), |
.DOA(do), |
|
// write port |
.CLKB(wclk), |
.RSTB(wrst), |
.ENB(wce), |
.ADDRB(waddr), |
.DIB(di), |
.WEB(we), |
.DOB() |
); |
|
defparam |
xilinx_ram.dwidth = dw, |
xilinx_ram.awidth = aw; |
|
`else |
|
`ifdef VENDOR_ALTERA |
// |
// Instantiation of FPGA memory: |
// |
// Altera FLEX/APEX EABs |
// |
altera_ram_dp altera_ram( |
// read port |
.rdclock(rclk), |
.rdclocken(rce), |
.rdaddress(raddr), |
.q(do), |
|
// write port |
.wrclock(wclk), |
.wrclocken(wce), |
.wren(we), |
.wraddress(waddr), |
.data(di) |
); |
|
defparam |
altera_ram.dwidth = dw, |
altera_ram.awidth = aw; |
|
`else |
|
`ifdef VENDOR_ARTISAN |
|
// |
// Instantiation of ASIC memory: |
// |
// Artisan Synchronous Double-Port RAM (ra2sh) |
// |
art_hsdp #(dw, 1<<aw, aw) artisan_sdp( |
// read port |
.qa(do), |
.clka(rclk), |
.cena(~rce), |
.wena(1'b1), |
.aa(raddr), |
.da( {dw{1'b0}} ), |
.oena(~oe), |
|
// write port |
.qb(), |
.clkb(wclk), |
.cenb(~wce), |
.wenb(~we), |
.ab(waddr), |
.db(di), |
.oenb(1'b1) |
); |
|
`else |
|
`ifdef VENDOR_AVANT |
|
// |
// Instantiation of ASIC memory: |
// |
// Avant! Asynchronous Two-Port RAM |
// |
avant_atp avant_atp( |
.web(~we), |
.reb(), |
.oeb(~oe), |
.rcsb(), |
.wcsb(), |
.ra(raddr), |
.wa(waddr), |
.di(di), |
.do(do) |
); |
|
`else |
|
`ifdef VENDOR_VIRAGE |
|
// |
// Instantiation of ASIC memory: |
// |
// Virage Synchronous 2-port R/W RAM |
// |
virage_stp virage_stp( |
// read port |
.CLKA(rclk), |
.MEA(rce_a), |
.ADRA(raddr), |
.DA( {dw{1'b0}} ), |
.WEA(1'b0), |
.OEA(oe), |
.QA(do), |
|
// write port |
.CLKB(wclk), |
.MEB(wce), |
.ADRB(waddr), |
.DB(di), |
.WEB(we), |
.OEB(1'b1), |
.QB() |
); |
|
`else |
|
// |
// Generic dual-port synchronous RAM model |
// |
|
// |
// Generic RAM's registers and wires |
// |
reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content |
reg [dw-1:0] do_reg; // RAM data output register |
|
// |
// Data output drivers |
// |
assign do = (oe & rce) ? do_reg : {dw{1'bz}}; |
|
// read operation |
always @(posedge rclk) |
if (rce) |
do_reg <= #1 (we && (waddr==raddr)) ? {dw{1'b x}} : mem[raddr]; |
|
// write operation |
always @(posedge wclk) |
if (wce && we) |
mem[waddr] <= #1 di; |
|
|
// Task prints range of memory |
// *** Remember that tasks are non reentrant, don't call this task in parallel for multiple instantiations. |
task print_ram; |
input [aw-1:0] start; |
input [aw-1:0] finish; |
integer rnum; |
begin |
for (rnum=start;rnum<=finish;rnum=rnum+1) |
$display("Addr %h = %h",rnum,mem[rnum]); |
end |
endtask |
|
`endif // !VENDOR_VIRAGE |
`endif // !VENDOR_AVANT |
`endif // !VENDOR_ARTISAN |
`endif // !VENDOR_ALTERA |
`endif // !VENDOR_XILINX |
`endif // !VENDOR_FPGA |
|
endmodule |
|
// |
// Black-box modules |
// |
|
`ifdef VENDOR_ALTERA |
module altera_ram_dp( |
data, |
wraddress, |
rdaddress, |
wren, |
wrclock, |
wrclocken, |
rdclock, |
rdclocken, |
q) /* synthesis black_box */; |
|
parameter awidth = 7; |
parameter dwidth = 8; |
|
input [dwidth -1:0] data; |
input [awidth -1:0] wraddress; |
input [awidth -1:0] rdaddress; |
input wren; |
input wrclock; |
input wrclocken; |
input rdclock; |
input rdclocken; |
output [dwidth -1:0] q; |
|
// synopsis translate_off |
// exemplar translate_off |
|
syn_dpram_rowr #( |
"UNUSED", |
dwidth, |
awidth, |
1 << awidth |
) |
altera_dpram_model ( |
// read port |
.RdClock(rdclock), |
.RdClken(rdclocken), |
.RdAddress(rdaddress), |
.RdEn(1'b1), |
.Q(q), |
|
// write port |
.WrClock(wrclock), |
.WrClken(wrclocken), |
.WrAddress(wraddress), |
.WrEn(wren), |
.Data(data) |
); |
|
// exemplar translate_on |
// synopsis translate_on |
|
endmodule |
`endif // VENDOR_ALTERA |
|
`ifdef VENDOR_XILINX |
module xilinx_ram_dp ( |
ADDRA, |
CLKA, |
ADDRB, |
CLKB, |
DIA, |
WEA, |
DIB, |
WEB, |
ENA, |
ENB, |
RSTA, |
RSTB, |
DOA, |
DOB) /* synthesis black_box */ ; |
|
parameter awidth = 7; |
parameter dwidth = 8; |
|
// port_a |
input CLKA; |
input RSTA; |
input ENA; |
input [awidth-1:0] ADDRA; |
input [dwidth-1:0] DIA; |
input WEA; |
output [dwidth-1:0] DOA; |
|
// port_b |
input CLKB; |
input RSTB; |
input ENB; |
input [awidth-1:0] ADDRB; |
input [dwidth-1:0] DIB; |
input WEB; |
output [dwidth-1:0] DOB; |
|
// insert simulation model |
|
|
// synopsys translate_off |
// exemplar translate_off |
|
C_MEM_DP_BLOCK_V1_0 #( |
awidth, |
awidth, |
1, |
1, |
"0", |
1 << awidth, |
1 << awidth, |
1, |
1, |
1, |
1, |
1, |
1, |
1, |
1, |
1, |
1, |
1, |
1, |
1, |
"", |
16, |
0, |
0, |
1, |
1, |
1, |
1, |
dwidth, |
dwidth) |
xilinx_dpram_model ( |
.ADDRA(ADDRA), |
.CLKA(CLKA), |
.ADDRB(ADDRB), |
.CLKB(CLKB), |
.DIA(DIA), |
.WEA(WEA), |
.DIB(DIB), |
.WEB(WEB), |
.ENA(ENA), |
.ENB(ENB), |
.RSTA(RSTA), |
.RSTB(RSTB), |
.DOA(DOA), |
.DOB(DOB)); |
|
// exemplar translate_on |
// synopsys translate_on |
|
endmodule |
`endif // VENDOR_XILINX |