library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity ram_top is port ( CLOCK_50 : in std_logic; KEY : in std_logic_vector(3 downto 0); -- KEY3 не используется, KEY2/1/0 SW : in std_logic_vector(0 downto 0); -- SW0: write enable HEX7 : out std_logic_vector(6 downto 0); -- адрес: старший разряд (десятичный) HEX6 : out std_logic_vector(6 downto 0); -- адрес: младший разряд (десятичный) HEX5 : out std_logic_vector(6 downto 0); -- данные: старший nibble (hex) HEX4 : out std_logic_vector(6 downto 0); -- данные: младший nibble (hex) HEX3 : out std_logic_vector(6 downto 0); -- чтение: старший nibble (hex) HEX2 : out std_logic_vector(6 downto 0) -- чтение: младший nibble (hex) ); end ram_top; architecture behavior of ram_top is -- Компонент RAM (библиотечный модуль) component ram_module port ( clock : in std_logic; wren : in std_logic; address : in std_logic_vector(4 downto 0); data : in std_logic_vector(7 downto 0); q : out std_logic_vector(7 downto 0) ); end component; -- Счетчики signal addr_counter : unsigned(4 downto 0) := (others => '0'); -- адрес 0-31 signal data_counter : unsigned(7 downto 0) := (others => '0'); -- данные 0-255 signal ram_data_in : std_logic_vector(7 downto 0); -- вход RAM signal ram_data_out : std_logic_vector(7 downto 0); -- выход RAM signal ram_wren : std_logic; -- разрешение записи -- Синхронизация кнопок signal key_sync1 : std_logic_vector(1 downto 0); -- KEY1 (data+) signal key_sync2 : std_logic_vector(1 downto 0); -- KEY2 (addr+) signal key_sync0 : std_logic_vector(1 downto 0); -- KEY0 (clock) -- Обнаружение нажатий signal key1_press : std_logic; -- data increment signal key2_press : std_logic; -- addr increment signal key0_press : std_logic; -- RAM clock pulse begin -- Синхронизация кнопок process(CLOCK_50) begin if rising_edge(CLOCK_50) then key_sync1 <= key_sync1(0) & KEY(1); key_sync2 <= key_sync2(0) & KEY(2); key_sync0 <= key_sync0(0) & KEY(0); end if; end process; -- Детекция нажатий (спадний фронт) key1_press <= '1' when key_sync1(1) = '1' and key_sync1(0) = '0' else '0'; key2_press <= '1' when key_sync2(1) = '1' and key_sync2(0) = '0' else '0'; key0_press <= '1' when key_sync0(1) = '1' and key_sync0(0) = '0' else '0'; -- Счетчики адреса и данных process(CLOCK_50) begin if rising_edge(CLOCK_50) then if key2_press = '1' then addr_counter <= addr_counter + 1; -- адрес 0->1->...->31->0 end if; if key1_press = '1' then data_counter <= data_counter + 1; -- данные 0->1->...->255->0 end if; end if; end process; -- Подготовка данных для RAM ram_data_in <= std_logic_vector(data_counter); ram_wren <= SW(0) and key0_press; -- запись только при SW0=1 И KEY0 -- RAM модуль ram_inst : ram_module port map ( clock => CLOCK_50, wren => ram_wren, address => std_logic_vector(addr_counter), data => ram_data_in, q => ram_data_out ); -- ОТображение АДРЕСА в ДЕСЯТИЧНОМ виде (HEX7+HEX6) -- addr_counter[4:0] -> десятки + единицы (0-31) process(addr_counter) variable tens, units : unsigned(3 downto 0); begin tens := addr_counter / 10; -- десятки (0-3) units := addr_counter mod 10; -- единицы (0-9) -- HEX7: десятки (0-3) case tens is when "0000" => HEX7 <= "1000000"; -- 0 when "0001" => HEX7 <= "1111001"; -- 1 when "0010" => HEX7 <= "0100100"; -- 2 when "0011" => HEX7 <= "0110000"; -- 3 when others => HEX7 <= "1111111"; end case; -- HEX6: единицы (0-9) case units is when "0000" => HEX6 <= "1000000"; -- 0 when "0001" => HEX6 <= "1111001"; -- 1 when "0010" => HEX6 <= "0100100"; -- 2 when "0011" => HEX6 <= "0110000"; -- 3 when "0100" => HEX6 <= "0011001"; -- 4 when "0101" => HEX6 <= "0010010"; -- 5 when "0110" => HEX6 <= "0000010"; -- 6 when "0111" => HEX6 <= "1111000"; -- 7 when "1000" => HEX6 <= "0000000"; -- 8 when "1001" => HEX6 <= "0010000"; -- 9 when others => HEX6 <= "1111111"; end case; end process; -- ОТображение ДАННЫХ ВВОДА в HEX (HEX5+HEX4) process(data_counter) begin -- HEX5: старший nibble (0-F) case data_counter(7 downto 4) 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 "1010" => HEX5 <= "0001000"; -- A when "1011" => HEX5 <= "0000011"; -- b when "1100" => HEX5 <= "1000110"; -- C when "1101" => HEX5 <= "0100001"; -- d when "1110" => HEX5 <= "0000110"; -- E when "1111" => HEX5 <= "0001111"; -- F when others => HEX5 <= "1111111"; end case; -- HEX4: младший nibble (0-F) case data_counter(3 downto 0) is when "0000" => HEX4 <= "1000000"; -- 0 when "0001" => HEX4 <= "1111001"; -- 1 when "0010" => HEX4 <= "0100100"; -- 2 when "0011" => HEX4 <= "0110000"; -- 3 when "0100" => HEX4 <= "0011001"; -- 4 when "0101" => HEX4 <= "0010010"; -- 5 when "0110" => HEX4 <= "0000010"; -- 6 when "0111" => HEX4 <= "1111000"; -- 7 when "1000" => HEX4 <= "0000000"; -- 8 when "1001" => HEX4 <= "0010000"; -- 9 when "1010" => HEX4 <= "0001000"; -- A when "1011" => HEX4 <= "0000011"; -- b when "1100" => HEX4 <= "1000110"; -- C when "1101" => HEX4 <= "0100001"; -- d when "1110" => HEX4 <= "0000110"; -- E when "1111" => HEX4 <= "0001111"; -- F when others => HEX4 <= "1111111"; end case; end process; -- ОТображение ДАННЫХ ЧТЕНИЯ из RAM в HEX (HEX3+HEX2) process(ram_data_out) begin -- HEX3: старший nibble case ram_data_out(7 downto 4) 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 "1001" => HEX3 <= "0010000"; -- 9 when "1010" => HEX3 <= "0001000"; -- A when "1011" => HEX3 <= "0000011"; -- b when "1100" => HEX3 <= "1000110"; -- C when "1101" => HEX3 <= "0100001"; -- d when "1110" => HEX3 <= "0000110"; -- E when "1111" => HEX3 <= "0001111"; -- F when others => HEX3 <= "1111111"; end case; -- HEX2: младший nibble case ram_data_out(3 downto 0) 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 "1010" => HEX2 <= "0001000"; -- A when "1011" => HEX2 <= "0000011"; -- b when "1100" => HEX2 <= "1000110"; -- C when "1101" => HEX2 <= "0100001"; -- d when "1110" => HEX2 <= "0000110"; -- E when "1111" => HEX2 <= "0001111"; -- F when others => HEX2 <= "1111111"; end case; end process; end behavior;