-------------------------------------------------------------------------------
--
-- Copyright (C) 2014
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program 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 General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
--
-------------------------------------------------------------------------------

-- Purpose: IP components declarations for various devices that get wrapped by the tech components

library IEEE;
use IEEE.std_logic_1164.all;

package tech_memory_component_pkg is

  -----------------------------------------------------------------------------
  -- ip_stratixiv
  -----------------------------------------------------------------------------

  component ip_stratixiv_ram_crwk_crw is  -- support different port data widths and corresponding address ranges
  generic (
    g_adr_a_w     : natural := 5;
    g_dat_a_w     : natural := 32;
    g_adr_b_w     : natural := 7;
    g_dat_b_w     : natural := 8;
    g_nof_words_a : natural := 2**5;
    g_nof_words_b : natural := 2**7;
    g_rd_latency  : natural := 2;  -- choose 1 or 2
    g_init_file   : string  := "UNUSED"
  );
  port (
    address_a   : in std_logic_vector(g_adr_a_w - 1 downto 0);
    address_b   : in std_logic_vector(g_adr_b_w - 1 downto 0);
    clock_a   : in std_logic  := '1';
    clock_b   : in std_logic;
    data_a    : in std_logic_vector(g_dat_a_w - 1 downto 0);
    data_b    : in std_logic_vector(g_dat_b_w - 1 downto 0);
    enable_a    : in std_logic  := '1';
    enable_b    : in std_logic  := '1';
    rden_a    : in std_logic  := '1';
    rden_b    : in std_logic  := '1';
    wren_a    : in std_logic  := '0';
    wren_b    : in std_logic  := '0';
    q_a   : out std_logic_vector(g_dat_a_w - 1 downto 0);
    q_b   : out std_logic_vector(g_dat_b_w - 1 downto 0)
  );
  end component;

  component ip_stratixiv_ram_crw_crw is
  generic (
    g_adr_w      : natural := 5;
    g_dat_w      : natural := 8;
    g_nof_words  : natural := 2**5;
    g_rd_latency : natural := 2;  -- choose 1 or 2
    g_init_file  : string  := "UNUSED"
  );
  port (
    address_a   : in std_logic_vector(g_adr_w - 1 downto 0);
    address_b   : in std_logic_vector(g_adr_w - 1 downto 0);
    clock_a   : in std_logic  := '1';
    clock_b   : in std_logic;
    data_a    : in std_logic_vector(g_dat_w - 1 downto 0);
    data_b    : in std_logic_vector(g_dat_w - 1 downto 0);
    enable_a    : in std_logic  := '1';
    enable_b    : in std_logic  := '1';
    rden_a    : in std_logic  := '1';
    rden_b    : in std_logic  := '1';
    wren_a    : in std_logic  := '0';
    wren_b    : in std_logic  := '0';
    q_a   : out std_logic_vector(g_dat_w - 1 downto 0);
    q_b   : out std_logic_vector(g_dat_w - 1 downto 0)
  );
  end component;

  component ip_stratixiv_ram_cr_cw is
  generic (
    g_adr_w      : natural := 5;
    g_dat_w      : natural := 8;
    g_nof_words  : natural := 2**5;
    g_rd_latency : natural := 2;  -- choose 1 or 2
    g_init_file  : string  := "UNUSED"
  );
  port (
    data      : in  std_logic_vector(g_dat_w - 1 downto 0);
    rdaddress : in  std_logic_vector(g_adr_w - 1 downto 0);
    rdclock   : in  std_logic;
    rdclocken : in  std_logic  := '1';
    wraddress : in  std_logic_vector(g_adr_w - 1 downto 0);
    wrclock   : in  std_logic  := '1';
    wrclocken : in  std_logic  := '1';
    wren      : in  std_logic  := '0';
    q         : out std_logic_vector(g_dat_w - 1 downto 0)
  );
  end component;

  component ip_stratixiv_ram_r_w is
  generic (
    g_adr_w     : natural := 5;
    g_dat_w     : natural := 8;
    g_nof_words : natural := 2**5;
    g_init_file : string  := "UNUSED"
  );
  port (
    clock       : in std_logic  := '1';
    enable      : in std_logic  := '1';
    data        : in std_logic_vector(g_dat_w - 1 downto 0);
    rdaddress   : in std_logic_vector(g_adr_w - 1 downto 0);
    wraddress   : in std_logic_vector(g_adr_w - 1 downto 0);
    wren        : in std_logic  := '0';
    q           : out std_logic_vector(g_dat_w - 1 downto 0)
  );
  end component;

  component ip_stratixiv_rom_r is
  generic (
    g_adr_w     : natural := 5;
    g_dat_w     : natural := 8;
    g_nof_words : natural := 2**5;
    g_init_file : string  := "UNUSED"
  );
  port (
    address   : in std_logic_vector(g_adr_w - 1 downto 0);
    clock     : in std_logic  := '1';
    clken     : in std_logic  := '1';
    q         : out std_logic_vector(g_dat_w - 1 downto 0)
  );
  end component;


  -----------------------------------------------------------------------------
  -- ip_arria10
  -----------------------------------------------------------------------------

  component ip_arria10_ram_crwk_crw is
  generic (
    g_adr_a_w     : natural := 5;
    g_dat_a_w     : natural := 32;
    g_adr_b_w     : natural := 4;
    g_dat_b_w     : natural := 64;
    g_nof_words_a : natural := 2**5;
    g_nof_words_b : natural := 2**4;
    g_rd_latency  : natural := 1;  -- choose 1 or 2
    g_init_file   : string  := "UNUSED"
  );
  port
  (
    address_a : in std_logic_vector(g_adr_a_w - 1 downto 0);
    address_b : in std_logic_vector(g_adr_b_w - 1 downto 0);
    clk_a     : in std_logic  := '1';
    clk_b     : in std_logic;
    data_a    : in std_logic_vector(g_dat_a_w - 1 downto 0);
    data_b    : in std_logic_vector(g_dat_b_w - 1 downto 0);
    wren_a    : in std_logic  := '0';
    wren_b    : in std_logic  := '0';
    q_a       : out std_logic_vector(g_dat_a_w - 1 downto 0);
    q_b       : out std_logic_vector(g_dat_b_w - 1 downto 0)
  );
  end component;

  component ip_arria10_ram_crw_crw is
  generic (
    g_inferred   : boolean := false;
    g_adr_w      : natural := 5;
    g_dat_w      : natural := 8;
    g_nof_words  : natural := 2**5;
    g_rd_latency : natural := 1;  -- choose 1 or 2
    g_init_file  : string  := "UNUSED"
  );
  port
  (
    address_a : in std_logic_vector(g_adr_w - 1 downto 0);
    address_b : in std_logic_vector(g_adr_w - 1 downto 0);
    clk_a     : in std_logic  := '1';
    clk_b     : in std_logic;
    data_a    : in std_logic_vector(g_dat_w - 1 downto 0);
    data_b    : in std_logic_vector(g_dat_w - 1 downto 0);
    wren_a    : in std_logic  := '0';
    wren_b    : in std_logic  := '0';
    q_a       : out std_logic_vector(g_dat_w - 1 downto 0);
    q_b       : out std_logic_vector(g_dat_w - 1 downto 0)
  );
  end component;

  component ip_arria10_ram_cr_cw is
  generic (
    g_inferred   : boolean := false;
    g_adr_w      : natural := 5;
    g_dat_w      : natural := 8;
    g_nof_words  : natural := 2**5;
    g_rd_latency : natural := 1;  -- choose 1 or 2
    g_init_file  : string  := "UNUSED"
  );
  port
  (
    data      : in  std_logic_vector(g_dat_w - 1 downto 0);
    rdaddress : in  std_logic_vector(g_adr_w - 1 downto 0);
    rdclk     : in  std_logic;
    wraddress : in  std_logic_vector(g_adr_w - 1 downto 0);
    wrclk     : in  std_logic  := '1';
    wren      : in  std_logic  := '0';
    q         : out std_logic_vector(g_dat_w - 1 downto 0)
  );
  end component;

  component ip_arria10_ram_r_w is
  generic (
    g_inferred   : boolean := false;
    g_adr_w      : natural := 5;
    g_dat_w      : natural := 8;
    g_nof_words  : natural := 2**5;
    g_rd_latency : natural := 1;  -- choose 1 or 2
    g_init_file  : string  := "UNUSED"
  );
  port (
    clk         : in std_logic  := '1';
    data        : in std_logic_vector(g_dat_w - 1 downto 0) := (others => '0');
    rdaddress   : in std_logic_vector(g_adr_w - 1 downto 0) := (others => '0');
    wraddress   : in std_logic_vector(g_adr_w - 1 downto 0) := (others => '0');
    wren        : in std_logic  := '0';
    q           : out std_logic_vector(g_dat_w - 1 downto 0)
  );
  end component;

  -----------------------------------------------------------------------------
  -- ip_arria10_e3sge3
  -----------------------------------------------------------------------------

  component ip_arria10_e3sge3_ram_crwk_crw is
  generic (
    g_adr_a_w     : natural := 5;
    g_dat_a_w     : natural := 32;
    g_adr_b_w     : natural := 4;
    g_dat_b_w     : natural := 64;
    g_nof_words_a : natural := 2**5;
    g_nof_words_b : natural := 2**4;
    g_rd_latency  : natural := 1;  -- choose 1 or 2
    g_init_file   : string  := "UNUSED"
  );
  port
  (
    address_a : in std_logic_vector(g_adr_a_w - 1 downto 0);
    address_b : in std_logic_vector(g_adr_b_w - 1 downto 0);
    clk_a     : in std_logic  := '1';
    clk_b     : in std_logic;
    data_a    : in std_logic_vector(g_dat_a_w - 1 downto 0);
    data_b    : in std_logic_vector(g_dat_b_w - 1 downto 0);
    wren_a    : in std_logic  := '0';
    wren_b    : in std_logic  := '0';
    q_a       : out std_logic_vector(g_dat_a_w - 1 downto 0);
    q_b       : out std_logic_vector(g_dat_b_w - 1 downto 0)
  );
  end component;

  component ip_arria10_e3sge3_ram_crw_crw is
  generic (
    g_inferred   : boolean := false;
    g_adr_w      : natural := 5;
    g_dat_w      : natural := 8;
    g_nof_words  : natural := 2**5;
    g_rd_latency : natural := 1;  -- choose 1 or 2
    g_init_file  : string  := "UNUSED"
  );
  port
  (
    address_a : in std_logic_vector(g_adr_w - 1 downto 0);
    address_b : in std_logic_vector(g_adr_w - 1 downto 0);
    clk_a     : in std_logic  := '1';
    clk_b     : in std_logic;
    data_a    : in std_logic_vector(g_dat_w - 1 downto 0);
    data_b    : in std_logic_vector(g_dat_w - 1 downto 0);
    wren_a    : in std_logic  := '0';
    wren_b    : in std_logic  := '0';
    q_a       : out std_logic_vector(g_dat_w - 1 downto 0);
    q_b       : out std_logic_vector(g_dat_w - 1 downto 0)
  );
  end component;

  component ip_arria10_e3sge3_ram_cr_cw is
  generic (
    g_inferred   : boolean := false;
    g_adr_w      : natural := 5;
    g_dat_w      : natural := 8;
    g_nof_words  : natural := 2**5;
    g_rd_latency : natural := 1;  -- choose 1 or 2
    g_init_file  : string  := "UNUSED"
  );
  port
  (
    data      : in  std_logic_vector(g_dat_w - 1 downto 0);
    rdaddress : in  std_logic_vector(g_adr_w - 1 downto 0);
    rdclk     : in  std_logic;
    wraddress : in  std_logic_vector(g_adr_w - 1 downto 0);
    wrclk     : in  std_logic  := '1';
    wren      : in  std_logic  := '0';
    q         : out std_logic_vector(g_dat_w - 1 downto 0)
  );
  end component;

  component ip_arria10_e3sge3_ram_r_w is
  generic (
    g_inferred   : boolean := false;
    g_adr_w      : natural := 5;
    g_dat_w      : natural := 8;
    g_nof_words  : natural := 2**5;
    g_rd_latency : natural := 1;  -- choose 1 or 2
    g_init_file  : string  := "UNUSED"
  );
  port (
    clk         : in std_logic  := '1';
    data        : in std_logic_vector(g_dat_w - 1 downto 0) := (others => '0');
    rdaddress   : in std_logic_vector(g_adr_w - 1 downto 0) := (others => '0');
    wraddress   : in std_logic_vector(g_adr_w - 1 downto 0) := (others => '0');
    wren        : in std_logic  := '0';
    q           : out std_logic_vector(g_dat_w - 1 downto 0)
  );
  end component;

  -----------------------------------------------------------------------------
  -- ip_arria10_e1sg
  -----------------------------------------------------------------------------

  component ip_arria10_e1sg_ram_crwk_crw is
  generic (
    g_adr_a_w     : natural := 5;
    g_dat_a_w     : natural := 32;
    g_adr_b_w     : natural := 4;
    g_dat_b_w     : natural := 64;
    g_nof_words_a : natural := 2**5;
    g_nof_words_b : natural := 2**4;
    g_rd_latency  : natural := 1;  -- choose 1 or 2
    g_init_file   : string  := "UNUSED"
  );
  port
  (
    address_a : in std_logic_vector(g_adr_a_w - 1 downto 0);
    address_b : in std_logic_vector(g_adr_b_w - 1 downto 0);
    clk_a     : in std_logic  := '1';
    clk_b     : in std_logic;
    data_a    : in std_logic_vector(g_dat_a_w - 1 downto 0);
    data_b    : in std_logic_vector(g_dat_b_w - 1 downto 0);
    wren_a    : in std_logic  := '0';
    wren_b    : in std_logic  := '0';
    q_a       : out std_logic_vector(g_dat_a_w - 1 downto 0);
    q_b       : out std_logic_vector(g_dat_b_w - 1 downto 0)
  );
  end component;

  component ip_arria10_e1sg_ram_crw_crw is
  generic (
    g_inferred   : boolean := false;
    g_adr_w      : natural := 5;
    g_dat_w      : natural := 8;
    g_nof_words  : natural := 2**5;
    g_rd_latency : natural := 1;  -- choose 1 or 2
    g_init_file  : string  := "UNUSED"
  );
  port
  (
    address_a : in std_logic_vector(g_adr_w - 1 downto 0);
    address_b : in std_logic_vector(g_adr_w - 1 downto 0);
    clk_a     : in std_logic  := '1';
    clk_b     : in std_logic;
    data_a    : in std_logic_vector(g_dat_w - 1 downto 0);
    data_b    : in std_logic_vector(g_dat_w - 1 downto 0);
    wren_a    : in std_logic  := '0';
    wren_b    : in std_logic  := '0';
    q_a       : out std_logic_vector(g_dat_w - 1 downto 0);
    q_b       : out std_logic_vector(g_dat_w - 1 downto 0)
  );
  end component;

  component ip_arria10_e1sg_ram_cr_cw is
  generic (
    g_inferred   : boolean := false;
    g_adr_w      : natural := 5;
    g_dat_w      : natural := 8;
    g_nof_words  : natural := 2**5;
    g_rd_latency : natural := 1;  -- choose 1 or 2
    g_init_file  : string  := "UNUSED"
  );
  port
  (
    data      : in  std_logic_vector(g_dat_w - 1 downto 0);
    rdaddress : in  std_logic_vector(g_adr_w - 1 downto 0);
    rdclk     : in  std_logic;
    wraddress : in  std_logic_vector(g_adr_w - 1 downto 0);
    wrclk     : in  std_logic  := '1';
    wren      : in  std_logic  := '0';
    q         : out std_logic_vector(g_dat_w - 1 downto 0)
  );
  end component;

  component ip_arria10_e1sg_ram_r_w is
  generic (
    g_inferred   : boolean := false;
    g_adr_w      : natural := 5;
    g_dat_w      : natural := 8;
    g_nof_words  : natural := 2**5;
    g_rd_latency : natural := 1;  -- choose 1 or 2
    g_init_file  : string  := "UNUSED"
  );
  port (
    clk         : in std_logic  := '1';
    data        : in std_logic_vector(g_dat_w - 1 downto 0) := (others => '0');
    rdaddress   : in std_logic_vector(g_adr_w - 1 downto 0) := (others => '0');
    wraddress   : in std_logic_vector(g_adr_w - 1 downto 0) := (others => '0');
    wren        : in std_logic  := '0';
    q           : out std_logic_vector(g_dat_w - 1 downto 0)
  );
  end component;

  -----------------------------------------------------------------------------
  -- ip_arria10_e2sg
  -----------------------------------------------------------------------------

  component ip_arria10_e2sg_ram_crwk_crw is
  generic (
    g_adr_a_w     : natural := 5;
    g_dat_a_w     : natural := 32;
    g_adr_b_w     : natural := 4;
    g_dat_b_w     : natural := 64;
    g_nof_words_a : natural := 2**5;
    g_nof_words_b : natural := 2**4;
    g_rd_latency  : natural := 1;  -- choose 1 or 2
    g_init_file   : string  := "UNUSED"
  );
  port
  (
    address_a : in std_logic_vector(g_adr_a_w - 1 downto 0);
    address_b : in std_logic_vector(g_adr_b_w - 1 downto 0);
    clk_a     : in std_logic  := '1';
    clk_b     : in std_logic;
    data_a    : in std_logic_vector(g_dat_a_w - 1 downto 0);
    data_b    : in std_logic_vector(g_dat_b_w - 1 downto 0);
    wren_a    : in std_logic  := '0';
    wren_b    : in std_logic  := '0';
    q_a       : out std_logic_vector(g_dat_a_w - 1 downto 0);
    q_b       : out std_logic_vector(g_dat_b_w - 1 downto 0)
  );
  end component;

  component ip_arria10_e2sg_ram_crw_crw is
  generic (
    g_inferred   : boolean := false;
    g_adr_w      : natural := 5;
    g_dat_w      : natural := 8;
    g_nof_words  : natural := 2**5;
    g_rd_latency : natural := 1;  -- choose 1 or 2
    g_init_file  : string  := "UNUSED"
  );
  port
  (
    address_a : in std_logic_vector(g_adr_w - 1 downto 0);
    address_b : in std_logic_vector(g_adr_w - 1 downto 0);
    clk_a     : in std_logic  := '1';
    clk_b     : in std_logic;
    data_a    : in std_logic_vector(g_dat_w - 1 downto 0);
    data_b    : in std_logic_vector(g_dat_w - 1 downto 0);
    wren_a    : in std_logic  := '0';
    wren_b    : in std_logic  := '0';
    q_a       : out std_logic_vector(g_dat_w - 1 downto 0);
    q_b       : out std_logic_vector(g_dat_w - 1 downto 0)
  );
  end component;

  component ip_arria10_e2sg_ram_cr_cw is
  generic (
    g_inferred   : boolean := false;
    g_adr_w      : natural := 5;
    g_dat_w      : natural := 8;
    g_nof_words  : natural := 2**5;
    g_rd_latency : natural := 1;  -- choose 1 or 2
    g_init_file  : string  := "UNUSED"
  );
  port
  (
    data      : in  std_logic_vector(g_dat_w - 1 downto 0);
    rdaddress : in  std_logic_vector(g_adr_w - 1 downto 0);
    rdclk     : in  std_logic;
    wraddress : in  std_logic_vector(g_adr_w - 1 downto 0);
    wrclk     : in  std_logic  := '1';
    wren      : in  std_logic  := '0';
    q         : out std_logic_vector(g_dat_w - 1 downto 0)
  );
  end component;

  component ip_arria10_e2sg_ram_r_w is
  generic (
    g_inferred   : boolean := false;
    g_adr_w      : natural := 5;
    g_dat_w      : natural := 8;
    g_nof_words  : natural := 2**5;
    g_rd_latency : natural := 1;  -- choose 1 or 2
    g_init_file  : string  := "UNUSED"
  );
  port (
    clk         : in std_logic  := '1';
    data        : in std_logic_vector(g_dat_w - 1 downto 0) := (others => '0');
    rdaddress   : in std_logic_vector(g_adr_w - 1 downto 0) := (others => '0');
    wraddress   : in std_logic_vector(g_adr_w - 1 downto 0) := (others => '0');
    wren        : in std_logic  := '0';
    q           : out std_logic_vector(g_dat_w - 1 downto 0)
  );
  end component;

  -----------------------------------------------------------------------------
  -- ip_ultrascale
  -----------------------------------------------------------------------------
  component ip_ultrascale_ram_crw_crw is
  generic (
    g_inferred   : boolean := false;
    g_adr_w      : natural := 5;
    g_dat_w      : natural := 8;
    g_nof_words  : natural := 2**5;
    g_rd_latency : natural := 1;  -- choose 1 or 2
    g_init_file  : string  := "none"
  );
  port
  (
    address_a : in std_logic_vector(g_adr_w - 1 downto 0);
    address_b : in std_logic_vector(g_adr_w - 1 downto 0);
    clk_a     : in std_logic  := '1';
    clk_b     : in std_logic;
    data_a    : in std_logic_vector(g_dat_w - 1 downto 0);
    data_b    : in std_logic_vector(g_dat_w - 1 downto 0);
    wren_a    : in std_logic  := '0';
    wren_b    : in std_logic  := '0';
    q_a       : out std_logic_vector(g_dat_w - 1 downto 0);
    q_b       : out std_logic_vector(g_dat_w - 1 downto 0)
  );
  end component;

  component ip_ultrascale_ram_cr_cw is
  generic (
    g_inferred   : boolean := false;
    g_adr_w      : natural := 5;
    g_dat_w      : natural := 8;
    g_nof_words  : natural := 2**5;
    g_rd_latency : natural := 1;  -- choose 1 or 2
    g_init_file  : string  := "none"
  );
  port
  (
    data      : in  std_logic_vector(g_dat_w - 1 downto 0);
    rdaddress : in  std_logic_vector(g_adr_w - 1 downto 0);
    rdclk     : in  std_logic;
    wraddress : in  std_logic_vector(g_adr_w - 1 downto 0);
    wrclk     : in  std_logic  := '1';
    wren      : in  std_logic  := '0';
    q         : out std_logic_vector(g_dat_w - 1 downto 0)
  );
  end component;

end tech_memory_component_pkg;