-------------------------------------------------------------------------------
--
-- 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, technology_lib;
USE IEEE.STD_LOGIC_1164.ALL;
USE technology_lib.technology_pkg.ALL;

PACKAGE tech_flash_component_pkg IS

  -----------------------------------------------------------------------------
  -- ip_stratixiv
  -----------------------------------------------------------------------------
  
  COMPONENT ip_stratixiv_asmi_parallel IS
  GENERIC (
    g_sim_flash_model : BOOLEAN := FALSE
  );
  PORT (
    addr          : IN STD_LOGIC_VECTOR (23 DOWNTO 0);
    clkin         : IN STD_LOGIC ;
    datain        : IN STD_LOGIC_VECTOR (7 DOWNTO 0);
    rden          : IN STD_LOGIC ;
    read          : IN STD_LOGIC ;
    sector_erase  : IN STD_LOGIC ;
    shift_bytes   : IN STD_LOGIC ;
    wren          : IN STD_LOGIC ;
    write         : IN STD_LOGIC ;
    busy          : OUT STD_LOGIC ;
    data_valid    : OUT STD_LOGIC ;
    dataout       : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
    illegal_erase : OUT STD_LOGIC ;
    illegal_write : OUT STD_LOGIC 
  );
  END COMPONENT;
  
  COMPONENT ip_stratixiv_remote_update IS
  PORT (
    clock       : IN STD_LOGIC ;
    data_in     : IN STD_LOGIC_VECTOR (23 DOWNTO 0);
    param       : IN STD_LOGIC_VECTOR (2 DOWNTO 0);
    read_param  : IN STD_LOGIC ;
    reconfig    : IN STD_LOGIC ;
    reset       : IN STD_LOGIC ;
    reset_timer : IN STD_LOGIC ;
    write_param : IN STD_LOGIC ;
    busy        : OUT STD_LOGIC ;
    data_out    : OUT STD_LOGIC_VECTOR (23 DOWNTO 0)
  );
  END COMPONENT;

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

  component ip_arria10_asmi_parallel is
  port (
    addr          : in  std_logic_vector(31 downto 0);
    clkin         : in  std_logic;
    datain        : in  std_logic_vector(7 downto 0); 
    rden          : in  std_logic;
    read          : in  std_logic;
    sector_erase  : in  std_logic;
    shift_bytes   : in  std_logic;
    wren          : in  std_logic;
    write         : in  std_logic;
    busy          : out std_logic;
    data_valid    : out std_logic;
    dataout       : out std_logic_vector(7 downto 0);
    illegal_erase : out std_logic;
    illegal_write : out std_logic;
    reset         : in  std_logic; 
    sce           : in  std_logic_vector(2 downto 0);
    en4b_addr     : in  std_logic
  );
  end component ip_arria10_asmi_parallel;

  -- note the EPCQ-L1024 device appears not to be supported yet.
  -- the EPCA-512 was chosen instead

  component ip_arria10_remote_update is
  port (
    clock       : in  std_logic;
    data_in     : in  std_logic_vector(31 downto 0);
    param       : in  std_logic_vector(2 downto 0);
    read_param  : in  std_logic;
    reconfig    : in  std_logic;
    reset       : in  std_logic; 
    reset_timer : in  std_logic; 
    write_param : in  std_logic; 
    busy        : out std_logic; 
    data_out    : out std_logic_vector(31 downto 0)
  );
  end component ip_arria10_remote_update;


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

  component ip_arria10_e3sge3_asmi_parallel is
  port (
    addr          : in  std_logic_vector(31 downto 0);
    clkin         : in  std_logic;
    datain        : in  std_logic_vector(7 downto 0); 
    rden          : in  std_logic;
    read          : in  std_logic;
    sector_erase  : in  std_logic;
    shift_bytes   : in  std_logic;
    wren          : in  std_logic;
    write         : in  std_logic;
    busy          : out std_logic;
    data_valid    : out std_logic;
    dataout       : out std_logic_vector(7 downto 0);
    illegal_erase : out std_logic;
    illegal_write : out std_logic;
    reset         : in  std_logic; 
    sce           : in  std_logic_vector(2 downto 0);
    en4b_addr     : in  std_logic
  );
  end component ip_arria10_e3sge3_asmi_parallel;

  -- note the EPCQ-L1024 device appears not to be supported yet.
  -- the EPCA-512 was chosen instead

  component ip_arria10_e3sge3_remote_update is
  port (
    clock       : in  std_logic;
    data_in     : in  std_logic_vector(31 downto 0);
    param       : in  std_logic_vector(2 downto 0);
    read_param  : in  std_logic;
    reconfig    : in  std_logic;
    reset       : in  std_logic; 
    reset_timer : in  std_logic; 
    write_param : in  std_logic; 
    busy        : out std_logic; 
    data_out    : out std_logic_vector(31 downto 0)
  );
  end component ip_arria10_e3sge3_remote_update;

  function tech_flash_addr_w( technology: in integer ) return integer;
  function tech_flash_data_w( technology: in integer ) return integer;

END tech_flash_component_pkg;

package body tech_flash_component_pkg is

  function tech_flash_addr_w( technology : in integer )  return integer is 
  begin
    if technology = c_tech_stratixiv then
        return 24;
    end if;
    if technology = c_tech_arria10 then
        return 32;
    end if;		  
    if technology = c_tech_arria10_e3sge3 then
        return 32;
    end if;		  
  end;

  function tech_flash_data_w( technology : in integer )  return integer is 
  begin
    if technology = c_tech_stratixiv then
        return 24;
    end if;
    if technology = c_tech_arria10 then
        return 32;
    end if;		  
    if technology = c_tech_arria10_e3sge3 then
        return 32;
    end if;		  
  end;


END tech_flash_component_pkg;