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


library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity calculator is
    port(
        clk     : in  std_logic;
        key     : in  std_logic_vector(1 downto 0);
        result  : out integer;
        trigger : out std_logic
    );
end calculator;

architecture rtl of calculator is
    -- Константы для умножения
    constant A_VAL : integer := 4;
    constant B_VAL : integer := 2;
    
    -- Компоненты
    component logic is
        port(
            a      : in  integer;
            b      : in  integer;
            result : out integer
        );
    end component;
    
    component mult_5 is
        port(
            dataa  : in  std_logic_vector(7 downto 0);
            datab  : in  std_logic_vector(7 downto 0);
            result : out std_logic_vector(15 downto 0)
        );
    end component;
    
    -- Сигналы для синхронизации кнопок
    signal key_reg  : std_logic_vector(1 downto 0) := (others => '1');
    signal key_prev : std_logic_vector(1 downto 0) := (others => '1');
    signal mode     : std_logic := '0';  -- 0=logic, 1=dsp
    
    -- Сигналы для умножения
    signal logic_result : integer := 0;
    signal dsp_result_int : integer := 0;
    signal dsp_result_vector : std_logic_vector(15 downto 0);
    signal dsp_a : std_logic_vector(7 downto 0);
    signal dsp_b : std_logic_vector(7 downto 0);
    
    -- Сигнал управления мультиплексорами (sel)
    signal sel : std_logic := '0';
    
    -- Входные мультиплексоры (выбор 0 или число)
    signal mux_a_out : std_logic_vector(7 downto 0);
    signal mux_b_out : std_logic_vector(7 downto 0);
    
    -- Триггеры для A и B (фиксация на 1 такт)
    signal a_reg : std_logic_vector(7 downto 0) := (others => '0');
    signal b_reg : std_logic_vector(7 downto 0) := (others => '0');
    
    -- Регистр результата
    signal result_reg : integer := 0;
    signal trigger_reg : std_logic := '0';
    
begin
    -- =============================================
    -- 1. ЛОГИЧЕСКОЕ УМНОЖЕНИЕ (отдельный модуль)
    -- =============================================
    logic_inst: logic
        port map(
            a      => A_VAL,
            b      => B_VAL,
            result => logic_result
        );
    
    -- =============================================
    -- 2. DSP УМНОЖЕНИЕ (mult_5)
    -- =============================================
    dsp_a <= std_logic_vector(to_unsigned(A_VAL, 8));
    dsp_b <= std_logic_vector(to_unsigned(B_VAL, 8));
    
    mult_inst: mult_5
        port map(
            dataa  => dsp_a,
            datab  => dsp_b,
            result => dsp_result_vector
        );
    
    dsp_result_int <= to_integer(unsigned(dsp_result_vector));
    
    -- =============================================
    -- 3. ГЕНЕРАТОР SEL (0 -> 1 -> 0 -> 1 ...)
    -- =============================================
    process(clk)
        type state_type is (S0, S1);
        variable state : state_type := S0;
    begin
        if rising_edge(clk) then
            case state is
                when S0 =>
                    sel <= '0';
                    state := S1;
                when S1 =>
                    sel <= '1';
                    state := S0;
            end case;
        end if;
    end process;
    
    -- =============================================
    -- 4. ВХОДНЫЕ МУЛЬТИПЛЕКСОРЫ
    --    sel=0: подаём 0 на вход умножителя
    --    sel=1: подаём A и B
    -- =============================================
    mux_a_out <= std_logic_vector(to_unsigned(A_VAL, 8)) when sel = '1' else (others => '0');
    mux_b_out <= std_logic_vector(to_unsigned(B_VAL, 8)) when sel = '1' else (others => '0');
    
    -- =============================================
    -- 5. ТРИГГЕРЫ ДЛЯ A И B (фиксация на 1 такт)
    -- =============================================
    process(clk)
    begin
        if rising_edge(clk) then
            a_reg <= mux_a_out;
            b_reg <= mux_b_out;
        end if;
    end process;
    
    -- =============================================
    -- 6. ОБРАБОТКА КНОПОК (выбор режима)
    -- =============================================
    process(clk)
    begin
        if rising_edge(clk) then
            key_reg <= key;
            key_prev <= key_reg;
            
            -- Переключение режима по нажатию
            if key_prev(0) = '1' and key_reg(0) = '0' then
                mode <= '0';  -- Логическое умножение
            elsif key_prev(1) = '1' and key_reg(1) = '0' then
                mode <= '1';  -- DSP умножение
            end if;
        end if;
    end process;
    
    -- =============================================
    -- 7. РЕГИСТР РЕЗУЛЬТАТА
    -- =============================================
    process(clk)
    begin
        if rising_edge(clk) then
            -- Выбор результата в зависимости от режима
            if mode = '0' then
                result_reg <= logic_result;  -- Логическое умножение
            else
                result_reg <= dsp_result_int;  -- DSP умножение
            end if;
            
            trigger_reg <= '1';  -- Результат всегда готов
        end if;
    end process;
    
    -- =============================================
    -- 8. ВЫХОДЫ
    -- =============================================
    result  <= result_reg;
    trigger <= trigger_reg;
    
end rtl;