----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 06/28/2021 04:30:23 PM
-- Design Name:
-- Module Name: constants - Behavioral
-- Project Name:
-- Target Devices:
-- Tool Versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------


library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

--==============================================================================
--! Entity declaration for constants
--==============================================================================
entity constants is
    generic (
        g_phyaddr           : integer := 9;
        g_config_vector     : integer := 0;
        g_config_valid      : integer := 0;
        g_signal_detect     : integer := 1
    );
    port (
        pl_clk_i            : in std_logic;
        --! Vector indicating status. We need bits 0 and 1 of the vector
        status_vector       : in std_logic_vector(15 downto 0);
        --! Management clock, (<= 2.5MHz)
        mdc_i               : in std_logic;
          mdc_clk_led       : out std_logic;
        --! Reset of the module, coming from PS
        pl_resetn_i         : in std_logic;
        reset_o             : out std_logic;
        --! Autoneg
        an_config_o         : out std_logic;
        an_config_vec_o     : out std_logic_vector(15 downto 0);
        tx_disable_o        : out std_logic;
        --! EMIO GPIOs
        p_pres_i            : in  std_logic_vector(1 downto 0);
        pwr_cycle_req_o     : out std_logic;
        bckpl_servmod_i     : in  std_logic_vector(7 downto 0);
        bckpl_servmod_o     : out std_logic_vector(7 downto 0);
        bckpl_servmod_t_o   : out std_logic_vector(7 downto 0);
        bckpl_rst_n_o       : out std_logic;
        psu_alert_i         : in  std_logic;
        f_rst_i             : in  std_logic;
        f_rst_o             : out std_logic;
        f_rst_t_o           : out std_logic;
        ps_emio_o           : out std_logic_vector(15 downto 0);
        ps_emio_i           : in  std_logic_vector(15 downto 0);
        ps_emio_t_i         : in  std_logic_vector(15 downto 0);
        --! I2C busses
        wrflash_i2c_irq_i  : in std_logic;
        bckpl_i2c_irq_i    : in std_logic;
        ps_irq_o           : out std_logic_vector(1 downto 0);
        --! Constants module
        --! Addr of the PHY device(slave). A constant number
        phyaddr                 : out std_logic_vector(4 downto 0);
        configuration_vector    : out std_logic_vector(4 downto 0);
        configuration_valid     : out std_logic_vector(0 downto 0);
        --!'1' (if not connected to an optical module), otherwise, default is '0'
        signal_detect           : out std_logic_vector(0 downto 0);
        --! Slices module
        link_status_led         : out std_logic;
        link_sync_led           : out std_logic;
        clk_src_sel_o           : out std_logic_vector(1 downto 0)
    );
end constants;

--==============================================================================
--! Architecture declaration
--==============================================================================
architecture Behavioral of constants is

    --! Because we want to check if mdc_i<=2.5MHz, cnt must be up to 4096
    signal s_cnt       : unsigned(11 downto 0);
    signal s_mdc_led_o : std_logic;
    type t_pwr_state is (IDLE, RST);
    signal pwr_state : t_pwr_state;
    signal ps_emio2_d0 : std_logic;
    signal ps_emio2_p  : std_logic;

--==============================================================================
--! Architecture begin
--==============================================================================
begin

    an_config_o <= '0';
    an_config_vec_o <= x"D801";
    tx_disable_o <= '0';

    phyaddr <= std_logic_vector(to_unsigned(g_phyaddr, phyaddr'length));
    configuration_vector <= std_logic_vector(to_unsigned(g_config_vector, configuration_vector'length));
    configuration_valid <= std_logic_vector(to_unsigned(g_config_valid, configuration_valid'length));
    signal_detect <= std_logic_vector(to_unsigned(g_signal_detect, signal_detect'length));

    reset_o <= '1' when (pl_resetn_i = '0') else '0';

    link_status_led <= status_vector(0);
    link_sync_led   <= status_vector(1);
    clk_src_sel_o   <= "11";

    p_calc_mdc: process(mdc_i, pl_resetn_i)
    begin
        if (pl_resetn_i = '0') then
            s_cnt <= (others=>'0');
            s_mdc_led_o <= '0';
        elsif (rising_edge(mdc_i)) then
            if (s_cnt = 4096-2) then
                s_cnt     <= (others=>'0');
                s_mdc_led_o <= '1';
            else
                s_mdc_led_o <= '0';
                s_cnt <= s_cnt + 1;
            end if;
        end if;
    end process p_calc_mdc;

    mdc_clk_led <= s_mdc_led_o;

    --! EMIO -> PL GPIO
    ps_emio_o(4 downto 0) <= p_pres_i(1 downto 0) & "000";
    ps_emio2_p <= '1' when (ps_emio2_d0 = '0' and ps_emio_i(2) = '1') else '0';

    p_pwr: process(pl_clk_i)
    begin
        if rising_edge(pl_clk_i) then
            ps_emio2_d0 <= ps_emio_i(2);
            if pl_resetn_i = '0' or (ps_emio2_p = '1' and ps_emio_i(1) = '1') then
                pwr_state <= IDLE;
                pwr_cycle_req_o <= '0';
            else
                if pwr_state = IDLE then
                    pwr_cycle_req_o <= '0';
                    if ps_emio2_p = '1' and ps_emio_i(1) = '0' then
                        pwr_state <= RST;
                    end if;
                elsif pwr_state = RST then
                    pwr_cycle_req_o <= '1';
                end if;
            end if;
        end if;
    end process p_pwr;

    --! EMIO 83..90
    ps_emio_o(12 downto 5) <= bckpl_servmod_i(7 downto 0);
    bckpl_servmod_o(7 downto 0) <= ps_emio_i(12 downto 5);
    bckpl_servmod_t_o(7 downto 0) <= ps_emio_t_i(12 downto 5);

    --! EMIO 91
    ps_emio_o(13) <= ps_emio_i(13);
    bckpl_rst_n_o <= ps_emio_i(13);

    --! EMIO 92
    ps_emio_o(14) <= psu_alert_i;

    --! EMIO 93
    ps_emio_o(15) <= f_rst_i;
    f_rst_o <= ps_emio_i(15);
    f_rst_t_o <= ps_emio_t_i(15);

    --! I2C irqs
    ps_irq_o(1 downto 0) <= bckpl_i2c_irq_i & wrflash_i2c_irq_i;

end Behavioral;
--==============================================================================
-- architecture end
--==============================================================================
