library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity top_level is port ( CLOCK_50 : in std_logic; -- системный clock KEY : in std_logic_vector(3 downto 0); -- кнопки KEY3-KEY0 HEX7 : out std_logic_vector(6 downto 0); -- 1-е число (0-9) HEX5 : out std_logic_vector(6 downto 0); -- 2-е число (0-9) HEX3 : out std_logic_vector(6 downto 0); -- старший разряд результата (0-8) HEX2 : out std_logic_vector(6 downto 0) -- младший разряд результата (0-9) ); end top_level; architecture behavior of top_level is -- Компонент LPM_MULT (библиотечный модуль) component LPM_MULT_0 port ( dataa : in std_logic_vector(3 downto 0); datab : in std_logic_vector(3 downto 0); result : out std_logic_vector(7 downto 0) ); end component; -- Сигналы для счетчиков (0-9) signal counter1 : unsigned(3 downto 0) := (others => '0'); -- первое число (KEY3+, KEY2-) signal counter2 : unsigned(3 downto 0) := (others => '0'); -- второе число (KEY1+, KEY0-) signal product : std_logic_vector(7 downto 0); -- результат умножения (0-81) signal prod_tens : unsigned(3 downto 0); -- десятки результата (0-8) signal prod_units : unsigned(3 downto 0); -- единицы результата (0-9) -- Сигналы синхронизации кнопок signal key_sync1 : std_logic_vector(1 downto 0); signal key_sync2 : std_logic_vector(1 downto 0); signal key_sync3 : std_logic_vector(1 downto 0); signal key_sync4 : std_logic_vector(1 downto 0); -- Сигналы для обнаружения нажатий кнопок (спадний фронт) signal key1_press : std_logic; signal key2_press : std_logic; signal key3_press : std_logic; signal key4_press : std_logic; begin -- Синхронизация кнопок (debouncing) process(CLOCK_50) begin if rising_edge(CLOCK_50) then key_sync1 <= key_sync1(0) & KEY(0); -- KEY0 key_sync2 <= key_sync2(0) & KEY(1); -- KEY1 key_sync3 <= key_sync3(0) & KEY(2); -- KEY2 key_sync4 <= key_sync4(0) & KEY(3); -- KEY3 end if; end process; -- Обнаружение нажатий кнопок (спадний фронт) key1_press <= '1' when key_sync2(1) = '1' and key_sync2(0) = '0' else '0'; -- KEY1+ key2_press <= '1' when key_sync3(1) = '1' and key_sync3(0) = '0' else '0'; -- KEY2- key3_press <= '1' when key_sync4(1) = '1' and key_sync4(0) = '0' else '0'; -- KEY3+ key4_press <= '1' when key_sync1(1) = '1' and key_sync1(0) = '0' else '0'; -- KEY0- -- Логика счетчиков process(CLOCK_50) begin if rising_edge(CLOCK_50) then if key3_press = '1' then -- KEY3: увеличение первого числа if counter1 < 9 then counter1 <= counter1 + 1; end if; elsif key2_press = '1' then -- KEY2: уменьшение первого числа if counter1 > 0 then counter1 <= counter1 - 1; end if; end if; if key1_press = '1' then -- KEY1: увеличение второго числа if counter2 < 9 then counter2 <= counter2 + 1; end if; elsif key4_press = '1' then -- KEY0: уменьшение второго числа if counter2 > 0 then counter2 <= counter2 - 1; end if; end if; end if; end process; -- Модуль умножения LPM_MULT mult_inst : LPM_MULT_0 port map ( dataa => std_logic_vector(counter1), datab => std_logic_vector(counter2), result => product ); -- Разделение результата на десятки и единицы prod_tens <= unsigned(product(7 downto 4)); -- старший разряд (0-8) prod_units <= unsigned(product(3 downto 0)); -- младший разряд (0-9) -- Декодер 7-сегментного индикатора для HEX7 (первое число 0-9) process(counter1) begin case counter1 is when "0000" => HEX7 <= "1000000"; -- 0 when "0001" => HEX7 <= "1111001"; -- 1 when "0010" => HEX7 <= "0100100"; -- 2 when "0011" => HEX7 <= "0110000"; -- 3 when "0100" => HEX7 <= "0011001"; -- 4 when "0101" => HEX7 <= "0010010"; -- 5 when "0110" => HEX7 <= "0000010"; -- 6 when "0111" => HEX7 <= "1111000"; -- 7 when "1000" => HEX7 <= "0000000"; -- 8 when "1001" => HEX7 <= "0010000"; -- 9 when others => HEX7 <= "1111111"; -- выкл end case; end process; -- Декодер 7-сегментного индикатора для HEX5 (второе число 0-9) process(counter2) begin case counter2 is when "0000" => HEX5 <= "1000000"; -- 0 when "0001" => HEX5 <= "1111001"; -- 1 when "0010" => HEX5 <= "0100100"; -- 2 when "0011" => HEX5 <= "0110000"; -- 3 when "0100" => HEX5 <= "0011001"; -- 4 when "0101" => HEX5 <= "0010010"; -- 5 when "0110" => HEX5 <= "0000010"; -- 6 when "0111" => HEX5 <= "1111000"; -- 7 when "1000" => HEX5 <= "0000000"; -- 8 when "1001" => HEX5 <= "0010000"; -- 9 when others => HEX5 <= "1111111"; -- выкл end case; end process; -- Декодер 7-сегментного индикатора для HEX3 (десятки результата 0-8) process(prod_tens) begin case prod_tens is when "0000" => HEX3 <= "1000000"; -- 0 when "0001" => HEX3 <= "1111001"; -- 1 when "0010" => HEX3 <= "0100100"; -- 2 when "0011" => HEX3 <= "0110000"; -- 3 when "0100" => HEX3 <= "0011001"; -- 4 when "0101" => HEX3 <= "0010010"; -- 5 when "0110" => HEX3 <= "0000010"; -- 6 when "0111" => HEX3 <= "1111000"; -- 7 when "1000" => HEX3 <= "0000000"; -- 8 when others => HEX3 <= "1111111"; -- выкл end case; end process; -- Декодер 7-сегментного индикатора для HEX2 (единицы результата 0-9) process(prod_units) begin case prod_units is when "0000" => HEX2 <= "1000000"; -- 0 when "0001" => HEX2 <= "1111001"; -- 1 when "0010" => HEX2 <= "0100100"; -- 2 when "0011" => HEX2 <= "0110000"; -- 3 when "0100" => HEX2 <= "0011001"; -- 4 when "0101" => HEX2 <= "0010010"; -- 5 when "0110" => HEX2 <= "0000010"; -- 6 when "0111" => HEX2 <= "1111000"; -- 7 when "1000" => HEX2 <= "0000000"; -- 8 when "1001" => HEX2 <= "0010000"; -- 9 when others => HEX2 <= "1111111"; -- выкл end case; end process; end behavior;