Загрузка данных


library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
 
entity calculator_top is
    port
    (
        clk   : in std_logic;
        key   : in std_logic_vector(3 downto 0);  -- key(0)=logic, key(1)=dsp
        dig   : out std_logic_vector(3 downto 0);
        seg   : out std_logic_vector(7 downto 0)
    );
end entity;
 
architecture struct of calculator_top is
    signal calc_result  : integer := 0;
    signal calc_trigger : std_logic := '0';
    signal display_result : integer := 0;
    
    signal c0, c1, c2, c3 : std_logic_vector(7 downto 0);
    
    component calc_mod is
        port(
            clk     : in std_logic;
            key     : in std_logic_vector(1 downto 0);
            result  : out integer;
            trigger : out std_logic
        );
    end component;
    
    component display_mux is
        port(
            clk   : in std_logic;
            reset : in std_logic;
            dig   : out std_logic_vector(3 downto 0);
            seg   : out std_logic_vector(7 downto 0);
            dig0  : in std_logic_vector(7 downto 0);
            dig1  : in std_logic_vector(7 downto 0);
            dig2  : in std_logic_vector(7 downto 0);
            dig3  : in std_logic_vector(7 downto 0)
        );
    end component;
    
    -- Функция декодирования числа в 7-сегментный код
    function num_to_seg(num : integer) return std_logic_vector is
    begin
        case num is
            when 0 => return "11000000";
            when 1 => return "11111001";
            when 2 => return "10100100";
            when 3 => return "10110000";
            when 4 => return "10011001";
            when 5 => return "10010010";
            when 6 => return "10000010";
            when 7 => return "11111000";
            when 8 => return "10000000";
            when 9 => return "10010000";
            when -1 => return "10111111";  -- Минус
            when others => return "11111111";
        end case;
    end function;
    
begin
    -- =============================================
    -- 1. КАЛЬКУЛЯТОР (основная логика)
    -- =============================================
    calc_inst: calc_mod
        port map(
            clk     => clk,
            key     => key(1 downto 0),
            result  => calc_result,
            trigger => calc_trigger
        );
    
    -- =============================================
    -- 2. ФИКСАЦИЯ РЕЗУЛЬТАТА ДЛЯ ДИСПЛЕЯ
    -- =============================================
    process(clk)
    begin
        if rising_edge(clk) then
            if calc_trigger = '1' then
                display_result <= calc_result;
            end if;
        end if;
    end process;
    
    -- =============================================
    -- 3. ДЕКОДИРОВАНИЕ НА 7-СЕГМЕНТНЫЙ ИНДИКАТОР
    -- =============================================
    process(display_result)
        variable tens, ones : integer;
    begin
        if display_result >= 0 and display_result <= 99 then
            tens := display_result / 10;
            ones := display_result mod 10;
            c3 <= num_to_seg(tens);
            c2 <= num_to_seg(ones);
            c1 <= "11111111";  -- Гасим неиспользуемые
            c0 <= "11111111";
        elsif display_result = -1 then
            c3 <= "10111111";  -- Минус
            c2 <= "11000000";  -- 0
            c1 <= "11111111";
            c0 <= "11111111";
        else
            c3 <= "11111111";
            c2 <= "11111111";
            c1 <= "11111111";
            c0 <= "11111111";
        end if;
    end process;
    
    -- =============================================
    -- 4. ДИНАМИЧЕСКАЯ ИНДИКАЦИЯ
    -- =============================================
    display_inst: display_mux
        port map(
            clk   => clk,
            reset => '0',
            seg   => seg,
            dig   => dig,
            dig0  => c0,
            dig1  => c1,
            dig2  => c2,
            dig3  => c3
        );
        
end struct;