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


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 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;
    
    component logic is
        port(
            a      : in  integer;
            b      : in  integer;
            result : out integer
        );
    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 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');
    
    -- Сигналы для преобразования в integer
    signal a_int : integer := 0;
    signal b_int : integer := 0;
    
    -- ============================================================
    -- РЕЗУЛЬТАТЫ УМНОЖЕНИЙ
    -- ============================================================
    signal dsp_result_vec : std_logic_vector(15 downto 0);
    signal dsp_result_int : integer := 0;
    signal logic_result   : integer := 0;
    
    -- Регистр результата
    signal result_reg : integer := 0;
    signal trigger_reg : std_logic := '0';
    
begin
    -- =============================================
    -- 1. ПРЕОБРАЗОВАНИЕ ДЛЯ ЛОГИЧЕСКОГО УМНОЖЕНИЯ
    -- =============================================
    a_int <= to_integer(unsigned(a_reg));
    b_int <= to_integer(unsigned(b_reg));
    
    -- =============================================
    -- 2. ГЕНЕРАТОР SEL (0 -> 1 -> 0 -> 1 ...)
    -- =============================================
    process(clk)
        type state_type is (S0, S1);
        variable state : state_type := S0;
        variable counter : integer := 0;
        constant DIVIDER : integer := 50000000;  -- 1 Гц при 50 МГц
    begin
        if rising_edge(clk) then
            if counter = DIVIDER - 1 then
                counter := 0;
                case state is
                    when S0 =>
                        sel <= '0';
                        state := S1;
                    when S1 =>
                        sel <= '1';
                        state := S0;
                end case;
            else
                counter := counter + 1;
            end if;
        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;  -- ← 0 или A
            b_reg <= mux_b_out;  -- ← 0 или B
        end if;
    end process;
    
    -- =============================================
    -- 5. DSP УМНОЖЕНИЕ (mult_5)
    --    НА ВХОД ПРИХОДИТ a_reg И b_reg (0 или числа)
    -- =============================================
    mult_inst: mult_5
        port map(
            dataa  => a_reg,   -- ← 0 или A
            datab  => b_reg,   -- ← 0 или B
            result => dsp_result_vec
        );
    
    dsp_result_int <= to_integer(unsigned(dsp_result_vec));
    
    -- =============================================
    -- 6. ЛОГИЧЕСКОЕ УМНОЖЕНИЕ (logic)
    --    НА ВХОД ПРИХОДИТ a_int И b_int (0 или числа)
    -- =============================================
    logic_inst: logic
        port map(
            a      => a_int,   -- ← 0 или A
            b      => b_int,   -- ← 0 или B
            result => logic_result
        );
    
    -- =============================================
    -- 7. ОБРАБОТКА КНОПОК (выбор режима)
    -- =============================================
    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;
    
    -- =============================================
    -- 8. РЕГИСТР РЕЗУЛЬТАТА (выбор режима)
    -- =============================================
    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;
    
    -- =============================================
    -- 9. ВЫХОДЫ
    -- =============================================
    result  <= result_reg;
    trigger <= trigger_reg;
    
end rtl;