-- top_modul.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity top_modul is
    Port ( CLK : in STD_LOGIC;
           RST : in STD_LOGIC;
           START : in STD_LOGIC;
           SW_MODE  : in  STD_LOGIC; -- '0' = HH:MM, '1' = MM:SS
           SW_DIN   : in STD_LOGIC_VECTOR (3 downto 0); -- Value to set
           BTN_LOAD : in STD_LOGIC_VECTOR (3 downto 0); -- Which digit to set
           SEGMENTS : out STD_LOGIC_VECTOR (7 downto 0);
           ANODS : out STD_LOGIC_VECTOR (3 downto 0));
end top_modul;

architecture Behavioral of top_modul is
    component divider is
        Port ( CLK : in STD_LOGIC;
               RST : in STD_LOGIC;
               CLK_1_Hz : out STD_LOGIC); -- Enable pulse
    end component;
    
    component divider_400Hz is
        Port ( CLK : in STD_LOGIC;
               RST : in STD_LOGIC;
               CLK_400_Hz : out STD_LOGIC); -- Enable pulse
    end component;
    
    signal clk_1_Hz   : std_logic;
    signal clk_400_Hz : std_logic;
    signal s_ce_units   : std_logic;
    
    -- You MUST declare these signals so top_modul can carry data between the two submodules
    signal sig_s_units, sig_s_tens : std_logic_vector(3 downto 0);
    signal sig_m_units, sig_m_tens : std_logic_vector(3 downto 0);
    signal sig_h_units, sig_h_tens : std_logic_vector(3 downto 0);
    
    -- Signals to send to the display
    signal d0, d1, d2, d3 : std_logic_vector(3 downto 0);

begin

    U_DIV_1HZ : divider
        port map (
            CLK => CLK,
            RST => RST,
            CLK_1_Hz => clk_1_Hz
        );
        
    U_DIV_REFRESH : divider_400Hz
        port map (
            CLK => CLK, 
            RST => RST, 
            CLK_400_Hz => clk_400_Hz
        );

    s_ce_units <= clk_1_Hz and START;

    -- Clock Engine submodule
    U_CLOCK_CORE : entity work.clock_logic
        port map (
            CLK      => CLK,
            RST      => RST,
            CE_1HZ   => s_ce_units,
            SW_DIN   => SW_DIN,
            BTN_LOAD => BTN_LOAD,
            S_UNITS  => sig_s_units,
            S_TENS   => sig_s_tens,
            M_UNITS  => sig_m_units,
            M_TENS   => sig_m_tens,
            H_UNITS  => sig_h_units,
            H_TENS   => sig_h_tens
        );

    -- Mode Multiplexing
    -- If SW_MODE = '1', show MM:SS. If '0', show HH:MM.
    d0 <= sig_s_units when SW_MODE = '1' else sig_m_units;
    d1 <= sig_s_tens  when SW_MODE = '1' else sig_m_tens;
    d2 <= sig_m_units when SW_MODE = '1' else sig_h_units;
    d3 <= sig_m_tens  when SW_MODE = '1' else sig_h_tens;
    
    U_DISPLAY : entity work.display_driver
        port map (
            CLK         => clk_400_Hz,
            RST         => RST,
            DIGIT_0     => d0,
            DIGIT_1     => d1,
            DIGIT_2     => d2,
            DIGIT_3     => d3,
            SEGMENTS    => SEGMENTS,
            ANODES      => ANODS
        );    
end Behavioral;
