-- clock_logic.vhd library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity clock_logic is Port ( CLK : in STD_LOGIC; RST : in STD_LOGIC; CE_1HZ : in STD_LOGIC; -- Enable signal from the divider DIGIT_SEL: in STD_LOGIC_VECTOR (3 downto 0); -- '0001'=M_UNITS, '0010'=M_TENS, atd. BTN_INC : in STD_LOGIC; -- drzanie tlacidla pre inkrement -- Outputs to the top module/display S_UNITS : out STD_LOGIC_VECTOR (3 downto 0); S_TENS : out STD_LOGIC_VECTOR (3 downto 0); M_UNITS : out STD_LOGIC_VECTOR (3 downto 0); M_TENS : out STD_LOGIC_VECTOR (3 downto 0); H_UNITS : out STD_LOGIC_VECTOR (3 downto 0); H_TENS : out STD_LOGIC_VECTOR (3 downto 0) ); end clock_logic; architecture Behavioral of clock_logic is -- TODO CHECK AGAINST COUNTER.VHD IF NEEDED component counter is Generic ( MAX_LIMIT : STD_LOGIC_VECTOR(3 downto 0) := "1001" ); -- Default to 9 Port ( CLK : in STD_LOGIC; CE : in STD_LOGIC; PE : in STD_LOGIC; DIN : in STD_LOGIC_VECTOR(3 downto 0); RST : in STD_LOGIC; TC : out STD_LOGIC; COUNT_OUT : out STD_LOGIC_VECTOR (3 downto 0)); end component; -- Internal signals to connect the counters 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); -- Carry signals (TC) signal tc_su, tc_st, tc_mu, tc_mt, tc_hu : std_logic; -- Reset for hours (to handle the 24 reset) signal hour_reset : std_logic; signal inc_m_units : std_logic; signal inc_m_tens : std_logic; signal inc_h_units : std_logic; signal inc_h_tens : std_logic; begin inc_m_units <= BTN_INC and DIGIT_SEL(0); inc_m_tens <= BTN_INC and DIGIT_SEL(1); inc_h_units <= BTN_INC and DIGIT_SEL(2); inc_h_tens <= BTN_INC and DIGIT_SEL(3); ------------------------------------------------------- -- SECONDS SECTION -- SECONDS UNITS (0-9) - Triggered by the 1Hz pulse U_CNT_SEC_UNITS : counter generic map ( MAX_LIMIT => "1001" ) -- do 9 port map ( CLK => CLK, RST => RST, CE => CE_1HZ, PE => '0', DIN => "0000", -- Seconds usually don't need manual load TC => tc_su, COUNT_OUT => sig_s_units ); -- SECONDS TENS (0-5) - Triggered when Sec Units reach 9 U_CNT_SEC_TENS : counter generic map ( MAX_LIMIT => "0101" ) -- do 5 port map ( CLK => CLK, RST => RST, CE => tc_su, PE => '0', DIN => "0000", TC => tc_st, COUNT_OUT => sig_s_tens ); ------------------------------------------------------- -- MINUTES SECTION -- MINUTES UNITS (0-9) - When Seconds reach 59 U_CNT_MIN_UNITS : counter generic map ( MAX_LIMIT => "1001" ) -- do 9 port map ( CLK => CLK, RST => RST, CE => tc_st, PE => inc_m_units, -- for M_UNITS (bit 0) DIN => "0001", TC => tc_mu, COUNT_OUT => sig_m_units ); -- MINUTES TENS (0-5) U_CNT_MIN_TENS : counter generic map ( MAX_LIMIT => "0101" ) -- do 5 port map ( CLK => CLK, RST => RST, CE => tc_mu, PE => inc_m_tens, DIN => "0010", TC => tc_mt, COUNT_OUT => sig_m_tens ); ------------------------------------------------------- -- HOURS SECTION -- If we are at 23:59:59, the next tick should reset hours process(sig_h_tens, sig_h_units, tc_mt, RST) begin if RST = '1' then hour_reset <= '1'; -- TICK: If clock is at 23:59:59 and the minutes tick over elsif (sig_h_tens = "0010" and sig_h_units = "0011" and tc_mt = '1') then hour_reset <= '1'; -- LOAD PROTECTION: If current value is 24:XX or higher -- This part works even if tc_mt is '0' (for the alarm) elsif (sig_h_tens = "0010" and sig_h_units >= "0100") then hour_reset <= '1'; elsif (sig_h_tens > "0010") then hour_reset <= '1'; else hour_reset <= '0'; end if; end process; -- HOURS UNITS (0-9) U_CNT_HOR_UNITS : counter generic map ( MAX_LIMIT => "1001" ) -- To 9 port map ( CLK => CLK, RST => hour_reset, CE => tc_mt, PE => inc_h_units, DIN => "0100", TC => tc_hu, COUNT_OUT => sig_h_units ); -- HOURS TENS (0-2) U_CNT_HOR_TENS : counter generic map ( MAX_LIMIT => "0010" ) -- To 2 port map ( CLK => CLK, RST => hour_reset, CE => tc_hu, PE => inc_h_tens, DIN => "1000", TC => open, COUNT_OUT => sig_h_tens ); -- Drive output ports 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; end Behavioral;