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


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

entity calculator is
port (
    clk      : in std_logic;
    reset    : in std_logic;
    key      : in std_logic_vector(1 downto 0);
    result   : out integer;
    s_a      : out std_logic_vector(7 downto 0);  -- Для Signal Tap
    s_b      : out std_logic_vector(7 downto 0);  -- Для Signal Tap
    s_result : out integer                        -- Для Signal Tap
);
end calculator;

architecture rtl of calculator is
    
    -- Константы
    constant A_VAL : integer := 5;  -- Множитель A (можно менять)
    constant B_VAL : integer := 7;  -- Множитель B (можно менять)
    
    -- Компоненты
    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 mux_a : std_logic_vector(7 downto 0);
    signal mux_b : std_logic_vector(7 downto 0);
    signal reg_a : std_logic_vector(7 downto 0) := (others => '0');
    signal reg_b : std_logic_vector(7 downto 0) := (others => '0');
    
    -- Сигналы результатов
    signal dsp_result_vec : std_logic_vector(15 downto 0);
    signal dsp_result_int : integer;
    signal logic_result   : integer;
    
    -- Сигналы управления
    signal capture_en    : std_logic := '0';
    signal mode          : std_logic := '0';  -- '0' = logic, '1' = DSP
    
    -- Счётчик для управления захватом
    signal counter       : integer range 0 to 50000000 := 0;
    constant DIVIDER     : integer := 50000000;  -- 1 секунда при 50 МГц
    
    -- Состояния конечного автомата
    type state_type is (IDLE, CAPTURE, MULTIPLY, HOLD);
    signal state : state_type := IDLE;
    
begin
    
    -- ========================================
    -- МУЛЬТИПЛЕКСОРЫ (выбор A/0 или B/0)
    -- ========================================
    mux_a <= std_logic_vector(to_unsigned(A_VAL, 8)) when capture_en = '1' else (others => '0');
    mux_b <= std_logic_vector(to_unsigned(B_VAL, 8)) when capture_en = '1' else (others => '0');
    
    -- ========================================
    -- РЕГИСТРЫ (захват значений)
    -- ========================================
    process(clk, reset)
    begin
        if reset = '1' then
            reg_a <= (others => '0');
            reg_b <= (others => '0');
        elsif rising_edge(clk) then
            if capture_en = '1' then
                reg_a <= mux_a;
                reg_b <= mux_b;
            else
                reg_a <= (others => '0');
                reg_b <= (others => '0');
            end if;
        end if;
    end process;
    
    -- ========================================
    -- КОНЕЧНЫЙ АВТОМАТ УПРАВЛЕНИЯ
    -- ========================================
    process(clk, reset)
    begin
        if reset = '1' then
            state <= IDLE;
            counter <= 0;
            capture_en <= '0';
        elsif rising_edge(clk) then
            case state is
                when IDLE =>
                    capture_en <= '0';
                    if counter >= DIVIDER - 1 then
                        counter <= 0;
                        state <= CAPTURE;
                    else
                        counter <= counter + 1;
                    end if;
                
                when CAPTURE =>
                    capture_en <= '1';
                    state <= MULTIPLY;
                
                when MULTIPLY =>
                    capture_en <= '0';
                    state <= HOLD;
                
                when HOLD =>
                    capture_en <= '0';
                    if counter >= DIVIDER - 1 then
                        counter <= 0;
                        state <= CAPTURE;
                    else
                        counter <= counter + 1;
                    end if;
            end case;
        end if;
    end process;
    
    -- ========================================
    -- УМНОЖИТЕЛИ
    -- ========================================
    
    -- DSP умножитель (mult_5)
    mult_inst: mult_5
    port map (
        dataa  => reg_a,
        datab  => reg_b,
        result => dsp_result_vec
    );
    
    dsp_result_int <= to_integer(unsigned(dsp_result_vec));
    
    -- Логический умножитель (logic)
    logic_inst: logic
    port map (
        a      => to_integer(unsigned(reg_a)),
        b      => to_integer(unsigned(reg_b)),
        result => logic_result
    );
    
    -- ========================================
    -- ВЫБОР РЕЖИМА ПО КНОПКЕ
    -- ========================================
    process(clk, reset)
    begin
        if reset = '1' then
            mode <= '0';
        elsif rising_edge(clk) then
            if key(1) = '0' then  -- Кнопка 1 переключает режим
                mode <= not mode;
            end if;
        end if;
    end process;
    
    -- ========================================
    -- ВЫХОДНЫЕ СИГНАЛЫ
    -- ========================================
    s_a <= reg_a;      -- Для просмотра в Signal Tap
    s_b <= reg_b;      -- Для просмотра в Signal Tap
    
    result <= logic_result when mode = '0' else dsp_result_int;
    s_result <= logic_result when mode = '0' else dsp_result_int;
    
end rtl;

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

entity calculator_top is
port (
    clk   : in std_logic;
    reset : in std_logic;
    key   : in std_logic_vector(1 downto 0);
    led   : out std_logic_vector(7 downto 0)  -- Простой вывод для теста
);
end calculator_top;

architecture struct of calculator_top is
    
    component calculator is
    port (
        clk      : in std_logic;
        reset    : in std_logic;
        key      : in std_logic_vector(1 downto 0);
        result   : out integer;
        s_a      : out std_logic_vector(7 downto 0);
        s_b      : out std_logic_vector(7 downto 0);
        s_result : out integer
    );
    end component;
    
    signal result_int : integer;
    signal s_a, s_b   : std_logic_vector(7 downto 0);
    signal s_result   : integer;
    
begin
    
    calc_inst: calculator
    port map (
        clk      => clk,
        reset    => reset,
        key      => key,
        result   => result_int,
        s_a      => s_a,
        s_b      => s_b,
        s_result => s_result
    );
    
    -- Вывод младшего байта результата на светодиоды
    led <= std_logic_vector(to_unsigned(result_int mod 256, 8));
    
end struct;