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


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;

    -- Сигнал переключения: '0' = захват нулей, '1' = захват A и B
    signal sel : std_logic := '0';

    -- Регистры для хранения текущих значений на входах умножителей
    signal a_reg : std_logic_vector(7 downto 0) := (others => '0');
    signal b_reg : std_logic_vector(7 downto 0) := (others => '0');

    -- Выходы умножителей
    signal dsp_result_vec : std_logic_vector(15 downto 0);
    signal logic_result   : integer;

    -- Преобразованный результат DSP
    signal dsp_result_int : integer;

    -- Режим (кнопка)
    signal mode : std_logic := '0';  -- '0' = logic, '1' = dsp

    -- Регистр результата
    signal result_reg : integer := 0;
    signal trigger_reg : std_logic := '0';

    -- Дребезг кнопок
    signal key_r0, key_r1 : std_logic_vector(1 downto 0) := (others => '1');

begin

    ---------------------------------------------------------------
    -- Переключение sel каждый такт
    ---------------------------------------------------------------
    process(clk)
    begin
        if rising_edge(clk) then
            sel <= not sel;  -- каждый такт меняется: 0 -> 1 -> 0 -> 1 ...
        end if;
    end process;

    ---------------------------------------------------------------
    -- Мультиплексоры для a_reg и b_reg
    -- sel='1' => константы A,B
    -- sel='0' => нули
    ---------------------------------------------------------------
    process(clk)
    begin
        if rising_edge(clk) then
            if sel = '1' then
                a_reg <= std_logic_vector(to_unsigned(A_VAL, 8));
                b_reg <= std_logic_vector(to_unsigned(B_VAL, 8));
            else
                a_reg <= (others => '0');
                b_reg <= (others => '0');
            end if;
        end if;
    end process;

    ---------------------------------------------------------------
    -- Умножители (работают постоянно)
    ---------------------------------------------------------------
    mult_inst: mult_5
        port map(
            dataa  => a_reg,
            datab  => b_reg,
            result => dsp_result_vec
        );

    dsp_result_int <= to_integer(unsigned(dsp_result_vec));

    logic_inst: logic
        port map(
            a      => to_integer(unsigned(a_reg)),
            b      => to_integer(unsigned(b_reg)),
            result => logic_result
        );

    ---------------------------------------------------------------
    -- Обработка кнопок выбора режима
    ---------------------------------------------------------------
    process(clk)
    begin
        if rising_edge(clk) then
            key_r0 <= key;
            key_r1 <= key_r0;

            if key_r1(0) = '1' and key_r0(0) = '0' then
                mode <= '0';  -- логическое умножение
            elsif key_r1(1) = '1' and key_r0(1) = '0' then
                mode <= '1';  -- DSP умножение
            end if;
        end if;
    end process;

    ---------------------------------------------------------------
    -- Выходной регистр (обновляется каждый такт)
    ---------------------------------------------------------------
    process(clk)
    begin
        if rising_edge(clk) then
            if mode = '0' then
                result_reg <= logic_result;
            else
                result_reg <= dsp_result_int;
            end if;
            trigger_reg <= '1';
        end if;
    end process;

    result  <= result_reg;
    trigger <= trigger_reg;

end rtl;