------------------------------------------------------------------------------- -- 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; -------------------------------------------------------------------------------