URL
https://opencores.org/ocsvn/common/common/trunk
Subversion Repositories common
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 12 to Rev 13
- ↔ Reverse comparison
Rev 12 → Rev 13
/tags/initial/generic_memories/rtl/verilog/generic_spram.v
0,0 → 1,405
////////////////////////////////////////////////////////////////////// |
//// //// |
//// Generic Single-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 single-port //// |
//// synchronous memory interface for different //// |
//// types of ASIC and FPGA RAMs. Beside universal memory //// |
//// interface it also provides a behavioral model of generic //// |
//// single-port synchronous RAM. //// |
//// It also contains a 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 Single-Port Sync RAM //// |
//// - Avant! Two-Port Sync RAM (*) //// |
//// - Virage Single-Port Sync RAM //// |
//// - Virtual Silicon Single-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! two-port ram //// |
//// - add additional RAMs //// |
//// //// |
//// 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.2 2001/07/30 05:38:02 lampret |
// Adding empty directories required by HDL coding guidelines |
// |
// |
|
`include "timescale.v" |
|
//`define VENDOR_XILINX |
//`define VENDOR_ALTERA |
`define VENDOR_FPGA |
|
module generic_spram( |
// Generic synchronous single-port RAM interface |
clk, rst, ce, we, oe, addr, di, do |
); |
|
// |
// Default address and data buses width |
// |
parameter aw = 6; //number of address-bits |
parameter dw = 8; //number of data-bits |
|
// |
// Generic synchronous single-port RAM interface |
// |
input clk; // Clock, rising edge |
input rst; // Reset, active high |
input ce; // Chip enable input, active high |
input we; // Write enable input, active high |
input oe; // Output enable input, active high |
input [aw-1:0] addr; // address bus inputs |
input [dw-1:0] di; // input data bus |
output [dw-1:0] do; // output data bus |
|
// |
// 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]; |
reg [aw-1:0] raddr; |
|
always@(posedge clk) |
begin |
// read operation |
raddr <= #1 addr; // read address needs to be registered to read clock |
|
// write operation |
if (we && ce) |
mem[addr] <= #1 di; |
end |
|
assign #1 do = mem[raddr]; |
|
`else |
|
`ifdef VENDOR_XILINX |
|
wire [dw-1:0] q; // output from xilinx ram |
// |
// Instantiation of FPGA memory: |
// |
// Virtex/Spartan2 BlockRAMs |
// |
xilinx_ram_sp xilinx_ram( |
.clk(clk), |
.rst(rst), |
.addr(addr), |
.di(di), |
.en(ce), |
.we(we), |
.do(do) |
); |
|
defparam |
xilinx_ram.dwidth = dw, |
xilinx_ram.awidth = aw; |
|
`else |
|
`ifdef VENDOR_ALTERA |
|
// |
// Instantiation of FPGA memory: |
// |
// Altera FLEX EABs |
// |
|
altera_ram_sp altera_ram( |
.inclock(clk), |
.address(addr), |
.data(di), |
.we(we && ce), |
.q(do) |
); |
|
defparam |
altera_ram.dwidth = dw, |
altera_ram.awidth = aw; |
|
`else |
|
`ifdef VENDOR_ARTISAN |
|
// |
// Instantiation of ASIC memory: |
// |
// Artisan Synchronous Single-Port RAM (ra1sh) |
// |
artisan_ssp #(dw, 1<<aw, aw) artisan_ssp( |
.CLK(clk), |
.CEN(~ce), |
.WEN(~we), |
.A(addr), |
.D(di), |
.OEN(~oe), |
.Q(do) |
); |
|
`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(addr), |
.wa(addr), |
.di(di), |
.do(do) |
); |
|
`else |
|
`ifdef VENDOR_VIRAGE |
|
// |
// Instantiation of ASIC memory: |
// |
// Virage Synchronous 1-port R/W RAM |
// |
virage_ssp virage_ssp( |
.clk(clk), |
.adr(addr), |
.d(di), |
.we(we), |
.oe(oe), |
.me(ce), |
.q(do) |
); |
|
`else |
|
`ifdef VENDOR_VIRTUALSILICON |
|
// |
// Instantiation of ASIC memory: |
// |
// Virtual Silicon Single-Port Synchronous SRAM |
// |
virtualsilicon_spram #(1<<aw, aw-1, dw-1) virtualsilicon_ssp( |
.CK(clk), |
.ADR(addr), |
.DI(di), |
.WEN(~we), |
.CEN(~ce), |
.OEN(~oe), |
.DOUT(do) |
); |
|
`else |
|
// |
// Generic single-port synchronous RAM model |
// |
|
// |
// Generic RAM's registers and wires |
// |
reg [dw-1:0] mem [(1<<aw)-1:0]; // RAM content |
wire [dw-1:0] q; // RAM output |
reg [aw-1:0] raddr; // RAM read address |
// |
// Data output drivers |
// |
assign do = (oe) ? q : {dw{1'bz}}; |
|
// |
// RAM read and write |
// |
|
// read operation |
always@(posedge clk) |
if (ce) // && !we) |
raddr <= #1 addr; // read address needs to be registered to read clock |
|
assign #1 q = rst ? {dw{1'b0}} : mem[raddr]; |
|
// write operation |
always@(posedge clk) |
if (ce && we) |
mem[addr] <= #1 di; |
|
|
`endif // !VIRTUALSILICON_SSP |
`endif // !VIRAGE_SSP |
`endif // !AVANT_ATP |
`endif // !ARTISAN_SSP |
`endif // !VENDOR_ALTERA |
`endif // !VENDOR_XILINX |
`endif // !VENDOR_FPGA |
|
endmodule |
|
|
// |
// Black-box modules |
// |
|
`ifdef VENDOR_ALTERA |
module altera_ram_sp ( |
address, |
inclock, |
we, |
data, |
q) /* synthesis black_box */; |
|
parameter awidth = 7; |
parameter dwidth = 8; |
|
input [awidth -1:0] address; |
input inclock; |
input we; |
input [dwidth -1:0] data; |
output [dwidth -1:0] q; |
|
// synopsis translate_off |
// exemplar translate_off |
|
syn_ram_irou #( |
"UNUSED", |
dwidth, |
awidth, |
1 << awidth |
) |
altera_spram_model ( |
.Inclock(inclock), |
.Address(address), |
.Data(data), |
.WE(we), |
.Q(q) |
); |
|
// exemplar translate_on |
// synopsis translate_on |
|
endmodule |
`endif // VENDOR_ALTERA |
|
`ifdef VENDOR_XILINX |
module xilinx_ram_sp ( |
clk, |
rst, |
addr, |
di, |
en, |
we, |
do) /* synthesis black_box */ ; |
|
parameter awidth = 7; |
parameter dwidth = 8; |
|
input clk; |
input rst; |
input [awidth -1:0] addr; |
input [dwidth -1:0] di; |
input en; |
input we; |
output [dwidth -1:0] do; |
|
// insert simulation model |
|
|
// synopsys translate_off |
// exemplar translate_off |
|
C_MEM_SP_BLOCK_V1_0 #( |
awidth, |
1, |
"0", |
1 << awidth, |
1, |
1, |
1, |
1, |
1, |
1, |
1, |
"", |
16, |
0, |
0, |
1, |
1, |
dwidth |
) |
xilinx_spram_model ( |
.CLK(clk), |
.RST(rst), |
.ADDR(addr), |
.DI(di), |
.EN(en), |
.WE(we), |
.DO(do) |
); |
|
// exemplar translate_on |
// synopsys translate_on |
|
endmodule |
`endif // VENDOR_XILINX |
|
/tags/initial/generic_memories/rtl/verilog/generic_dpram.v
0,0 → 1,480
////////////////////////////////////////////////////////////////////// |
//// //// |
//// 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.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 [dw-1:0] do; // data output registers |
|
// read operation |
|
/* |
always@(posedge rclk) |
if (rce) // clock enable instructs Xilinx tools to use SelectRAM (LUTS) instead of BlockRAM |
do <= #1 mem[raddr]; |
*/ |
|
always@(posedge rclk) |
do <= #1 mem[raddr]; |
|
// 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) ? do_reg : {dw{1'bz}}; |
|
// read operation |
always @(posedge rclk) |
if (rce) |
do_reg <= #1 mem[raddr]; |
|
// write operation |
always @(posedge wclk) |
if (wce && we) |
mem[waddr] <= #1 di; |
|
`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 |