-------------------------------------------------------------------------------
-- Title : Dual port RAM
-- Project : Memory Cores
-------------------------------------------------------------------------------
-- File : dpmem.vhd
-- Author : Jamil Khatib (khatib@ieee.org)
-- Organization: OpenIPCore Project
-- Created : 1999/5/14
-- Last update : 2000/12/19
-- Platform :
-- Simulators : Modelsim 5.3XE/Windows98
-- Synthesizers: Leonardo/WindowsNT
-- Target :
-- Dependency : ieee.std_logic_1164,ieee.std_logic_unsigned
-------------------------------------------------------------------------------
-- Description: Dual Port memory
-------------------------------------------------------------------------------
-- Copyright (c) 2000 Jamil Khatib
--
-- This VHDL design file is an open design; you can redistribute it and/or
-- modify it and/or implement it after contacting the author
-- You can check the draft license at
-- http://www.opencores.org/OIPC/license.shtml
-------------------------------------------------------------------------------
-- Revisions :
-- Revision Number : 1
-- Version : 0.1
-- Date : 12 May 1999
-- Modifier : Jamil Khatib (khatib@ieee.org)
-- Desccription : Created
-- Known bugs :
-- To Optimze :
-------------------------------------------------------------------------------
-- Revisions :
-- Revision Number : 2
-- Version : 0.2
-- Date : 19 Dec 2000
-- Modifier : Jamil Khatib (khatib@ieee.org)
-- Desccription : General review
-- Two versions are now available with reset and without
-- Default output can can be defined
-- Known bugs :
-- To Optimze :
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
-- Dual port Memory core
entity dpmem_ent is
generic (USE_RESET : boolean := true; -- use system reset
USE_CS : boolean := true; -- use chip select signal
-- This parameter is not used and the CS pin is
-- always unconnected
DEFAULT_OUT : std_logic := '1'; -- Default output
CLK_DOMAIN : integer := 2; -- Clock Domain
-- 2 := 2 clocks one for read and one
-- for write
-- 1 := Single clock for read and write
-- 0 := Read does not have any clock
ADD_WIDTH : integer := 3;
WIDTH : integer := 8);
port (
W_clk : in std_logic; -- write clock , or system clock
R_clk : in std_logic; -- Read clock
reset : in std_logic; -- System Reset
W_add : in std_logic_vector(add_width -1 downto 0); -- Write Address
R_add : in std_logic_vector(add_width -1 downto 0); -- Read Address
Data_In : in std_logic_vector(WIDTH - 1 downto 0); -- input data
Data_Out : out std_logic_vector(WIDTH -1 downto 0); -- output Data
WR : in std_logic; -- Write Enable
RE : in std_logic); -- Read Enable
end dpmem_ent;
-------------------------------------------------------------------------------
architecture dpmem_beh of dpmem_ent is
type data_array is array (integer range <>) of std_logic_vector(WIDTH -1 downto 0);
-- Memory Type
signal data : data_array(0 to (2** add_width-1) ); -- Local data
procedure init_mem(signal memory_cell : inout data_array ) is
begin
for i in 0 to (2** add_width-1) loop
memory_cell(i) <= (others => '0');
end loop;
end init_mem;
begin -- dpmem_beh
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
REASET_ENABLED : if USE_RESET = true generate
CLOCKS_2 : if CLK_DOMAIN = 2 generate
-----------------------------------------------------------------------------
-- purpose: Read process
-- type : sequential
-- inputs : R_clk,reset
-- outputs:
ReProc : process (R_clk, reset)
begin -- process ReProc
if reset = '0' then
Data_out <= (others => DEFAULT_OUT);
elsif R_clk'event and R_clk = '1' then -- rising clock edge
if Re = '1' then
Data_out <= data(conv_integer(R_add));
else
Data_out <= (others => DEFAULT_OUT);
end if;
end if;
end process ReProc;
-----------------------------------------------------------------------------
-- purpose: Write process
-- type : sequential
-- inputs : W_clk,reset
-- outputs:
WrProc : process (W_clk, reset)
begin -- process WrProc
if reset = '0' then
init_mem ( data);
elsif W_clk'event and W_clk = '1' then -- rising clock edge
if Wr = '1' then
data(conv_integer(W_add)) <= Data_in;
end if;
end if;
end process WrProc;
-------------------------------------------------------------------------------
end generate CLOCKS_2;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
CLOCKS_1 : if CLK_DOMAIN = 1 generate
process (w_clk, reset)
begin -- PROCESS
-- activities triggered by asynchronous reset (active low)
if reset = '0' then
data_out <= (others => DEFAULT_OUT);
init_mem (data);
-- activities triggered by rising edge of clock
elsif w_clk'event and w_clk = '1' then
if RE = '1' then
data_out <= data(conv_integer(R_add));
else
data_out <= (others => DEFAULT_OUT); -- Defualt value
end if;
if WR = '1' then
data(conv_integeR(W_add)) <= Data_In;
end if;
end if;
end process;
end generate CLOCKS_1;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
CLOCKS_0 : if CLK_DOMAIN = 0 generate
-- purpose: Write process
-- type : sequential
-- inputs : W_clk,reset
-- outputs:
WrProc : process (W_clk, reset)
begin -- process WrProc
if reset = '0' then
init_mem (data);
elsif W_clk'event and W_clk = '1' then -- rising clock edge
if Wr = '1' then
data(conv_integer(W_add)) <= Data_in;
end if;
end if;
end process WrProc;
data_out <= data(conv_integer(R_add)) when RE = '1' else (others => DEFAULT_OUT);
end generate CLOCKS_0;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
end generate REASET_ENABLED;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
RESET_DISABLED : if USE_RESET = false generate
CLOCKS_2 : if CLK_DOMAIN = 2 generate
-----------------------------------------------------------------------------
-- purpose: Read process
-- type : sequential
-- inputs : R_clk
-- outputs:
ReProc : process (R_clk)
begin -- process ReProc
if R_clk'event and R_clk = '1' then -- rising clock edge
if Re = '1' then
Data_out <= data(conv_integer(R_add));
else
Data_out <= (others => DEFAULT_OUT);
end if;
end if;
end process ReProc;
-----------------------------------------------------------------------------
-- purpose: Write process
-- type : sequential
-- inputs : W_clk
-- outputs:
WrProc : process (W_clk)
begin -- process WrProc
if W_clk'event and W_clk = '1' then -- rising clock edge
if Wr = '1' then
data(conv_integer(W_add)) <= Data_in;
end if;
end if;
end process WrProc;
-------------------------------------------------------------------------------
end generate CLOCKS_2;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
CLOCKS_1 : if CLK_DOMAIN = 1 generate
process (w_clk)
begin -- PROCESS
-- activities triggered by rising edge of clock
if w_clk'event and w_clk = '1' then
if RE = '1' then
data_out <= data(conv_integer(R_add));
else
data_out <= (others => DEFAULT_OUT); -- Defualt value
end if;
if WR = '1' then
data(conv_integeR(W_add)) <= Data_In;
end if;
end if;
end process;
end generate CLOCKS_1;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
CLOCKS_0 : if CLK_DOMAIN = 0 generate
-- purpose: Write process
-- type : sequential
-- inputs : W_clk
-- outputs:
WrProc : process (W_clk)
begin -- process WrProc
if W_clk'event and W_clk = '1' then -- rising clock edge
if Wr = '1' then
data(conv_integer(W_add)) <= Data_in;
end if;
end if;
end process WrProc;
data_out <= data(conv_integer(R_add)) when RE = '1' else (others => DEFAULT_OUT);
end generate CLOCKS_0;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
end generate RESET_DISABLED;
end dpmem_beh;
-------------------------------------------------------------------------------