library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity seg is port( clk_50MHz_i : in std_logic; reset_i : in std_logic; x0_i : in std_logic_vector(3 downto 0); x1_i : in std_logic_vector(3 downto 0); x2_i : in std_logic_vector(3 downto 0); x3_i : in std_logic_vector(3 downto 0); seg_o : out std_logic_vector(6 downto 0); dp_o : out std_logic; an_o : out std_logic_vector(3 downto 0) ); end seg; architecture Behavioral of seg is -- States of the system type states is (AN0, AN1, AN2, AN3); signal state : states := AN0; -- Counter used to divide the entry clock (could use the clock_gen entity for this) signal counter : unsigned(15 downto 0) := (others => '0'); -- Arrays used to translate the input hexadecimal to segments type array4x4 is array(0 to 3) of std_logic_vector(3 downto 0); signal number : array4x4 := (others => (others => '0')); type array4x7 is array(0 to 3) of std_logic_vector(6 downto 0); signal segments : array4x7 := (others => (others => '0')); begin -- Always hide the point dp_o <= '1'; -- Convert the numbers to segments number(0) <= x0_i; number(1) <= x1_i; number(2) <= x2_i; number(3) <= x3_i; translate_loop: for I in 0 to 3 generate begin with number(I) select segments(I) <= "1000000" when "0000", -- 0 "1111001" when "0001", -- 1 "0100100" when "0010", -- 2 "0110000" when "0011", -- 3 "0011001" when "0100", -- 4 "0010010" when "0101", -- 5 "0000010" when "0110", -- 6 "1111000" when "0111", -- 7 "0000000" when "1000", -- 8 "0010000" when "1001", -- 9 "0001000" when "1010", -- A "0000011" when "1011", -- B "1000110" when "1100", -- C "0100001" when "1101", -- D "0000110" when "1110", -- E "0001110" when "1111", -- F "1111111" when others; end generate; -- Change states process(clk_50MHz_i) begin if (rising_edge(clk_50MHz_i)) then -- Reset if (reset_i = '1') then -- Reset the counter counter <= (others => '0'); else -- Act every 1 ms if (counter = 50_000) then -- Reset the counter counter <= (others => '0'); -- Change the state case state is when AN0 => state <= AN1; when AN1 => state <= AN2; when AN2 => state <= AN3; when AN3 => state <= AN0; when others => state <= AN0; end case; else counter <= counter + 1; end if; end if; end if; end process; -- Action on states process(clk_50MHz_i) begin if (rising_edge(clk_50MHz_i)) then if (reset_i = '1') then -- Disable all characters on reset an_o <= "1111"; seg_o <= (others => '1'); else -- For each state, set the anode signal and give the correct value to the cathodes case state is when AN0 => an_o <= "1110"; seg_o <= segments(0); when AN1 => an_o <= "1101"; seg_o <= segments(1); when AN2 => an_o <= "1011"; seg_o <= segments(2); when AN3 => an_o <= "0111"; seg_o <= segments(3); when others => an_o <= "1111"; seg_o <= (others => '1'); end case; end if; end if; end process; end Behavioral;