-------------------------------------------------------------------------------
-- 
-- Copyright Jamil Khatib 1999
-- 
--
-- This VHDL design file is an open design; you can redistribute it and/or
-- modify it and/or implement it under the terms of the Openip General Public
-- License as it is going to be published by the OpenIP Organization and any
-- coming versions of this license.
-- You can check the draft license at
-- http://www.openip.org/oc/license.html
--
--
-- Creator : Jamil Khatib
-- Date 14/5/99
--
-- version 0.19991224
--
-- This file was tested on the ModelSim 5.2EE
-- The test vecors for model sim is included in vectors.do file
-- This VHDL design file is proved through simulation but not verified on Silicon
-- 
--
-------------------------------------------------------------------------------
LIBRARY ieee;

USE ieee.std_logic_1164.ALL;


USE ieee.std_logic_signed.ALL;




-- Dual port Memory core



ENTITY dpmem IS

generic ( ADD_WIDTH: integer := 8 ;
		 WIDTH : integer := 8);
  port (
    clk      : in  std_logic;                                -- write 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;


-------------------------------------------------------------------------------

ARCHITECTURE dpmem_v1 OF dpmem 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) );  -- Local data



  procedure init_mem(signal memory_cell : inout data_array ) is

  begin

    for i in 0 to (2** add_width) loop
      memory_cell(i) <= (others => '0');
    end loop;

  end init_mem;


begin  -- dpmem_v1

  process (clk, reset)

  begin  -- PROCESS


    -- activities triggered by asynchronous reset (active low)
    if reset = '0' then
      data_out <= (others => 'Z');
      init_mem ( data);

      -- activities triggered by rising edge of clock
    elsif clk'event and clk = '1' then
      if RE = '1' then
        data_out <= data(conv_integer(R_add));
      else
        data_out <= (others => 'Z');    -- Defualt value
      end if;

      if WR = '1' then
        data(conv_integeR(W_add)) <= Data_In;
      end if;
    end if;



  end process;


end dpmem_v1;



-------------------------------------------------------------------------------

-- This Architecture was tested on the ModelSim 5.2EE
-- The test vectors for model sim is included in vectors.do file
-- It is Synthesized using Xilinx Webfitter
--
-- 
-- The variable result_data is used as an intermediate variable in the process
-- 

ARCHITECTURE dpmem_v2 OF dpmem 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) );  -- Local data


-- Initialize the memory to zeros 
  procedure init_mem(signal memory_cell : inout data_array ) is

  begin

    for i in 0 to (2** add_width) loop
      memory_cell(i) <= (others => '0');
    end loop;

  end init_mem;

 
begin  -- dpmem_v2

  process (clk, reset)

    variable result_data : std_logic_vector(WIDTH -1  downto 0);

  begin  -- PROCESS

-- init data_out


    -- activities triggered by asynchronous reset (active low)
    if reset = '0' then
      result_data := (others => 'Z');
      init_mem ( data);

      -- activities triggered by rising edge of clock
    elsif clk'event and clk = '1' then
      if RE = '1' then
        result_data := data(conv_integer(R_add));
      else
        result_data := (others => 'Z');    -- Defualt value
      end if;

      if WR = '1' then
        data(conv_integeR(W_add)) <= Data_In;
      end if;
    end if;

data_out <= result_data;


end process;


end dpmem_v2;



-------------------------------------------------------------------------------
-- This Architecture was tested on the ModelSim 5.2EE
-- The test vectors for model sim is included in vectors.do file
-- It is Synthesized using Xilinx Webpack
--
-- This is the same as dpmem_v1 but without the Z state
-- instead the output goes to all 1's during reset and 
-- when RE = 0

ARCHITECTURE dpmem_v3 OF dpmem 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) );  -- Local data



  procedure init_mem(signal memory_cell : inout data_array ) is

  begin

    for i in 0 to (2** add_width) loop
      memory_cell(i) <= (others => '0');
    end loop;

  end init_mem;


begin  -- dpmem_v3

  process (clk, reset)

  begin  -- PROCESS


    -- activities triggered by asynchronous reset (active low)
    if reset = '0' then
      data_out <= (others => '1');
      init_mem ( data);

      -- activities triggered by rising edge of clock
    elsif clk'event and clk = '1' then
      if RE = '1' then
        data_out <= data(conv_integer(R_add));
      else
        data_out <= (others => '1');    -- Defualt value
      end if;

      if WR = '1' then
        data(conv_integeR(W_add)) <= Data_In;
      end if;
    end if;



  end process;


end dpmem_v3;



-------------------------------------------------------------------------------
1