-- ********************************************************************/
-- Actel Corporation Proprietary and Confidential
-- Copyright 2010 Actel Corporation.  All rights reserved.
--
-- ANY USE OR REDISTRIBUTION IN PART OR IN WHOLE MUST BE HANDLED IN
-- ACCORDANCE WITH THE ACTEL LICENSE AGREEMENT AND MUST BE APPROVED
-- IN ADVANCE IN WRITING.
--
-- Description:	CoreAHBLite address decode logic
--				for master 0 and master 1
--
-- Revision Information:
-- Date			Description
-- ----			-----------------------------------------
-- 10Feb10		Production Release Version 3.1
--
-- SVN Revision Information:
-- SVN $Revision: 11955 $
-- SVN $Date: 2010-01-30 15:35:13 -0800 (Sat, 30 Jan 2010) $
--
-- Resolved SARs
-- SAR      Date     Who   Description
--
-- Notes:
-- 1. best viewed with tabstops set to "4" (tabs used throughout file)
--
-- *********************************************************************/
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity COREAHBLITE_ADDRDEC is
    generic (
        MODE_CFG         : integer range 0 to 1 := 0;
        M_AHBSLOTENABLE  : integer range 0 to (2**17)-1 := (2**17)-1;
        M_INITCFGENABLE  : integer range 0 to (2**16)-1 := 0
    );
    port (
        ADDR             : in std_logic_vector(31 downto 0);
        REMAP            : in std_logic;
        ADDRDEC          : out std_logic_vector(16 downto 0);
        CLIENTDEC        : out std_logic_vector(15 downto 0);
        ABSOLUTEADDR     : out std_logic_vector(31 downto 0);
        RESERVEDDEC      : out std_logic
    );
end entity COREAHBLITE_ADDRDEC;

architecture COREAHBLITE_ADDRDEC_arch of COREAHBLITE_ADDRDEC is

constant SLAVE_0      : std_logic_vector(15 downto 0) := "0000000000000001";
constant SLAVE_1      : std_logic_vector(15 downto 0) := "0000000000000010";
constant SLAVE_2      : std_logic_vector(15 downto 0) := "0000000000000100";
constant SLAVE_3      : std_logic_vector(15 downto 0) := "0000000000001000";
constant SLAVE_4      : std_logic_vector(15 downto 0) := "0000000000010000";
constant SLAVE_5      : std_logic_vector(15 downto 0) := "0000000000100000";
constant SLAVE_6      : std_logic_vector(15 downto 0) := "0000000001000000";
constant SLAVE_7      : std_logic_vector(15 downto 0) := "0000000010000000";
constant SLAVE_8      : std_logic_vector(15 downto 0) := "0000000100000000";
constant SLAVE_9      : std_logic_vector(15 downto 0) := "0000001000000000";
constant SLAVE_10     : std_logic_vector(15 downto 0) := "0000010000000000";
constant SLAVE_11     : std_logic_vector(15 downto 0) := "0000100000000000";
constant SLAVE_12     : std_logic_vector(15 downto 0) := "0001000000000000";
constant SLAVE_13     : std_logic_vector(15 downto 0) := "0010000000000000";
constant SLAVE_14     : std_logic_vector(15 downto 0) := "0100000000000000";
constant SLAVE_15     : std_logic_vector(15 downto 0) := "1000000000000000";

constant CLIENT_0     : std_logic_vector(15 downto 0) := "0000000000000001";
constant CLIENT_1     : std_logic_vector(15 downto 0) := "0000000000000010";
constant CLIENT_2     : std_logic_vector(15 downto 0) := "0000000000000100";
constant CLIENT_3     : std_logic_vector(15 downto 0) := "0000000000001000";
constant CLIENT_4     : std_logic_vector(15 downto 0) := "0000000000010000";
constant CLIENT_5     : std_logic_vector(15 downto 0) := "0000000000100000";
constant CLIENT_6     : std_logic_vector(15 downto 0) := "0000000001000000";
constant CLIENT_7     : std_logic_vector(15 downto 0) := "0000000010000000";
constant CLIENT_8     : std_logic_vector(15 downto 0) := "0000000100000000";
constant CLIENT_9     : std_logic_vector(15 downto 0) := "0000001000000000";
constant CLIENT_10    : std_logic_vector(15 downto 0) := "0000010000000000";
constant CLIENT_11    : std_logic_vector(15 downto 0) := "0000100000000000";
constant CLIENT_12    : std_logic_vector(15 downto 0) := "0001000000000000";
constant CLIENT_13    : std_logic_vector(15 downto 0) := "0010000000000000";
constant CLIENT_14    : std_logic_vector(15 downto 0) := "0100000000000000";
constant CLIENT_15    : std_logic_vector(15 downto 0) := "1000000000000000";

constant NONE         : std_logic_vector(15 downto 0) := "0000000000000000";

signal sdec         : std_logic_vector(15 downto 0);
signal cdec         : std_logic_vector(15 downto 0);
signal hdec         : std_logic;
signal absaddr      : std_logic_vector(31 downto 0);
signal ADDRDEC_pre  : std_logic_vector(16 downto 0);

begin
    xhdl0 : if (MODE_CFG = 0) generate
        signal m0_slotdec   : std_logic_vector(3 downto 0);
    begin
        m0_slotdec <= ADDR(31 downto 28);
        process (ADDR, m0_slotdec, REMAP)
        begin
            absaddr(31 downto 0) <= ADDR(31 downto 0);
            cdec(15 downto 0) <= NONE;
            hdec <= '0';
            case m0_slotdec is
                when "0000" =>
                    if (REMAP = '0') then
                        sdec(15 downto 0) <= SLAVE_0;
                    else
                        absaddr(28) <= '1';
                        sdec(15 downto 0) <= SLAVE_1;
                    end if;
                when "0001" =>
                    if (REMAP = '0') then
                        sdec(15 downto 0) <= SLAVE_1;
                    else
                        absaddr(28) <= '0';
                        sdec(15 downto 0) <= SLAVE_0;
                    end if;
                when "0010" => sdec(15 downto 0) <= SLAVE_2;
                when "0011" => sdec(15 downto 0) <= SLAVE_3;
                when "0100" => sdec(15 downto 0) <= SLAVE_4;
                when "0101" => sdec(15 downto 0) <= SLAVE_5;
                when "0110" => sdec(15 downto 0) <= SLAVE_6;
                when "0111" => sdec(15 downto 0) <= SLAVE_7;
                when "1000" => sdec(15 downto 0) <= SLAVE_8;
                when "1001" => sdec(15 downto 0) <= SLAVE_9;
                when "1010" => sdec(15 downto 0) <= SLAVE_10;
                when "1011" => sdec(15 downto 0) <= SLAVE_11;
                when "1100" => sdec(15 downto 0) <= SLAVE_12;
                when "1101" => sdec(15 downto 0) <= SLAVE_13;
                when "1110" => sdec(15 downto 0) <= SLAVE_14;
                when others => sdec(15 downto 0) <= SLAVE_15;
            end case;
        end process;
        RESERVEDDEC <= '0';
    end generate;
    xhdl1 : if (not(MODE_CFG = 0)) generate
        xhdl2 : if (MODE_CFG = 1) generate
            signal m1_slotdec       : std_logic_vector(3 downto 0);
            signal m1_hugeslotdec   : std_logic;
            signal m1_otherslotsdec : std_logic;
            signal m1_clientdec     : std_logic_vector(3 downto 0);
        begin
            m1_hugeslotdec   <= '1' when (ADDR(31) = '1') else '0';
            m1_otherslotsdec <= '1' when (ADDR(30 downto 20) = "00000000000") else '0';
            m1_slotdec <= ADDR(19 downto 16);
            m1_clientdec <= ADDR(15 downto 12);
            process (ADDR, m1_hugeslotdec, m1_otherslotsdec, m1_slotdec, REMAP, m1_clientdec)
            begin
                absaddr(31 downto 0) <= ADDR(31 downto 0);
                hdec <= '0';
                cdec(15 downto 0) <= NONE;
                sdec(15 downto 0) <= NONE;
                if (m1_hugeslotdec = '1') then
                    hdec <= '1';
                elsif (m1_otherslotsdec = '1') then
                    case m1_slotdec is
                        when "0000" =>
                            if (REMAP = '0') then
                                sdec(15 downto 0) <= SLAVE_0;
                            else
                                absaddr(16) <= '1';
                                sdec(15 downto 0) <= SLAVE_1;
                            end if;
                        when "0001" =>
                            if (REMAP = '0') then
                                sdec(15 downto 0) <= SLAVE_1;
                            else
                                absaddr(16) <= '0';
                                sdec(15 downto 0) <= SLAVE_0;
                            end if;
                        when "0010" => sdec(15 downto 0) <= SLAVE_2;
                        when "0011" => sdec(15 downto 0) <= SLAVE_3;
                        when "0100" =>
                            case m1_clientdec is
                                when "0000" => cdec(15 downto 0) <= CLIENT_0;
                                when "0001" => cdec(15 downto 0) <= CLIENT_1;
                                when "0010" => cdec(15 downto 0) <= CLIENT_2;
                                when "0011" => cdec(15 downto 0) <= CLIENT_3;
                                when "0100" => cdec(15 downto 0) <= CLIENT_4;
                                when "0101" => cdec(15 downto 0) <= CLIENT_5;
                                when "0110" => cdec(15 downto 0) <= CLIENT_6;
                                when "0111" => cdec(15 downto 0) <= CLIENT_7;
                                when "1000" => cdec(15 downto 0) <= CLIENT_8;
                                when "1001" => cdec(15 downto 0) <= CLIENT_9;
                                when "1010" => cdec(15 downto 0) <= CLIENT_10;
                                when "1011" => cdec(15 downto 0) <= CLIENT_11;
                                when "1100" => cdec(15 downto 0) <= CLIENT_12;
                                when "1101" => cdec(15 downto 0) <= CLIENT_13;
                                when "1110" => cdec(15 downto 0) <= CLIENT_14;
                                when others => cdec(15 downto 0) <= CLIENT_15;
                            end case;
                        when "0101" => sdec(15 downto 0) <= SLAVE_5;
                        when "0110" => sdec(15 downto 0) <= SLAVE_6;
                        when "0111" => sdec(15 downto 0) <= SLAVE_7;
                        when "1000" => sdec(15 downto 0) <= SLAVE_8;
                        when "1001" => sdec(15 downto 0) <= SLAVE_9;
                        when "1010" => sdec(15 downto 0) <= SLAVE_10;
                        when "1011" => sdec(15 downto 0) <= SLAVE_11;
                        when "1100" => sdec(15 downto 0) <= SLAVE_12;
                        when "1101" => sdec(15 downto 0) <= SLAVE_13;
                        when "1110" => sdec(15 downto 0) <= SLAVE_14;
                        when others => sdec(15 downto 0) <= SLAVE_15;
                    end case;
                end if;
            end process;
            RESERVEDDEC <= '1' when m1_hugeslotdec='0' and m1_otherslotsdec='0'
                           else '0';
        end generate;
    end generate;
    ADDRDEC_pre(16 downto 0) <= (hdec & sdec(15 downto 0));
    ABSOLUTEADDR(31 downto 0) <= absaddr(31 downto 0);
    ADDRDEC(16 downto 0) <= ADDRDEC_pre(16 downto 0);
    CLIENTDEC <= cdec(15 downto 0);
    
end architecture COREAHBLITE_ADDRDEC_arch;
