--------------------------------------------------------------------------------- -- Bcd_Counter: -- Clk_50MHz for synchronous design -- Reset for synchronous reset -- Enable will be useful for counting up/down -- Btn will be debounced and edge-detected before it used for counting -- upDOWN=0 => count up, upDOWN=1 => count down -- TCO will be 1 to indicate that the next counter should be active -- Bcd will be the actual value between 0 and 9 ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; entity Bcd_Counter is Port ( Clk_50MHz : in STD_LOGIC; Reset : in STD_LOGIC; Enable : in STD_LOGIC; Btn : in STD_LOGIC; upDOWN : in STD_LOGIC; TCO : out STD_LOGIC; Bcd : out STD_LOGIC_VECTOR (3 downto 0)); end Bcd_Counter; architecture Behavioral of Bcd_Counter is Signal Internal_Clk: STD_LOGIC; Signal Q : STD_LOGIC_VECTOR (3 downto 0) := "0000"; begin Bcd <= Q; Debouncher: process( Clk_50MHz) variable Scale: STD_LOGIC_VECTOR (15 downto 0) := (others=>'0'); variable Old_Btn: STD_LOGIC := '0'; begin if rising_edge( Clk_50MHz) then Internal_Clk <= '0'; -- Important, default value '0' if Scale(15)='1' then -- after 0.5 msek approx. Scale(15) :='0'; -- Scale = "0000000000000000" Internal_Clk <= not Old_Btn and Btn; --Rising edge @ Btn => '1' Old_Btn := Btn; -- Remember the value of Btn end if; Scale := Scale+1; -------------- Scale up count end if; end process; Bcd_Counter: process( Clk_50MHz) begin if rising_edge( Clk_50MHz) then if Reset='1' then Q <= "0000"; elsif Internal_clk='1' or Enable='1' then if upDOWN='0' then --------------------- Count up -------------- if Q<9 then Q <= Q+1; else Q <= "0000"; end if; else ----------------------------------- Count down ------------ if Q>0 then Q <= Q-1; else Q <= "1001"; end if; end if; end if; end if; end process; ------------------------------------------- Concurrent - Combinatorial code TCO <= '1' when (Internal_clk='1' or Enable='1') and ((Q=9 and upDOWN='0')or(Q=0 and upDOWN='1')) else '0'; end Behavioral;