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


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);  -- 0=logic, 1=dsp
        result  : out integer;
        trigger : out std_logic
    );
end entity;
 
architecture rtl of calculator is
    -- Числа для умножения
    constant A_VAL : integer := 4;
    constant B_VAL : integer := 2;
    
    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
    
    -- =============================================
    -- СИГНАЛ УПРАВЛЕНИЯ МУЛЬТИПЛЕКСОРАМИ (sel)
    -- Формирует последовательность: 0 -> 1 -> 0
    -- =============================================
    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 mult_out : std_logic_vector(15 downto 0);
    signal mult_int : integer := 0;
    
    -- =============================================
    -- ТРИГГЕР РЕЗУЛЬТАТА
    -- =============================================
    signal result_reg : integer := 0;
    signal trigger_reg : std_logic := '0';
    
    -- =============================================
    -- ЛОГИЧЕСКОЕ УМНОЖЕНИЕ (быстрое)
    -- =============================================
    signal logic_result : integer := 0;
    
begin
    -- =============================================
    -- 1. ВЫБОР РЕЖИМА ПО КНОПКАМ
    --    Кнопка 0 = логическое умножение
    --    Кнопка 1 = DSP умножение
    -- =============================================
    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;
    
    -- =============================================
    -- 2. ГЕНЕРАТОР СИГНАЛА SEL
    --    Формирует: 0 -> 1 -> 0 -> 1 -> 0 ...
    -- =============================================
    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';  -- На входе 0
                    state := S1;
                when S1 =>
                    sel <= '1';  -- На входе A и B
                    state := S0;
            end case;
        end if;
    end process;
    
    -- =============================================
    -- 3. ВХОДНЫЕ МУЛЬТИПЛЕКСОРЫ
    --    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');
    
    -- =============================================
    -- 4. ТРИГГЕРЫ ДЛЯ 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;
    
    -- =============================================
    -- 5. УМНОЖИТЕЛЬ (комбинаторный)
    -- =============================================
    mult_inst: mult_5 port map(
        dataa  => a_reg,
        datab  => b_reg,
        result => mult_out
    );
    
    mult_int <= to_integer(unsigned(mult_out));
    
    -- =============================================
    -- 6. ЛОГИЧЕСКОЕ УМНОЖЕНИЕ (для сравнения)
    -- =============================================
    logic_result <= A_VAL * B_VAL;
    
    -- =============================================
    -- 7. ТРИГГЕР РЕЗУЛЬТАТА
    --    Сохраняет результат в зависимости от режима
    -- =============================================
    process(clk)
    begin
        if rising_edge(clk) then
            if mode = '0' then
                -- Логическое умножение (быстрое)
                result_reg <= logic_result;
            else
                -- DSP умножение (через умножитель)
                result_reg <= mult_int;
            end if;
            
            trigger_reg <= '1';  -- Результат всегда готов
        end if;
    end process;
    
    -- =============================================
    -- 8. ВЫХОДЫ
    -- =============================================
    result  <= result_reg;
    trigger <= trigger_reg;
    
end rtl;